/* # Licensed Materials - Property of IBM # Copyright IBM Corp. 2014 */ package com.ibm.streamsx.inet.rest.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.BufferedInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; import org.junit.Test; import com.ibm.json.java.JSON; import com.ibm.json.java.JSONArray; import com.ibm.json.java.JSONArtifact; import com.ibm.json.java.JSONObject; import com.ibm.streams.flow.declare.InputPortDeclaration; import com.ibm.streams.flow.declare.OperatorGraph; import com.ibm.streams.flow.declare.OperatorGraphFactory; import com.ibm.streams.flow.declare.OperatorInvocation; import com.ibm.streams.flow.javaprimitives.JavaOperatorTester; import com.ibm.streams.flow.javaprimitives.JavaTestableGraph; import com.ibm.streams.operator.OutputTuple; import com.ibm.streams.operator.StreamingOutput; import com.ibm.streams.operator.types.RString; import com.ibm.streamsx.inet.rest.ops.ServletOperator; import com.ibm.streamsx.inet.rest.ops.TupleView; public class TupleViewTest { /** * Test an embedded jsonString attribute is converted * to JSON rather than a string that is serialized JSON. */ @Test public void testJSONStringAttribute() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); OperatorInvocation<TupleView> op = graph.addOperator("TestJSONStringAttribute", TupleView.class); op.setIntParameter("port", 0); // Set the content to have a fixed URL op.setStringParameter("context", "TupleViewTest"); op.setStringParameter("contextResourceBase", "/tmp"); // not actually serving any static content InputPortDeclaration tuplesToView = op .addInput("tuple<int32 a, rstring jsonString>"); // Just need to see the last tuple in the HTTP request. tuplesToView.sliding().evictCount(1).triggerCount(1); // Create the testable version of the graph JavaTestableGraph testableGraph = new JavaOperatorTester() .executable(graph); // Create the injector to inject test tuples. StreamingOutput<OutputTuple> injector = testableGraph.getInputTester(tuplesToView); // Execute the initialization of operators within graph. testableGraph.initialize().get().allPortsReady().get(); // Create a JSON object for the jsonString attribute. JSONObject json = new JSONObject(); json.put("b", 37l); json.put("c", "HelloWorld!"); // and submit to the operator injector.submitAsTuple(32, new RString(json.serialize())); URL url = new URL(getJettyURLBase(testableGraph, op) + "/TupleViewTest/TestJSONStringAttribute/ports/input/0/tuples"); JSONArray tuples = getJSONTuples(url); assertEquals(1, tuples.size()); JSONObject jtuple = (JSONObject) tuples.get(0); assertEquals(32l, jtuple.get("a")); // integral values always returned as long Object js = jtuple.get("jsonString"); assertTrue(js instanceof JSONObject); JSONObject jso = (JSONObject) js; assertEquals(37l, jso.get("b")); assertEquals("HelloWorld!", jso.get("c")); testableGraph.shutdown().get(); } /** * Test an rstring jsonString tuple is converted * to JSON rather than a string that is serialized JSON. */ @Test public void testJSONStringTuple() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); OperatorInvocation<TupleView> op = graph.addOperator("TestJSONStringTuple", TupleView.class); op.setIntParameter("port", 0); // Set the content to have a fixed URL op.setStringParameter("context", "TupleViewTest"); op.setStringParameter("contextResourceBase", "/tmp"); // not actually serving any static content InputPortDeclaration tuplesToView = op .addInput("tuple<rstring jsonString>"); // Just need to see the last tuple in the HTTP request. tuplesToView.sliding().evictCount(2).triggerCount(1); // Create the testable version of the graph JavaTestableGraph testableGraph = new JavaOperatorTester() .executable(graph); // Create the injector to inject test tuples. StreamingOutput<OutputTuple> injector = testableGraph.getInputTester(tuplesToView); // Execute the initialization of operators within graph. testableGraph.initialize().get().allPortsReady().get(); // Create a JSON object for the jsonString attribute. JSONObject json = new JSONObject(); json.put("b", 93l); json.put("c", "Bonjour!"); // and submit to the operator injector.submitAsTuple(new RString(json.serialize())); json.put("c", "Hola!"); json.put("d", 423l); injector.submitAsTuple(new RString(json.serialize())); URL url = new URL(getJettyURLBase(testableGraph, op) + "/TupleViewTest/TestJSONStringTuple/ports/input/0/tuples"); JSONArray tuples = getJSONTuples(url); assertEquals(2, tuples.size()); JSONObject jtuple = (JSONObject) tuples.get(0); assertEquals(93l, jtuple.get("b")); assertEquals("Bonjour!", jtuple.get("c")); jtuple = (JSONObject) tuples.get(1); assertEquals(93l, jtuple.get("b")); assertEquals("Hola!", jtuple.get("c")); assertEquals(423l, jtuple.get("d")); testableGraph.shutdown().get(); } /** * Get the server port from the operator's metric. */ public static int getJettyPort(JavaTestableGraph tg, OperatorInvocation<? extends ServletOperator> op) { return (int) tg.getOperatorInstance(op).getServerPort().getValue(); } /** * Get the base part of the URL for a ServletOperator instance. */ public static String getJettyURLBase(JavaTestableGraph tg, OperatorInvocation<? extends ServletOperator> op) throws UnknownHostException { int port = getJettyPort(tg, op); return "http://" + InetAddress.getLocalHost().getHostName() + ":" + port; } /** * Get the JSON array of tuples from a URL assumed to be HTTPTupleView (TupleView.class). */ public static JSONArray getJSONTuples(URL url) throws IOException { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); assertTrue(conn.getContentType().startsWith("application/json")); JSONArtifact jsonResponse = JSON.parse(new BufferedInputStream(conn.getInputStream(), 4096)); conn.disconnect(); assertTrue(jsonResponse instanceof JSONArray); return (JSONArray) jsonResponse; } }