INT-881, Decoupled SI Services configuration from service interaction with the Control Bus
This commit is contained in:
@@ -24,8 +24,8 @@ import org.osgi.framework.ServiceReference;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.integration.controlbus.ControlBus;
|
||||
import org.springframework.integration.osgi.AbstractSIConfigBundleTestDeployer;
|
||||
import org.springframework.integration.osgi.IntegrationOSGiConstants;
|
||||
import org.springframework.integration.osgi.stubs.SIBundleContextStub;
|
||||
import org.springframework.intergration.osgi.IntegrationOSGiConstants;
|
||||
|
||||
|
||||
/**
|
||||
@@ -40,12 +40,11 @@ public class BusConfigParserTests extends AbstractSIConfigBundleTestDeployer {
|
||||
ApplicationContext ac = this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/config/xml/",
|
||||
"BusConfigParserTests-default.xml");
|
||||
ControlBus controlBus = (ControlBus) ac.getBean(IntegrationOSGiConstants.DEFAULT_BUS_GROUP_NAME);
|
||||
ControlBus controlBus = (ControlBus) ac.getBean(ControlBusOSGiUtils.DEFAULT_BUS_GROUP_NAME);
|
||||
assertNotNull(controlBus);
|
||||
assertTrue(controlBus.getBusName().equals(IntegrationOSGiConstants.DEFAULT_BUS_GROUP_NAME));
|
||||
ServiceReference[] sr = bundleContext.getServiceReferences(ControlBus.class.getName(),
|
||||
"(&(" + IntegrationOSGiConstants.OSGI_BEAN_NAME + "=" +
|
||||
IntegrationOSGiConstants.DEFAULT_BUS_GROUP_NAME + "))");
|
||||
ControlBusOSGiUtils.DEFAULT_BUS_GROUP_NAME + "))");
|
||||
assertNotNull(sr);
|
||||
assertTrue(sr.length == 1);
|
||||
controlBus = (ControlBus) bundleContext.getService(sr[0]);
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.springframework.integration.osgi.AbstractSIConfigBundleTestDeployer;
|
||||
import org.springframework.integration.osgi.stubs.SIBundleContextStub;
|
||||
|
||||
/**
|
||||
* THis test bootstraps two instances of the Control Bus, then shuts down one demonstrating and testing
|
||||
* This test bootstraps two instances of the Control Bus, then shuts down one demonstrating and testing
|
||||
* transparent fail-over to another instance of the Control Bus
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
@@ -38,8 +38,9 @@ import org.springframework.integration.osgi.stubs.SIBundleContextStub;
|
||||
public class BusUsageFailoverTests extends AbstractSIConfigBundleTestDeployer {
|
||||
static MessageHandler handler = Mockito.mock(MessageHandler.class);
|
||||
|
||||
|
||||
@Test
|
||||
public void testDefaultControlBusConfig() throws Exception {
|
||||
public void testControlBusFailover() throws Exception {
|
||||
BundleContext bundleContext = SIBundleContextStub.getInstance();
|
||||
|
||||
ConfigurableApplicationContext primaryAc = this.deploySIConfig(bundleContext,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si-service="http://www.springframework.org/schema/integration/integration-service-extender"
|
||||
xmlns:si-control="http://www.springframework.org/schema/integration/integration-control-bus"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xmlns:osgi="http://www.springframework.org/schema/osgi"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/integration/integration-control-bus http://www.springframework.org/schema/integration/integration-control-bus/spring-integration-bus-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/integration-service-extender http://www.springframework.org/schema/integration/integration-service-extender/spring-integration-service-extender-1.0.xsd
|
||||
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd">
|
||||
|
||||
<si:publish-subscribe-channel id="channelA"/>
|
||||
<si:publish-subscribe-channel id="channelB"/>
|
||||
|
||||
<si:channel id="channelC"/>
|
||||
|
||||
<si-service:config>
|
||||
<si-service:export si-type="publish-subscribe-channel"/>
|
||||
<si-service:export ref="channelC"/>
|
||||
</si-service:config>
|
||||
|
||||
<osgi:reference id="channelA-reference" interface="org.springframework.integration.channel.SubscribableChannel"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si-service="http://www.springframework.org/schema/integration/integration-service-extender"
|
||||
xmlns:si-control="http://www.springframework.org/schema/integration/integration-control-bus"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xmlns:osgi="http://www.springframework.org/schema/osgi"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/integration/integration-control-bus http://www.springframework.org/schema/integration/integration-control-bus/spring-integration-bus-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/integration-service-extender http://www.springframework.org/schema/integration/integration-service-extender/spring-integration-service-extender-1.0.xsd
|
||||
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd">
|
||||
|
||||
<si:publish-subscribe-channel id="channelA"/>
|
||||
<si:publish-subscribe-channel id="channelB"/>
|
||||
|
||||
<si:channel id="channelC"/>
|
||||
|
||||
<si-service:config>
|
||||
<si-service:export si-type="publish-subscribe-channel" control-bus="DEFAULT_CONTROL_GROUP"/>
|
||||
<si-service:export ref="channelC" control-bus="DEFAULT_CONTROL_GROUP"/>
|
||||
</si-service:config>
|
||||
</beans>
|
||||
|
||||
|
||||
<!-- <si-service:import name="foo"/>-->
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.osgi.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.channel.SubscribableChannel;
|
||||
import org.springframework.integration.controlbus.ControlBus;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageHandler;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.osgi.AbstractSIConfigBundleTestDeployer;
|
||||
import org.springframework.integration.osgi.stubs.SIBundleContextStub;
|
||||
|
||||
/**
|
||||
* Tests 'config' element.
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ConfigParserExporterTests extends AbstractSIConfigBundleTestDeployer {
|
||||
|
||||
@Test
|
||||
public void testBasicSIServiceConfig() throws Exception {
|
||||
BundleContext bundleContext = SIBundleContextStub.getNewInstance();
|
||||
ApplicationContext ac = this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/config/xml/",
|
||||
"ConfigParserExporterTests-default.xml");
|
||||
assertNotNull(ac.getBean("channelA-Service"));
|
||||
assertNotNull(ac.getBean("channelB-Service"));
|
||||
assertNotNull(ac.getBean("channelC-Service"));
|
||||
|
||||
SubscribableChannel channel = (SubscribableChannel) ac.getBean("channelA");
|
||||
SubscribableChannel channel_reference = ac.getBean("channelA-reference", SubscribableChannel.class);
|
||||
// verify that standar OSGi configuration can still bind to this service
|
||||
MessageHandler handler = Mockito.mock(MessageHandler.class);
|
||||
channel_reference.subscribe(handler);
|
||||
Message<String> message = new StringMessage("hello");
|
||||
channel.send(message);
|
||||
Mockito.verify(handler, Mockito.times(1)).handleMessage(message);
|
||||
}
|
||||
@Test
|
||||
public void testControlBusAttributeWithBusPresent() throws Exception {
|
||||
BundleContext bundleContext = SIBundleContextStub.getNewInstance();
|
||||
ConfigurableApplicationContext busAC = this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/config/xml/",
|
||||
"BusConfigParserTests-default.xml");
|
||||
ConfigurableApplicationContext ac = this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/config/xml/",
|
||||
"ConfigParserExporterTests-withbus-attribute.xml");
|
||||
assertNotNull(ac.getBean("channelA-Service"));
|
||||
assertNotNull(ac.getBean("channelB-Service"));
|
||||
assertNotNull(ac.getBean("channelC-Service"));
|
||||
ControlBus bus = (ControlBus) ac.getBean("DEFAULT_CONTROL_GROUP");
|
||||
assertNotNull(bus);
|
||||
MessageHandler handler = Mockito.mock(MessageHandler.class);
|
||||
bus.subscribe(handler);
|
||||
ac.close();
|
||||
// should be 3 notification messages sent to the bus
|
||||
Mockito.verify(handler, Mockito.times(3)).handleMessage((Message<?>) Mockito.any());
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si-control="http://www.springframework.org/schema/integration/integration-control-bus"
|
||||
xmlns:si-service="http://www.springframework.org/schema/integration/integration-service-extender"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xmlns:osgi="http://www.springframework.org/schema/osgi"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/integration/integration-control-bus http://www.springframework.org/schema/integration/integration-control-bus/spring-integration-bus-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/integration-service-extender http://www.springframework.org/schema/integration/integration-service-extender/spring-integration-service-extender-1.0.xsd
|
||||
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd">
|
||||
|
||||
<si-control:bus group-name="DEFAULT_CONTROL_GROUP" >
|
||||
<si-control:manage-producer ref="exportedChannel"/>
|
||||
</si-control:bus>
|
||||
|
||||
<si:publish-subscribe-channel id="exportedChannel"/>
|
||||
<si-service:config>
|
||||
<si-service:import name="channelA" si-type="publish-subscribe-channel"/>
|
||||
</si-service:config>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.osgi.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.integration.osgi.AbstractSIConfigBundleTestDeployer;
|
||||
import org.springframework.integration.osgi.stubs.SIBundleContextStub;
|
||||
|
||||
/**
|
||||
* Tests 'config' element.
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ConfigParserImporterTests extends AbstractSIConfigBundleTestDeployer {
|
||||
|
||||
@Test
|
||||
public void testBasicSIServiceConfig() throws Exception {
|
||||
BundleContext bundleContext = SIBundleContextStub.getNewInstance();
|
||||
ApplicationContext ac = this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/config/xml/",
|
||||
"ConfigParserImporterTests-default.xml");
|
||||
assertNotNull(ac.getBean("channelA"));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
<!-- END SERVICE BINDING CONFIG-->
|
||||
|
||||
<!-- CONTROL BUS channel, exposed as an OSGi service -->
|
||||
<si:publish-subscribe-channel id="controlMessagesDistributionChannel"/>
|
||||
<si:publish-subscribe-channel id="DEFAULT_CONTROL_DIST_CHANNEL"/>
|
||||
<!-- END CONTROL BUS channel, exposed as an OSGi service -->
|
||||
|
||||
<si:header-value-router input-channel="controlMessagesDistributionChannel" header-name="INTEGRATION_EVENT_TYPE">
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.osgi.extender;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.omg.CORBA.MARSHAL;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.controlbus.ControlBus;
|
||||
import org.springframework.integration.osgi.AbstractSIConfigBundleTestDeployer;
|
||||
import org.springframework.integration.osgi.stubs.SIBundleContextStub;
|
||||
import org.springframework.osgi.config.internal.adapter.OsgiServiceRegistrationListenerAdapter;
|
||||
import org.springframework.osgi.mock.MockServiceReference;
|
||||
import org.springframework.osgi.service.exporter.OsgiServiceRegistrationListener;
|
||||
import org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean;
|
||||
import org.springframework.osgi.util.OsgiServiceUtils;
|
||||
|
||||
/**
|
||||
* TODO - insert COMMENT
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class BusParserProducersTests extends AbstractSIConfigBundleTestDeployer {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testBusWithSubscribersBusPresent() throws Exception {
|
||||
SIBundleContextStub bundleContext = SIBundleContextStub.getInstance();
|
||||
this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/config/xml/",
|
||||
"BusConfigParserTests-default.xml");
|
||||
ApplicationContext ac = this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/extender/",
|
||||
"BusParserProducersTests.xml");
|
||||
Map beans = ac.getBeansOfType(OsgiServiceFactoryBean.class);
|
||||
assertTrue(beans.size() == 1);
|
||||
OsgiServiceFactoryBean serviceExporter = (OsgiServiceFactoryBean) beans.values().toArray()[0];
|
||||
assertTrue(serviceExporter.getTargetBeanName().equals("exportedChannel"));
|
||||
DirectFieldAccessor serviceExporterAccessor = new DirectFieldAccessor(serviceExporter);
|
||||
OsgiServiceRegistrationListener[] listeners =
|
||||
(OsgiServiceRegistrationListener[]) serviceExporterAccessor.getPropertyValue("listeners");
|
||||
assertTrue(listeners.length == 1);
|
||||
|
||||
ServiceReference sr =
|
||||
bundleContext.getServiceReferences(null, "(&(org.springframework.osgi.bean.name=exportedChannel))")[0];
|
||||
assertNotNull(sr);
|
||||
}
|
||||
@Test
|
||||
public void testBusWithSubscribersBusNotPresent() throws Exception {
|
||||
SIBundleContextStub bundleContext = SIBundleContextStub.getInstance();
|
||||
this.deploySIConfig(bundleContext,
|
||||
"org/springframework/integration/osgi/extender/",
|
||||
"BusParserProducersTests.xml");
|
||||
assertTrue(true); // if exception was not thrown we are ok
|
||||
}
|
||||
}
|
||||
@@ -181,4 +181,9 @@ public class SIBundleContextStub extends MockBundleContext {
|
||||
public Map<ServiceReference, Object> getServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
public void remove(ServiceReference sr){
|
||||
services.remove(sr);
|
||||
serviceReferences.remove(sr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,15 +38,15 @@ public class SIServiceRegistrationStub extends MockServiceRegistration {
|
||||
public void setBundleContext(SIBundleContextStub context){
|
||||
this.context = context;
|
||||
}
|
||||
// public void unregister() {
|
||||
// ServiceReference ref = this.getReference();
|
||||
// DirectFieldAccessor refAccessor = new DirectFieldAccessor(ref);
|
||||
// Dictionary properties = (Dictionary) refAccessor.getPropertyValue("properties");
|
||||
//
|
||||
// context.removeService(this.getReference());
|
||||
// Set<ServiceListener> listeners = context.getFilteredListeners(properties);
|
||||
// for (ServiceListener serviceListener : listeners) {
|
||||
// serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, ref));
|
||||
// }
|
||||
// }
|
||||
public void unregister() {
|
||||
ServiceReference ref = this.getReference();
|
||||
DirectFieldAccessor refAccessor = new DirectFieldAccessor(ref);
|
||||
Dictionary properties = (Dictionary) refAccessor.getPropertyValue("properties");
|
||||
|
||||
context.remove(this.getReference());
|
||||
Set<ServiceListener> listeners = context.getFilteredListeners(properties);
|
||||
for (ServiceListener serviceListener : listeners) {
|
||||
serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, ref));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.osgi">
|
||||
<level value="debug" />
|
||||
<level value="trace" />
|
||||
</logger>
|
||||
|
||||
<!-- Root Logger -->
|
||||
|
||||
Reference in New Issue
Block a user