From d7601ace468c4c5749c3b4c9617ba969db661e4f Mon Sep 17 00:00:00 2001 From: rcernich Date: Wed, 3 Jul 2013 14:47:36 -0600 Subject: [PATCH] SWITCHYARD-1694 rework message metrics calculations --- .../org/switchyard/admin/Application.java | 18 ++ .../java/org/switchyard/admin/Component.java | 30 +++- .../java/org/switchyard/admin/SwitchYard.java | 18 -- .../admin/base/BaseApplication.java | 154 ++++++++++++++++-- .../switchyard/admin/base/BaseComponent.java | 64 +++++--- .../switchyard/admin/base/BaseSwitchYard.java | 34 ---- .../admin/base/SwitchYardBuilder.java | 40 +---- .../base/MessageMetricsCollectionTest.java | 36 +++- .../admin/base/SwitchYardBuilderTest.java | 23 ++- .../admin/base/SwitchYardBuilderTestBase.java | 13 +- admin/src/test/resources/switchyard.xml | 5 +- .../java/org/switchyard/ServiceDomain.java | 13 ++ .../org/switchyard/deploy/ComponentNames.java | 16 ++ .../deploy/ServiceDomainManager.java | 11 +- .../org/switchyard/internal/DomainImpl.java | 11 ++ 15 files changed, 336 insertions(+), 150 deletions(-) diff --git a/admin/src/main/java/org/switchyard/admin/Application.java b/admin/src/main/java/org/switchyard/admin/Application.java index e5faada11..16017c298 100644 --- a/admin/src/main/java/org/switchyard/admin/Application.java +++ b/admin/src/main/java/org/switchyard/admin/Application.java @@ -61,6 +61,24 @@ public interface Application { */ public ComponentService getComponentService(QName componentServiceName); + /** + * List of implementation and gateway components currently installed in + * SwitchYard runtime. + * + * @return list of SwitchYard components + */ + public List getComponents(); + + /** + * Find a component with the specified name. + * + * @param name + * the name of the component. + * @return the component with the specified name; may be null if a component + * with the specified name is not registered with the system. + */ + public Component getComponent(QName name); + /** * @return the transformers provided by this application */ diff --git a/admin/src/main/java/org/switchyard/admin/Component.java b/admin/src/main/java/org/switchyard/admin/Component.java index 71b9af040..722517117 100644 --- a/admin/src/main/java/org/switchyard/admin/Component.java +++ b/admin/src/main/java/org/switchyard/admin/Component.java @@ -14,29 +14,47 @@ package org.switchyard.admin; +import java.util.List; import java.util.Map; -import java.util.Set; + +import javax.xml.namespace.QName; /** * Component * - * Represents a SwitchYard component registered with the SwitchYard runtime - * (e.g. camel). + * Represents a SwitchYard component within an application. */ public interface Component { /** * @return the name of this component. */ - String getName(); + QName getName(); /** - * @return supported activation types, e.g. bean, soap, etc. + * @return implementation type, e.g. bean, bpm, etc. */ - Set getTypes(); + String getType(); /** * @return component properties. */ Map getProperties(); + + /** + * @return the service provided by this component. + */ + ComponentService getService(); + + /** + * @return the references contained by this component. + */ + List getReferences(); + + /** + * @param componentReferenceName the name of a reference required by + * this component. + * @return the requested reference, may be null + */ + ComponentReference getReference(QName componentReferenceName); } diff --git a/admin/src/main/java/org/switchyard/admin/SwitchYard.java b/admin/src/main/java/org/switchyard/admin/SwitchYard.java index ba6c73842..9d59beecf 100644 --- a/admin/src/main/java/org/switchyard/admin/SwitchYard.java +++ b/admin/src/main/java/org/switchyard/admin/SwitchYard.java @@ -39,14 +39,6 @@ public interface SwitchYard extends MessageMetricsAware { */ List getApplications(); - /** - * List of implementation and gateway components currently installed in - * SwitchYard runtime. - * - * @return list of SwitchYard components - */ - List getComponents(); - /** * List of services currently registered in the SwitchYard runtime. * @@ -61,16 +53,6 @@ public interface SwitchYard extends MessageMetricsAware { */ List getReferences(); - /** - * Find a component with the specified name. - * - * @param name - * the name of the component. - * @return the component with the specified name; may be null if a component - * with the specified name is not registered with the system. - */ - Component getComponent(String name); - /** * Find an application with the specified name. * diff --git a/admin/src/main/java/org/switchyard/admin/base/BaseApplication.java b/admin/src/main/java/org/switchyard/admin/base/BaseApplication.java index 2788705a2..ae9024a22 100644 --- a/admin/src/main/java/org/switchyard/admin/base/BaseApplication.java +++ b/admin/src/main/java/org/switchyard/admin/base/BaseApplication.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.EventObject; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -23,32 +24,39 @@ import javax.xml.namespace.QName; +import org.switchyard.Exchange; import org.switchyard.admin.Application; +import org.switchyard.admin.Component; +import org.switchyard.admin.ComponentReference; import org.switchyard.admin.ComponentService; import org.switchyard.admin.Reference; import org.switchyard.admin.Service; import org.switchyard.admin.Transformer; import org.switchyard.admin.Validator; import org.switchyard.config.model.composite.ComponentModel; +import org.switchyard.config.model.composite.ComponentReferenceModel; import org.switchyard.config.model.composite.ComponentServiceModel; import org.switchyard.config.model.composite.CompositeReferenceModel; import org.switchyard.config.model.composite.CompositeServiceModel; import org.switchyard.config.model.composite.InterfaceModel; import org.switchyard.config.model.property.PropertyModel; -import org.switchyard.config.model.switchyard.EsbInterfaceModel; import org.switchyard.config.model.switchyard.SwitchYardModel; import org.switchyard.config.model.transform.TransformModel; import org.switchyard.config.model.validate.ValidateModel; +import org.switchyard.deploy.ComponentNames; import org.switchyard.deploy.internal.AbstractDeployment; +import org.switchyard.event.EventObserver; +import org.switchyard.runtime.event.ExchangeCompletionEvent; /** * Base implementation of Application. */ -public class BaseApplication implements Application { +public class BaseApplication implements Application, EventObserver { private final QName _name; private Map _services; private Map _references; + private Map _components; private Map _componentServices; private List _transformers; private List _validators; @@ -69,6 +77,14 @@ public BaseApplication(AbstractDeployment deployment) { addServices(); addReferences(); addProperties(); + + // register event listener for metrics + _deployment.getDomain().addEventObserver(this, ExchangeCompletionEvent.class); + } + + void dispose() { + // remove event listener for metrics + _deployment.getDomain().removeObserver(this); } @Override @@ -129,6 +145,16 @@ public ComponentService getComponentService(QName componentServiceName) { return _componentServices.get(componentServiceName); } + @Override + public Component getComponent(QName name) { + return _components.get(name); + } + + @Override + public List getComponents() { + return new ArrayList(_components.values()); + } + @Override public List getTransformers() { return Collections.unmodifiableList(_transformers); @@ -145,6 +171,13 @@ public Map getProperties() { return Collections.unmodifiableMap(_properties); } + @Override + public void notify(EventObject event) { + if (event instanceof ExchangeCompletionEvent) { + exchangeCompleted((ExchangeCompletionEvent)event); + } + } + /** * @return the deployment associated with this application. */ @@ -195,35 +228,120 @@ private void addValidators() { } private void addComponents() { + _components = new LinkedHashMap(); _componentServices = new LinkedHashMap(); if (getConfig().getComposite().getComponents() == null) { return; } - for (ComponentModel component : getConfig().getComposite().getComponents()) { - // TODO: we need a separate node for components, to support cases - // where the component implements no services. Should also consider - // multiple services per component. - if (component.getServices().size() > 0) { - ComponentServiceModel service = component.getServices().get(0); - if (service.getInterface() == null || EsbInterfaceModel.ESB.equals(service.getInterface().getType())) { - _componentServices.put(service.getQName(), new BaseNoopComponentService(service, component, this)); - } else if (InterfaceModel.JAVA.equals(service.getInterface().getType())) { - _componentServices.put(service.getQName(), new BaseJavaComponentService(service, component, this)); - } else if (InterfaceModel.WSDL.equals(service.getInterface().getType())) { - _componentServices.put(service.getQName(), new BaseWsdlComponentService(service, component, this)); + for (ComponentModel componentConfig : getConfig().getComposite().getComponents()) { + // TODO: Should consider multiple services per component. + final ComponentService service; + if (componentConfig.getServices().size() > 0) { + ComponentServiceModel serviceConfig = componentConfig.getServices().get(0); + if (serviceConfig.getInterface() == null) { + service = new BaseNoopComponentService(serviceConfig, componentConfig, this); + } else if (InterfaceModel.JAVA.equals(serviceConfig.getInterface().getType())) { + service = new BaseJavaComponentService(serviceConfig, componentConfig, this); + } else if (InterfaceModel.WSDL.equals(serviceConfig.getInterface().getType())) { + service = new BaseWsdlComponentService(serviceConfig, componentConfig, this); + } else { + // ESB or unknown + service = new BaseNoopComponentService(serviceConfig, componentConfig, this); + } + _componentServices.put(serviceConfig.getQName(), service); + } else { + service = null; + } + final Map references = new LinkedHashMap(); + if (service == null) { + for (ComponentReferenceModel referenceModel : componentConfig.getReferences()) { + references.put(referenceModel.getQName(), new BaseComponentReference(referenceModel.getQName(), + getInterfaceName(referenceModel.getInterface()))); + } + } else { + for (ComponentReference reference : service.getReferences()) { + references.put(reference.getName(), reference); } } + final BaseComponent component = new BaseComponent(componentConfig.getQName(), + componentConfig.getImplementation() == null ? "null" : componentConfig.getImplementation() + .getType(), service, references, convertProperties(componentConfig.getProperties())); + _components.put(component.getName(), component); } } private void addProperties() { - _properties = new LinkedHashMap(); if (getConfig().getComposite() == null) { - return; + _properties = convertProperties(null); + } else { + _properties = convertProperties(getConfig().getComposite().getProperties()); + } + } + + private Map convertProperties(final Map properties) { + final Map retVal = new LinkedHashMap(); + if (properties == null) { + return retVal; } - for (PropertyModel property : getConfig().getComposite().getProperties().values()) { - _properties.put(property.getName(), property.getValue()); + for (PropertyModel property : properties.values()) { + retVal.put(property.getName(), property.getValue()); } + return retVal; } + private String getInterfaceName(InterfaceModel interfaceModel) { + if (interfaceModel == null) { + return null; + } + return interfaceModel.getInterface(); + } + + void exchangeCompleted(final ExchangeCompletionEvent event) { + // Recording metrics at multiple levels at this point instead of + // aggregating them. + final Exchange exchange = event.getExchange(); + final QName qualifiedReferenceName = exchange.getConsumer().getName(); + final QName referenceName = ComponentNames.unqualify(qualifiedReferenceName); + final QName componentName = ComponentNames.comopnentName(qualifiedReferenceName); + if (componentName == null) { + // service gateway initiated exchange + final Service service = _services.get(referenceName); + if (service != null) { + /* + * service also records promoted component service metrics too + * (i.e. producer metrics) + */ + service.recordMetrics(exchange); + } + } else { + // component reference initiated exchange + // 1 - recored service metrics (producer) + final QName serviceName = exchange.getProvider().getName(); + final ComponentService service = _componentServices.get(serviceName); + if (service == null) { + // must be routed to composite reference + final Reference reference = _references.get(serviceName); + if (reference != null) { + reference.recordMetrics(exchange); + } + } else { + /* + * XXX: this could throw off metrics for composite services + * since they simply return the metrics for the component + * service they promote. That said, the metrics for the gateways + * will correlate with the global metrics. + */ + service.recordMetrics(exchange); + } + // 2 - record reference metrics (consumer) + final Component component = _components.get(componentName); + if (component != null) { + final ComponentReference reference = component.getReference(referenceName); + if (reference != null) { + reference.recordMetrics(exchange); + } + // else may have been an internal invocation, e.g. orders demo + } + } + } } diff --git a/admin/src/main/java/org/switchyard/admin/base/BaseComponent.java b/admin/src/main/java/org/switchyard/admin/base/BaseComponent.java index bd13efc77..993a8f347 100644 --- a/admin/src/main/java/org/switchyard/admin/base/BaseComponent.java +++ b/admin/src/main/java/org/switchyard/admin/base/BaseComponent.java @@ -14,13 +14,16 @@ package org.switchyard.admin.base; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; -import java.util.Set; + +import javax.xml.namespace.QName; import org.switchyard.admin.Component; +import org.switchyard.admin.ComponentReference; +import org.switchyard.admin.ComponentService; /** * BaseComponent @@ -29,27 +32,27 @@ */ public class BaseComponent implements Component { - private Map _properties; - private String _name; - private Set _types; + private final QName _name; + private final String _type; + private final ComponentService _service; + private final Map _references; + private final Map _properties; /** * Create a new BaseComponent. * * @param name the name of the component. - * @param types the type of the component. + * @param type the type of the component. + * @param service the service provided by this component (may be null). + * @param references the references required by this component. * @param properties the configuration properties of this component. */ - public BaseComponent(String name, Collection types, Map properties) { + public BaseComponent(QName name, String type, ComponentService service, Map references, Map properties) { _name = name; - _types = new HashSet(); - if (types != null) { - _types.addAll(types); - } - _properties = new HashMap(); - if (properties != null) { - _properties.putAll(properties); - } + _type = type; + _service = service; + _references = references; + _properties = properties; } @Override @@ -58,12 +61,33 @@ public Map getProperties() { } @Override - public String getName() { + public QName getName() { return _name; } @Override - public Set getTypes() { - return _types; + public String getType() { + return _type; + } + + @Override + public ComponentService getService() { + return _service; + } + + @Override + public List getReferences() { + if (_references == null) { + return Collections.emptyList(); + } + return new ArrayList(_references.values()); + } + + @Override + public ComponentReference getReference(QName componentReferenceName) { + if (_references == null) { + return null; + } + return _references.get(componentReferenceName); } } diff --git a/admin/src/main/java/org/switchyard/admin/base/BaseSwitchYard.java b/admin/src/main/java/org/switchyard/admin/base/BaseSwitchYard.java index 14fede9a7..abdafd219 100644 --- a/admin/src/main/java/org/switchyard/admin/base/BaseSwitchYard.java +++ b/admin/src/main/java/org/switchyard/admin/base/BaseSwitchYard.java @@ -27,7 +27,6 @@ import javax.xml.namespace.QName; import org.switchyard.admin.Application; -import org.switchyard.admin.Component; import org.switchyard.admin.Reference; import org.switchyard.admin.Service; import org.switchyard.admin.SwitchYard; @@ -43,7 +42,6 @@ public class BaseSwitchYard extends BaseMessageMetricsAware implements SwitchYar private final String _version; private ConcurrentMap _applications = new ConcurrentHashMap(); - private ConcurrentMap _components = new ConcurrentHashMap(); private List _services = Collections.synchronizedList(new LinkedList()); private List _references = Collections.synchronizedList(new LinkedList()); private Set _socketBindingNames = Collections.synchronizedSet(new HashSet()); @@ -101,33 +99,6 @@ public BaseSwitchYard removeApplication(QName name) { return this; } - @Override - public List getComponents() { - return new ArrayList(_components.values()); - } - - /** - * Add a component. - * - * @param component component to add - * @return reference to this admin object - */ - public BaseSwitchYard addComponent(Component component) { - _components.putIfAbsent(component.getName(), component); - return this; - } - - /** - * Remove a component. - * - * @param component component to remove - * @return reference to this admin object - */ - public BaseSwitchYard removeComponent(Component component) { - _components.remove(component.getName()); - return this; - } - @Override public List getServices() { return new ArrayList(_services); @@ -190,11 +161,6 @@ public String getVersion() { return _version; } - @Override - public Component getComponent(String name) { - return _components.get(name); - } - @Override public Application getApplication(QName name) { return _applications.get(name); diff --git a/admin/src/main/java/org/switchyard/admin/base/SwitchYardBuilder.java b/admin/src/main/java/org/switchyard/admin/base/SwitchYardBuilder.java index 3e4ed4fe2..9273ef83f 100644 --- a/admin/src/main/java/org/switchyard/admin/base/SwitchYardBuilder.java +++ b/admin/src/main/java/org/switchyard/admin/base/SwitchYardBuilder.java @@ -18,10 +18,6 @@ import javax.xml.namespace.QName; import org.switchyard.Exchange; -import org.switchyard.admin.Application; -import org.switchyard.admin.ComponentReference; -import org.switchyard.admin.Reference; -import org.switchyard.admin.Service; import org.switchyard.admin.SwitchYard; import org.switchyard.admin.mbean.internal.LocalManagement; import org.switchyard.admin.mbean.internal.MBeans; @@ -123,42 +119,22 @@ void applicationDeployed(ApplicationDeployedEvent event) { void applicationUndeployed(ApplicationUndeployedEvent event) { AbstractDeployment deployment = event.getDeployment(); if (deployment.getName() != null) { - Application app = _switchYard.getApplication(deployment.getName()); + BaseApplication app = (BaseApplication) _switchYard.getApplication(deployment.getName()); if (app != null) { MBeans.unregisterApplication(app); _switchYard.removeApplication(deployment.getName()); + app.dispose(); } } } void exchangeCompleted(ExchangeCompletionEvent event) { - // Recording metrics at multiple levels at this point instead of - // aggregating them. - Exchange exchange = event.getExchange(); - QName serviceName = exchange.getProvider().getName(); - QName referenceName = ComponentNames.unqualify(exchange.getConsumer().getName()); - for (Service service : _switchYard.getServices()) { - if (service.getName().equals(serviceName)) { - // 1 - the aggregate switchyard stats - _switchYard.recordMetrics(exchange); - - // 2 - service stats - service.recordMetrics(exchange); - } - // 3 - reference stats - // XXX: this looks like it lumps the stats into every component reference with a matching name - for (ComponentReference reference : service.getPromotedService().getReferences()) { - if (reference.getName().equals(referenceName)) { - ((BaseComponentReference)reference).recordMetrics(exchange); - } - } - } - // 4 - reference stats - for (Reference reference : _switchYard.getReferences()) { - if (reference.getName().equals(referenceName)) { - reference.recordMetrics(exchange); - break; - } + final Exchange exchange = event.getExchange(); + final QName componentName = ComponentNames.comopnentName(exchange.getConsumer().getName()); + if (componentName == null) { + // service gateway initiated exchange + _switchYard.recordMetrics(exchange); } + // else - don't include internally generated exchanges } } diff --git a/admin/src/test/java/org/switchyard/admin/base/MessageMetricsCollectionTest.java b/admin/src/test/java/org/switchyard/admin/base/MessageMetricsCollectionTest.java index 7da35102d..62881164d 100644 --- a/admin/src/test/java/org/switchyard/admin/base/MessageMetricsCollectionTest.java +++ b/admin/src/test/java/org/switchyard/admin/base/MessageMetricsCollectionTest.java @@ -25,6 +25,7 @@ import org.switchyard.Exchange; import org.switchyard.ExchangeState; import org.switchyard.Property; +import org.switchyard.admin.ComponentReference; import org.switchyard.admin.ComponentService; import org.switchyard.deploy.ComponentNames; import org.switchyard.runtime.event.ExchangeCompletionEvent; @@ -36,8 +37,9 @@ public class MessageMetricsCollectionTest extends SwitchYardBuilderTestBase { private static final String OPERATION_NAME = "greet"; private static final QName TEST_SERVICE = new QName("urn:m1app:example:1.0", "M1AppService"); + private static final QName TEST_ANOTHER_SERVICE = new QName("urn:m1app:example:1.0", "AnotherService"); private static final QName TEST_PROMOTED_SERVICE = new QName("urn:m1app:example:1.0", "SimpleService"); - private static final QName TEST_REFERENCE = ComponentNames.qualify(TEST_PROMOTED_SERVICE, new QName("urn:m1app:example:1.0", "anotherService")); + private static final QName TEST_ANOTHER_REFERENCE = ComponentNames.qualify(TEST_PROMOTED_SERVICE, TEST_ANOTHER_SERVICE); private static final String TEST_GATEWAY = "_M1AppService_sca_1"; public MessageMetricsCollectionTest() throws Exception { @@ -49,7 +51,7 @@ public void testSwitchyardLevelCollection() { Exchange ex = createMock(); defaultExpectations(ex); - _builder.notify(new ExchangeCompletionEvent(ex)); + _deployment.getDomain().getEventPublisher().publish(new ExchangeCompletionEvent(ex)); assertEquals(1, _switchYard.getMessageMetrics().getSuccessCount()); assertEquals(10.0, _switchYard.getMessageMetrics().getAverageProcessingTime(), 0); @@ -60,9 +62,10 @@ public void testOperationLevelCollection() { Exchange ex = createMock(); defaultExpectations(ex); - Mockito.when(ex.getContract().getProviderOperation().getName()).thenReturn(OPERATION_NAME); + when(ex.getContext().getPropertyValue(ExchangeCompletionEvent.GATEWAY_NAME)).thenReturn(TEST_GATEWAY); + when(ex.getContract().getProviderOperation().getName()).thenReturn(OPERATION_NAME); - _builder.notify(new ExchangeCompletionEvent(ex)); + _deployment.getDomain().getEventPublisher().publish(new ExchangeCompletionEvent(ex)); assertEquals(1, _switchYard.getMessageMetrics().getSuccessCount()); assertEquals(10.0, _switchYard.getMessageMetrics().getAverageProcessingTime(), 0); @@ -72,17 +75,36 @@ public void testOperationLevelCollection() { assertEquals(10.0, _switchYard.getApplication(TEST_APP).getService(TEST_SERVICE).getGateway(TEST_GATEWAY).getMessageMetrics().getAverageProcessingTime(), 0); } + @Test + public void testComponentReferenceInvocation() { + Exchange ex = createMock(); + defaultExpectations(ex); + + when(ex.getConsumer().getName()).thenReturn(TEST_ANOTHER_REFERENCE); + when(ex.getProvider().getName()).thenReturn(TEST_ANOTHER_SERVICE); + when(ex.getContract().getProviderOperation().getName()).thenReturn(OPERATION_NAME); + + _deployment.getDomain().getEventPublisher().publish(new ExchangeCompletionEvent(ex)); + + assertEquals(0, _switchYard.getMessageMetrics().getSuccessCount()); + assertEquals(0, _switchYard.getMessageMetrics().getAverageProcessingTime(), 0); + ComponentService componentService = _switchYard.getApplication(TEST_APP).getComponentService(TEST_ANOTHER_SERVICE); + assertEquals(10.0, componentService.getMessageMetrics().getAverageProcessingTime(), 0); + assertEquals(10.0, componentService.getServiceOperation(OPERATION_NAME).getMessageMetrics().getAverageProcessingTime(), 0); + ComponentReference componentReference = _switchYard.getApplication(TEST_APP).getComponent(TEST_PROMOTED_SERVICE).getReference(TEST_ANOTHER_SERVICE); + assertEquals(10.0, componentReference.getMessageMetrics().getAverageProcessingTime(), 0); + } + private Exchange createMock() { return mock(Exchange.class, Mockito.RETURNS_DEEP_STUBS); } private void defaultExpectations(Exchange ex) { - when(ex.getProvider().getName()).thenReturn(TEST_SERVICE); - when(ex.getConsumer().getName()).thenReturn(TEST_REFERENCE); + when(ex.getConsumer().getName()).thenReturn(TEST_SERVICE); + when(ex.getProvider().getName()).thenReturn(TEST_PROMOTED_SERVICE); when(ex.getState()).thenReturn(ExchangeState.OK); Property property = mock(Property.class); when(property.getValue()).thenReturn(new Long(10)); when(ex.getContext().getProperty(ExchangeCompletionEvent.EXCHANGE_DURATION)).thenReturn(property); - when(ex.getContext().getPropertyValue(ExchangeCompletionEvent.GATEWAY_NAME)).thenReturn(TEST_GATEWAY); } } diff --git a/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTest.java b/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTest.java index 707bc98f4..4e4af523c 100644 --- a/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTest.java +++ b/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTest.java @@ -18,9 +18,12 @@ import org.junit.Assert; import org.junit.Test; +import org.switchyard.ServiceDomain; import org.switchyard.config.model.ModelPuller; import org.switchyard.config.model.switchyard.SwitchYardModel; +import org.switchyard.deploy.ServiceDomainManager; import org.switchyard.deploy.event.ApplicationDeployedEvent; +import org.switchyard.deploy.event.ApplicationUndeployedEvent; import org.switchyard.deploy.internal.Deployment; public class SwitchYardBuilderTest extends SwitchYardBuilderTestBase { @@ -48,25 +51,33 @@ public void testComponent() { public void testNoComponentService() throws Exception{ Deployment testDeployment = new MockDeployment( new ModelPuller().pull("switchyard_multiappweb.xml", getClass()), - QName.valueOf("{urn:switchyard-quickstart-demo:multiapp:0.1.0}web")); - SwitchYardBuilder builder = new SwitchYardBuilder(); - builder.notify(new ApplicationDeployedEvent(testDeployment)); - - Assert.assertEquals(1, builder.getSwitchYard().getApplications().size()); + QName.valueOf("{urn:switchyard-quickstart-demo:multiapp:0.1.0}web"), _domainManager); + _domainManager.getEventManager().publish(new ApplicationDeployedEvent(testDeployment)); + Assert.assertEquals(2, _builder.getSwitchYard().getApplications().size()); + _domainManager.getEventManager().publish(new ApplicationUndeployedEvent(testDeployment)); + Assert.assertEquals(1, _builder.getSwitchYard().getApplications().size()); } } class MockDeployment extends Deployment { + private ServiceDomain _domain; private QName _name; - MockDeployment(SwitchYardModel config, QName name) { + MockDeployment(SwitchYardModel config, QName name, ServiceDomainManager sdm) { super(config); _name = name; + _domain = sdm.createDomain(name, config); } @Override public QName getName() { return _name; } + + @Override + public ServiceDomain getDomain() { + return _domain; + } + } diff --git a/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTestBase.java b/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTestBase.java index 6b42ef8f8..8d9909df8 100644 --- a/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTestBase.java +++ b/admin/src/test/java/org/switchyard/admin/base/SwitchYardBuilderTestBase.java @@ -21,6 +21,7 @@ import org.switchyard.admin.SwitchYard; import org.switchyard.config.model.ModelPuller; import org.switchyard.config.model.switchyard.SwitchYardModel; +import org.switchyard.deploy.ServiceDomainManager; import org.switchyard.deploy.event.ApplicationDeployedEvent; import org.switchyard.deploy.event.ApplicationUndeployedEvent; import org.switchyard.deploy.internal.Deployment; @@ -35,23 +36,27 @@ public class SwitchYardBuilderTestBase { protected SwitchYard _switchYard; protected Deployment _deployment; protected SwitchYardBuilder _builder; + protected ServiceDomainManager _domainManager; public SwitchYardBuilderTestBase() throws Exception { - _deployment = new MockDeployment(new ModelPuller().pull("switchyard.xml", getClass()), - TEST_APP); } @Before public void setUp() throws Exception { + _domainManager = new ServiceDomainManager(); _builder = new SwitchYardBuilder(); + _builder.init(_domainManager); _switchYard = _builder.getSwitchYard(); - _builder.notify(new ApplicationDeployedEvent(_deployment)); + _deployment = new MockDeployment(new ModelPuller().pull("switchyard.xml", getClass()), + TEST_APP, _domainManager); + _domainManager.getEventManager().publish(new ApplicationDeployedEvent(_deployment)); //Thread.sleep(300 * 1000); } @After public void tearDown() { - _builder.notify(new ApplicationUndeployedEvent(_deployment)); + _domainManager.getEventManager().publish(new ApplicationUndeployedEvent(_deployment)); + _builder.destroy(); } } \ No newline at end of file diff --git a/admin/src/test/resources/switchyard.xml b/admin/src/test/resources/switchyard.xml index 383509f81..7abe97b9b 100644 --- a/admin/src/test/resources/switchyard.xml +++ b/admin/src/test/resources/switchyard.xml @@ -38,7 +38,7 @@ - + @@ -70,9 +70,6 @@ - - - diff --git a/api/src/main/java/org/switchyard/ServiceDomain.java b/api/src/main/java/org/switchyard/ServiceDomain.java index fcc116ccf..ab1a7ed80 100644 --- a/api/src/main/java/org/switchyard/ServiceDomain.java +++ b/api/src/main/java/org/switchyard/ServiceDomain.java @@ -152,6 +152,19 @@ ServiceReference registerServiceReference(QName serviceName, */ ServiceDomain addEventObserver(EventObserver observer, Class eventType); + /** + * Remove all event registrations for a given EventObserver instance. + * @param observer the observer to unregister + */ + void removeObserver(EventObserver observer); + + /** + * Remove an EventObserver from a specific event type. + * @param observer the EventObserver to unregister + * @param event the event to unregister + */ + void removeObserverForEvent(EventObserver observer, Class event); + /** * Returns the EventPublisher for this domain, which can be used to notify * event observers of activity. diff --git a/deploy/base/src/main/java/org/switchyard/deploy/ComponentNames.java b/deploy/base/src/main/java/org/switchyard/deploy/ComponentNames.java index bb7723173..98a9f4cdd 100644 --- a/deploy/base/src/main/java/org/switchyard/deploy/ComponentNames.java +++ b/deploy/base/src/main/java/org/switchyard/deploy/ComponentNames.java @@ -73,4 +73,20 @@ public static QName unqualify(QName refName) { } return refName; } + + /** + * Return the qualified name of the component from the given service + * reference name, removing the name of the reference. + * + * @param refName service reference name + * @return component name without reference name included; null if no + * component prefix exists. + */ + public static QName comopnentName(QName refName) { + if (refName.getLocalPart().contains("/")) { + String name = refName.getLocalPart().split("/")[0]; + return new QName(refName.getNamespaceURI(), name); + } + return null; + } } diff --git a/deploy/base/src/main/java/org/switchyard/deploy/ServiceDomainManager.java b/deploy/base/src/main/java/org/switchyard/deploy/ServiceDomainManager.java index 19dd6686f..d112a468e 100644 --- a/deploy/base/src/main/java/org/switchyard/deploy/ServiceDomainManager.java +++ b/deploy/base/src/main/java/org/switchyard/deploy/ServiceDomainManager.java @@ -14,6 +14,7 @@ package org.switchyard.deploy; +import java.util.EventObject; import java.util.HashMap; import java.util.Map; @@ -111,7 +112,7 @@ public ServiceDomain createDomain(QName domainName, SwitchYardModel switchyardCo ServiceDomainSecurity serviceDomainSecurity = getServiceDomainSecurity(switchyardConfig); DomainImpl domain = new DomainImpl( - domainName, _registry, bus, transformerRegistry, validatorRegistry, _eventManager, serviceDomainSecurity); + domainName, _registry, bus, transformerRegistry, validatorRegistry, new DomainEventManager(), serviceDomainSecurity); camelContext.setServiceDomain(domain); // set properties on the domain @@ -173,4 +174,12 @@ private PropertiesModel getProperties(SwitchYardModel config) { return config.getDomain().getProperties(); } } + + private final class DomainEventManager extends EventManager { + @Override + public void publish(EventObject event) { + super.publish(event); + _eventManager.publish(event); + } + } } diff --git a/runtime/src/main/java/org/switchyard/internal/DomainImpl.java b/runtime/src/main/java/org/switchyard/internal/DomainImpl.java index 88cb45a1a..d0d8c72fb 100644 --- a/runtime/src/main/java/org/switchyard/internal/DomainImpl.java +++ b/runtime/src/main/java/org/switchyard/internal/DomainImpl.java @@ -228,6 +228,17 @@ public ServiceDomain addEventObserver(EventObserver observer, Class eventType) { + _eventManager.removeObserverForEvent(observer, eventType); + } + @Override public EventPublisher getEventPublisher() { return _eventManager;