Repository: aries-rsa Updated Branches: refs/heads/master 44943bcef -> 19849747e
[ARIES-1758] First impl for serializing Version Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/19849747 Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/19849747 Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/19849747 Branch: refs/heads/master Commit: 19849747e5d300e4613bd9759cacdfe0570edad9 Parents: 9a08b23 Author: Christian Schneider <[email protected]> Authored: Thu Feb 8 17:33:36 2018 +0100 Committer: Christian Schneider <[email protected]> Committed: Thu Feb 8 17:40:34 2018 +0100 ---------------------------------------------------------------------- .../aries/rsa/provider/tcp/MethodInvoker.java | 18 ++++- .../aries/rsa/provider/tcp/SerVersion.java | 25 +++++++ .../aries/rsa/provider/tcp/TCPServer.java | 1 + .../rsa/provider/tcp/TcpInvocationHandler.java | 38 +++++++++- .../rsa/provider/tcp/VersionDeserializer.java | 67 +++++++++++++++++ .../rsa/provider/tcp/VersionSerializer.java | 79 ++++++++++++++++++++ .../provider/tcp/TcpProviderPrimitiveTest.java | 14 ++++ .../tcp/myservice/PrimitiveService.java | 6 ++ .../tcp/myservice/PrimitiveServiceImpl.java | 12 +++ 9 files changed, 256 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/MethodInvoker.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/MethodInvoker.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/MethodInvoker.java index d5f2a03..dadf5f7 100644 --- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/MethodInvoker.java +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/MethodInvoker.java @@ -24,6 +24,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import org.osgi.framework.Version; + public class MethodInvoker { private HashMap<Object, Object> primTypes; @@ -39,9 +41,11 @@ public class MethodInvoker { this.primTypes.put(Float.TYPE, Float.class); this.primTypes.put(Double.TYPE, Double.class); this.primTypes.put(Boolean.TYPE, Boolean.class); + this.primTypes.put(Character.TYPE, Character.class); } public Object invoke(String methodName, Object[] args) { + args = VersionDeserializer.replaceAr(args); Class<?>[] parameterTypesAr = getTypes(args); Method method = null; try { @@ -52,6 +56,18 @@ public class MethodInvoker { } } + private void readReplaceVersion(Object[] args) { + if (args != null) { + for (int c=0; c<args.length; c++) { + Object current = args[c]; + if (current instanceof SerVersion) { + SerVersion serVersion = (SerVersion)current; + args[c] = new Version(serVersion.getVersion()); + } + } + } + } + private Method getMethod(String methodName, Class<?>[] parameterTypesAr) { try { return service.getClass().getMethod(methodName, parameterTypesAr); @@ -87,7 +103,7 @@ public class MethodInvoker { } return type.isAssignableFrom(paramType); } - + private Class<?>[] getTypes(Object[] args) { List<Class<?>> parameterTypes = new ArrayList<>(); if (args != null) { http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/SerVersion.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/SerVersion.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/SerVersion.java new file mode 100644 index 0000000..ad912df --- /dev/null +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/SerVersion.java @@ -0,0 +1,25 @@ +package org.apache.aries.rsa.provider.tcp; + +import java.io.Serializable; + +import org.osgi.framework.Version; + +public class SerVersion implements Serializable { + private static final long serialVersionUID = 4725855052866235835L; + + private String version; + + public SerVersion() { + } + + public SerVersion(Version version) { + this.version = version.toString(); + } + + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } +} http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPServer.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPServer.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPServer.java index ce1b06a..fca6df3 100644 --- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPServer.java +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPServer.java @@ -86,6 +86,7 @@ public class TCPServer implements Closeable, Runnable { Object[] args = (Object[])ois.readObject(); Object result = invoker.invoke(methodName, args); result = resolveAsnyc(result); + result = VersionSerializer.replace(result); if (result instanceof InvocationTargetException) { result = ((InvocationTargetException) result).getCause(); } http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpInvocationHandler.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpInvocationHandler.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpInvocationHandler.java index fbda0ec..0fd3526 100644 --- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpInvocationHandler.java +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpInvocationHandler.java @@ -24,12 +24,17 @@ import java.io.ObjectOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.net.Socket; +import java.net.SocketTimeoutException; import java.net.UnknownHostException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.Future; import java.util.function.Supplier; +import org.osgi.framework.ServiceException; +import org.osgi.framework.Version; import org.osgi.util.promise.Deferred; import org.osgi.util.promise.Promise; @@ -90,18 +95,23 @@ public class TcpInvocationHandler implements InvocationHandler { } private Object handleSyncCall(Method method, Object[] args) throws Throwable { + args = (Object[])VersionSerializer.replace(args); Object result; try ( - Socket socket = new Socket(this.host, this.port); + Socket socket = openSocket(); ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()) ) { socket.setSoTimeout(timeoutMillis); out.writeObject(method.getName()); + out.writeObject(args); out.flush(); result = parseResult(socket); + result = VersionDeserializer.replace(result); + } catch (SocketTimeoutException e) { + throw new ServiceException("Timeout calling " + host + ":" + port + " method: " + method.getName(), ServiceException.REMOTE, e); } catch (Throwable e) { - throw new RuntimeException("Error calling " + host + ":" + port + " method: " + method.getName(), e); + throw new ServiceException("Error calling " + host + ":" + port + " method: " + method.getName(), ServiceException.REMOTE, e); } if (result instanceof Throwable) { throw (Throwable)result; @@ -109,9 +119,31 @@ public class TcpInvocationHandler implements InvocationHandler { return result; } + private Socket openSocket() throws UnknownHostException, IOException { + return AccessController.doPrivileged(new PrivilegedAction<Socket>() { + + @Override + public Socket run() { + try { + return new Socket(host, port); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + }); + } + private Object parseResult(Socket socket) throws Throwable { try (ObjectInputStream in = new LoaderObjectInputStream(socket.getInputStream(), cl)) { - return in.readObject(); + return readReplaceVersion(in.readObject()); + } + } + + private Object readReplaceVersion(Object readObject) { + if (readObject instanceof SerVersion) { + return new Version(((SerVersion)readObject).getVersion()); + } else { + return readObject; } } http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionDeserializer.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionDeserializer.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionDeserializer.java new file mode 100644 index 0000000..84d965e --- /dev/null +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionDeserializer.java @@ -0,0 +1,67 @@ +/** + * 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; + +import org.osgi.framework.Version; + +public class VersionDeserializer { + + public static Object[] replaceAr(Object[] args) { + if (args == null) { + return null; + } + Object[] result = new Object[args.length]; + for (int c=0; c<args.length; c++) { + result[c] = replace(args[c]); + } + return result; + } + + public static Object replace(Object obj) { + if (obj == null) { + return obj; + } + if (obj.getClass().isArray()) { + if (obj.getClass().getComponentType() == SerVersion.class) { + return replaceVersionAr((SerVersion[]) obj); + } else if (obj.getClass().getComponentType() == Object.class) { + return replaceAr((Object[]) obj); + } else { + return obj; + } + } else if (obj instanceof SerVersion) { + SerVersion serVersion = (SerVersion) obj; + return Version.parseVersion(serVersion.getVersion()); + } else { + return obj; + } + } + + private static Version[] replaceVersionAr(SerVersion[] obj) { + if (obj == null) { + return null; + } + Version[] result = new Version[obj.length]; + for (int c=0; c<obj.length; c++) { + result[c] = Version.parseVersion(obj[c].getVersion()); + } + return result; + } + +} http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionSerializer.java ---------------------------------------------------------------------- diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionSerializer.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionSerializer.java new file mode 100644 index 0000000..2de7114 --- /dev/null +++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/VersionSerializer.java @@ -0,0 +1,79 @@ +/** + * 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; + +import java.util.ArrayList; +import java.util.List; + +import org.osgi.framework.Version; + +public class VersionSerializer { + + public static Object replace(Object obj) { + if (obj == null) { + return null; + } + if (obj.getClass().isArray()) { + if (obj.getClass().getComponentType() == Version.class) { + return replaceVersionAr((Version[]) obj); + } else if (obj.getClass().getComponentType() == Object.class) { + return replaceAr((Object[]) obj); + } else { + return obj; + } + } else if (obj instanceof List) { + return replaceList((List)obj); + } else if (obj instanceof Version) { + return new SerVersion((Version) obj); + } else { + return obj; + } + } + + private static Object replaceList(List<Version> obj) { + List<SerVersion> result = new ArrayList<>(); + for (Version version : obj) { + result.add(new SerVersion(version)); + } + return result; + } + + private static SerVersion[] replaceVersionAr(Version[] obj) { + if (obj == null) { + return null; + } + SerVersion[] result = new SerVersion[obj.length]; + for (int c=0; c<obj.length; c++) { + result[c] = new SerVersion((Version) obj[c]); + } + return result; + } + + public static Object[] replaceAr(Object[] args) { + if (args == null) { + return null; + } + Object[] result = new Object[args.length]; + for (int c=0; c<args.length; c++) { + result[c] = replace(args[c]); + } + return result; + } + +} http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/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 2c08104..8badef7 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 @@ -18,7 +18,10 @@ */ 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.assertThat; +import static org.osgi.framework.Version.parseVersion; import java.io.IOException; import java.util.HashMap; @@ -34,6 +37,7 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.osgi.framework.BundleContext; +import org.osgi.framework.Version; public class TcpProviderPrimitiveTest { @@ -98,6 +102,16 @@ public class TcpProviderPrimitiveTest { public void testByteAr() { Assert.assertArrayEquals(new byte[]{1}, myServiceProxy.callByteAr(new byte[]{1})); } + + @Test + public void testVersion() { + assertThat(myServiceProxy.callVersion(parseVersion("1.0.0")), equalTo(parseVersion("1.0.0"))); + } + + @Test + public void testVersionAr() { + assertThat(myServiceProxy.callVersionAr(new Version[] {parseVersion("1.0.0")}), equalTo(new Version[] {parseVersion("1.0.0")})); + } @AfterClass public static void close() throws IOException { http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/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 d7988a5..679c2fa 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 @@ -18,6 +18,8 @@ */ package org.apache.aries.rsa.provider.tcp.myservice; +import org.osgi.framework.Version; + public interface PrimitiveService { byte callByte(byte num); @@ -35,4 +37,8 @@ public interface PrimitiveService { boolean callBoolean(boolean bool); byte[] callByteAr(byte[] byteAr); + + Version callVersion(Version version); + + Version[] callVersionAr(Version[] version); } http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/19849747/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 1e6e5fd..9039dc2 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 @@ -1,5 +1,7 @@ package org.apache.aries.rsa.provider.tcp.myservice; +import org.osgi.framework.Version; + public class PrimitiveServiceImpl implements PrimitiveService { @Override @@ -43,4 +45,14 @@ public class PrimitiveServiceImpl implements PrimitiveService { return byteAr; } + @Override + public Version callVersion(Version version) { + return version; + } + + @Override + public Version[] callVersionAr(Version[] version) { + return version; + } + }
