* 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.wamblee.system.spring;
import java.io.IOException;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.wamblee.io.ClassPathResource;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.DefaultRequiredInterface;
+import org.wamblee.system.core.DefaultScope;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
+import org.wamblee.system.core.Scope;
import org.wamblee.system.core.SystemAssemblyException;
+import org.wamblee.test.EventTracker;
public class SpringComponentTest extends TestCase {
- private static final String HELLO_SERVICE_SPRING_XML = "test.org.wamblee.system.spring.xml";
- private static final String HELLO_SERVICE_SPRING_WITH_REQS_XML = "test.org.wamblee.system.springWithRequirements.xml";
- private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
+ private static final String HELLO_SERVICE_SPRING_XML = "test.org.wamblee.system.spring.xml";
+ private static final String HELLO_SERVICE_SPRING_WITH_REQS_XML = "test.org.wamblee.system.springWithRequirements.xml";
+ private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
+ private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 = "test.org.wamblee.system.springWithProperties2.xml";
+
private static final String PROPERTY_FILE = "test.org.wamblee.system.spring.properties";
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- public void testBlackboxSystem() {
- SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_XML },
- new HashMap<String, ProvidedInterface>(),
- new HashMap<RequiredInterface, String>());
- system.start();
- ProvidedInterface[] services = system.getRunningServices();
- assertEquals(0, services.length);
-
- system.stop();
- }
-
- public void testOneProvidedService() {
- Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
- provided.put("helloService", new DefaultProvidedInterface(
- "hello", HelloService.class));
-
- SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_XML }, provided,
- new HashMap<RequiredInterface, String>());
- system.start();
- ProvidedInterface[] services = system.getRunningServices();
- assertEquals(1, services.length);
- assertTrue(services[0].getImplementation() instanceof HelloService);
- assertEquals("Hello world!", ((HelloService)services[0].getImplementation())
- .say());
- system.stop();
- }
-
- public void testWithProperties() throws IOException {
- Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
- provided.put("helloService", new DefaultProvidedInterface(
- "hello", HelloService.class));
- SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
- provided,
- new HashMap<RequiredInterface, String>());
- Properties props = new Properties();
- props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
- system.addProperties(props);
-
- system.start();
- ProvidedInterface[] services = system.getRunningServices();
- assertEquals("Property Value",
- ((HelloService)services[0].getImplementation()).say());
- }
-
- public void testWithMissingRequirement() {
- try {
- SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
- new HashMap<String, ProvidedInterface>(),
- new HashMap<RequiredInterface, String>());
- system.start();
- } catch (SystemAssemblyException e) {
- //e.printStackTrace();
- return;
- }
- fail();
- }
-
- public void testWithRequirement() {
- Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
- required.put(new DefaultRequiredInterface("hello", HelloService.class),
- "helloService");
- SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
- new HashMap<String, ProvidedInterface>(), required);
-
- HelloService helloObject = new HelloService("ladida");
- ProvidedInterface helloService = new DefaultProvidedInterface("hello", HelloService.class);
- helloService.publish(helloObject);
- system.getRequiredServices()[0].setProvider(helloService);
-
- system.start();
- system.stop();
- }
-
- public void testWithRequirementAndProvidedService() {
- Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
- required.put(new DefaultRequiredInterface("hello", HelloService.class),
- "helloService");
- Map<String,ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
- provided.put("blaService", new DefaultProvidedInterface("bla",
- BlaService.class));
-
- SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
- provided, required);
-
- HelloService helloObject = new HelloService("ladida");
- ProvidedInterface helloService =
- new DefaultProvidedInterface("hello", HelloService.class);
- helloService.publish(helloObject);
- system.getRequiredServices()[0].setProvider(helloService);
- system.start();
- ProvidedInterface started = system.getProvidedServices()[0];
-
- assertNotNull(started.getImplementation());
- assertTrue(started.getImplementation() instanceof BlaService);
- assertEquals("ladida",
- ((BlaService)started.getImplementation()).execute());
- system.stop();
- }
+ public static EventTracker<String> EVENT_TRACKER;
+
+ private Scope _externalScope;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ EVENT_TRACKER = new EventTracker<String>();
+ _externalScope = new DefaultScope(new ProvidedInterface[0]);
+ }
+
+ public void testBlackboxSystem() {
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_XML },
+ new HashMap<String, ProvidedInterface>(),
+ new HashMap<RequiredInterface, String>());
+
+ Scope runtime = system.start(_externalScope);
+ assertEquals(0, _externalScope.getProvidedInterfaces().size());
+
+ system.stop(runtime);
+ }
+
+ public void testOneProvidedService() {
+ Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
+ provided.put("helloService", new DefaultProvidedInterface("hello",
+ HelloService.class));
+
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_XML }, provided,
+ new HashMap<RequiredInterface, String>());
+ Scope runtime = system.start(_externalScope);
+ List<ProvidedInterface> services = runtime.getProvidedInterfaces();
+
+ assertEquals(1, services.size());
+ Object service = runtime.getInterfaceImplementation(services.get(0),
+ Object.class);
+ assertTrue(service instanceof HelloService);
+
+ // BUG; Provided services should be made available in the external
+ // scope.
+ Object service2 = _externalScope.getInterfaceImplementation(provided
+ .get("helloService"), Object.class);
+ assertSame(service, service2);
+
+ assertEquals("Hello world!", ((HelloService) service).say());
+ system.stop(runtime);
+ }
+
+ public void testWithProperties() throws IOException {
+ Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
+ provided.put("helloService", new DefaultProvidedInterface("hello",
+ HelloService.class));
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
+ provided, new HashMap<RequiredInterface, String>());
+ Properties props = new Properties();
+ props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
+ system.addProperties(props);
+
+ Scope scope = system.start(_externalScope);
+ // BUG: Hello service was constructed multiple times. Once with the
+ // unprocessed property
+ // and another time with the processed property.
+ assertEquals(1, EVENT_TRACKER.getEventCount());
+ List<ProvidedInterface> services = scope.getProvidedInterfaces();
+ assertEquals("Property Value", scope.getInterfaceImplementation(
+ services.get(0), HelloService.class).say());
+ }
+
+ public void testWithPropertiesAsBean() throws IOException {
+ Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
+ provided.put("helloService", new DefaultProvidedInterface("hello",
+ HelloService2.class));
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 },
+ provided, new HashMap<RequiredInterface, String>());
+ Properties props = new Properties();
+ props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
+ system.addProperties("properties", props);
+
+ Scope scope = system.start(_externalScope);
+
+ List<ProvidedInterface> services = scope.getProvidedInterfaces();
+
+ Properties props2 = scope.getInterfaceImplementation(services.get(0),
+ HelloService2.class).getProperties();
+ assertEquals(props, props2);
+ }
+
+ public void testWithMissingRequirement() {
+ try {
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
+ new HashMap<String, ProvidedInterface>(),
+ new HashMap<RequiredInterface, String>());
+ system.start(_externalScope);
+ } catch (SystemAssemblyException e) {
+ // e.printStackTrace();
+ return;
+ }
+ fail();
+ }
+
+ public void testWithRequirement() {
+ Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
+ required.put(new DefaultRequiredInterface("hello", HelloService.class),
+ "helloService");
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
+ new HashMap<String, ProvidedInterface>(), required);
+
+ HelloService helloObject = new HelloService("ladida");
+ ProvidedInterface helloService = new DefaultProvidedInterface("hello",
+ HelloService.class);
+ Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
+ scope.publishInterface(helloService, helloObject);
+ system.getRequiredInterfaces().get(0).setProvider(helloService);
+
+ Scope runtime = system.start(scope);
+ system.stop(runtime);
+ }
+
+ public void testWithRequirementAndProvidedService() {
+ Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
+ required.put(new DefaultRequiredInterface("hello", HelloService.class),
+ "helloService");
+ Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
+ provided.put("blaService", new DefaultProvidedInterface("bla",
+ BlaService.class));
+
+ SpringComponent system = new SpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML }, provided,
+ required);
+
+ HelloService helloObject = new HelloService("ladida");
+ ProvidedInterface helloService = new DefaultProvidedInterface("hello",
+ HelloService.class);
+ Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
+ scope.publishInterface(helloService, helloObject);
+ system.getRequiredInterfaces().get(0).setProvider(helloService);
+ Scope runtime = system.start(scope);
+ ProvidedInterface started = runtime.getProvidedInterfaces().get(0);
+
+ Object impl = runtime.getInterfaceImplementation(started,
+ BlaService.class);
+ assertNotNull(impl);
+ assertTrue(impl instanceof BlaService);
+ assertEquals("ladida", ((BlaService) impl).execute());
+ system.stop(runtime);
+ }
+
+ /**
+ * Tests a scenario where a subclass of SpringComponent adds a new provided
+ * interface where the interface is provided by the subclass itself and not
+ * by the spring configs inside.
+ */
+ public void testWithProvidedFromSubClassNotFromConfig() {
+ Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
+ provided.put("helloService", new DefaultProvidedInterface("hello",
+ HelloService.class));
+
+ SubSpringComponent system = new SubSpringComponent("system",
+ new String[] { HELLO_SERVICE_SPRING_XML }, provided,
+ new HashMap<RequiredInterface, String>());
+
+ Scope runtime = system.start(_externalScope);
+ List<ProvidedInterface> services = runtime.getProvidedInterfaces();
+
+ assertEquals(2, services.size());
+ Object service = runtime.getInterfaceImplementation(services.get(0),
+ Object.class);
+ assertTrue(service instanceof HelloService);
+
+ // BUG; Provided services should be made available in the external
+ // scope.
+ Object service2 = _externalScope.getInterfaceImplementation(provided
+ .get("helloService"), Object.class);
+ assertSame(service, service2);
+
+ Object floatsvc = _externalScope.getInterfaceImplementation(system
+ .getProvidedInterfaces().get(1), Object.class);
+ assertTrue(floatsvc instanceof Float);
+ assertTrue((((Float) floatsvc).floatValue() - 100.345f) < 0.00001);
+
+ assertEquals("Hello world!", ((HelloService) service).say());
+ system.stop(runtime);
+ }
+
+ /**
+ * Tests the spring component with an additional requirement from the subclass
+ * which is not required by the spring config files inside.
+ */
+ public void testWithRequirementFromSubClass() {
+ Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
+ required.put(new DefaultRequiredInterface("hello", HelloService.class),
+ "helloService");
+ SpringComponent system = new SubSpringComponent2("system",
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
+ new HashMap<String, ProvidedInterface>(), required);
+
+ HelloService helloObject = new HelloService("ladida");
+ ProvidedInterface helloService = new DefaultProvidedInterface("hello",
+ HelloService.class);
+
+ ProvidedInterface floatService = new DefaultProvidedInterface("float", Float.class);
+
+ Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
+ scope.publishInterface(helloService, helloObject);
+ scope.publishInterface(floatService, 100.234f);
+ system.getRequiredInterfaces().get(0).setProvider(helloService);
+ system.getRequiredInterfaces().get(1).setProvider(floatService);
+
+ Scope runtime = system.start(scope);
+ system.stop(runtime);
+
+ assertEquals(100.234f, ((Float)runtime.get("floatValue")).floatValue(), 0.0001f);
+ }
}