Repository: aries-rsa Updated Branches: refs/heads/master 177cb0aef -> a421c659b
[ARIES-1758] Support transport of DTOs using felix converter Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/a421c659 Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/a421c659 Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/a421c659 Branch: refs/heads/master Commit: a421c659bb3984650f786398a62b5beb68593d95 Parents: 177cb0a Author: Christian Schneider <cschn...@adobe.com> Authored: Fri Feb 9 16:39:57 2018 +0100 Committer: Christian Schneider <cschn...@adobe.com> Committed: Fri Feb 9 16:39:57 2018 +0100 ---------------------------------------------------------------------- parent/pom.xml | 5 ++++ provider/tcp/bnd.bnd | 4 +++ provider/tcp/pom.xml | 6 +++- .../tcp/ser/BasicObjectInputStream.java | 11 ++++++- .../tcp/ser/BasicObjectOutputStream.java | 7 +++-- .../aries/rsa/provider/tcp/ser/DTOMarker.java | 31 ++++++++++++++++++++ .../provider/tcp/TcpProviderPrimitiveTest.java | 18 ++++++++++++ .../aries/rsa/provider/tcp/TcpProviderTest.java | 25 ++++++++++++++-- .../rsa/provider/tcp/myservice/DTOType.java | 23 +++++++++++++++ .../tcp/myservice/PrimitiveService.java | 4 +++ .../tcp/myservice/PrimitiveServiceImpl.java | 10 +++++++ 11 files changed, 137 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/parent/pom.xml ---------------------------------------------------------------------- diff --git a/parent/pom.xml b/parent/pom.xml index af59c55..fd4e1a5 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -199,6 +199,11 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.converter</artifactId> + <version>0.3.0-SNAPSHOT</version> + </dependency> </dependencies> </dependencyManagement> http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/bnd.bnd ---------------------------------------------------------------------- diff --git a/provider/tcp/bnd.bnd b/provider/tcp/bnd.bnd index c9917d9..62caa2c 100644 --- a/provider/tcp/bnd.bnd +++ b/provider/tcp/bnd.bnd @@ -1,3 +1,7 @@ Bundle-Activator: org.apache.aries.rsa.provider.tcp.Activator Provide-Capability: osgi.remoteserviceadmin.distribution;\ configs:List<String>="aries.tcp"; version:Version=1.1.0 +Private-Package: \ + org.apache.aries.rsa.util,\ + org.apache.aries.rsa.provider.tcp*,\ + org.osgi.util.converter \ No newline at end of file http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/pom.xml ---------------------------------------------------------------------- diff --git a/provider/tcp/pom.xml b/provider/tcp/pom.xml index f743563..072fc25 100644 --- a/provider/tcp/pom.xml +++ b/provider/tcp/pom.xml @@ -28,7 +28,11 @@ <groupId>org.osgi</groupId> <artifactId>org.osgi.util.promise</artifactId> <version>1.0.0</version> - </dependency> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.converter</artifactId> + </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectInputStream.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectInputStream.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectInputStream.java index d9bde6c..33c44d3 100644 --- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectInputStream.java +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectInputStream.java @@ -24,8 +24,11 @@ import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import org.osgi.framework.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class BasicObjectInputStream extends ObjectInputStream { + Logger log = LoggerFactory.getLogger(this.getClass()); private ClassLoader loader; @@ -38,8 +41,11 @@ public class BasicObjectInputStream extends ObjectInputStream { @Override protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { try { - return loader.loadClass(desc.getName()); + String className = desc.getName(); + // Must use Class.forName instead of loader.loadClass to handle cases like array of user classes + return Class.forName(className, false, loader); } catch (ClassNotFoundException e) { + log.warn("Error loading class using classloader of user bundle", e); return super.resolveClass(desc); } } @@ -49,6 +55,9 @@ public class BasicObjectInputStream extends ObjectInputStream { if (obj instanceof VersionMarker) { VersionMarker verionMarker = (VersionMarker)obj; return Version.parseVersion(verionMarker.getVersion()); + } else if (obj instanceof DTOMarker) { + DTOMarker dtoMarker = (DTOMarker)obj; + return dtoMarker.getDTO(loader); } else { return super.resolveObject(obj); } http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectOutputStream.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectOutputStream.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectOutputStream.java index 39b5399..98b6248 100644 --- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectOutputStream.java +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/BasicObjectOutputStream.java @@ -3,6 +3,7 @@ package org.apache.aries.rsa.provider.tcp.ser; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; +import java.io.Serializable; import org.osgi.framework.Version; @@ -15,10 +16,12 @@ public class BasicObjectOutputStream extends ObjectOutputStream { @Override protected Object replaceObject(Object obj) throws IOException { - if (obj instanceof Version) { + if (obj instanceof Serializable || obj.getClass().isArray()) { + return obj; + } else if (obj instanceof Version) { return new VersionMarker((Version) obj); } else { - return super.replaceObject(obj); + return new DTOMarker(obj); } } } http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/DTOMarker.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/DTOMarker.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/DTOMarker.java new file mode 100644 index 0000000..9b71ae0 --- /dev/null +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/ser/DTOMarker.java @@ -0,0 +1,31 @@ +package org.apache.aries.rsa.provider.tcp.ser; + +import java.io.Serializable; +import java.util.Map; + +import org.osgi.util.converter.Converter; +import org.osgi.util.converter.Converters; + +public class DTOMarker implements Serializable { + private static final long serialVersionUID = 2248068618419940217L; + + private String className; + private Map<String, Object> content; + + @SuppressWarnings("unchecked") + public DTOMarker(Object dto) { + Converter converter = Converters.standardConverter(); + className = dto.getClass().getName(); + content = converter.convert(dto).sourceAsDTO().to(Map.class); + } + + public Object getDTO(ClassLoader classLoader) { + try { + Class<?> clazz = classLoader.loadClass(className); + Converter converter = Converters.standardConverter(); + return converter.convert(content).targetAsDTO().to(clazz); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Exception deserializing DTO " + className, e); + } + } +} http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderPrimitiveTest.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderPrimitiveTest.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderPrimitiveTest.java index 05ceb8b..ea26c54 100644 --- a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderPrimitiveTest.java +++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderPrimitiveTest.java @@ -22,6 +22,7 @@ import static java.util.Arrays.asList; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.everyItem; import static org.hamcrest.Matchers.isIn; +import static org.hamcrest.Matchers.samePropertyValuesAs; import static org.hamcrest.core.StringStartsWith.startsWith; import static org.junit.Assert.assertThat; import static org.osgi.framework.Version.parseVersion; @@ -33,6 +34,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.apache.aries.rsa.provider.tcp.myservice.DTOType; import org.apache.aries.rsa.provider.tcp.myservice.PrimitiveService; import org.apache.aries.rsa.provider.tcp.myservice.PrimitiveServiceImpl; import org.apache.aries.rsa.spi.Endpoint; @@ -137,6 +139,22 @@ public class TcpProviderPrimitiveTest { assertThat(myServiceProxy.callVersionMap(map).entrySet(), everyItem(isIn(map.entrySet()))); } + @Test + public void testDTO() { + DTOType dto = new DTOType(); + dto.value = "Test"; + assertThat(myServiceProxy.callDTO(dto), samePropertyValuesAs(dto)); + } + + @Test + public void testDTOAr() { + DTOType dto = new DTOType(); + dto.value = "Test"; + DTOType[] dtoAr = new DTOType[] {dto}; + DTOType[] result = myServiceProxy.callDTOAr(dtoAr); + assertThat(result[0], samePropertyValuesAs(dtoAr[0])); + } + @AfterClass public static void close() throws IOException { ep.close(); http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java index 67678f3..dc4737e 100644 --- a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java +++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java @@ -21,7 +21,9 @@ package org.apache.aries.rsa.provider.tcp; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.core.StringStartsWith.startsWith; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -36,6 +38,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import org.apache.aries.rsa.provider.tcp.myservice.ExpectedTestException; @@ -50,7 +53,9 @@ import org.junit.BeforeClass; import org.junit.Test; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceException; +import org.osgi.util.function.Predicate; import org.osgi.util.promise.Promise; +import org.osgi.util.promise.Success; public class TcpProviderTest { @@ -160,9 +165,23 @@ public class TcpProviderTest { @Test public void testAsyncPromise() throws Exception { - Promise<String> result = myServiceProxy.callAsyncPromise(100); - String answer = result.getValue(); - assertEquals("Finished", answer); + final Semaphore s = new Semaphore(0); + Promise<String> p = myServiceProxy.callAsyncPromise(100); + p.filter(new Predicate<String>() { + @Override + public boolean test(String x) { + return "Finished".equals(x); + } + }).then(new Success<String,Object>() { + @Override + public Promise<Object> call(Promise<String> x) + throws Exception { + s.release(); + return null; + } + }); + assertFalse(s.tryAcquire()); + assertTrue(s.tryAcquire(1, TimeUnit.SECONDS)); } @Test(expected = ExpectedTestException.class) http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/DTOType.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/DTOType.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/DTOType.java new file mode 100644 index 0000000..7608660 --- /dev/null +++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/DTOType.java @@ -0,0 +1,23 @@ +/** + * 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.provider.tcp.myservice; + +public class DTOType { + public String value; +} http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveService.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveService.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveService.java index 33d0d06..357300c 100644 --- a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveService.java +++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveService.java @@ -51,4 +51,8 @@ public interface PrimitiveService { Map<Version, Version> callVersionMap(Map<Version, Version> map); Set<Version> callVersionSet(Set<Version> set); + + DTOType callDTO(DTOType dto); + + DTOType[] callDTOAr(DTOType[] dtoAr); } http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/a421c659/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveServiceImpl.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveServiceImpl.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveServiceImpl.java index 7bf3fe1..ed6dc6e 100644 --- a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveServiceImpl.java +++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/myservice/PrimitiveServiceImpl.java @@ -74,4 +74,14 @@ public class PrimitiveServiceImpl implements PrimitiveService { return set; } + + @Override + public DTOType callDTO(DTOType dto) { + return dto; + } + + @Override + public DTOType[] callDTOAr(DTOType[] dtoAr) { + return dtoAr; + } }