| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.apache.aries.rsa.core; |
| |
| import static org.easymock.EasyMock.anyObject; |
| import static org.easymock.EasyMock.expect; |
| import static org.easymock.EasyMock.expectLastCall; |
| import static org.hamcrest.Matchers.array; |
| import static org.hamcrest.Matchers.contains; |
| import static org.hamcrest.Matchers.equalTo; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertThat; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Dictionary; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.aries.rsa.core.event.EventProducer; |
| import org.apache.aries.rsa.spi.DistributionProvider; |
| import org.apache.aries.rsa.spi.Endpoint; |
| import org.easymock.EasyMock; |
| import org.easymock.IAnswer; |
| import org.easymock.IMocksControl; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.Version; |
| import org.osgi.service.remoteserviceadmin.EndpointDescription; |
| import org.osgi.service.remoteserviceadmin.ExportReference; |
| import org.osgi.service.remoteserviceadmin.ExportRegistration; |
| import org.osgi.service.remoteserviceadmin.ImportRegistration; |
| import org.osgi.service.remoteserviceadmin.RemoteConstants; |
| |
| @SuppressWarnings({ |
| "rawtypes", "unchecked" |
| }) |
| public class RemoteServiceAdminCoreTest { |
| |
| private static final String MYCONFIG = "myconfig"; |
| private IMocksControl c; |
| private BundleContext rsaContext; |
| private RemoteServiceAdminCore rsaCore; |
| private BundleContext apiContext; |
| private DummyProvider provider; |
| |
| @Before |
| public void setup() throws InvalidSyntaxException { |
| c = EasyMock.createControl(); |
| rsaContext = c.createMock(BundleContext.class); |
| Bundle b = createDummyRsaBundle(rsaContext); |
| expect(rsaContext.getProperty(Constants.FRAMEWORK_VERSION)).andReturn("1111").anyTimes(); |
| expect(rsaContext.getProperty(Constants.FRAMEWORK_UUID)).andReturn("some_uuid1").anyTimes(); |
| |
| expect(rsaContext.getBundle()).andReturn(b).anyTimes(); |
| apiContext = c.createMock(BundleContext.class); |
| provider = new DummyProvider(); |
| PackageUtil packageUtil = new PackageUtil(rsaContext) { |
| @Override |
| public String getVersion(Class<?> iClass) { |
| return "1.0.0"; |
| } |
| }; |
| EventProducer eventProducer = new EventProducer(rsaContext) { |
| protected void notifyListeners(org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent rsae) { |
| // skip |
| } |
| }; |
| rsaCore = new RemoteServiceAdminCore(rsaContext, apiContext, eventProducer, provider, packageUtil) { |
| protected void createServiceListener() {} |
| }; |
| } |
| |
| @Test |
| public void testDontExportOwnServiceProxies() throws InvalidSyntaxException { |
| Map<String, Object> sProps = new HashMap<>(); |
| sProps.put("objectClass", new String[] {"a.b.C"}); |
| sProps.put(RemoteConstants.SERVICE_IMPORTED, true); |
| sProps.put("service.exported.interfaces", "*"); |
| ServiceReference sref = mockServiceReference(sProps); |
| |
| c.replay(); |
| |
| List<ExportRegistration> exRefs = rsaCore.exportService(sref, null); |
| |
| assertNotNull(exRefs); |
| assertEquals(0, exRefs.size()); |
| assertEquals(rsaCore.getExportedServices().size(), 0); |
| |
| c.verify(); |
| } |
| |
| @Test |
| public void testDoNotImportUnsupportedConfig() { |
| EndpointDescription endpoint = createEndpointDesc("unsupportedConfiguration"); |
| |
| c.replay(); |
| |
| assertNull(rsaCore.importService(endpoint)); |
| assertEquals(0, rsaCore.getImportedEndpoints().size()); |
| |
| c.verify(); |
| } |
| |
| @Test |
| public void testImport() { |
| expect(apiContext.registerService(EasyMock.aryEq(new String[]{"es.schaaf.my.class"}), anyObject(), anyObject())).andReturn(null); |
| |
| c.replay(); |
| EndpointDescription endpoint2 = createEndpointDesc(MYCONFIG); |
| |
| ImportRegistration ireg = rsaCore.importService(endpoint2); |
| assertNotNull(ireg); |
| |
| assertEquals(1, rsaCore.getImportedEndpoints().size()); |
| |
| // lets import the same endpoint once more -> should get a copy of the ImportRegistration |
| ImportRegistration ireg2 = rsaCore.importService(endpoint2); |
| assertNotNull(ireg2); |
| assertEquals(2, rsaCore.getImportedEndpoints().size()); |
| |
| assertEquals(ireg.getImportReference(), (rsaCore.getImportedEndpoints().toArray())[0]); |
| |
| assertEquals(ireg.getImportReference().getImportedEndpoint(), ireg2.getImportReference() |
| .getImportedEndpoint()); |
| |
| // remove the registration |
| |
| // first call shouldn't remove the import |
| ireg2.close(); |
| assertEquals(1, rsaCore.getImportedEndpoints().size()); |
| |
| // second call should really close and remove the import |
| ireg.close(); |
| assertEquals(0, rsaCore.getImportedEndpoints().size()); |
| |
| c.verify(); |
| } |
| |
| @Test |
| public void testImportWithMultipleInterfaces() { |
| expect(apiContext.registerService(EasyMock.aryEq(new String[]{"es.schaaf.my.class", "java.lang.Runnable"}), anyObject(), anyObject())).andReturn(null); |
| |
| c.replay(); |
| |
| Map<String, Object> p = new HashMap<>(); |
| p.put(RemoteConstants.ENDPOINT_ID, "http://google.de"); |
| p.put(Constants.OBJECTCLASS, new String[] { |
| "es.schaaf.my.class", |
| "java.lang.Runnable" |
| }); |
| p.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, MYCONFIG); |
| EndpointDescription endpoint = new EndpointDescription(p); |
| |
| ImportRegistration ireg = rsaCore.importService(endpoint); |
| |
| assertNotNull(ireg); |
| assertEquals(1, rsaCore.getImportedEndpoints().size()); |
| |
| // lets import the same endpoint once more -> should get a copy of the ImportRegistration |
| ImportRegistration ireg2 = rsaCore.importService(endpoint); |
| assertNotNull(ireg2); |
| assertEquals(2, rsaCore.getImportedEndpoints().size()); |
| |
| assertEquals(ireg.getImportReference(), (rsaCore.getImportedEndpoints().toArray())[0]); |
| |
| assertEquals(ireg.getImportReference().getImportedEndpoint(), ireg2.getImportReference() |
| .getImportedEndpoint()); |
| |
| EndpointDescription importedEndpoint = ireg.getImportReference().getImportedEndpoint(); |
| assertEquals(2, importedEndpoint.getInterfaces().size()); |
| |
| c.verify(); |
| } |
| |
| @Test |
| public void testExport() throws Exception { |
| final Map<String, Object> sProps = new HashMap<>(); |
| sProps.put("objectClass", new String[] {"java.lang.Runnable"}); |
| sProps.put("service.id", 51L); |
| sProps.put("myProp", "myVal"); |
| sProps.put("service.exported.interfaces", "*"); |
| ServiceReference sref = mockServiceReference(sProps); |
| |
| provider.endpoint = createEndpoint(sProps); |
| ServiceReference sref2 = mockServiceReference(sProps); |
| c.replay(); |
| |
| // Export the service for the first time |
| List<ExportRegistration> eregs = rsaCore.exportService(sref, null); |
| assertEquals(1, eregs.size()); |
| ExportRegistration ereg = eregs.iterator().next(); |
| assertNull(ereg.getException()); |
| assertSame(sref, ereg.getExportReference().getExportedService()); |
| EndpointDescription endpoint = ereg.getExportReference().getExportedEndpoint(); |
| |
| Map<String, Object> edProps = endpoint.getProperties(); |
| assertEquals("http://something", edProps.get("endpoint.id")); |
| assertNotNull(edProps.get("service.imported")); |
| assertThat((String[]) edProps.get("objectClass"), array(equalTo("java.lang.Runnable"))); |
| assertThat((String[]) edProps.get("service.imported.configs"), array(equalTo(MYCONFIG))); |
| |
| // Ask to export the same service again, this should not go through the whole process again but simply return |
| // a copy of the first instance. |
| List<ExportRegistration> eregs2 = rsaCore.exportService(sref2, null); |
| assertEquals(1, eregs2.size()); |
| ExportRegistration ereg2 = eregs2.iterator().next(); |
| assertNull(ereg2.getException()); |
| assertEquals(ereg.getExportReference().getExportedEndpoint().getProperties(), |
| ereg2.getExportReference().getExportedEndpoint().getProperties()); |
| |
| assertNumExports(2); |
| |
| ereg.close(); |
| assertNumExports(1); |
| |
| ereg2.close(); |
| assertNumExports(0); |
| } |
| |
| private void assertNumExports(int expectedNum) { |
| assertThat("Number of export references", rsaCore.getExportedServices().size(), equalTo(expectedNum)); |
| } |
| |
| @Test |
| public void testExportWrongConfig() throws Exception { |
| final Map<String, Object> sProps = new HashMap<>(); |
| sProps.put("objectClass", new String[] {"java.lang.Runnable"}); |
| sProps.put("service.id", 51L); |
| sProps.put("myProp", "myVal"); |
| sProps.put("service.exported.interfaces", "*"); |
| sProps.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, "org.apache.cxf.ws"); |
| ServiceReference sref = mockServiceReference(sProps); |
| |
| c.replay(); |
| List<ExportRegistration> ereg = rsaCore.exportService(sref, null); |
| |
| // Service should not be exported as the exported config does not match |
| assertEquals(0, ereg.size()); |
| c.verify(); |
| } |
| |
| @Test |
| public void testExportOneConfigSupported() throws Exception { |
| final Map<String, Object> sProps = new HashMap<>(); |
| sProps.put("objectClass", new String[] {"java.lang.Runnable"}); |
| sProps.put("service.id", 51L); |
| sProps.put("myProp", "myVal"); |
| sProps.put("service.exported.interfaces", "*"); |
| sProps.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, new String[]{MYCONFIG, "aconfig"}); |
| ServiceReference sref = mockServiceReference(sProps); |
| provider.endpoint = createEndpoint(sProps); |
| c.replay(); |
| |
| List<ExportRegistration> ereg = rsaCore.exportService(sref, null); |
| assertEquals(1, ereg.size()); |
| ExportRegistration first = ereg.iterator().next(); |
| EndpointDescription exportedEndpoint = first.getExportReference().getExportedEndpoint(); |
| assertThat(exportedEndpoint.getConfigurationTypes(), contains(MYCONFIG)); |
| } |
| |
| @Test |
| public void testExportException() throws Exception { |
| final Map<String, Object> sProps = new HashMap<>(); |
| sProps.put("objectClass", new String[] {"java.lang.Runnable"}); |
| sProps.put("service.id", 51L); |
| sProps.put("service.exported.interfaces", "*"); |
| ServiceReference sref = mockServiceReference(sProps); |
| |
| c.replay(); |
| provider.ex = new TestException(); |
| |
| List<ExportRegistration> ereg = rsaCore.exportService(sref, sProps); |
| assertEquals(1, ereg.size()); |
| assertTrue(ereg.get(0).getException() instanceof TestException); |
| |
| Collection<ExportReference> exportedServices = rsaCore.getExportedServices(); |
| assertEquals("No service was exported", 0, exportedServices.size()); |
| c.verify(); |
| } |
| |
| @Test |
| public void testCreateEndpointProps() { |
| c.replay(); |
| Map<String, Object> sd = new HashMap<>(); |
| sd.put(org.osgi.framework.Constants.SERVICE_ID, 42); |
| Map<String, Object> props = rsaCore.createEndpointProps(sd, new Class[]{String.class}); |
| |
| Assert.assertFalse(props.containsKey(org.osgi.framework.Constants.SERVICE_ID)); |
| assertEquals(42, props.get(RemoteConstants.ENDPOINT_SERVICE_ID)); |
| assertEquals("some_uuid1", props.get(RemoteConstants.ENDPOINT_FRAMEWORK_UUID)); |
| assertEquals(Arrays.asList("java.lang.String"), |
| Arrays.asList((Object[]) props.get(org.osgi.framework.Constants.OBJECTCLASS))); |
| assertEquals("1.0.0", props.get("endpoint.package.version.java.lang")); |
| c.verify(); |
| } |
| |
| private Endpoint createEndpoint(final Map<String, Object> sProps) throws IOException { |
| Map<String, Object> eProps = new HashMap<>(sProps); |
| eProps.put("endpoint.id", "http://something"); |
| eProps.put("service.imported.configs", new String[] {MYCONFIG}); |
| final EndpointDescription epd = new EndpointDescription(eProps); |
| Endpoint er = c.createMock(Endpoint.class); |
| expect(er.description()).andReturn(epd).anyTimes(); |
| er.close(); |
| expectLastCall(); |
| return er; |
| } |
| |
| private Bundle createDummyRsaBundle(BundleContext bc) { |
| Bundle b = c.createMock(Bundle.class); |
| expect(b.getBundleContext()).andReturn(bc).anyTimes(); |
| expect(b.getSymbolicName()).andReturn("rsabundle").anyTimes(); |
| expect(b.getBundleId()).andReturn(10L).anyTimes(); |
| expect(b.getVersion()).andReturn(new Version("1.0.0")).anyTimes(); |
| expect(b.getHeaders()).andReturn(new Hashtable<>()).anyTimes(); |
| return b; |
| } |
| |
| private ServiceReference mockServiceReference(final Map<String, Object> sProps) { |
| BundleContext bc = c.createMock(BundleContext.class); |
| Bundle sb = c.createMock(Bundle.class); |
| expect(sb.getBundleContext()).andReturn(bc).anyTimes(); |
| expect(bc.getBundle()).andReturn(sb).anyTimes(); |
| |
| String[] propKeys = sProps.keySet().toArray(new String[] {}); |
| ServiceReference sref = c.createMock(ServiceReference.class); |
| expect(sref.getBundle()).andReturn(sb).anyTimes(); |
| expect(sref.getPropertyKeys()).andReturn(propKeys).anyTimes(); |
| expect(sref.getProperty(EasyMock.anyObject())).andAnswer(new IAnswer<Object>() { |
| @Override |
| public Object answer() throws Throwable { |
| return sProps.get(EasyMock.getCurrentArguments()[0]); |
| } |
| }).anyTimes(); |
| Runnable svcObject = c.createMock(Runnable.class); |
| expect(bc.getService(sref)).andReturn(svcObject).anyTimes(); |
| return sref; |
| } |
| |
| private EndpointDescription createEndpointDesc(String configType) { |
| Map<String, Object> p = new HashMap<>(); |
| p.put(RemoteConstants.ENDPOINT_ID, "http://google.de"); |
| p.put(Constants.OBJECTCLASS, new String[] { |
| "es.schaaf.my.class" |
| }); |
| p.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, configType); |
| return new EndpointDescription(p); |
| } |
| |
| @SuppressWarnings("serial") |
| private static class TestException extends RuntimeException { |
| } |
| |
| class DummyProvider implements DistributionProvider { |
| |
| Endpoint endpoint; |
| RuntimeException ex; |
| |
| @Override |
| public String[] getSupportedTypes() { |
| return new String[]{MYCONFIG}; |
| } |
| |
| @Override |
| public Endpoint exportService(Object serviceO, BundleContext serviceContext, |
| Map<String, Object> effectiveProperties, Class[] exportedInterfaces) { |
| if (ex != null) { |
| throw ex; |
| } |
| return endpoint; |
| } |
| |
| @Override |
| public Object importEndpoint(ClassLoader cl, BundleContext consumerContext, Class[] interfaces, |
| EndpointDescription endpoint) { |
| return null; |
| } |
| } |
| } |