Configuration.java
001 /*
002  *
003  * Licensed to the Apache Software Foundation (ASF) under one
004  * or more contributor license agreements.  See the NOTICE file
005  * distributed with this work for additional information
006  * regarding copyright ownership.  The ASF licenses this file
007  * to you under the Apache License, Version 2.0 (the
008  * "License"); you may not use this file except in compliance
009  * with the License.  You may obtain a copy of the License at
010  *
011  *   http://www.apache.org/licenses/LICENSE-2.0
012  *
013  * Unless required by applicable law or agreed to in writing,
014  * software distributed under the License is distributed on an
015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016  * KIND, either express or implied.  See the License for the
017  * specific language governing permissions and limitations
018  * under the License.
019  *
020  */
021 package org.apache.qpid.management.configuration;
022 
023 import java.util.HashMap;
024 import java.util.Map;
025 import java.util.Set;
026 import java.util.UUID;
027 import java.util.Map.Entry;
028 
029 import org.apache.qpid.management.Messages;
030 import org.apache.qpid.management.Names;
031 import org.apache.qpid.management.domain.handler.base.IMessageHandler;
032 import org.apache.qpid.management.domain.model.AccessMode;
033 import org.apache.qpid.management.domain.model.type.Type;
034 import org.apache.qpid.transport.DeliveryProperties;
035 import org.apache.qpid.transport.Header;
036 import org.apache.qpid.transport.MessageProperties;
037 import org.apache.qpid.transport.ReplyTo;
038 import org.apache.qpid.transport.util.Logger;
039 
040 /**
041  * Qpid Management bridge configuration.
042  * Basically iy is a singleton that is holding all the configurtion data loaded at startup.
043  */
044 public final class Configuration
045 {    
046     private final static Logger LOGGER = Logger.get(Configuration.class);
047     private static Configuration INSTANCE = new Configuration();
048     
049     // Work Manager default settings
050     private int _poolSize = 5;
051     private int _maxPoolSize = 15;
052     private long _keepAliveTime = 5000;
053     
054     Map<Integer, Type> _typeMappings = new HashMap<Integer,Type>();
055     Map<Integer,AccessMode> _accessModes = new HashMap<Integer, AccessMode>();
056     Map<Type,String> _validators = new HashMap<Type, String>();
057     
058     Map<UUID,BrokerConnectionData> _brokerConnectionInfos = new HashMap<UUID, BrokerConnectionData>();
059     
060     Map<Character, IMessageHandler> _managementQueueHandlers = new HashMap<Character, IMessageHandler>();
061     Map<Character, IMessageHandler> _methodReplyQueueHandlers = new HashMap<Character, IMessageHandler>();
062     
063     private String _managementQueueName;
064     private String _methodReplyQueueName;
065     
066     private Header _headerForCommandMessages;
067     private DeliveryProperties _deliveryProperties = new DeliveryProperties();
068     private MessageProperties _messageProperties = new MessageProperties();
069         
070     // Private constructor.
071     private Configuration()
072     {
073         defineQueueNames();
074         createHeaderForCommandMessages();
075     }
076 
077     void clean()
078     {
079       INSTANCE = new Configuration();
080     }
081     
082     /**
083      * Returns the singleton instance.
084      
085      @return the singleton instance.
086      */
087     public static Configuration getInstance ()
088     {
089         return INSTANCE;
090     }  
091     
092     /**
093      * Returns true if this configuration has at least one broker connection data.
094      
095      @return true if this configuration has at least one broker connection data.
096      */
097     public boolean hasOneOrMoreBrokersDefined()
098     {
099       return !_brokerConnectionInfos.isEmpty();
100     }
101     
102     /**
103      * Returns the type associated to the given code.
104      
105      @param code the code used as search criteria.
106      @return the type associated to the given code.
107      @throws UnknownTypeCodeException when the given code is not associated to any type.
108      */
109     public Type getType(int codethrows UnknownTypeCodeException 
110     {
111         Type result = _typeMappings.get(code);
112         if (result == null
113         {
114             throw new UnknownTypeCodeException(code);
115         }
116         return result;
117     }
118     
119     /**
120      * Returns the access mode associated to the given code.
121      
122      @param code the code used as search criteria.
123      @return the access mode associated to the given code.
124      @throws UnknownAccessCodeException when the given code is not associated to any access mode.
125      */
126     public AccessMode getAccessMode(int codethrows UnknownAccessCodeException
127     {
128         AccessMode result = _accessModes.get(code);
129         if (result == null
130         {
131             throw new UnknownAccessCodeException(code);
132         }
133         return result;
134     }
135 
136     /**
137      * Returns the validator class name associated to the given type.
138      
139      @param type the type. 
140      @return the validator class name associated to the given type.
141      */
142     public String getValidatorClassName (Type type)
143     {
144         return _validators.get(type);
145     }
146     
147     /**
148      * Gets from this configuration the list of known broker (I mean, only their connection data).
149      
150      @return the list of known broker 
151      */
152     public Set<Entry<UUID, BrokerConnectionData>> getConnectionInfos(){
153         return _brokerConnectionInfos.entrySet();
154     }
155 
156     /**
157      * Gets from this configuration the connection data of the broker associated with the given id.
158      
159      @param brokerId the broker identifier.
160      @return the connection data of the broker associated with the given id.
161      @throws UnknownBrokerException when the given id is not associated with any broker.
162      */
163     public BrokerConnectionData getBrokerConnectionData (UUID brokerIdthrows UnknownBrokerException
164     {
165         BrokerConnectionData connectionData = _brokerConnectionInfos.get(brokerId);
166         if (connectionData == null)
167         {
168             throw new UnknownBrokerException(brokerId);
169         }
170         return _brokerConnectionInfos.get(brokerId);
171     }
172     
173     /**
174      * Returns the name of the management queue.
175      *  
176      @return the name of the management queue.
177      */
178     public String getManagementQueueName() {
179         return _managementQueueName;
180     }
181     
182     /**
183      * Returns the name of the method-reply queue.
184      
185      @return the name of the method-reply queue.
186      */
187     public String getMethodReplyQueueName() {
188         return _methodReplyQueueName;
189     }
190     
191     /**
192      * Returns a map containing all the configured management message handlers.
193      * A management message handler it is a basically a processor for a management queue incoming message associated 
194      * with a specific opcode.
195      
196      @return a map containing all the configured management message handlers.
197      */
198     public Map<Character, IMessageHandler> getManagementQueueHandlers() 
199     {
200       return _managementQueueHandlers;
201     }
202 
203     /**
204      * Returns a map containing all the configured method-reply message handlers.
205      * A management message handler it is a basically a processor for a method-reply queue incoming message associated 
206      * with a specific opcode.
207      
208      @return a map containing all the configured method-reply  message handlers.
209      */
210     public Map<Character, IMessageHandler> getMethodReplyQueueHandlers() 
211     {
212       return _methodReplyQueueHandlers;
213     }
214 
215     /**
216      * Returns the message header used for sending command message on management queue.
217      
218      @return the message header used for sending command message on management queue.
219      */
220     public Header getCommandMessageHeader ()
221     {
222         return _headerForCommandMessages;
223     }
224 
225     /**
226      * Returns the command message properties.
227      *  
228      @return the command message properties.
229      */
230     public MessageProperties getCommandMessageProperties ()
231     {
232         return _messageProperties;
233     }
234 
235     /**
236      * Returns the command message delivery properties.
237      *  
238      @return the command message delivery properties.
239      */
240     public DeliveryProperties getCommandDeliveryProperties ()
241     {
242         return _deliveryProperties;
243     }        
244     
245     /**
246      * Adds a new type mapping to this configuration.
247      
248      @param mapping the type mapping that will be added.
249      */
250     void addTypeMapping(TypeMapping mapping) {
251         int code = mapping.getCode();
252         Type type = mapping.getType();
253         String validatorClassName = mapping.getValidatorClassName();
254         _typeMappings.put(code, type);
255         _validators.put(type, validatorClassName);
256         
257         LOGGER.info(Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, code,type,validatorClassName);
258     }
259     
260     /**
261      * Adds a new access mode mapping to this configuration.
262      
263      @param mapping the mapping that will be added.
264      */
265     void addAccessModeMapping(AccessModeMapping mapping){
266         int code = mapping.getCode();
267         AccessMode accessMode = mapping.getAccessMode();
268         _accessModes.put(code, accessMode);
269         
270         LOGGER.info(Messages.QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED, code,accessMode);        
271     }    
272     
273     /**
274      * Adds a new management message handler to this configuration.
275      * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used
276      * for processing incoming messages with that opcode.
277      
278      @param mapping the message handler mapping.
279      */
280     void addManagementMessageHandlerMapping (MessageHandlerMapping mapping)
281     {
282         Character opcode = mapping.getOpcode();
283         IMessageHandler handler = mapping.getMessageHandler();
284         _managementQueueHandlers.put(opcode, handler);
285         
286         LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName())
287     }
288 
289     /**
290      * Adds a new method-reply message handler to this configuration.
291      * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used
292      * for processing incoming messages with that opcode.
293      
294      @param mapping the message handler mapping.
295      */
296     void addMethodReplyMessageHandlerMapping (MessageHandlerMapping mapping)
297     {
298         Character opcode = mapping.getOpcode();
299         IMessageHandler handler = mapping.getMessageHandler();
300         _methodReplyQueueHandlers.put(opcode, handler);
301         
302         LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName());     
303     }
304     
305     /**
306      * Adds to this configuration a new broker connection data.
307      
308      @param brokerId the broker identifier.
309      @param connectionData the connection data.
310      @throws BrokerAlreadyConnectedException when the broker is already connected.
311      @throws BrokerConnectionException when a connection cannot be estabilished.
312      */
313     void addBrokerConnectionData (UUID brokerId, BrokerConnectionData connectionDatathrows BrokerAlreadyConnectedException, BrokerConnectionException 
314     {
315       if (_brokerConnectionInfos.containsValue(connectionData))
316       {
317         throw new BrokerAlreadyConnectedException(connectionData);
318       }
319       
320       try 
321       {
322           QpidDatasource.getInstance().addConnectionPool(brokerId, connectionData);
323             _brokerConnectionInfos.put(brokerId,connectionData);
324 
325             LOGGER.info(Messages.QMAN_000009_BROKER_DATA_CONFIGURED,brokerId,connectionData);        
326       catch(Exception exception)
327       {
328         throw new BrokerConnectionException(exception);
329       }
330       
331     }
332     
333     /**
334      * Header for command messages is created once because it only contains static values.
335      */
336     private void createHeaderForCommandMessages ()
337     {
338         ReplyTo replyTo=new ReplyTo();
339         replyTo.setRoutingKey(_methodReplyQueueName);
340         _messageProperties.setReplyTo(replyTo);
341         _deliveryProperties.setRoutingKey(Names.AGENT_ROUTING_KEY);        
342         _headerForCommandMessages = new Header(_deliveryProperties, _messageProperties);
343     }
344     
345     /**
346      * Creates the name of the queues used by this service. 
347      * This is done because if a broker should be managed by one or more management client, then each of them
348      * must have its own channels to communicate with.
349      */
350     private void defineQueueNames() 
351     {
352         UUID uuid = UUID.randomUUID();
353         _managementQueueName = Names.MANAGEMENT_QUEUE_PREFIX+uuid;
354         _methodReplyQueueName = Names.METHOD_REPLY_QUEUE_PREFIX+uuid;
355         
356         LOGGER.debug(Messages.QMAN_200004_MANAGEMENT_QUEUE_NAME,_managementQueueName);
357         LOGGER.debug(Messages.QMAN_200005_METHOD_REPLY_QUEUE_NAME,_methodReplyQueueName);        
358     }
359 
360     /**
361      * Returns the worker manager thread pool size.
362      
363      @return the worker manager thread pool size.
364      */
365   public int getWorkerManagerPoolSize()
366   {
367     return _poolSize;
368   }
369 
370   /**
371    * Sets the size of the worker manager thread pool.
372    
373    @param poolSize the size of the worker manager thread pool.
374    */
375   void setWorkerManagerPoolSize(int poolSize)
376   {
377     this._poolSize = poolSize;
378   }
379 
380   /**
381    * Returns the maximum size of the worker manager 
382    * thread pool size.
383    
384    @return the max size of the worker manager thread pool.
385    */
386   public int getWorkerManagerMaxPoolSize()
387   {
388     return _maxPoolSize;
389   }
390 
391   /**
392    * Sets the maximum size of the worker manager 
393    * thread pool size.
394    
395    @param maxPoolSize the max size of the worker manager thread pool.
396    */  
397   void setWorkerManagerMaxPoolSize(int maxPoolSize)
398   {
399     this._maxPoolSize = maxPoolSize;
400   }
401 
402   /**
403    * Returns the max amount of time that an excess thread
404    * can be idle before purging from the pool.
405    
406    @return the max keep alive time.
407    */
408   public long getWorkerManagerKeepAliveTime()
409   {
410     return _keepAliveTime;
411   }
412 
413   /**
414    * Sets the max amount of time that an excess thread
415    * can be idle before purging from the pool.
416    
417    @param keepAliveTime the max keep alive time.
418    */
419   void setWorkerManagerKeepAliveTime(long keepAliveTime)
420   {
421     this._keepAliveTime = keepAliveTime;
422   }
423 }