changeset 577:08e9d364c9d2

QlikWebsocketClient
author Devel 1
date Fri, 29 Sep 2017 15:04:33 +0200
parents 27c9d6ce06bb
children fab4175d7fec
files stress-tester-qlik/pom.xml stress-tester-qlik/src/main/java/com/passus/st/qlik/Protocol.java stress-tester-qlik/src/main/java/com/passus/st/qlik/QlikWebsocketClient.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessagePredicate.java
diffstat 4 files changed, 287 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester-qlik/pom.xml	Fri Sep 29 15:04:33 2017 +0200
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.passus.st</groupId>
+    <artifactId>stress-tester-qlik</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+    </properties>
+    
+    <repositories>
+        <repository>
+            <id>repo.dev.passus.com.pl-release</id>
+            <url>http://repo.dev.passus.com.pl/libs-release-local</url>
+        </repository>
+        <repository>
+            <id>repo.dev.passus.com.pl-snapshots</id>
+            <url>http://repo.dev.passus.com.pl/libs-snapshot-local</url>
+        </repository>
+    </repositories>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse.jetty.websocket</groupId>
+            <artifactId>websocket-client</artifactId>
+            <version>9.4.7.v20170914</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.minidev</groupId>
+            <artifactId>json-smart</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>6.8.1</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester-qlik/src/main/java/com/passus/st/qlik/Protocol.java	Fri Sep 29 15:04:33 2017 +0200
@@ -0,0 +1,137 @@
+package com.passus.st.qlik;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
+import net.minidev.json.JSONValue;
+
+/**
+ *
+ * @author mikolaj.podbielski
+ */
+public class Protocol {
+
+    static final String METHOD = "method";
+    static final String HANDLE = "handle";
+    static final String PARAMS = "params";
+    static final String JSONRPC = "jsonrpc";
+    static final String ID = "id";
+    static final String RESULT = "result";
+
+    static final String JSONRPC_VER = "2.0";
+    static final int NULL_HANDLE = -1;
+
+    static final String GetDocList = "GetDocList";
+    static final String OpenDoc = "OpenDoc";
+    static final String DoReload = "DoReload";
+
+    AtomicInteger id = new AtomicInteger();
+
+    JSONObject createMethodCall(int handle, String methodName, Object params) {
+        JSONObject result = new JSONObject();
+        result.put(METHOD, methodName);
+        result.put(HANDLE, handle);
+        result.put(PARAMS, params);
+        result.put(JSONRPC, JSONRPC_VER);
+        result.put(ID, id.incrementAndGet());
+        return result;
+    }
+
+    JSONObject createGlobalMethodCall(String methodName, Object params) {
+        return createMethodCall(NULL_HANDLE, methodName, params);
+    }
+
+    public JSONObject createGetDocList() {
+        return createGlobalMethodCall(GetDocList, Collections.emptyList());
+    }
+
+    public JSONObject createOpenDoc(String docId) {
+        return createGlobalMethodCall(OpenDoc, Arrays.asList(docId));
+    }
+
+    public JSONObject createDoReload(int handle) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("qMode", 0);
+        params.put("qPartial", false);
+        params.put("qDebug", false);
+        return createMethodCall(handle, DoReload, params);
+    }
+
+    static JSONObject jsonObject(Object o) {
+        if (!(o instanceof JSONObject)) {
+            throw new IllegalArgumentException();
+        }
+        return (JSONObject) o;
+    }
+
+    static JSONArray jsonArray(Object o) {
+        if (!(o instanceof JSONArray)) {
+            throw new IllegalArgumentException();
+        }
+        return (JSONArray) o;
+    }
+
+    public static JSONObject parseObject(String json) {
+        return jsonObject(JSONValue.parse(json));
+    }
+
+    public static int getID(JSONObject root) {
+        Object id = root.get(ID);
+        if (!(id instanceof Number)) {
+            throw new IllegalArgumentException();
+        }
+        return ((Number) id).intValue();
+    }
+
+    static List<DocInfo> parseGetDocListResponse(String json) {
+        return parseGetDocListResponse(parseObject(json));
+    }
+
+    public static List<DocInfo> parseGetDocListResponse(JSONObject root) {
+        JSONObject result = jsonObject(root.get(RESULT));
+        JSONArray docList = jsonArray(result.get("qDocList"));
+        List<DocInfo> docInfos = new ArrayList<>(docList.size());
+
+        for (Object object : docList) {
+            JSONObject entry = jsonObject(object);
+            DocInfo info = new DocInfo();
+            info.docName = (String) entry.get("qDocName");
+            info.docId = (String) entry.get("qDocId");
+            info.title = (String) entry.get("qTitle");
+            info.key = (String) entry.get("key");
+            docInfos.add(info);
+        }
+        return docInfos;
+    }
+
+    public static class DocInfo {
+
+        private String docName;
+        private String docId;
+        private String title;
+        private String key;
+
+        public String getDocName() {
+            return docName;
+        }
+
+        public String getDocId() {
+            return docId;
+        }
+
+        public String getTitle() {
+            return title;
+        }
+
+        public String getKey() {
+            return key;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester-qlik/src/main/java/com/passus/st/qlik/QlikWebsocketClient.java	Fri Sep 29 15:04:33 2017 +0200
@@ -0,0 +1,106 @@
+package com.passus.st.qlik;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import net.minidev.json.JSONObject;
+import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
+import org.eclipse.jetty.websocket.api.annotations.WebSocket;
+import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+
+/**
+ *
+ * @author mikolaj.podbielski
+ */
+public class QlikWebsocketClient {
+
+    @WebSocket(maxTextMessageSize = 64 * 1024)
+    static class QlikEndpoint {
+
+        Map<Integer, CompletableFuture<JSONObject>> futures = new HashMap<>();
+        private Session session;
+
+        @OnWebSocketConnect
+        public void onConnect(Session session) {
+            System.out.println("connected");
+            this.session = session;
+        }
+
+        @OnWebSocketMessage
+        public void onMessage(String msg) {
+            JSONObject root = Protocol.parseObject(msg);
+            int id = Protocol.getID(root);
+            CompletableFuture<JSONObject> future = futures.remove(id);
+            if (future != null) {
+                future.complete(root);
+            }
+        }
+
+        public void sendMessage(String msg) throws IOException {
+            session.getRemote().sendString(msg);
+        }
+
+        public void sendMessageNoFuture(JSONObject obj) throws IOException {
+            sendMessage(obj.toJSONString());
+        }
+
+        public Future<JSONObject> sendMessage(JSONObject obj) throws IOException {
+            int id = Protocol.getID(obj);
+            CompletableFuture<JSONObject> future = new CompletableFuture<>();
+            futures.put(id, future);
+            sendMessage(obj.toJSONString());
+            return future;
+        }
+    }
+
+    private static Session openSession(WebSocketClient client, String url, Object websocket)
+            throws IOException, InterruptedException, ExecutionException, URISyntaxException {
+        ClientUpgradeRequest request = new ClientUpgradeRequest();
+        Future<Session> future = client.connect(websocket, new URI(url), request);
+        Session session = future.get();
+        return session;
+    }
+    
+//    private static DocInfo findByDocName()
+
+    static boolean reload(String host, int port, String docName) throws Exception {
+        Protocol proto = new Protocol();
+        QlikEndpoint endpoint = new QlikEndpoint();
+        WebSocketClient client = new WebSocketClient();
+        client.start();
+
+        String url = "ws://" + host + ":" + port + "/app/";
+        
+        try (Session session = openSession(client, url, endpoint)) {
+            Future<JSONObject> responseFuture = endpoint.sendMessage(proto.createGetDocList());
+            JSONObject response = responseFuture.get();
+            List<Protocol.DocInfo> infos = Protocol.parseGetDocListResponse(response);
+            for (Protocol.DocInfo info : infos) {
+                
+            }
+        }
+
+        // sess = sess(url(host,port))
+        // list = sess.getDocList()
+        // info = findByDocName(list,docName)
+        // sess.close()
+        // sess = sess(url(host,port,info.docId))
+        // ignore = sess.OpenDoc(info.docId)
+        // ignore = sess.DoReload()
+        client.stop();
+        throw new UnsupportedOperationException();
+    }
+    
+    public static Future<Boolean> asyncReload() {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessagePredicate.java	Fri Sep 29 10:40:17 2017 +0200
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessagePredicate.java	Fri Sep 29 15:04:33 2017 +0200
@@ -1,14 +1,10 @@
 package com.passus.st.client.http.filter;
 
 import com.passus.commons.Assert;
-import com.passus.commons.ConversionException;
-import com.passus.config.NodeException;
-import com.passus.filter.config.PredicateNodeTransformer;
 import com.passus.net.http.HttpMessage;
 import com.passus.net.http.HttpRequest;
 import com.passus.net.http.HttpResponse;
 import com.passus.st.client.http.HttpFlowContext;
-import java.io.IOException;
 import java.util.function.Predicate;
 
 /**