Loading plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/DefaultAdapter.java +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ public class DefaultAdapter implements Validator, Reporter, RuntimeHelper { @Override public void setVerdict(Verdict verdict) { // TODO Auto-generated method stub System.out.println("Set verdict to " + verdict.name); System.out.println("Set verdict to " + verdict.getName()); } } plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpSystemAdapter.java +106 −20 Original line number Diff line number Diff line Loading @@ -2,6 +2,9 @@ package org.etsi.mts.tdl.execution.java.adapters.http; import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; Loading @@ -20,14 +23,17 @@ import org.etsi.mts.tdl.execution.java.rt.core.PojoData; import org.etsi.mts.tdl.execution.java.tri.Argument; import org.etsi.mts.tdl.execution.java.tri.Connection; import org.etsi.mts.tdl.execution.java.tri.Data; import org.etsi.mts.tdl.execution.java.tri.ElementAnnotation; import org.etsi.mts.tdl.execution.java.tri.Mapping; import org.etsi.mts.tdl.execution.java.tri.Procedure; import org.etsi.mts.tdl.execution.java.tri.Reporter; import org.etsi.mts.tdl.execution.java.tri.SystemAdapter; import org.etsi.mts.tdl.execution.java.tri.Type; import org.etsi.mts.tdl.execution.java.tri.Validator; import org.etsi.mts.tdl.execution.java.tri.Value; import org.openapitools.jackson.nullable.JsonNullableModule; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; Loading @@ -35,14 +41,13 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; public class HttpSystemAdapter implements SystemAdapter { private Validator validator; private Reporter reporter; protected Validator validator; protected Reporter reporter; private HttpClient.Builder builder; private HttpClient client; private ObjectMapper mapper; private String baseUri = "https://example.com"; private List<HttpHeader> defaultHeaders = new ArrayList<HttpHeader>(); Loading @@ -60,8 +65,8 @@ public class HttpSystemAdapter implements SystemAdapter { } /** * Set headers that are applied to all requests, such as authentication. * The default implementation adds by default: * Set headers that are applied to all requests, such as authentication. The * default implementation adds by default: * <ul> * <li>Content-Type: application/json</li> * <li>Accept: application/json</li> Loading Loading @@ -111,6 +116,7 @@ public class HttpSystemAdapter implements SystemAdapter { } private void handleError(Throwable t) { t.printStackTrace(); reporter.runtimeError(t); throw new RuntimeException(t); } Loading @@ -125,7 +131,7 @@ public class HttpSystemAdapter implements SystemAdapter { @Override public void send(Data message, Connection connection) { HttpRequestData httpData = (HttpRequestData) message.getValue(); HttpRequestData httpData = getRequestData(message); HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(); applyDefaults(requestBuilder); Loading Loading @@ -170,9 +176,9 @@ public class HttpSystemAdapter implements SystemAdapter { requestBuilder.uri(uri); // TODO logging reporter.comment("Outgoing: " + httpData.method.toString() + " | " + uri + " | " + mapper.writeValueAsString(httpData.body)); reporter.comment("Outgoing (headers): " + httpData.method.toString() + " | " + uri); byte[] body = mapper.writeValueAsBytes(httpData.body); byte[] body = encodeBody(httpData.body); requestBuilder.method(httpData.method.toString(), HttpRequest.BodyPublishers.ofByteArray(body)); for (HttpHeader header : httpData.headers) Loading @@ -183,14 +189,14 @@ public class HttpSystemAdapter implements SystemAdapter { responseFuture.whenCompleteAsync(this::handleResponse); } catch (JsonProcessingException e) { } catch (IOException e) { handleError(e); } } @Override public Data receive(Data expected, Connection connection) throws InterruptedException, AssertionError { HttpResponseData expectedHttpData = expected != null ? (HttpResponseData) expected.getValue() : null; HttpResponseData expectedHttpData = expected != null ? getResponseData(expected) : null; synchronized (unhandledResponses) { HttpResponse<String> response = unhandledResponses.peek(); Loading @@ -215,8 +221,7 @@ public class HttpSystemAdapter implements SystemAdapter { Data received = new PojoData<>(receivedHttpData); if (expected != null) { if (expectedHttpData.body != null) { receivedHttpData.body = this.mapper.readValue(response.body(), expectedHttpData.body.getClass()); receivedHttpData.body = decodeBody(response.body(), expectedHttpData.body.getClass()); } if (this.validator.matches(expected, received)) { unhandledResponses.remove(); Loading @@ -229,7 +234,7 @@ public class HttpSystemAdapter implements SystemAdapter { return received; } } catch (JsonProcessingException e) { } catch (IOException e) { handleError(e); } } Loading @@ -237,6 +242,15 @@ public class HttpSystemAdapter implements SystemAdapter { return null; } protected byte[] encodeBody(Object body) throws IOException { reporter.comment("Outgoing (body): " + mapper.writeValueAsString(body)); return mapper.writeValueAsBytes(body); } protected Object decodeBody(String body, Class<?> type) throws IOException { return this.mapper.readValue(body, type); } @Override public Data call(Procedure operation, Argument[] arguments, Data expectedReturn, Data expectedException, Connection connection) { Loading @@ -252,4 +266,76 @@ public class HttpSystemAdapter implements SystemAdapter { public void replyCall(Procedure operation, Data returnValue, Data exception, Connection connection) { throw new UnsupportedOperationException("Procedure-based communication is not supported by this adapter."); } protected HttpRequestData getRequestData(Data message) { if (message.getValue() instanceof HttpRequestData) return (HttpRequestData) message.getValue(); if (message.getType() instanceof Type) { HttpRequestData req = (HttpRequestData) getMappedObject(message); return req; } throw new RuntimeException("Request data in unsupported format"); } private Object getMappedObject(Data<Type, Value> data) { Type t = (Type) data.getType(); Value v = data.getValue(); if (!t.isStructure() && !t.isCollection() && v.getValue() != null) return v.getValue(); Mapping m = t.getMapping(); if (m == null || !m.getMappingName().equalsIgnoreCase("Java")) return data; Mapping rs = m.getResource(); boolean isMapped = false; for (ElementAnnotation a : rs.annotations) { if (a.key.equals("Tdl::MappingName") && a.value.equals("Java")) { isMapped = true; break; } } if (!isMapped) return null; String cName = rs.getUri() + "." + m.getUri(); Object obj = null; try { Class<?> cl = getClass().getClassLoader().loadClass(cName); if (cl.isEnum()) { String literal = null; if (v.getValue() != null) literal = v.getValue().toString(); else if (v.getMapping() != null) literal = v.getMapping().getUri(); obj = Enum.valueOf((Class<Enum>) cl, literal); } else obj = cl.getDeclaredConstructor().newInstance(); if (t.isStructure()) { for (String pName : t.getParameters()) { Data<Type, Value> pData = data.getValue().getParameter(pName); if (pData != null) { Object pObj = getMappedObject(pData); Field pField = cl.getDeclaredField(m.getParameter(pName).getUri()); pField.set(obj, pObj); } } } // TODO isCollection() } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException e) { handleError(e); } return obj; } protected HttpResponseData getResponseData(Data message) { if (message.getValue() instanceof HttpResponseData) return (HttpResponseData) message.getValue(); // XXX return null; } } No newline at end of file plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ReceiverHub.java +1 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public class ReceiverHub { this.systemAdapter = systemAdapter; this.connection = connection; this.thread = new Thread(() -> run(), "Receive from SystemAdapter on " + connection.name); this.thread = new Thread(() -> run(), "Receive from SystemAdapter on " + connection.getName()); this.thread.setDaemon(true); this.thread.start(); } Loading plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/TestControl.java +6 −6 Original line number Diff line number Diff line Loading @@ -109,16 +109,16 @@ public class TestControl { for (Connection c : connections) { int testerEP = -1; for (int i = 0; i <= 1; i++) if (c.endPoints[i].component.name.equals(testerComponentName) && c.endPoints[i].gate.name.equals(testerGateName)) { if (c.endPoints[i].component.getName().equals(testerComponentName) && c.endPoints[i].gate.getName().equals(testerGateName)) { testerEP = i; break; } if (testerEP == -1) continue; int targetEP = testerEP == 0 ? 1 : 0; if (c.endPoints[targetEP].component.name.equals(remoteComponentName) && c.endPoints[targetEP].gate.name.equals(remoteGateName)) if (c.endPoints[targetEP].component.getName().equals(remoteComponentName) && c.endPoints[targetEP].gate.getName().equals(remoteGateName)) return c; } throw new RuntimeException(String.format("Unknown connection: from %s.%s to %s.%s", testerComponentName, Loading @@ -128,8 +128,8 @@ public class TestControl { public GateReference getGateReference(String testerComponentName, String testerGateName) { for (Connection c : connections) { for (int i = 0; i <= 1; i++) if (c.endPoints[i].component.name.equals(testerComponentName) && c.endPoints[i].gate.name.equals(testerGateName)) { if (c.endPoints[i].component.getName().equals(testerComponentName) && c.endPoints[i].gate.getName().equals(testerGateName)) { return c.endPoints[i]; } } Loading Loading
plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/DefaultAdapter.java +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ public class DefaultAdapter implements Validator, Reporter, RuntimeHelper { @Override public void setVerdict(Verdict verdict) { // TODO Auto-generated method stub System.out.println("Set verdict to " + verdict.name); System.out.println("Set verdict to " + verdict.getName()); } }
plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/adapters/http/HttpSystemAdapter.java +106 −20 Original line number Diff line number Diff line Loading @@ -2,6 +2,9 @@ package org.etsi.mts.tdl.execution.java.adapters.http; import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; Loading @@ -20,14 +23,17 @@ import org.etsi.mts.tdl.execution.java.rt.core.PojoData; import org.etsi.mts.tdl.execution.java.tri.Argument; import org.etsi.mts.tdl.execution.java.tri.Connection; import org.etsi.mts.tdl.execution.java.tri.Data; import org.etsi.mts.tdl.execution.java.tri.ElementAnnotation; import org.etsi.mts.tdl.execution.java.tri.Mapping; import org.etsi.mts.tdl.execution.java.tri.Procedure; import org.etsi.mts.tdl.execution.java.tri.Reporter; import org.etsi.mts.tdl.execution.java.tri.SystemAdapter; import org.etsi.mts.tdl.execution.java.tri.Type; import org.etsi.mts.tdl.execution.java.tri.Validator; import org.etsi.mts.tdl.execution.java.tri.Value; import org.openapitools.jackson.nullable.JsonNullableModule; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; Loading @@ -35,14 +41,13 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; public class HttpSystemAdapter implements SystemAdapter { private Validator validator; private Reporter reporter; protected Validator validator; protected Reporter reporter; private HttpClient.Builder builder; private HttpClient client; private ObjectMapper mapper; private String baseUri = "https://example.com"; private List<HttpHeader> defaultHeaders = new ArrayList<HttpHeader>(); Loading @@ -60,8 +65,8 @@ public class HttpSystemAdapter implements SystemAdapter { } /** * Set headers that are applied to all requests, such as authentication. * The default implementation adds by default: * Set headers that are applied to all requests, such as authentication. The * default implementation adds by default: * <ul> * <li>Content-Type: application/json</li> * <li>Accept: application/json</li> Loading Loading @@ -111,6 +116,7 @@ public class HttpSystemAdapter implements SystemAdapter { } private void handleError(Throwable t) { t.printStackTrace(); reporter.runtimeError(t); throw new RuntimeException(t); } Loading @@ -125,7 +131,7 @@ public class HttpSystemAdapter implements SystemAdapter { @Override public void send(Data message, Connection connection) { HttpRequestData httpData = (HttpRequestData) message.getValue(); HttpRequestData httpData = getRequestData(message); HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(); applyDefaults(requestBuilder); Loading Loading @@ -170,9 +176,9 @@ public class HttpSystemAdapter implements SystemAdapter { requestBuilder.uri(uri); // TODO logging reporter.comment("Outgoing: " + httpData.method.toString() + " | " + uri + " | " + mapper.writeValueAsString(httpData.body)); reporter.comment("Outgoing (headers): " + httpData.method.toString() + " | " + uri); byte[] body = mapper.writeValueAsBytes(httpData.body); byte[] body = encodeBody(httpData.body); requestBuilder.method(httpData.method.toString(), HttpRequest.BodyPublishers.ofByteArray(body)); for (HttpHeader header : httpData.headers) Loading @@ -183,14 +189,14 @@ public class HttpSystemAdapter implements SystemAdapter { responseFuture.whenCompleteAsync(this::handleResponse); } catch (JsonProcessingException e) { } catch (IOException e) { handleError(e); } } @Override public Data receive(Data expected, Connection connection) throws InterruptedException, AssertionError { HttpResponseData expectedHttpData = expected != null ? (HttpResponseData) expected.getValue() : null; HttpResponseData expectedHttpData = expected != null ? getResponseData(expected) : null; synchronized (unhandledResponses) { HttpResponse<String> response = unhandledResponses.peek(); Loading @@ -215,8 +221,7 @@ public class HttpSystemAdapter implements SystemAdapter { Data received = new PojoData<>(receivedHttpData); if (expected != null) { if (expectedHttpData.body != null) { receivedHttpData.body = this.mapper.readValue(response.body(), expectedHttpData.body.getClass()); receivedHttpData.body = decodeBody(response.body(), expectedHttpData.body.getClass()); } if (this.validator.matches(expected, received)) { unhandledResponses.remove(); Loading @@ -229,7 +234,7 @@ public class HttpSystemAdapter implements SystemAdapter { return received; } } catch (JsonProcessingException e) { } catch (IOException e) { handleError(e); } } Loading @@ -237,6 +242,15 @@ public class HttpSystemAdapter implements SystemAdapter { return null; } protected byte[] encodeBody(Object body) throws IOException { reporter.comment("Outgoing (body): " + mapper.writeValueAsString(body)); return mapper.writeValueAsBytes(body); } protected Object decodeBody(String body, Class<?> type) throws IOException { return this.mapper.readValue(body, type); } @Override public Data call(Procedure operation, Argument[] arguments, Data expectedReturn, Data expectedException, Connection connection) { Loading @@ -252,4 +266,76 @@ public class HttpSystemAdapter implements SystemAdapter { public void replyCall(Procedure operation, Data returnValue, Data exception, Connection connection) { throw new UnsupportedOperationException("Procedure-based communication is not supported by this adapter."); } protected HttpRequestData getRequestData(Data message) { if (message.getValue() instanceof HttpRequestData) return (HttpRequestData) message.getValue(); if (message.getType() instanceof Type) { HttpRequestData req = (HttpRequestData) getMappedObject(message); return req; } throw new RuntimeException("Request data in unsupported format"); } private Object getMappedObject(Data<Type, Value> data) { Type t = (Type) data.getType(); Value v = data.getValue(); if (!t.isStructure() && !t.isCollection() && v.getValue() != null) return v.getValue(); Mapping m = t.getMapping(); if (m == null || !m.getMappingName().equalsIgnoreCase("Java")) return data; Mapping rs = m.getResource(); boolean isMapped = false; for (ElementAnnotation a : rs.annotations) { if (a.key.equals("Tdl::MappingName") && a.value.equals("Java")) { isMapped = true; break; } } if (!isMapped) return null; String cName = rs.getUri() + "." + m.getUri(); Object obj = null; try { Class<?> cl = getClass().getClassLoader().loadClass(cName); if (cl.isEnum()) { String literal = null; if (v.getValue() != null) literal = v.getValue().toString(); else if (v.getMapping() != null) literal = v.getMapping().getUri(); obj = Enum.valueOf((Class<Enum>) cl, literal); } else obj = cl.getDeclaredConstructor().newInstance(); if (t.isStructure()) { for (String pName : t.getParameters()) { Data<Type, Value> pData = data.getValue().getParameter(pName); if (pData != null) { Object pObj = getMappedObject(pData); Field pField = cl.getDeclaredField(m.getParameter(pName).getUri()); pField.set(obj, pObj); } } } // TODO isCollection() } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException e) { handleError(e); } return obj; } protected HttpResponseData getResponseData(Data message) { if (message.getValue() instanceof HttpResponseData) return (HttpResponseData) message.getValue(); // XXX return null; } } No newline at end of file
plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/ReceiverHub.java +1 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public class ReceiverHub { this.systemAdapter = systemAdapter; this.connection = connection; this.thread = new Thread(() -> run(), "Receive from SystemAdapter on " + connection.name); this.thread = new Thread(() -> run(), "Receive from SystemAdapter on " + connection.getName()); this.thread.setDaemon(true); this.thread.start(); } Loading
plugins/org.etsi.mts.tdl.execution.java.runtime/src/org/etsi/mts/tdl/execution/java/rt/core/TestControl.java +6 −6 Original line number Diff line number Diff line Loading @@ -109,16 +109,16 @@ public class TestControl { for (Connection c : connections) { int testerEP = -1; for (int i = 0; i <= 1; i++) if (c.endPoints[i].component.name.equals(testerComponentName) && c.endPoints[i].gate.name.equals(testerGateName)) { if (c.endPoints[i].component.getName().equals(testerComponentName) && c.endPoints[i].gate.getName().equals(testerGateName)) { testerEP = i; break; } if (testerEP == -1) continue; int targetEP = testerEP == 0 ? 1 : 0; if (c.endPoints[targetEP].component.name.equals(remoteComponentName) && c.endPoints[targetEP].gate.name.equals(remoteGateName)) if (c.endPoints[targetEP].component.getName().equals(remoteComponentName) && c.endPoints[targetEP].gate.getName().equals(remoteGateName)) return c; } throw new RuntimeException(String.format("Unknown connection: from %s.%s to %s.%s", testerComponentName, Loading @@ -128,8 +128,8 @@ public class TestControl { public GateReference getGateReference(String testerComponentName, String testerGateName) { for (Connection c : connections) { for (int i = 0; i <= 1; i++) if (c.endPoints[i].component.name.equals(testerComponentName) && c.endPoints[i].gate.name.equals(testerGateName)) { if (c.endPoints[i].component.getName().equals(testerComponentName) && c.endPoints[i].gate.getName().equals(testerGateName)) { return c.endPoints[i]; } } Loading