/* # 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.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.URL; import java.util.Random; import org.junit.Test; import com.ibm.json.java.JSONObject; 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.declare.OutputPortDeclaration; import com.ibm.streams.flow.handlers.MostRecent; import com.ibm.streams.flow.javaprimitives.JavaOperatorTester; import com.ibm.streams.flow.javaprimitives.JavaTestableGraph; import com.ibm.streams.operator.Tuple; import com.ibm.streamsx.inet.rest.ops.PostJSON; public class InjectJSONTest { @Test public void testGoodOnlyJSONSchemaFirstPort() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.addOutput("tuple<rstring jsonString>"); assertTrue(graph.compileChecks()); } @Test public void testGoodJSONSchemaFirstPort() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.addOutput("tuple<int32 a, rstring jsonString>"); assertTrue(graph.compileChecks()); } @Test public void testGoodStringSchemaFirstPort() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.addOutput("tuple<rstring a, int32 b>"); assertTrue(graph.compileChecks()); } @Test public void testBadSchemaFirstPort() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.addOutput("tuple<int32 a>"); assertFalse(graph.compileChecks()); } @Test public void testInjectSinglePort() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); // Declare a HTTPJSONInjection operator OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.setIntParameter("port", 8081); OutputPortDeclaration injectedTuples = op.addOutput("tuple<rstring jsonString>"); // Create the testable version of the graph JavaTestableGraph testableGraph = new JavaOperatorTester() .executable(graph); MostRecent<Tuple> mrt = new MostRecent<Tuple>(); testableGraph.registerStreamHandler(injectedTuples, mrt); // Execute the initialization of operators within graph. testableGraph.initialize().get().allPortsReady().get(); assertNull(mrt.getMostRecentTuple()); URL postTuple = new URL("http://" + InetAddress.getLocalHost().getHostName() + ":8081/" + op.getName() + "/ports/output/0/inject"); // Make an JSON POST request with an empty JSON object postJSONAndTest(postTuple, new JSONObject(), mrt); JSONObject json = new JSONObject(); json.put("a", 37l); // JSON library always reads ints back as long values json.put("b", "Hello!"); postJSONAndTest(postTuple, json, mrt); testableGraph.shutdown().get(); } @Test public void testInjectTwoPorts() throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); // Declare a HTTPJSONInjection operator OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.setIntParameter("port", 8082); OutputPortDeclaration injectedTuples0 = op.addOutput("tuple<rstring jsonString>"); OutputPortDeclaration injectedTuples1 = op.addOutput("tuple<rstring a>"); // Create the testable version of the graph JavaTestableGraph testableGraph = new JavaOperatorTester() .executable(graph); MostRecent<Tuple> mrt0 = new MostRecent<Tuple>(); testableGraph.registerStreamHandler(injectedTuples0, mrt0); MostRecent<Tuple> mrt1 = new MostRecent<Tuple>(); testableGraph.registerStreamHandler(injectedTuples1, mrt1); // Execute the initialization of operators within graph. testableGraph.initialize().get().allPortsReady().get(); URL postTuple0 = new URL("http://" + InetAddress.getLocalHost().getHostName() + ":8082/" + op.getName() + "/ports/output/0/inject"); JSONObject json0 = new JSONObject(); json0.put("a", 37l); // JSON library always reads ints back as long values json0.put("b", "Hello!"); postJSONAndTest(postTuple0, json0, mrt0); assertNull(mrt1.getMostRecentTuple()); URL postTuple1 = new URL("http://" + InetAddress.getLocalHost().getHostName() + ":8082/" + op.getName() + "/ports/output/1/inject"); JSONObject json1 = new JSONObject(); json1.put("a", 99l); // JSON library always reads ints back as long values json1.put("b", "Goodbye!"); postJSONAndTest(postTuple1, json1, mrt1); assertNull(mrt0.getMostRecentTuple()); testableGraph.shutdown().get(); } @Test public void testBigInjectFails() throws Exception { // Make an JSON POST request with an 800KB+ JSON object _testBigInject(800); } public void _testBigInject(int nk) throws Exception { OperatorGraph graph = OperatorGraphFactory.newGraph(); // Declare a HTTPJSONInjection operator OperatorInvocation<PostJSON> op = graph.addOperator(PostJSON.class); op.setIntParameter("port", 0); OutputPortDeclaration injectedTuples = op.addOutput("tuple<rstring jsonString>"); // Create the testable version of the graph JavaTestableGraph testableGraph = new JavaOperatorTester() .executable(graph); MostRecent<Tuple> mrt = new MostRecent<Tuple>(); testableGraph.registerStreamHandler(injectedTuples, mrt); // Execute the initialization of operators within graph. testableGraph.initialize().get().allPortsReady().get(); assertNull(mrt.getMostRecentTuple()); URL postTuple = new URL(TupleViewTest.getJettyURLBase(testableGraph, op) + "/" + op.getName() + "/ports/output/0/inject"); try { Random r = new Random(); char[] chars = new char[nk * 1000]; for (int i = 0; i < chars.length; i++) { chars[i] = (char) ('a' + (char) r.nextInt(26)); } String s = new String(chars); JSONObject j = new JSONObject(); j.put("bigString", s); postJSONAndTest(postTuple, j, mrt); } finally { testableGraph.shutdown().get(); } } private static void postJSONAndTest(URL postTuple, JSONObject json, MostRecent<Tuple> mrt) throws IOException { byte[] dataBytes = json.serialize().getBytes("UTF-8"); HttpURLConnection conn = (HttpURLConnection) postTuple.openConnection(); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Content-Length", String.valueOf(dataBytes.length)); OutputStream out = conn.getOutputStream(); out.write(dataBytes); out.flush(); out.close(); assertEquals(HttpURLConnection.HTTP_NO_CONTENT, conn.getResponseCode()); conn.disconnect(); JSONObject tuple = JSONObject.parse(mrt.getMostRecentTuple().getString(0)); assertEquals(json, tuple); mrt.clear(); } }