001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.synapse.config;
021:
022: import org.apache.axis2.AxisFault;
023: import org.apache.axis2.engine.AxisConfiguration;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.synapse.*;
027: import org.apache.synapse.config.xml.MediatorFactoryFinder;
028: import org.apache.synapse.config.xml.endpoints.XMLToEndpointMapper;
029: import org.apache.synapse.core.SynapseEnvironment;
030: import org.apache.synapse.core.axis2.ProxyService;
031: import org.apache.synapse.endpoints.Endpoint;
032: import org.apache.synapse.mediators.base.SequenceMediator;
033: import org.apache.synapse.registry.Registry;
034:
035: import javax.xml.namespace.QName;
036: import java.io.IOException;
037: import java.util.*;
038:
039: /**
040: * The SynapseConfiguration holds the global configuration for a Synapse
041: * instance.
042: */
043: public class SynapseConfiguration implements ManagedLifecycle {
044:
045: private static final Log log = LogFactory
046: .getLog(SynapseConfiguration.class);
047:
048: /**
049: * The remote registry made available to the Synapse configuration. Only one
050: * is supported
051: */
052: Registry registry = null;
053:
054: /**
055: * This holds the default QName of the configuration.
056: */
057: private QName defaultQName = null;
058:
059: /**
060: * Holds Proxy services defined through Synapse
061: */
062: private Map<String, ProxyService> proxyServices = new HashMap<String, ProxyService>();
063:
064: /**
065: * This holds a Map of ManagedLifecycle objects
066: */
067: private Map<String, Startup> startups = new HashMap<String, Startup>();
068:
069: /**
070: * The local registry is a simple HashMap and provides the ability to
071: * override definitions of a remote registry for entries defined locally
072: * with the same key
073: */
074: private Map<String, Object> localRegistry = new HashMap<String, Object>();
075:
076: /** Holds the synapse properties */
077: private Properties properties = new Properties();
078:
079: /**
080: * This will provide the timer daemon object for the scheduled tasks.
081: */
082: private Timer synapseTimer = new Timer(true);
083:
084: /** Hold reference to the Axis2 ConfigurationContext */
085: private AxisConfiguration axisConfiguration = null;
086:
087: /**
088: * Save the path to the configuration file loaded, to save it later if
089: * required
090: */
091: private String pathToConfigFile = null;
092:
093: /**
094: * Add a named sequence into the local registry
095: *
096: * @param key
097: * the name for the sequence
098: * @param mediator
099: * a Sequence mediator
100: */
101: public void addSequence(String key, Mediator mediator) {
102: localRegistry.put(key, mediator);
103: }
104:
105: /**
106: * Allow a dynamic sequence to be cached and made available through the
107: * local registry
108: *
109: * @param key
110: * the key to lookup the sequence from the remote registry
111: * @param entry
112: * the Entry object which holds meta information and the cached
113: * resource
114: */
115: public void addSequence(String key, Entry entry) {
116: localRegistry.put(key, entry);
117: }
118:
119: /**
120: * Returns the map of defined sequences in the configuration excluding the
121: * fetched sequences from remote registry.
122: *
123: * @return Map of SequenceMediators defined in the local configuration
124: */
125: public Map<String, SequenceMediator> getDefinedSequences() {
126:
127: Map<String, SequenceMediator> definedSequences = new HashMap<String, SequenceMediator>();
128:
129: for (Object o : localRegistry.values()) {
130:
131: if (o instanceof SequenceMediator) {
132: SequenceMediator seq = (SequenceMediator) o;
133: definedSequences.put(seq.getName(), seq);
134: }
135: }
136: return definedSequences;
137: }
138:
139: /**
140: * Return the sequence specified with the given key
141: *
142: * @param key
143: * the key being referenced
144: * @return the sequence referenced by the key
145: */
146: public Mediator getSequence(String key) {
147: Object o = localRegistry.get(key);
148: if (o != null && o instanceof Mediator) {
149: return (Mediator) o;
150: }
151:
152: Entry entry;
153: if (o != null && o instanceof Entry) {
154: entry = (Entry) o;
155: } else {
156: entry = new Entry(key);
157: entry.setType(Entry.REMOTE_ENTRY);
158: entry.setMapper(MediatorFactoryFinder.getInstance());
159: }
160:
161: if (registry != null) {
162: o = registry.getResource(entry);
163: if (o != null && o instanceof Mediator) {
164: localRegistry.put(key, entry);
165: return (Mediator) o;
166: }
167: }
168:
169: return null;
170: }
171:
172: /**
173: * Removes a sequence from the local registry
174: *
175: * @param key
176: * of the sequence to be removed
177: */
178: public void removeSequence(String key) {
179: localRegistry.remove(key);
180: }
181:
182: /**
183: * Return the main/default sequence to be executed. This is the sequence
184: * which will execute for all messages when message mediation takes place
185: *
186: * @return the main mediator sequence
187: */
188: public Mediator getMainSequence() {
189: return getSequence(SynapseConstants.MAIN_SEQUENCE_KEY);
190: }
191:
192: /**
193: * Return the fault sequence to be executed when Synapse encounters a fault
194: * scenario during processing
195: *
196: * @return the fault sequence
197: */
198: public Mediator getFaultSequence() {
199: return getSequence(SynapseConstants.FAULT_SEQUENCE_KEY);
200: }
201:
202: /**
203: * Define a resource to the local registry. All static resources (e.g. URL
204: * source) are loaded during this definition phase, and the inability to
205: * load such a resource will not allow the definition of the resource to the
206: * local registry
207: *
208: * @param key
209: * the key associated with the resource
210: * @param entry
211: * the Entry that holds meta information about the resource and
212: * its contents (or cached contents if the Entry refers to a
213: * dynamic resource off a remote registry)
214: */
215: public void addEntry(String key, Entry entry) {
216:
217: if (entry.getType() == Entry.URL_SRC) {
218: try {
219: entry
220: .setValue(SynapseConfigUtils
221: .getOMElementFromURL(entry.getSrc()
222: .toString()));
223: localRegistry.put(key, entry);
224: } catch (IOException e) {
225: handleException("Can not read from source URL : "
226: + entry.getSrc());
227: }
228: } else {
229: localRegistry.put(key, entry);
230: }
231: }
232:
233: /**
234: * Gives the set of remote entries that are cached in localRegistry as mapping of entry key
235: * to the Entry definition
236: *
237: * @return Map of locally cached entries
238: */
239: public Map<String, Entry> getCachedEntries() {
240:
241: Map<String, Entry> cachedEntries = new HashMap<String, Entry>();
242: for (Object o : localRegistry.values()) {
243:
244: if (o != null && o instanceof Entry) {
245: Entry entry = (Entry) o;
246: if (entry.isDynamic() && entry.isCached()) {
247: cachedEntries.put(entry.getKey(), entry);
248: }
249: }
250: }
251:
252: return cachedEntries;
253: }
254:
255: /**
256: * Returns the map of defined entries in the configuration excluding the
257: * fetched entries from remote registry.
258: *
259: * @return Map of Entries defined in the local configuraion
260: */
261: public Map<String, Entry> getDefinedEntries() {
262:
263: Map<String, Entry> definedEntries = new HashMap<String, Entry>();
264: for (Object o : localRegistry.values()) {
265:
266: if (o instanceof Entry
267: && ((Entry) o).getType() != Entry.REMOTE_ENTRY) {
268:
269: Entry entry = (Entry) o;
270: definedEntries.put(entry.getKey(), entry);
271: }
272: }
273: return definedEntries;
274: }
275:
276: /**
277: * Get the resource with the given key
278: *
279: * @param key
280: * the key of the resource required
281: * @return its value
282: */
283: public Object getEntry(String key) {
284: Object o = localRegistry.get(key);
285: if (o != null && o instanceof Entry) {
286: Entry entry = (Entry) o;
287: if (entry.isDynamic()) {
288: if (entry.isCached() && !entry.isExpired()) {
289: return entry.getValue();
290: } else if (registry != null) {
291: o = registry.getResource(entry);
292: } else {
293: if (log.isDebugEnabled()) {
294: log
295: .debug("Will not evaluate the value of the remote entry with a key "
296: + key
297: + ", because the registry is not available");
298: }
299: return null; // otherwise will return an entry with a value null
300: // (method expects return a value not an entry )
301: }
302: } else {
303: return entry.getValue();
304: }
305: }
306: return o;
307: }
308:
309: /**
310: * Get the Entry object mapped to the given key
311: *
312: * @param key
313: * the key for which the Entry is required
314: * @return its value
315: */
316: public Entry getEntryDefinition(String key) {
317: Object o = localRegistry.get(key);
318: if (o == null || o instanceof Entry) {
319: if (o == null) {
320: // this is not a local definition
321: Entry entry = new Entry(key);
322: entry.setType(Entry.REMOTE_ENTRY);
323: addEntry(key, entry);
324: return entry;
325: }
326: return (Entry) o;
327: } else {
328: handleException("Invalid local registry entry : " + key);
329: return null;
330: }
331: }
332:
333: /**
334: * Deletes any reference mapped to the given key from the local registry
335: *
336: * @param key
337: * the key of the reference to be removed
338: */
339: public void removeEntry(String key) {
340: localRegistry.remove(key);
341: }
342:
343: /**
344: * Clears the cache of the remote entry with the key specified
345: *
346: * @param key - String key of the entry
347: */
348: public void clearCachedEntry(String key) {
349: Entry entry = getEntryDefinition(key);
350: if (entry.isDynamic() && entry.isCached()) {
351: entry.clearCache();
352: }
353: }
354:
355: /**
356: * Clears the cache of all the remote entries which has been
357: * cached in the configuration
358: */
359: public void clearCache() {
360:
361: for (Object o : localRegistry.values()) {
362:
363: if (o != null && o instanceof Entry) {
364: Entry entry = (Entry) o;
365: if (entry.isDynamic() && entry.isCached()) {
366: entry.clearCache();
367: }
368: }
369: }
370: }
371:
372: /**
373: * Define a named endpoint with the given key
374: *
375: * @param key
376: * the key for the endpoint
377: * @param endpoint
378: * the endpoint definition
379: */
380: public void addEndpoint(String key, Endpoint endpoint) {
381: localRegistry.put(key, endpoint);
382: }
383:
384: /**
385: * Add a dynamic endpoint definition to the local registry
386: *
387: * @param key
388: * the key for the endpoint definition
389: * @param entry
390: * the actual endpoint definition to be added
391: */
392: public void addEndpoint(String key, Entry entry) {
393: localRegistry.put(key, entry);
394: }
395:
396: /**
397: * Returns the map of defined endpoints in the configuration excluding the
398: * fetched endpoints from remote registry
399: *
400: * @return Map of Endpoints defined in the local configuration
401: */
402: public Map<String, Endpoint> getDefinedEndpoints() {
403:
404: Map<String, Endpoint> definedEndpoints = new HashMap<String, Endpoint>();
405: for (Object o : localRegistry.values()) {
406:
407: if (o instanceof Endpoint) {
408: Endpoint ep = (Endpoint) o;
409: definedEndpoints.put(ep.getName(), ep);
410: }
411: }
412:
413: return definedEndpoints;
414: }
415:
416: /**
417: * Get the definition of the endpoint with the given key
418: *
419: * @param key
420: * the key of the endpoint
421: * @return the endpoint definition
422: */
423: public Endpoint getEndpoint(String key) {
424:
425: Object o = localRegistry.get(key);
426: if (o != null && o instanceof Endpoint) {
427: return (Endpoint) o;
428: }
429:
430: Entry entry;
431: if (o != null && o instanceof Entry) {
432: entry = (Entry) o;
433: } else {
434: entry = new Entry(key);
435: entry.setType(Entry.REMOTE_ENTRY);
436: entry.setMapper(XMLToEndpointMapper.getInstance());
437: }
438:
439: if (registry != null) {
440: o = registry.getResource(entry);
441: if (o != null && o instanceof Endpoint) {
442: localRegistry.put(key, entry);
443: return (Endpoint) o;
444: }
445: }
446:
447: return null;
448: }
449:
450: /**
451: * Deletes the endpoint with the given key
452: *
453: * @param key
454: * of the endpoint to be deleted
455: */
456: public void removeEndpoint(String key) {
457: localRegistry.remove(key);
458: }
459:
460: /**
461: * Add a Proxy service to the configuration
462: *
463: * @param name
464: * the name of the Proxy service
465: * @param proxy
466: * the Proxy service instance
467: */
468: public void addProxyService(String name, ProxyService proxy) {
469: proxyServices.put(name, proxy);
470: }
471:
472: /**
473: * Get the Proxy service with the given name
474: *
475: * @param name
476: * the name being looked up
477: * @return the Proxy service
478: */
479: public ProxyService getProxyService(String name) {
480: return proxyServices.get(name);
481: }
482:
483: /**
484: * Deletes the Proxy Service named with the given name
485: *
486: * @param name
487: * of the Proxy Service to be deleted
488: */
489: public void removeProxyService(String name) {
490: Object o = proxyServices.get(name);
491: if (o == null) {
492: handleException("Unknown proxy service for name : " + name);
493: } else {
494: try {
495: if (getAxisConfiguration()
496: .getServiceForActivation(name) != null) {
497: if (getAxisConfiguration().getServiceForActivation(
498: name).isActive()) {
499: getAxisConfiguration().getService(name)
500: .setActive(false);
501: }
502: getAxisConfiguration().removeService(name);
503: }
504: proxyServices.remove(name);
505: } catch (AxisFault axisFault) {
506: handleException(axisFault.getMessage());
507: }
508: }
509: }
510:
511: /**
512: * Return the list of defined proxy services
513: *
514: * @return the proxy services defined
515: */
516: public Collection<ProxyService> getProxyServices() {
517: return proxyServices.values();
518: }
519:
520: /**
521: * Return an unmodifiable copy of the local registry
522: *
523: * @return an unmodifiable copy of the local registry
524: */
525: public Map getLocalRegistry() {
526: return Collections.unmodifiableMap(localRegistry);
527: }
528:
529: /**
530: * Get the remote registry defined (if any)
531: *
532: * @return the currently defined remote registry
533: */
534: public Registry getRegistry() {
535: return registry;
536: }
537:
538: /**
539: * Set the remote registry for the configuration
540: *
541: * @param registry
542: * the remote registry for the configuration
543: */
544: public void setRegistry(Registry registry) {
545: this .registry = registry;
546: }
547:
548: /**
549: * Set the Axis2 AxisConfiguration to the SynapseConfiguration
550: *
551: * @param axisConfig AxisConfiguration to be set
552: */
553: public void setAxisConfiguration(AxisConfiguration axisConfig) {
554: this .axisConfiguration = axisConfig;
555: }
556:
557: /**
558: * Get the Axis2 AxisConfiguration for the SynapseConfiguration
559: *
560: * @return AxisConfiguration of the Axis2
561: */
562: public AxisConfiguration getAxisConfiguration() {
563: return axisConfiguration;
564: }
565:
566: /**
567: * The path to the currently loaded configuration file
568: *
569: * @return file path to synapse.xml
570: */
571: public String getPathToConfigFile() {
572: return pathToConfigFile;
573: }
574:
575: /**
576: * Set the path to the loaded synapse.xml
577: *
578: * @param pathToConfigFile
579: * path to the synapse.xml loaded
580: */
581: public void setPathToConfigFile(String pathToConfigFile) {
582: this .pathToConfigFile = pathToConfigFile;
583: }
584:
585: /**
586: * Set the default QName of the Synapse Configuration
587: *
588: * @param defaultQName
589: * QName specifying the default QName of the configuration
590: */
591: public void setDefaultQName(QName defaultQName) {
592: this .defaultQName = defaultQName;
593: }
594:
595: /**
596: * Get the default QName of the configuration.
597: *
598: * @return default QName of the configuration
599: */
600: public QName getDefaultQName() {
601: return defaultQName;
602: }
603:
604: /**
605: * Get the timer object for the Synapse Configuration
606: *
607: * @return synapseTimer timer object of the configuration
608: */
609: public Timer getSynapseTimer() {
610: return synapseTimer;
611: }
612:
613: /**
614: * Get the startup collection in the configuration
615: *
616: * @return collection of startup objects registered
617: */
618: public Collection<Startup> getStartups() {
619: return startups.values();
620: }
621:
622: /**
623: * Get the Startup with the specified name
624: *
625: * @param id - String name of the startup to be retrieved
626: * @return Startup object with the specified name or null
627: */
628: public Startup getStartup(String id) {
629: return startups.get(id);
630: }
631:
632: /**
633: * Add a startup to the startups map in the configuration
634: *
635: * @param startup - Startup object to be added
636: */
637: public void addStartup(Startup startup) {
638: startups.put(startup.getName(), startup);
639: }
640:
641: /**
642: * Removes the startup specified by the name
643: *
644: * @param name - name of the startup that needs to be removed
645: */
646: public void removeStartup(String name) {
647: startups.remove(name);
648: }
649:
650: /**
651: * Gets the properties to configure the Synapse environment.
652: *
653: * @return set of properties as Properties
654: */
655: public Properties getProperties() {
656: return properties;
657: }
658:
659: /**
660: * Sets the properties to configure the Synapse enviornment.
661: *
662: * @param properties - Properties which needs to be set
663: */
664: public void setProperties(Properties properties) {
665: this .properties = properties;
666: }
667:
668: /**
669: * Gets the String representation of the property value if there is a property for the
670: * given propKey or returns the default value passed
671: *
672: * @param propKey - key for the property lookup
673: * @param def - default value
674: * @return String representation of the property value with the given key or the def value
675: */
676: public String getProperty(String propKey, String def) {
677: String val = System.getProperty(propKey);
678: if (val == null) {
679: val = properties.getProperty(propKey);
680: }
681:
682: if (val != null) {
683: if (log.isDebugEnabled()) {
684: log.debug("Using synapse tuning parameter : " + propKey
685: + " = " + val);
686: }
687: return val;
688: }
689: return def;
690: }
691:
692: /**
693: * Gets the propety value if the property specified by the propKey is there or null else
694: *
695: * @param propKey - key for the property lookup
696: * @return String representation of the property value if found or null else
697: */
698: public String getProperty(String propKey) {
699: String val = System.getProperty(propKey);
700: if (val == null) {
701: val = properties.getProperty(propKey);
702: }
703:
704: if (val != null) {
705: if (log.isDebugEnabled()) {
706: log.debug("Using synapse tuning parameter : " + propKey
707: + " = " + val);
708: }
709: return val;
710: }
711: return null;
712: }
713:
714: /**
715: * This method will be called on the soft shutdown or destroying the configuration
716: * and will destroy all the stateful managed parts of the configuration.
717: */
718: public void destroy() {
719:
720: if (log.isDebugEnabled()) {
721: log.debug("Destroying the Synapse Configuration");
722: }
723:
724: // clear the timer tasks of Synapse
725: synapseTimer.cancel();
726: synapseTimer = null;
727:
728: // stop and shutdown all the proxy services
729: for (ProxyService p : getProxyServices()) {
730:
731: if (p.getTargetInLineInSequence() != null) {
732: p.getTargetInLineInSequence().destroy();
733: }
734:
735: if (p.getTargetInLineOutSequence() != null) {
736: p.getTargetInLineOutSequence().destroy();
737: }
738: }
739:
740: // destroy the managed mediators
741: for (SequenceMediator seq : getDefinedSequences().values()) {
742: if (seq != null) {
743: seq.destroy();
744: }
745: }
746:
747: // destroy the startups
748: if (startups != null) {
749:
750: for (Startup stp : startups.values()) {
751: if (stp != null) {
752: stp.destroy();
753: }
754: }
755: }
756: }
757:
758: /**
759: * This method will be called in the startup of Synapse or in an initiation
760: * and will initialize all the managed parts of the Synapse Configuration
761: *
762: * @param se
763: * SynapseEnvironment specifying the env to be initialized
764: */
765: public void init(SynapseEnvironment se) {
766:
767: if (log.isDebugEnabled()) {
768: log.debug("Initializing the Synapse Configuration");
769: }
770:
771: // initialize registry
772: if (registry != null && registry instanceof ManagedLifecycle) {
773: ((ManagedLifecycle) registry).init(se);
774: }
775:
776: // initialize all the proxy services
777: for (ProxyService p : getProxyServices()) {
778:
779: if (p.getTargetInLineInSequence() != null) {
780: p.getTargetInLineInSequence().init(se);
781: }
782:
783: if (p.getTargetInLineOutSequence() != null) {
784: p.getTargetInLineOutSequence().init(se);
785: }
786: }
787:
788: // initialize managed mediators
789: for (SequenceMediator seq : getDefinedSequences().values()) {
790: if (seq != null) {
791: seq.init(se);
792: }
793: }
794: }
795:
796: private void handleException(String msg) {
797: log.error(msg);
798: throw new SynapseException(msg);
799: }
800: }
|