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 */
017 package org.apache.servicemix.jbi.framework;
018
019 import java.io.File;
020 import java.util.ArrayList;
021 import java.util.Collection;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.concurrent.ConcurrentHashMap;
025 import java.util.concurrent.CopyOnWriteArrayList;
026
027 import javax.jbi.JBIException;
028 import javax.jbi.component.Component;
029 import javax.jbi.component.ComponentContext;
030 import javax.jbi.management.DeploymentException;
031 import javax.jbi.servicedesc.ServiceEndpoint;
032 import javax.management.JMException;
033 import javax.management.MBeanAttributeInfo;
034 import javax.management.ObjectName;
035 import javax.xml.namespace.QName;
036
037 import org.w3c.dom.Document;
038 import org.w3c.dom.DocumentFragment;
039 import org.w3c.dom.Element;
040 import org.w3c.dom.Node;
041 import org.w3c.dom.NodeList;
042
043 import org.apache.commons.logging.Log;
044 import org.apache.commons.logging.LogFactory;
045 import org.apache.servicemix.executors.Executor;
046 import org.apache.servicemix.jbi.container.ActivationSpec;
047 import org.apache.servicemix.jbi.container.EnvironmentContext;
048 import org.apache.servicemix.jbi.container.JBIContainer;
049 import org.apache.servicemix.jbi.container.ServiceAssemblyEnvironment;
050 import org.apache.servicemix.jbi.container.SubscriptionSpec;
051 import org.apache.servicemix.jbi.deployment.ServiceAssembly;
052 import org.apache.servicemix.jbi.deployment.ServiceUnit;
053 import org.apache.servicemix.jbi.management.AttributeInfoHelper;
054 import org.apache.servicemix.jbi.management.BaseSystemService;
055 import org.apache.servicemix.jbi.messaging.DeliveryChannelImpl;
056 import org.apache.servicemix.jbi.messaging.MessageExchangeImpl;
057 import org.apache.servicemix.jbi.resolver.URIResolver;
058 import org.apache.servicemix.jbi.servicedesc.AbstractServiceEndpoint;
059 import org.apache.servicemix.jbi.servicedesc.DynamicEndpoint;
060 import org.apache.servicemix.jbi.servicedesc.InternalEndpoint;
061 import org.apache.servicemix.jbi.util.DOMUtil;
062 import org.apache.servicemix.jbi.util.WSAddressingConstants;
063
064 /**
065 * Registry - state infomation including running state, SA's deployed etc.
066 *
067 * @version $Revision: 695373 $
068 */
069 public class Registry extends BaseSystemService implements RegistryMBean {
070
071 private static final Log LOG = LogFactory.getLog(Registry.class);
072
073 private ComponentRegistry componentRegistry;
074 private EndpointRegistry endpointRegistry;
075 private SubscriptionRegistry subscriptionRegistry;
076 private ServiceAssemblyRegistry serviceAssemblyRegistry;
077 private Map<String, SharedLibrary> sharedLibraries;
078 private Map<String, ServiceUnitLifeCycle> serviceUnits;
079 private List<ServiceAssemblyLifeCycle> pendingAssemblies;
080 private List<ComponentMBeanImpl> pendingComponents;
081 private Executor executor;
082
083 /**
084 * Constructor
085 */
086 public Registry() {
087 this.componentRegistry = new ComponentRegistry(this);
088 this.endpointRegistry = new EndpointRegistry(this);
089 this.subscriptionRegistry = new SubscriptionRegistry(this);
090 this.serviceAssemblyRegistry = new ServiceAssemblyRegistry(this);
091 this.serviceUnits = new ConcurrentHashMap<String, ServiceUnitLifeCycle>();
092 this.pendingAssemblies = new CopyOnWriteArrayList<ServiceAssemblyLifeCycle>();
093 this.sharedLibraries = new ConcurrentHashMap<String, SharedLibrary>();
094 this.pendingComponents = new CopyOnWriteArrayList<ComponentMBeanImpl>();
095 }
096
097 /**
098 * Get the description
099 * @return description
100 */
101 public String getDescription() {
102 return "Registry of Components/SU's and Endpoints";
103 }
104
105 protected Class getServiceMBean() {
106 return RegistryMBean.class;
107 }
108
109
110 public ComponentRegistry getComponentRegistry() {
111 return componentRegistry;
112 }
113
114 public EndpointRegistry getEndpointRegistry() {
115 return endpointRegistry;
116 }
117
118 public void init(JBIContainer container) throws JBIException {
119 super.init(container);
120 executor = container.getExecutorFactory().createExecutor("services.registry");
121 }
122
123 /**
124 * start brokering
125 *
126 * @throws JBIException
127 */
128 public void start() throws JBIException {
129 componentRegistry.start();
130 serviceAssemblyRegistry.start();
131 super.start();
132 }
133
134 /**
135 * stop brokering
136 *
137 * @throws JBIException
138 */
139 public void stop() throws JBIException {
140 serviceAssemblyRegistry.stop();
141 componentRegistry.stop();
142 super.stop();
143 }
144
145 /**
146 * shutdown all Components
147 *
148 * @throws JBIException
149 */
150 public void shutDown() throws JBIException {
151 serviceAssemblyRegistry.shutDown();
152 componentRegistry.shutDown();
153 super.shutDown();
154 container.getManagementContext().unregisterMBean(this);
155 executor.shutdown();
156 }
157
158 /**
159 * @return the EnvironmentContext
160 */
161 protected EnvironmentContext getEnvironmentContext() {
162 return container.getEnvironmentContext();
163 }
164
165 /**
166 * @return true if the container is embedded
167 */
168 protected boolean isContainerEmbedded() {
169 return container.isEmbedded();
170 }
171
172 protected InternalEndpoint matchEndpointByName(ServiceEndpoint[] endpoints, String endpointName) {
173 InternalEndpoint result = null;
174 if (endpoints != null && endpointName != null && endpointName.length() > 0) {
175 for (int i = 0; i < endpoints.length; i++) {
176 if (endpoints[i].getEndpointName().equals(endpointName)) {
177 result = (InternalEndpoint) endpoints[i];
178 break;
179 }
180 }
181 }
182 return result;
183 }
184
185 /**
186 * @param context
187 * @param serviceName
188 * @param endpointName
189 * @return EndPointReference
190 * @throws JBIException
191 */
192 public ServiceEndpoint activateEndpoint(ComponentContextImpl context,
193 QName serviceName,
194 String endpointName) throws JBIException {
195 return endpointRegistry.registerInternalEndpoint(context, serviceName, endpointName);
196 }
197
198 public ServiceEndpoint[] getEndpointsForComponent(ComponentNameSpace cns) {
199 return endpointRegistry.getEndpointsForComponent(cns);
200 }
201
202 /**
203 * @param interfaceName qualified name
204 * @return an array of available endpoints for the specified interface name;
205 */
206 public ServiceEndpoint[] getEndpointsForInterface(QName interfaceName) {
207 return endpointRegistry.getEndpointsForInterface(interfaceName);
208 }
209
210 /**
211 * @param provider
212 * @param serviceEndpoint
213 */
214 public void deactivateEndpoint(ComponentContext provider, InternalEndpoint serviceEndpoint) {
215 endpointRegistry.unregisterInternalEndpoint(provider, serviceEndpoint);
216 }
217
218 /**
219 * Retrieve the service description metadata for the specified endpoint.
220 * <p>
221 * Note that the result can use either the WSDL 1.1 or WSDL 2.0 description language.
222 *
223 * @param endpoint endpoint reference; must be non-null.
224 * @return metadata describing endpoint, or <code>null</code> if metadata is unavailable.
225 * @throws JBIException invalid endpoint reference.
226 */
227 public Document getEndpointDescriptor(ServiceEndpoint endpoint) throws JBIException {
228 if (!(endpoint instanceof AbstractServiceEndpoint)) {
229 throw new JBIException("Descriptors can not be queried for external endpoints");
230 }
231 AbstractServiceEndpoint se = (AbstractServiceEndpoint) endpoint;
232 // TODO: what if the endpoint is linked or dynamic
233 ComponentMBeanImpl component = getComponent(se.getComponentNameSpace());
234 return component.getComponent().getServiceDescription(endpoint);
235 }
236
237 /**
238 * Resolve the given endpoint reference into a service endpoint. This is called by the component when it has an EPR
239 * that it wants to resolve into a service endpoint.
240 * <p>
241 * Note that the service endpoint returned refers to a dynamic endpoint; the endpoint will exist only as long as
242 * this component retains a strong reference to the object returned by this method. The endpoint may not be included
243 * in the list of "activated" endpoints.
244 *
245 * @param epr endpoint reference as an XML fragment; must be non-null.
246 * @return the service endpoint corresponding to the given endpoint reference; <code>null</code> if the reference
247 * cannot be resolved.
248 */
249 public ServiceEndpoint resolveEndpointReference(DocumentFragment epr) {
250 for (ComponentMBeanImpl connector : getComponents()) {
251 ServiceEndpoint se = connector.getComponent().resolveEndpointReference(epr);
252 if (se != null) {
253 return new DynamicEndpoint(connector.getComponentNameSpace(), se, epr);
254 }
255 }
256 ServiceEndpoint se = resolveInternalEPR(epr);
257 if (se != null) {
258 return se;
259 }
260 return resolveStandardEPR(epr);
261 }
262
263 /**
264 * <p>
265 * Resolve an internal JBI EPR conforming to the format defined in the JBI specification.
266 * </p>
267 *
268 * <p>The EPR would look like:
269 * <pre>
270 * <jbi:end-point-reference xmlns:jbi="http://java.sun.com/xml/ns/jbi/end-point-reference"
271 * jbi:end-point-name="endpointName"
272 * jbi:service-name="foo:serviceName"
273 * xmlns:foo="urn:FooNamespace"/>
274 * </pre>
275 * </p>
276 *
277 * @author Maciej Szefler m s z e f l e r @ g m a i l . c o m
278 * @param epr EPR fragment
279 * @return internal service endpoint corresponding to the EPR, or <code>null</code>
280 * if the EPR is not an internal EPR or if the EPR cannot be resolved
281 */
282 public ServiceEndpoint resolveInternalEPR(DocumentFragment epr) {
283 if (epr == null) {
284 throw new NullPointerException("resolveInternalEPR(epr) called with null epr.");
285 }
286 NodeList nl = epr.getChildNodes();
287 for (int i = 0; i < nl.getLength(); ++i) {
288 Node n = nl.item(i);
289 if (n.getNodeType() != Node.ELEMENT_NODE) {
290 continue;
291 }
292 Element el = (Element) n;
293 // Namespace should be "http://java.sun.com/jbi/end-point-reference"
294 if (el.getNamespaceURI() == null
295 || !el.getNamespaceURI().equals("http://java.sun.com/jbi/end-point-reference"))
296 {
297 continue;
298 }
299 if (el.getLocalName() == null || !el.getLocalName().equals("end-point-reference")) {
300 continue;
301 }
302 String serviceName = el.getAttributeNS(el.getNamespaceURI(), "service-name");
303 // Now the DOM pain-in-the-you-know-what: we need to come up with QName for this;
304 // fortunately, there is only one place where the xmlns:xxx attribute could be, on
305 // the end-point-reference element!
306 QName serviceQName = DOMUtil.createQName(el, serviceName);
307 String endpointName = el.getAttributeNS(el.getNamespaceURI(), "end-point-name");
308 return getInternalEndpoint(serviceQName, endpointName);
309 }
310 return null;
311 }
312
313 /**
314 * Resolve a standard EPR understood by ServiceMix container.
315 * Currently, the supported syntax is the WSA one, the address uri
316 * being parsed with the following possiblities:
317 * jbi:endpoint:service-namespace/service-name/endpoint
318 * jbi:endpoint:service-namespace:service-name:endpoint
319 *
320 * The full EPR will look like:
321 * <epr xmlns:wsa="http://www.w3.org/2005/08/addressing">
322 * <wsa:Address>jbi:endpoint:http://foo.bar.com/service/endpoint</wsa:Address>
323 * </epr>
324 *
325 * BCs should also be able to resolve such EPR but using their own URI parsing,
326 * for example:
327 * <epr xmlns:wsa="http://www.w3.org/2005/08/addressing">
328 * <wsa:Address>http://foo.bar.com/myService?http.soap=true</wsa:Address>
329 * </epr>
330 *
331 * or
332 * <epr xmlns:wsa="http://www.w3.org/2005/08/addressing">
333 * <wsa:Address>jms://activemq/queue/FOO.BAR?persistent=true</wsa:Address>
334 * </epr>
335 *
336 * Note that the separator should be same as the one used in the namespace
337 * depending on the namespace:
338 * http://foo.bar.com => '/'
339 * urn:foo:bar => ':'
340 *
341 * The syntax is the same as the one that can be used to specifiy a target
342 * for a JBI exchange with the restriction that it only allows the
343 * endpoint subprotocol to be used.
344 *
345 * @param epr
346 * @return
347 */
348 public ServiceEndpoint resolveStandardEPR(DocumentFragment epr) {
349 try {
350 NodeList children = epr.getChildNodes();
351 for (int i = 0; i < children.getLength(); ++i) {
352 Node n = children.item(i);
353 if (n.getNodeType() != Node.ELEMENT_NODE) {
354 continue;
355 }
356 Element elem = (Element) n;
357 String[] namespaces = new String[] {WSAddressingConstants.WSA_NAMESPACE_200508,
358 WSAddressingConstants.WSA_NAMESPACE_200408,
359 WSAddressingConstants.WSA_NAMESPACE_200403,
360 WSAddressingConstants.WSA_NAMESPACE_200303 };
361 NodeList nl = null;
362 for (int ns = 0; ns < namespaces.length; ns++) {
363 NodeList tnl = elem.getElementsByTagNameNS(namespaces[ns], WSAddressingConstants.EL_ADDRESS);
364 if (tnl.getLength() == 1) {
365 nl = tnl;
366 break;
367 }
368 }
369 if (nl != null) {
370 Element address = (Element) nl.item(0);
371 String uri = DOMUtil.getElementText(address);
372 if (uri != null) {
373 uri = uri.trim();
374 }
375 if (uri.startsWith("endpoint:")) {
376 uri = uri.substring("endpoint:".length());
377 String[] parts = URIResolver.split3(uri);
378 return getInternalEndpoint(new QName(parts[0], parts[1]), parts[2]);
379 } else if (uri.startsWith("service:")) {
380 uri = uri.substring("service:".length());
381 String[] parts = URIResolver.split2(uri);
382 return getEndpoint(new QName(parts[0], parts[1]), parts[1]);
383 }
384 // TODO should we support interface: and operation: here?
385 }
386 }
387 } catch (Exception e) {
388 LOG.debug("Unable to resolve EPR: " + e);
389 }
390 return null;
391 }
392
393 /**
394 * @param provider
395 * @param externalEndpoint the external endpoint to be registered, must be non-null.
396 * @throws JBIException
397 */
398 public void registerExternalEndpoint(ComponentNameSpace cns, ServiceEndpoint externalEndpoint) throws JBIException {
399 if (externalEndpoint != null) {
400 endpointRegistry.registerExternalEndpoint(cns, externalEndpoint);
401 }
402 }
403
404 /**
405 * @param provider
406 * @param externalEndpoint the external endpoint to be deregistered; must be non-null.
407 */
408 public void deregisterExternalEndpoint(ComponentNameSpace cns, ServiceEndpoint externalEndpoint) {
409 endpointRegistry.unregisterExternalEndpoint(cns, externalEndpoint);
410 }
411
412 /**
413 * @param service
414 * @param name
415 * @return endpoint
416 */
417 public ServiceEndpoint getEndpoint(QName service, String name) {
418 return endpointRegistry.getEndpoint(service, name);
419 }
420
421 public ServiceEndpoint getInternalEndpoint(QName service, String name) {
422 return endpointRegistry.getInternalEndpoint(service, name);
423 }
424
425 /**
426 * @param serviceName
427 * @return endpoints
428 */
429 public ServiceEndpoint[] getEndpointsForService(QName serviceName) {
430 return endpointRegistry.getEndpointsForService(serviceName);
431 }
432
433 /**
434 * @param interfaceName
435 * @return endpoints
436 */
437 public ServiceEndpoint[] getExternalEndpoints(QName interfaceName) {
438 return endpointRegistry.getExternalEndpointsForInterface(interfaceName);
439 }
440
441 /**
442 * @param serviceName
443 * @return endpoints
444 */
445 public ServiceEndpoint[] getExternalEndpointsForService(QName serviceName) {
446 return endpointRegistry.getExternalEndpointsForService(serviceName);
447 }
448
449 /**
450 * REgister a local Component
451 *
452 * @param name
453 * @param description
454 * @param component
455 * @param dc
456 * @param binding
457 * @param service
458 * @return ComponentConnector
459 * @throws JBIException
460 */
461 public ComponentMBeanImpl registerComponent(ComponentNameSpace name,
462 String description,
463 Component component,
464 boolean binding,
465 boolean service,
466 String[] sharedLibs) throws JBIException {
467 return componentRegistry.registerComponent(name, description, component, binding, service, sharedLibs);
468 }
469
470 /**
471 * @param component
472 * @return ComponentConnector
473 */
474 public void deregisterComponent(ComponentMBeanImpl component) {
475 componentRegistry.deregisterComponent(component);
476 }
477
478 /**
479 * @return all local ComponentConnectors
480 */
481 public Collection<ComponentMBeanImpl> getComponents() {
482 return componentRegistry.getComponents();
483 }
484
485 /**
486 * Get a Component
487 * @param cns
488 * @return the Component
489 */
490 public ComponentMBeanImpl getComponent(ComponentNameSpace cns) {
491 return componentRegistry.getComponent(cns);
492 }
493
494 /**
495 * Get a Component
496 * @param name
497 * @return the Componment
498 */
499 public ComponentMBeanImpl getComponent(String name) {
500 ComponentNameSpace cns = new ComponentNameSpace(container.getName(), name);
501 return getComponent(cns);
502 }
503
504 /**
505 * Get a list of all engines currently installed.
506 * @return array of JMX object names of all installed SEs.
507 */
508 public ObjectName[] getEngineComponents() {
509 ObjectName[] result = null;
510 List<ObjectName> tmpList = new ArrayList<ObjectName>();
511 for (ComponentMBeanImpl lcc : getComponents()) {
512 if (!lcc.isPojo() && lcc.isService() && lcc.getMBeanName() != null) {
513 tmpList.add(lcc.getMBeanName());
514 }
515 }
516 result = new ObjectName[tmpList.size()];
517 tmpList.toArray(result);
518 return result;
519
520 }
521
522 /**
523 * Get a list of all binding components currently installed.
524 * @return array of JMX object names of all installed BCs.
525 */
526 public ObjectName[] getBindingComponents() {
527 ObjectName[] result = null;
528 List<ObjectName> tmpList = new ArrayList<ObjectName>();
529 for (ComponentMBeanImpl lcc : getComponents()) {
530 if (!lcc.isPojo() && lcc.isBinding() && lcc.getMBeanName() != null) {
531 tmpList.add(lcc.getMBeanName());
532 }
533 }
534 result = new ObjectName[tmpList.size()];
535 tmpList.toArray(result);
536 return result;
537 }
538
539 /**
540 * Get a list of all pojos currently installed.
541 * @return array of JMX object names of all installed PJOJO Conponents.
542 */
543 public ObjectName[] getPojoComponents() {
544 ObjectName[] result = null;
545 List<ObjectName> tmpList = new ArrayList<ObjectName>();
546 for (ComponentMBeanImpl lcc : getComponents()) {
547 if (lcc.isPojo() && lcc.getMBeanName() != null) {
548 tmpList.add(lcc.getMBeanName());
549 }
550 }
551 result = new ObjectName[tmpList.size()];
552 tmpList.toArray(result);
553 return result;
554 }
555
556 /**
557 * Register All subscriptions
558 * @param context
559 * @param as
560 */
561 public void registerSubscriptions(ComponentContextImpl context, ActivationSpec as) {
562 QName service = as.getService();
563 String endpointName = as.getEndpoint();
564 InternalEndpoint endpoint = new InternalEndpoint(context.getComponentNameSpace(), endpointName, service);
565 SubscriptionSpec[] specs = as.getSubscriptions();
566 if (specs != null) {
567 for (int i = 0; i < specs.length; i++) {
568 registerSubscription(context, specs[i], endpoint);
569 }
570 }
571 }
572
573 /**
574 * Deregister All subscriptions
575 * @param context
576 * @param as
577 */
578 public void deregisterSubscriptions(ComponentContextImpl context, ActivationSpec as) {
579 SubscriptionSpec[] specs = as.getSubscriptions();
580 if (specs != null) {
581 for (int i = 0; i < specs.length; i++) {
582 deregisterSubscription(context, specs[i]);
583 }
584 }
585 }
586
587 /**
588 * @param context
589 * @param subscription
590 * @param endpoint
591 */
592 public void registerSubscription(ComponentContextImpl context, SubscriptionSpec subscription, ServiceEndpoint endpoint) {
593 InternalEndpoint sei = (InternalEndpoint)endpoint;
594 subscription.setName(context.getComponentNameSpace());
595 subscriptionRegistry.registerSubscription(subscription, sei);
596 }
597
598 /**
599 * @param context
600 * @param subscription
601 * @return the ServiceEndpoint
602 */
603 public InternalEndpoint deregisterSubscription(ComponentContextImpl context, SubscriptionSpec subscription) {
604 subscription.setName(context.getComponentNameSpace());
605 return subscriptionRegistry.deregisterSubscription(subscription);
606 }
607
608
609 /**
610 * @param exchange
611 * @return a List of matching endpoints - can return null if no matches
612 */
613 public List<InternalEndpoint> getMatchingSubscriptionEndpoints(MessageExchangeImpl exchange) {
614 return subscriptionRegistry.getMatchingSubscriptionEndpoints(exchange);
615 }
616
617 /**
618 * Register a service assembly
619 * @param sa
620 * @return true if not already registered
621 * @throws DeploymentException
622 */
623 public ServiceAssemblyLifeCycle registerServiceAssembly(ServiceAssembly sa,
624 ServiceAssemblyEnvironment env) throws DeploymentException {
625 return serviceAssemblyRegistry.register(sa, env);
626 }
627
628 /**
629 * Register a service assembly
630 * @param sa
631 * @return true if not already registered
632 * @throws DeploymentException
633 */
634 public ServiceAssemblyLifeCycle registerServiceAssembly(ServiceAssembly sa,
635 String[] suKeys,
636 ServiceAssemblyEnvironment env) throws DeploymentException {
637 return serviceAssemblyRegistry.register(sa, suKeys, env);
638 }
639
640 /**
641 * Un-register a service assembly
642 * @param saName
643 * @return true if successfully unregistered
644 */
645 public boolean unregisterServiceAssembly(String saName) {
646 return serviceAssemblyRegistry.unregister(saName);
647 }
648
649 /**
650 * Get a named ServiceAssembly
651 * @param name
652 * @return the ServiceAssembly or null if it doesn't exist
653 */
654 public ServiceAssemblyLifeCycle getServiceAssembly(String saName) {
655 return serviceAssemblyRegistry.getServiceAssembly(saName);
656 }
657
658 /**
659 * Returns a list of Service Units that are currently deployed to the given component.
660 *
661 * @param componentName name of the component.
662 * @return List of deployed service units
663 */
664 public ServiceUnitLifeCycle[] getDeployedServiceUnits(String componentName) {
665 List<ServiceUnitLifeCycle> tmpList = new ArrayList<ServiceUnitLifeCycle>();
666 for (ServiceUnitLifeCycle su : serviceUnits.values()) {
667 if (su.getComponentName().equals(componentName)) {
668 tmpList.add(su);
669 }
670 }
671 ServiceUnitLifeCycle[] result = new ServiceUnitLifeCycle[tmpList.size()];
672 tmpList.toArray(result);
673 return result;
674 }
675
676 /**
677 * Return a list of all service units.
678 *
679 * @return list of all service units
680 */
681 public Collection<ServiceUnitLifeCycle> getServiceUnits() {
682 return serviceUnits.values();
683 }
684
685 public Collection<ServiceAssemblyLifeCycle> getServiceAssemblies() {
686 return serviceAssemblyRegistry.getServiceAssemblies();
687 }
688
689 /**
690 * Returns a list of Service Assemblies deployed to the JBI enviroment.
691 *
692 * @return list of Service Assembly Name's.
693 */
694 public String[] getDeployedServiceAssemblies() {
695 return serviceAssemblyRegistry.getDeployedServiceAssemblies();
696 }
697
698 /**
699 * Returns a list of Service Assemblies that contain SUs for the given component.
700 *
701 * @param componentName name of the component.
702 * @return list of Service Assembly names.
703 */
704 public String[] getDeployedServiceAssembliesForComponent(String componentName) {
705 return serviceAssemblyRegistry.getDeployedServiceAssembliesForComponent(componentName);
706 }
707
708 /**
709 * Returns a list of components(to which SUs are targeted for) in a Service Assembly.
710 *
711 * @param saName name of the service assembly.
712 * @return list of component names.
713 */
714 public String[] getComponentsForDeployedServiceAssembly(String saName) {
715 return serviceAssemblyRegistry.getComponentsForDeployedServiceAssembly(saName);
716 }
717
718 /**
719 * Returns a boolean value indicating whether the SU is currently deployed.
720 *
721 * @param componentName - name of component.
722 * @param suName - name of the Service Unit.
723 * @return boolean value indicating whether the SU is currently deployed.
724 */
725 public boolean isSADeployedServiceUnit(String componentName, String suName) {
726 return serviceAssemblyRegistry.isDeployedServiceUnit(componentName, suName);
727 }
728
729 /**
730 * Get a ServiceUnit by its key.
731 *
732 * @param suKey the key of the service unit
733 * @return the ServiceUnit or null of it doesn't exist
734 */
735 public ServiceUnitLifeCycle getServiceUnit(String suKey) {
736 return serviceUnits.get(suKey);
737 }
738
739 /**
740 * Register a ServiceUnit.
741 *
742 * @param su the service unit to register
743 * @param serviceAssembly the service assembly the service unit belongs to
744 * @return the service unit key
745 */
746 public String registerServiceUnit(ServiceUnit su, String saName, File suDir) {
747 ServiceUnitLifeCycle sulc = new ServiceUnitLifeCycle(
748 su,
749 saName,
750 this,
751 suDir);
752 this.serviceUnits.put(sulc.getKey(), sulc);
753 try {
754 ObjectName objectName = getContainer().getManagementContext().createObjectName(sulc);
755 getContainer().getManagementContext().registerMBean(objectName, sulc, ServiceUnitMBean.class);
756 } catch (JMException e) {
757 LOG.error("Could not register MBean for service unit", e);
758 }
759 return sulc.getKey();
760 }
761
762 /**
763 * Unregister a ServiceUnit by its key.
764 *
765 * @param suKey the key of the service unit
766 */
767 public void unregisterServiceUnit(String suKey) {
768 ServiceUnitLifeCycle sulc = this.serviceUnits.remove(suKey);
769 if (sulc != null) {
770 try {
771 getContainer().getManagementContext().unregisterMBean(sulc);
772 } catch (JBIException e) {
773 LOG.error("Could not unregister MBean for service unit", e);
774 }
775 }
776 }
777
778 public void registerSharedLibrary(org.apache.servicemix.jbi.deployment.SharedLibrary sl,
779 File installationDir) {
780 SharedLibrary library = new SharedLibrary(sl, installationDir);
781 this.sharedLibraries.put(library.getName(), library);
782 try {
783 ObjectName objectName = getContainer().getManagementContext().createObjectName(library);
784 getContainer().getManagementContext().registerMBean(objectName, library, SharedLibraryMBean.class);
785 } catch (JMException e) {
786 LOG.error("Could not register MBean for service unit", e);
787 }
788 checkPendingComponents();
789 }
790
791 public void unregisterSharedLibrary(String name) {
792 // TODO: check for components depending on this library,
793 // shutdown them and add them to the list of pending components
794 SharedLibrary sl = this.sharedLibraries.remove(name);
795 if (sl != null) {
796 try {
797 getContainer().getManagementContext().unregisterMBean(sl);
798 sl.dispose();
799 } catch (JBIException e) {
800 LOG.error("Could not unregister MBean for shared library", e);
801 }
802 }
803 }
804
805 public SharedLibrary getSharedLibrary(String name) {
806 return sharedLibraries.get(name);
807 }
808
809 public Collection<SharedLibrary> getSharedLibraries() {
810 return sharedLibraries.values();
811 }
812
813 public void registerEndpointConnection(QName fromSvc, String fromEp, QName toSvc, String toEp, String link) throws JBIException {
814 endpointRegistry.registerEndpointConnection(fromSvc, fromEp, toSvc, toEp, link);
815 }
816
817 public void unregisterEndpointConnection(QName fromSvc, String fromEp) {
818 endpointRegistry.unregisterEndpointConnection(fromSvc, fromEp);
819 }
820
821 public void registerInterfaceConnection(QName fromItf, QName toSvc, String toEp) throws JBIException {
822 endpointRegistry.registerInterfaceConnection(fromItf, toSvc, toEp);
823 }
824
825 public void unregisterInterfaceConnection(QName fromItf) {
826 endpointRegistry.unregisterInterfaceConnection(fromItf);
827 }
828
829 public void registerRemoteEndpoint(ServiceEndpoint endpoint) {
830 endpointRegistry.registerRemoteEndpoint((InternalEndpoint) endpoint);
831 }
832
833 public void unregisterRemoteEndpoint(ServiceEndpoint endpoint) {
834 endpointRegistry.unregisterRemoteEndpoint((InternalEndpoint) endpoint);
835 }
836
837 public void checkPendingAssemblies() {
838 executor.execute(new Runnable() {
839 public void run() {
840 startPendingAssemblies();
841 }
842 });
843 }
844
845 public void addPendingAssembly(ServiceAssemblyLifeCycle sa) {
846 if (!pendingAssemblies.contains(sa)) {
847 pendingAssemblies.add(sa);
848 }
849 }
850
851 protected synchronized void startPendingAssemblies() {
852 for (ServiceAssemblyLifeCycle sa : pendingAssemblies) {
853 ServiceUnitLifeCycle[] sus = sa.getDeployedSUs();
854 boolean ok = true;
855 for (int i = 0; i < sus.length; i++) {
856 ComponentMBeanImpl c = getComponent(sus[i].getComponentName());
857 if (c == null || !c.isStarted()) {
858 ok = false;
859 break;
860 }
861 }
862 if (ok) {
863 try {
864 sa.restore();
865 pendingAssemblies.remove(sa);
866 } catch (Exception e) {
867 LOG.error("Error trying to restore service assembly state", e);
868 }
869 }
870 }
871 }
872
873 public void checkPendingComponents() {
874 executor.execute(new Runnable() {
875 public void run() {
876 startPendingComponents();
877 }
878 });
879 }
880
881 public void addPendingComponent(ComponentMBeanImpl comp) {
882 if (!pendingComponents.contains(comp)) {
883 pendingComponents.add(comp);
884 }
885 }
886
887 protected synchronized void startPendingComponents() {
888 for (ComponentMBeanImpl lcc : pendingComponents) {
889 // TODO: restore component state if
890 }
891 }
892
893 public ObjectName[] getComponentNames() {
894 List<ObjectName> tmpList = new ArrayList<ObjectName>();
895 for (ComponentMBeanImpl lcc : getComponents()) {
896 tmpList.add(container.getManagementContext().createObjectName(lcc));
897 }
898 return tmpList.toArray(new ObjectName[tmpList.size()]);
899 }
900
901 public ObjectName[] getEndpointNames() {
902 List<ObjectName> tmpList = new ArrayList<ObjectName>();
903 for (Endpoint ep : container.getRegistry().getEndpointRegistry().getEndpointMBeans()) {
904 tmpList.add(container.getManagementContext().createObjectName(ep));
905 }
906 return tmpList.toArray(new ObjectName[tmpList.size()]);
907 }
908
909 public ObjectName[] getServiceAssemblyNames() {
910 List<ObjectName> tmpList = new ArrayList<ObjectName>();
911 for (ServiceAssemblyLifeCycle sa : getServiceAssemblies()) {
912 tmpList.add(container.getManagementContext().createObjectName(sa));
913 }
914 return tmpList.toArray(new ObjectName[tmpList.size()]);
915 }
916
917 public ObjectName[] getServiceUnitNames() {
918 List<ObjectName> tmpList = new ArrayList<ObjectName>();
919 for (ServiceUnitLifeCycle su : serviceUnits.values()) {
920 tmpList.add(container.getManagementContext().createObjectName(su));
921 }
922 return tmpList.toArray(new ObjectName[tmpList.size()]);
923 }
924
925 public ObjectName[] getSharedLibraryNames() {
926 List<ObjectName> tmpList = new ArrayList<ObjectName>();
927 for (SharedLibrary sl : sharedLibraries.values()) {
928 tmpList.add(container.getManagementContext().createObjectName(sl));
929 }
930 return tmpList.toArray(new ObjectName[tmpList.size()]);
931 }
932
933 /**
934 * Get an array of MBeanAttributeInfo
935 *
936 * @return array of AttributeInfos
937 * @throws JMException
938 */
939 public MBeanAttributeInfo[] getAttributeInfos() throws JMException {
940 AttributeInfoHelper helper = new AttributeInfoHelper();
941 helper.addAttribute(getObjectToManage(), "componentNames", "list of components");
942 helper.addAttribute(getObjectToManage(), "serviceUnitNames", "list of service units");
943 helper.addAttribute(getObjectToManage(), "serviceAssemblyNames", "list of service assemblies");
944 helper.addAttribute(getObjectToManage(), "endpointNames", "list of endpoints");
945 helper.addAttribute(getObjectToManage(), "sharedLibraryNames", "list of shared libraries");
946 return AttributeInfoHelper.join(super.getAttributeInfos(), helper.getAttributeInfos());
947 }
948
949 /**
950 * Cancel pending exchanges in all components
951 */
952 public void cancelPendingExchanges() {
953 for (ComponentMBeanImpl mbean : componentRegistry.getComponents()) {
954 DeliveryChannelImpl channel = mbean.getDeliveryChannel();
955 if (channel != null) {
956 channel.cancelPendingExchanges();
957 }
958 }
959
960 }
961
962 }