001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.plugin.java; 018 019import java.util.Arrays; 020 021import org.apache.activemq.broker.Broker; 022import org.apache.activemq.broker.region.policy.PolicyEntry; 023import org.apache.activemq.broker.region.policy.PolicyMap; 024import org.apache.activemq.broker.region.virtual.VirtualDestination; 025import org.apache.activemq.command.ActiveMQDestination; 026import org.apache.activemq.network.DiscoveryNetworkConnector; 027import org.apache.activemq.plugin.AbstractRuntimeConfigurationBroker; 028import org.apache.activemq.plugin.UpdateVirtualDestinationsTask; 029import org.apache.activemq.plugin.util.PolicyEntryUtil; 030import org.apache.activemq.security.AuthorizationBroker; 031import org.apache.activemq.security.AuthorizationMap; 032import org.apache.activemq.security.SimpleAuthenticationBroker; 033import org.apache.activemq.security.SimpleAuthenticationPlugin; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037public class JavaRuntimeConfigurationBroker extends AbstractRuntimeConfigurationBroker { 038 039 /** 040 * @param next 041 */ 042 public JavaRuntimeConfigurationBroker(Broker next) { 043 super(next); 044 } 045 046 public static final Logger LOG = LoggerFactory.getLogger(JavaRuntimeConfigurationBroker.class); 047 048 049 //Virtual Destinations 050 public void setVirtualDestinations(final VirtualDestination[] virtualDestinations) { 051 this.addDestinationWork.add(new UpdateVirtualDestinationsTask(this) { 052 @Override 053 protected VirtualDestination[] getVirtualDestinations() { 054 return virtualDestinations; 055 } 056 }); 057 } 058 059 //New Destinations 060 public void setDestinations(final ActiveMQDestination[] destinations) { 061 for (ActiveMQDestination destination : destinations) { 062 try { 063 if (!containsDestination(destination)) { 064 this.addDestination(this.getBrokerService().getAdminConnectionContext(), destination, true); 065 this.info("Added destination " + destination); 066 } 067 } catch (Exception e) { 068 this.info("Failed to add a new destination for: " + destination, e); 069 } 070 } 071 } 072 073 protected boolean containsDestination(ActiveMQDestination destination) throws Exception { 074 return Arrays.asList(this.getBrokerService().getRegionBroker().getDestinations()).contains(destination); 075 } 076 077 public void addNewDestination(ActiveMQDestination destination) { 078 try { 079 this.addDestination(this.getBrokerService().getAdminConnectionContext(), destination, true); 080 this.info("Added destination " + destination); 081 } catch (Exception e) { 082 this.info("Failed to add a new destination for: " + destination, e); 083 } 084 } 085 086 //Network Connectors 087 public void addNetworkConnector(final DiscoveryNetworkConnector nc) { 088 try { 089 if (!getBrokerService().getNetworkConnectors().contains(nc)) { 090 getBrokerService().addNetworkConnector(nc); 091 nc.start(); 092 info("started new network connector: " + nc); 093 } else { 094 info("skipping network connector add, already exists: " + nc); 095 } 096 } catch (Exception e) { 097 info("Failed to add new networkConnector " + nc, e); 098 } 099 } 100 101 public void updateNetworkConnector(final DiscoveryNetworkConnector nc) { 102 removeNetworkConnector(nc); 103 addNetworkConnector(nc); 104 } 105 106 public void removeNetworkConnector(final DiscoveryNetworkConnector existingCandidate) { 107 if (getBrokerService().removeNetworkConnector(existingCandidate)) { 108 try { 109 existingCandidate.stop(); 110 info("stopped and removed networkConnector: " + existingCandidate); 111 } catch (Exception e) { 112 info("Failed to stop removed network connector: " + existingCandidate); 113 } 114 } 115 } 116 117 //Policy entries 118 public void addNewPolicyEntry(PolicyEntry addition) { 119 PolicyMap existingMap = getBrokerService().getDestinationPolicy(); 120 existingMap.put(addition.getDestination(), addition); 121 applyRetrospectively(addition); 122 info("added policy for: " + addition.getDestination()); 123 } 124 125 126 /** 127 * This method will modify an existing policy entry that matches the destination 128 * set on the PolicyEntry passed in. 129 * 130 * The PolicyEntry reference must already be in the PolicyMap or it won't be updated. 131 * To modify the entry the best way is to look up the existing PolicyEntry from the 132 * PolicyMap, make changes to it, and pass it to this method to apply. 133 * 134 * To create or replace an existing entry (if the destination matches), see 135 * {@link #modifyPolicyEntry(PolicyEntry, boolean) 136 * 137 * 138 * @param existing 139 */ 140 public void modifyPolicyEntry(PolicyEntry existing) { 141 modifyPolicyEntry(existing, false); 142 } 143 144 /** 145 * This method will modify an existing policy entry that matches the destination 146 * set on the PolicyEntry passed in. If createOrReplace is true, a new policy 147 * will be created if it doesn't exist and a policy will be replaced in the PolicyMap, 148 * versus modified, if it is a different reference but the destinations for the Policy match. 149 * 150 * If createOrReplace is false, the policy update will only be applied if 151 * the PolicyEntry reference already exists in the PolicyMap. 152 * 153 * @param existing 154 * @param createIfAbsent 155 */ 156 public void modifyPolicyEntry(PolicyEntry existing, boolean createOrReplace) { 157 PolicyMap existingMap = this.getBrokerService().getDestinationPolicy(); 158 159 //First just look up by the destination type to see if anything matches 160 PolicyEntry existingEntry = PolicyEntryUtil.findEntryByDestination(this, existing); 161 162 //handle createOrReplace 163 if (createOrReplace) { 164 //if not found at all, go ahead and insert the policy entry 165 if (existingEntry == null) { 166 existingMap.put(existing.getDestination(), existing); 167 existingEntry = existing; 168 //If found but the objects are different, remove the old policy entry 169 //and replace it with the new one 170 } else if (!existing.equals(existingEntry)) { 171 synchronized(existingMap) { 172 existingMap.remove(existingEntry.getDestination(), existingEntry); 173 existingMap.put(existing.getDestination(), existing); 174 } 175 existingEntry = existing; 176 } 177 } 178 179 //Make sure that at this point the passed in object and the entry in 180 //the map are the same 181 if (existingEntry != null && existingEntry.equals(existing)) { 182 applyRetrospectively(existingEntry); 183 this.info("updated policy for: " + existingEntry.getDestination()); 184 } else { 185 throw new IllegalArgumentException("The policy can not be updated because it either does not exist or the PolicyEntry" 186 + " reference does not match an existing PolicyEntry in the PolicyMap. To replace an" 187 + " entry (versus modifying) or add, set createOrReplace to true. " 188 + existing + ", destination:" + existing.getDestination()); 189 } 190 } 191 192 protected void applyRetrospectively(PolicyEntry updatedEntry) { 193 PolicyEntryUtil.applyRetrospectively(this, updatedEntry); 194 } 195 196 //authentication plugin 197 public void updateSimpleAuthenticationPlugin(final SimpleAuthenticationPlugin updatedPlugin) { 198 try { 199 final SimpleAuthenticationBroker authenticationBroker = 200 (SimpleAuthenticationBroker) getBrokerService().getBroker().getAdaptor(SimpleAuthenticationBroker.class); 201 addConnectionWork.add(new Runnable() { 202 @Override 203 public void run() { 204 authenticationBroker.setUserGroups(updatedPlugin.getUserGroups()); 205 authenticationBroker.setUserPasswords(updatedPlugin.getUserPasswords()); 206 authenticationBroker.setAnonymousAccessAllowed(updatedPlugin.isAnonymousAccessAllowed()); 207 authenticationBroker.setAnonymousUser(updatedPlugin.getAnonymousUser()); 208 authenticationBroker.setAnonymousGroup(updatedPlugin.getAnonymousGroup()); 209 } 210 }); 211 } catch (Exception e) { 212 info("failed to apply SimpleAuthenticationPlugin modifications to SimpleAuthenticationBroker", e); 213 } 214 } 215 216 //authorization map 217 public void updateAuthorizationMap(final AuthorizationMap authorizationMap) { 218 try { 219 // replace authorization map - need exclusive write lock to total broker 220 AuthorizationBroker authorizationBroker = 221 (AuthorizationBroker) getBrokerService().getBroker().getAdaptor(AuthorizationBroker.class); 222 223 authorizationBroker.setAuthorizationMap(authorizationMap); 224 } catch (Exception e) { 225 info("failed to apply modified AuthorizationMap to AuthorizationBroker", e); 226 } 227 } 228}