summaryrefslogtreecommitdiffstats
path: root/lib/doorman/src/test
diff options
context:
space:
mode:
authorsb5356 <sb5356@att.com>2020-03-30 13:14:46 -0400
committersb5356 <sb5356@att.com>2020-03-30 15:16:27 -0400
commit1c1791c5498dad7b7fd6b1591e0c5844d4c6c601 (patch)
treec4d718094ae13779ba2a858739b34945b48a8dde /lib/doorman/src/test
parent30691263393c3862ed0707220afeb1a9a44d7773 (diff)
Add new modules: Resource Lock and Doorman
Issue-ID: CCSDK-2226 Signed-off-by: Stan Bonev <sb5356@att.com> Change-Id: I30f83dd4a852fd185dbdaa9a833f5ba544d35ba1
Diffstat (limited to 'lib/doorman/src/test')
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueDataItem.java91
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTest.java222
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTestResult.java120
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Classifier.java21
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Handler.java10
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Classifier.java21
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Handler.java53
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/DbUtil.java92
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/FileUtil.java24
-rw-r--r--lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/util/TestJsonUtil.java26
-rw-r--r--lib/doorman/src/test/resources/it/tc1/result.json31
-rw-r--r--lib/doorman/src/test/resources/it/tc1/test.json67
-rw-r--r--lib/doorman/src/test/resources/it/tc2/request_entity1.txt4
-rw-r--r--lib/doorman/src/test/resources/it/tc2/request_entity2.txt4
-rw-r--r--lib/doorman/src/test/resources/it/tc2/request_other.txt4
-rw-r--r--lib/doorman/src/test/resources/it/tc2/response.txt3
-rw-r--r--lib/doorman/src/test/resources/it/tc2/result.json94
-rw-r--r--lib/doorman/src/test/resources/it/tc2/result2.json76
-rw-r--r--lib/doorman/src/test/resources/it/tc2/test.json202
-rw-r--r--lib/doorman/src/test/resources/schema.sql58
-rw-r--r--lib/doorman/src/test/resources/test1.json36
21 files changed, 1259 insertions, 0 deletions
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueDataItem.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueDataItem.java
new file mode 100644
index 000000000..32e94e5d3
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueDataItem.java
@@ -0,0 +1,91 @@
+package org.onap.ccsdk.features.lib.doorman.it;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.onap.ccsdk.features.lib.doorman.data.MessageAction;
+import org.onap.ccsdk.features.lib.doorman.data.MessageActionValue;
+import org.onap.ccsdk.features.lib.doorman.data.MessageStatus;
+
+public class MessageQueueDataItem implements Comparable<MessageQueueDataItem> {
+
+ public Date timeStamp;
+ public String extMessageId;
+ public MessageStatus status;
+ public MessageAction action;
+
+ @Override
+ public int compareTo(MessageQueueDataItem other) {
+ int c = timeStamp.compareTo(other.timeStamp);
+ if (c == 0) {
+ if (action != null && other.status != null) {
+ return -1;
+ }
+ if (status != null && other.action != null) {
+ return 1;
+ }
+ }
+ return c;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(extMessageId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof MessageQueueDataItem)) {
+ return false;
+ }
+ MessageQueueDataItem other = (MessageQueueDataItem) o;
+ if (!extMessageId.equals(other.extMessageId)) {
+ return false;
+ }
+ if (status != null && (other.status == null || status.status != other.status.status)) {
+ return false;
+ }
+ if (action != null) {
+ if (other.action == null || action.action != other.action.action) {
+ return false;
+ }
+ if (action.action == MessageActionValue.HOLD || action.action == MessageActionValue.RETURN_HOLD) {
+ if (action.holdTime != other.action.holdTime) {
+ return false;
+ }
+ } else if (action.action == MessageActionValue.RETURN_COMPLETE) {
+ if (!action.resolution.equals(other.action.resolution)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder ss = new StringBuilder();
+ if (timeStamp != null) {
+ ss.append(df.format(timeStamp)).append(" | ");
+ }
+ if (status != null) {
+ ss.append("STATUS: ");
+ } else {
+ ss.append("ACTION: ");
+ }
+ ss.append(String.format("%-20s | ", extMessageId));
+ if (status != null) {
+ ss.append(status.status);
+ } else {
+ ss.append(action.action);
+ if (action.holdTime > 0) {
+ ss.append(" | ").append(action.holdTime);
+ }
+ if (action.resolution != null) {
+ ss.append(" | ").append(action.resolution);
+ }
+ }
+ return ss.toString();
+ }
+
+ private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTest.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTest.java
new file mode 100644
index 000000000..ca1c4910d
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTest.java
@@ -0,0 +1,222 @@
+package org.onap.ccsdk.features.lib.doorman.it;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.onap.ccsdk.features.lib.doorman.MessageClassifier;
+import org.onap.ccsdk.features.lib.doorman.MessageInterceptor;
+import org.onap.ccsdk.features.lib.doorman.MessageInterceptorFactory;
+import org.onap.ccsdk.features.lib.doorman.MessageProcessor;
+import org.onap.ccsdk.features.lib.doorman.MessageQueueHandler;
+import org.onap.ccsdk.features.lib.doorman.dao.MessageDaoImpl;
+import org.onap.ccsdk.features.lib.doorman.data.MessageData;
+import org.onap.ccsdk.features.lib.doorman.data.Queue;
+import org.onap.ccsdk.features.lib.doorman.impl.MessageInterceptorFactoryImpl;
+import org.onap.ccsdk.features.lib.doorman.testutil.DbUtil;
+import org.onap.ccsdk.features.lib.doorman.util.JsonUtil;
+import org.onap.ccsdk.features.lib.rlock.LockHelperImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RunWith(Parameterized.class)
+public class MessageQueueTest {
+
+ private static final Logger log = LoggerFactory.getLogger(MessageQueueTest.class);
+
+ private String test;
+
+ public MessageQueueTest(String test) {
+ this.test = test;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void test() throws Exception {
+ log.info("#########################################################################");
+ log.info("MessageQueueTest: " + test + " started");
+
+ String testSetupJson = readResource("it/" + test + "/test.json");
+ Map<String, Object> testSetup = (Map<String, Object>) JsonUtil.jsonToData(testSetupJson);
+
+ Map<String, MessageQueueHandler> handlerMap = new HashMap<>();
+
+ for (Object o : (List<Object>) testSetup.get("handler_list")) {
+ Map<String, Object> handlerSetup = (Map<String, Object>) o;
+ String queueType = (String) handlerSetup.get("queue_type");
+ String handlerClassName = (String) handlerSetup.get("handler_class");
+ try {
+ Class<?> handlerClass = Class.forName("org.onap.ccsdk.features.lib.doorman.it." + test + "." + handlerClassName);
+ MessageQueueHandler handler = (MessageQueueHandler) handlerClass.newInstance();
+ handlerMap.put(queueType, handler);
+ log.info("Handler found for queue type: " + queueType + ": " + handlerClass.getName());
+ } catch (Exception e) {
+ }
+ }
+
+ MessageInterceptorFactory factory = setupMessageInterceptorFactory(handlerMap, new Classifier(), new Processor());
+
+ List<Object> requestList = (List<Object>) testSetup.get("request_list");
+
+ List<Thread> threadList = new ArrayList<>();
+
+ for (int i = 0; i < requestList.size(); i++) {
+ Map<String, Object> requestSetup = (Map<String, Object>) requestList.get(i);
+
+ MessageData request = new MessageData();
+ request.param = (Map<String, Object>) requestSetup.get("request_param");
+ Map<String, Object> requestBodyData = (Map<String, Object>) requestSetup.get("request_body");
+ if (requestBodyData != null) {
+ request.body = JsonUtil.dataToJson(requestBodyData);
+ } else {
+ request.body = readResource("it/" + test + "/" + requestSetup.get("request_body_file"));
+ }
+
+ MessageData response = new MessageData();
+ response.param = (Map<String, Object>) requestSetup.get("response_param");
+ Map<String, Object> responseBodyData = (Map<String, Object>) requestSetup.get("response_body");
+ if (responseBodyData != null) {
+ response.body = JsonUtil.dataToJson(responseBodyData);
+ } else {
+ response.body = readResource("it/" + test + "/" + requestSetup.get("response_body_file"));
+ }
+
+ long startTime = (Long) requestSetup.get("start_time");
+ long processTime = (Long) requestSetup.get("process_time");
+
+ MessageInterceptor interceptor = factory.create();
+
+ Thread t = new Thread((Runnable) () -> {
+ try {
+ Thread.sleep(startTime);
+ } catch (InterruptedException e) {
+ }
+
+ MessageData r = interceptor.processRequest(request);
+
+ if (r == null) {
+ try {
+ Thread.sleep(processTime);
+ } catch (InterruptedException e) {
+ }
+
+ interceptor.processResponse(response);
+ }
+
+ }, "Message-" + i);
+
+ threadList.add(t);
+ t.start();
+ }
+
+ for (Thread t : threadList) {
+ t.join();
+ }
+
+ log.info("MessageQueueTest: " + test + " completed");
+ log.info("Result:");
+
+ String testResultJson = readResource("it/" + test + "/result.json");
+ Map<String, Object> testResult = (Map<String, Object>) JsonUtil.jsonToData(testResultJson);
+ MessageQueueTestResult.checkResult(testResult);
+ }
+
+ private static class Classifier implements MessageClassifier {
+
+ @Override
+ public Queue determineQueue(MessageData request) {
+ Queue q = new Queue();
+ q.type = (String) request.param.get("queue_type");
+ q.id = (String) request.param.get("queue_id");
+ return q;
+ }
+
+ @Override
+ public String getExtMessageId(MessageData request) {
+ return (String) request.param.get("request_id");
+ }
+ }
+
+ private static class Processor implements MessageProcessor {
+
+ @Override
+ public void processMessage(MessageData request) {
+ long processTime = (Long) request.param.get("process_time");
+ try {
+ Thread.sleep(processTime);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public static MessageInterceptorFactory setupMessageInterceptorFactory(Map<String, MessageQueueHandler> handlerMap, MessageClassifier classifier, MessageProcessor processor) {
+ LockHelperImpl lockHelper = new LockHelperImpl();
+ lockHelper.setDataSource(DbUtil.getDataSource());
+ lockHelper.setLockWait(5);
+ lockHelper.setRetryCount(10);
+
+ MessageDaoImpl messageDao = new MessageDaoImpl();
+ messageDao.setDataSource(DbUtil.getDataSource());
+
+ MessageInterceptorFactoryImpl f = new MessageInterceptorFactoryImpl();
+ f.setMessageDao(messageDao);
+ f.setLockHelper(lockHelper);
+ f.setLockTimeout(20);
+ f.setHandlerMap(handlerMap);
+ f.setMessageClassifier(classifier);
+ f.setMessageProcessor(processor);
+ return f;
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Object[]> allTests() {
+ List<Object[]> ll = new ArrayList<>();
+
+ String[] tcList = list("it");
+ for (String tc : tcList) {
+ ll.add(new Object[] { tc });
+ }
+ return ll;
+ }
+
+ private static String[] list(String dir) {
+ try {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ URL url = loader.getResource(dir);
+ String path = url.getPath();
+ return new File(path).list();
+ } catch (Exception e) {
+ log.warn("Error getting directory list for: " + dir + ": " + e.getMessage(), e);
+ return new String[0];
+ }
+ }
+
+ private static String readResource(String resource) {
+ try {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ InputStream ins = loader.getResourceAsStream(resource);
+ BufferedReader in = new BufferedReader(new InputStreamReader(ins));
+ StringBuilder ss = new StringBuilder();
+ String line = in.readLine();
+ while (line != null) {
+ ss.append(line).append('\n');
+ line = in.readLine();
+ }
+ in.close();
+ return ss.toString();
+ } catch (Exception e) {
+ log.warn("Error reading resource: " + resource + ": " + e.getMessage(), e);
+ return null;
+ }
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTestResult.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTestResult.java
new file mode 100644
index 000000000..71a2eeafb
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/MessageQueueTestResult.java
@@ -0,0 +1,120 @@
+package org.onap.ccsdk.features.lib.doorman.it;
+
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.onap.ccsdk.features.lib.doorman.dao.MessageDaoImpl;
+import org.onap.ccsdk.features.lib.doorman.data.Message;
+import org.onap.ccsdk.features.lib.doorman.data.MessageAction;
+import org.onap.ccsdk.features.lib.doorman.data.MessageActionValue;
+import org.onap.ccsdk.features.lib.doorman.data.MessageStatus;
+import org.onap.ccsdk.features.lib.doorman.data.MessageStatusValue;
+import org.onap.ccsdk.features.lib.doorman.data.Queue;
+import org.onap.ccsdk.features.lib.doorman.testutil.DbUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MessageQueueTestResult {
+
+ private static final Logger log = LoggerFactory.getLogger(MessageQueueTest.class);
+
+ public static List<MessageQueueDataItem> readResult(String queueType, String queueId) {
+ MessageDaoImpl messageDao = new MessageDaoImpl();
+ messageDao.setDataSource(DbUtil.getDataSource());
+
+ Queue q = new Queue();
+ q.type = queueType;
+ q.id = queueId;
+
+ List<Message> messageList = messageDao.readMessageQueue(q);
+
+ List<MessageQueueDataItem> ll = new ArrayList<>();
+ if (messageList != null) {
+ for (Message m : messageList) {
+ if (m.statusHistory != null) {
+ for (MessageStatus s : m.statusHistory) {
+ MessageQueueDataItem item = new MessageQueueDataItem();
+ item.extMessageId = m.extMessageId;
+ item.status = s;
+ item.timeStamp = s.timestamp;
+ ll.add(item);
+ }
+ }
+ if (m.actionHistory != null) {
+ for (MessageAction a : m.actionHistory) {
+ MessageQueueDataItem item = new MessageQueueDataItem();
+ item.extMessageId = m.extMessageId;
+ item.action = a;
+ item.timeStamp = a.timestamp;
+ ll.add(item);
+ }
+ }
+ }
+ }
+ Collections.sort(ll);
+ return ll;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void checkResult(Map<String, Object> testResult) {
+ List<Object> resultSetupList = (List<Object>) testResult.get("queue_list");
+ if (resultSetupList != null) {
+ for (Object o : resultSetupList) {
+ Map<String, Object> resultSetup = (Map<String, Object>) o;
+ String queueType = (String) resultSetup.get("queue_type");
+ String queueId = (String) resultSetup.get("queue_id");
+ log.info(queueType + "::" + queueId);
+ List<MessageQueueDataItem> itemList = MessageQueueTestResult.readResult(queueType, queueId);
+ for (MessageQueueDataItem item : itemList) {
+ log.info(" --- " + item);
+ }
+
+ List<Object> checkSequenceList = (List<Object>) resultSetup.get("check_sequence_list");
+ for (int i = 0; i < checkSequenceList.size(); i++) {
+ List<Object> checkSequence = (List<Object>) checkSequenceList.get(i);
+ List<MessageQueueDataItem> checkItemList = new ArrayList<>();
+ for (Object o2 : checkSequence) {
+ String[] ss = ((String) o2).split("\\|");
+ MessageQueueDataItem item = new MessageQueueDataItem();
+ item.extMessageId = ss[1].trim();
+ if (ss[0].trim().equals("STATUS")) {
+ item.status = new MessageStatus();
+ item.status.status = MessageStatusValue.valueOf(ss[2].trim());
+ } else {
+ item.action = new MessageAction();
+ item.action.action = MessageActionValue.valueOf(ss[2].trim());
+ if (item.action.action == MessageActionValue.HOLD || item.action.action == MessageActionValue.RETURN_HOLD) {
+ item.action.holdTime = Integer.parseInt(ss[3].trim());
+ } else if (item.action.action == MessageActionValue.RETURN_COMPLETE) {
+ item.action.resolution = ss[3].trim();
+ }
+ }
+ checkItemList.add(item);
+ }
+ List<MessageQueueDataItem> itemList1 = new ArrayList<>(itemList);
+ itemList1.retainAll(checkItemList);
+ if (!itemList1.equals(checkItemList)) {
+ log.info("Expected sequence #" + i + " not found");
+ log.info("Expected sequence:");
+ for (MessageQueueDataItem item : checkItemList) {
+ log.info(" --- " + item);
+ }
+ log.info("Found sequence:");
+ for (MessageQueueDataItem item : itemList1) {
+ log.info(" --- " + item);
+ }
+ fail("Expected sequence #" + i + " not found");
+ } else {
+ log.info("Expected sequence #" + i + " found in the result:");
+ for (MessageQueueDataItem item : checkItemList) {
+ log.info(" --- " + item);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Classifier.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Classifier.java
new file mode 100644
index 000000000..254fd4ce4
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Classifier.java
@@ -0,0 +1,21 @@
+package org.onap.ccsdk.features.lib.doorman.it.tc1;
+
+import org.onap.ccsdk.features.lib.doorman.MessageClassifier;
+import org.onap.ccsdk.features.lib.doorman.data.MessageData;
+import org.onap.ccsdk.features.lib.doorman.data.Queue;
+
+public class Classifier implements MessageClassifier {
+
+ @Override
+ public Queue determineQueue(MessageData request) {
+ Queue q = new Queue();
+ q.type = "Cluster";
+ q.id = "test-queue";
+ return q;
+ }
+
+ @Override
+ public String getExtMessageId(MessageData request) {
+ return (String) request.param.get("request_id");
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Handler.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Handler.java
new file mode 100644
index 000000000..f57fdbc36
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc1/Handler.java
@@ -0,0 +1,10 @@
+package org.onap.ccsdk.features.lib.doorman.it.tc1;
+
+import org.onap.ccsdk.features.lib.doorman.impl.MessageHandlerBaseImpl;
+
+public class Handler extends MessageHandlerBaseImpl {
+
+ public Handler() {
+
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Classifier.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Classifier.java
new file mode 100644
index 000000000..a32f74650
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Classifier.java
@@ -0,0 +1,21 @@
+package org.onap.ccsdk.features.lib.doorman.it.tc2;
+
+import org.onap.ccsdk.features.lib.doorman.MessageClassifier;
+import org.onap.ccsdk.features.lib.doorman.data.MessageData;
+import org.onap.ccsdk.features.lib.doorman.data.Queue;
+
+public class Classifier implements MessageClassifier {
+
+ @Override
+ public Queue determineQueue(MessageData request) {
+ Queue q = new Queue();
+ q.type = "Cluster";
+ q.id = "test-queue";
+ return q;
+ }
+
+ @Override
+ public String getExtMessageId(MessageData request) {
+ return (String) request.param.get("request_id");
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Handler.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Handler.java
new file mode 100644
index 000000000..35b811c5f
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/it/tc2/Handler.java
@@ -0,0 +1,53 @@
+package org.onap.ccsdk.features.lib.doorman.it.tc2;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.ccsdk.features.lib.doorman.data.Message;
+import org.onap.ccsdk.features.lib.doorman.data.MessageData;
+import org.onap.ccsdk.features.lib.doorman.impl.MessageHandlerBaseImpl;
+import org.onap.ccsdk.features.lib.doorman.util.JsonUtil;
+
+public class Handler extends MessageHandlerBaseImpl {
+
+ public Handler() {
+ setMaxParallelCount(100);
+ setUpdateWaitTime(20);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected String determineUpdateGroup(Message msg) {
+ if (msg.request.body != null) {
+ Map<String, Object> body = (Map<String, Object>) JsonUtil.jsonToData(msg.request.body);
+ String op = (String) body.get("operation");
+ String entityId = (String) body.get("entity_id");
+ if ("update".equals(op)) {
+ return entityId;
+ }
+ }
+ return super.determineUpdateGroup(msg);
+ }
+
+ @Override
+ protected long determineUpdateSequence(Message msg) {
+ if (msg.request.param != null) {
+ Long n = (Long) msg.request.param.get("sequence_number");
+ if (n != null) {
+ return n;
+ }
+ }
+ return super.determineUpdateSequence(msg);
+ }
+
+ @Override
+ protected MessageData completeResponse(Resolution r, Message msg) {
+ if (r == Resolution.SKIPPED) {
+ MessageData response = new MessageData();
+ response.param = new HashMap<>();
+ response.param.put("http_code", 200L);
+ response.body = "{ \"status\": \"success\" }";
+ return response;
+ }
+ return super.completeResponse(r, msg);
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/DbUtil.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/DbUtil.java
new file mode 100644
index 000000000..1e525b4b2
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/DbUtil.java
@@ -0,0 +1,92 @@
+package org.onap.ccsdk.features.lib.doorman.testutil;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+
+import javax.sql.DataSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DbUtil {
+
+ private static final Logger log = LoggerFactory.getLogger(DbUtil.class);
+
+ private static DataSource dataSource = null;
+
+ public static synchronized DataSource getDataSource() {
+ if (dataSource == null) {
+ String url = "jdbc:h2:mem:app;DB_CLOSE_DELAY=-1";
+
+ dataSource = new DataSource() {
+
+ @Override
+ public <T> T unwrap(Class<T> arg0) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+ return false;
+ }
+
+ @Override
+ public void setLoginTimeout(int arg0) throws SQLException {
+ }
+
+ @Override
+ public void setLogWriter(PrintWriter arg0) throws SQLException {
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return null;
+ }
+
+ @Override
+ public int getLoginTimeout() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public PrintWriter getLogWriter() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Connection getConnection(String username, String password) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(url);
+ }
+ };
+
+ try {
+ String script = FileUtil.read("/schema.sql");
+
+ String[] sqlList = script.split(";");
+ try (Connection con = dataSource.getConnection()) {
+ for (String sql : sqlList) {
+ if (!sql.trim().isEmpty()) {
+ sql = sql.trim();
+ try (PreparedStatement ps = con.prepareStatement(sql)) {
+ log.info("Executing statement:\n" + sql);
+ ps.execute();
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return dataSource;
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/FileUtil.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/FileUtil.java
new file mode 100644
index 000000000..5ae92b4fc
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/testutil/FileUtil.java
@@ -0,0 +1,24 @@
+package org.onap.ccsdk.features.lib.doorman.testutil;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class FileUtil {
+
+ public static String read(String fileName) throws Exception {
+ String ss = "";
+ try (InputStream is = DbUtil.class.getResourceAsStream(fileName)) {
+ try (InputStreamReader isr = new InputStreamReader(is)) {
+ try (BufferedReader in = new BufferedReader(isr)) {
+ String s = in.readLine();
+ while (s != null) {
+ ss += s + '\n';
+ s = in.readLine();
+ }
+ }
+ }
+ }
+ return ss;
+ }
+}
diff --git a/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/util/TestJsonUtil.java b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/util/TestJsonUtil.java
new file mode 100644
index 000000000..f0ac87e24
--- /dev/null
+++ b/lib/doorman/src/test/java/org/onap/ccsdk/features/lib/doorman/util/TestJsonUtil.java
@@ -0,0 +1,26 @@
+package org.onap.ccsdk.features.lib.doorman.util;
+
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.ccsdk.features.lib.doorman.testutil.FileUtil;
+import org.onap.ccsdk.features.lib.doorman.util.JsonUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestJsonUtil {
+
+ private static final Logger log = LoggerFactory.getLogger(TestJsonUtil.class);
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testJsonConversion() throws Exception {
+ String json1 = FileUtil.read("/test1.json");
+ Map<String, Object> data1 = (Map<String, Object>) JsonUtil.jsonToData(json1);
+ String convJson1 = JsonUtil.dataToJson(data1);
+ log.info("Converted JSON:\n" + convJson1);
+ Map<String, Object> convData1 = (Map<String, Object>) JsonUtil.jsonToData(convJson1);
+ Assert.assertEquals(data1, convData1);
+ }
+}
diff --git a/lib/doorman/src/test/resources/it/tc1/result.json b/lib/doorman/src/test/resources/it/tc1/result.json
new file mode 100644
index 000000000..3b048827c
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc1/result.json
@@ -0,0 +1,31 @@
+{
+ "queue_list": [
+ {
+ "queue_type": "QQ",
+ "queue_id": "ALL",
+ "check_sequence_list": [
+ [
+ "STATUS | req-1 | ARRIVED",
+ "ACTION | req-1 | PROCESS",
+ "STATUS | req-1 | PROCESSING_SYNC",
+ "STATUS | req-2 | ARRIVED",
+ "ACTION | req-2 | HOLD | 60",
+ "STATUS | req-2 | IN_QUEUE",
+ "STATUS | req-3 | ARRIVED",
+ "ACTION | req-3 | HOLD | 60",
+ "STATUS | req-3 | IN_QUEUE",
+ "ACTION | req-1 | RETURN_COMPLETE | PROCESSED",
+ "ACTION | req-2 | PROCESS",
+ "STATUS | req-1 | COMPLETED",
+ "STATUS | req-2 | PROCESSING_SYNC",
+ "ACTION | req-2 | RETURN_COMPLETE | PROCESSED",
+ "ACTION | req-3 | PROCESS",
+ "STATUS | req-2 | COMPLETED",
+ "STATUS | req-3 | PROCESSING_SYNC",
+ "ACTION | req-3 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-3 | COMPLETED"
+ ]
+ ]
+ }
+ ]
+}
diff --git a/lib/doorman/src/test/resources/it/tc1/test.json b/lib/doorman/src/test/resources/it/tc1/test.json
new file mode 100644
index 000000000..0d96ce8dd
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc1/test.json
@@ -0,0 +1,67 @@
+{
+ "handler_list": [
+ {
+ "queue_type": "QQ",
+ "handler_class": "Handler"
+ }
+ ],
+ "request_list": [
+ {
+ "request_param": {
+ "request_id": "req-1",
+ "queue_type": "QQ",
+ "queue_id": "ALL",
+ "http_method": "POST"
+ },
+ "request_body": {
+ "siid": "test-siid-1"
+ },
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body": {
+ "status": "success"
+ },
+ "start_time": 100,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-2",
+ "queue_type": "QQ",
+ "queue_id": "ALL",
+ "http_method": "POST"
+ },
+ "request_body": {
+ "siid": "test-siid-2"
+ },
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body": {
+ "status": "success"
+ },
+ "start_time": 500,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-3",
+ "queue_type": "QQ",
+ "queue_id": "ALL",
+ "http_method": "POST"
+ },
+ "request_body": {
+ "siid": "test-siid-3"
+ },
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body": {
+ "status": "success"
+ },
+ "start_time": 900,
+ "process_time": 5000
+ }
+ ]
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/request_entity1.txt b/lib/doorman/src/test/resources/it/tc2/request_entity1.txt
new file mode 100644
index 000000000..abda4f381
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/request_entity1.txt
@@ -0,0 +1,4 @@
+{
+ "operation": "update",
+ "entity_id": "entity1"
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/request_entity2.txt b/lib/doorman/src/test/resources/it/tc2/request_entity2.txt
new file mode 100644
index 000000000..eb6ef6d92
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/request_entity2.txt
@@ -0,0 +1,4 @@
+{
+ "operation": "update",
+ "entity_id": "entity2"
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/request_other.txt b/lib/doorman/src/test/resources/it/tc2/request_other.txt
new file mode 100644
index 000000000..7763aeb7d
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/request_other.txt
@@ -0,0 +1,4 @@
+{
+ "operation": "add",
+ "entity_id": "entity5"
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/response.txt b/lib/doorman/src/test/resources/it/tc2/response.txt
new file mode 100644
index 000000000..21aad5aed
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/response.txt
@@ -0,0 +1,3 @@
+{
+ "status": "success",
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/result.json b/lib/doorman/src/test/resources/it/tc2/result.json
new file mode 100644
index 000000000..d2df2ea7b
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/result.json
@@ -0,0 +1,94 @@
+{
+ "queue_list": [
+ {
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "check_sequence_list": [
+ [
+ "STATUS | req-entity1-1 | ARRIVED",
+ "ACTION | req-entity1-1 | HOLD | 20",
+ "STATUS | req-entity1-1 | IN_QUEUE",
+ "STATUS | req-entity1-2 | ARRIVED",
+ "ACTION | req-entity1-1 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity1-2 | HOLD | 20",
+ "STATUS | req-entity1-2 | IN_QUEUE",
+ "STATUS | req-entity1-3 | ARRIVED",
+ "ACTION | req-entity1-2 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity1-3 | HOLD | 20",
+ "STATUS | req-entity1-3 | IN_QUEUE",
+ "STATUS | req-entity1-4 | ARRIVED",
+ "ACTION | req-entity1-3 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity1-4 | HOLD | 20",
+ "STATUS | req-entity1-4 | IN_QUEUE",
+ "ACTION | req-entity1-4 | PROCESS",
+ "STATUS | req-entity1-4 | PROCESSING_SYNC",
+ "ACTION | req-entity1-4 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-entity1-4 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity2-1 | ARRIVED",
+ "ACTION | req-entity2-1 | HOLD | 20",
+ "STATUS | req-entity2-1 | IN_QUEUE",
+ "STATUS | req-entity2-2 | ARRIVED",
+ "ACTION | req-entity2-1 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity2-2 | HOLD | 20",
+ "STATUS | req-entity2-2 | IN_QUEUE",
+ "STATUS | req-entity2-3 | ARRIVED",
+ "ACTION | req-entity2-2 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity2-3 | HOLD | 20",
+ "STATUS | req-entity2-3 | IN_QUEUE",
+ "STATUS | req-entity2-4 | ARRIVED",
+ "ACTION | req-entity2-3 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity2-4 | HOLD | 20",
+ "STATUS | req-entity2-4 | IN_QUEUE",
+ "ACTION | req-entity2-4 | PROCESS",
+ "STATUS | req-entity2-4 | PROCESSING_SYNC",
+ "ACTION | req-entity2-4 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-entity2-4 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity1-1 | ARRIVED",
+ "ACTION | req-entity1-1 | HOLD | 20",
+ "STATUS | req-entity1-1 | IN_QUEUE",
+ "ACTION | req-entity1-1 | RETURN_COMPLETE | SKIPPED",
+ "STATUS | req-entity1-1 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity1-2 | ARRIVED",
+ "ACTION | req-entity1-2 | HOLD | 20",
+ "STATUS | req-entity1-2 | IN_QUEUE",
+ "ACTION | req-entity1-2 | RETURN_COMPLETE | SKIPPED",
+ "STATUS | req-entity1-2 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity1-3 | ARRIVED",
+ "ACTION | req-entity1-3 | HOLD | 20",
+ "STATUS | req-entity1-3 | IN_QUEUE",
+ "ACTION | req-entity1-3 | RETURN_COMPLETE | SKIPPED",
+ "STATUS | req-entity1-3 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity2-1 | ARRIVED",
+ "ACTION | req-entity2-1 | HOLD | 20",
+ "STATUS | req-entity2-1 | IN_QUEUE",
+ "ACTION | req-entity2-1 | RETURN_COMPLETE | SKIPPED",
+ "STATUS | req-entity2-1 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity2-2 | ARRIVED",
+ "ACTION | req-entity2-2 | HOLD | 20",
+ "STATUS | req-entity2-2 | IN_QUEUE",
+ "ACTION | req-entity2-2 | RETURN_COMPLETE | SKIPPED",
+ "STATUS | req-entity2-2 | COMPLETED"
+ ],
+ [
+ "STATUS | req-entity2-3 | ARRIVED",
+ "ACTION | req-entity2-3 | HOLD | 20",
+ "STATUS | req-entity2-3 | IN_QUEUE",
+ "ACTION | req-entity2-3 | RETURN_COMPLETE | SKIPPED",
+ "STATUS | req-entity2-3 | COMPLETED"
+ ]
+ ]
+ }
+ ]
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/result2.json b/lib/doorman/src/test/resources/it/tc2/result2.json
new file mode 100644
index 000000000..551f1ae17
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/result2.json
@@ -0,0 +1,76 @@
+{
+ "queue_list": [
+ {
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "check_sequence_list": [
+ [
+ "STATUS | req-entity1-1 | ARRIVED",
+ "ACTION | req-entity1-1 | HOLD | 20",
+ "STATUS | req-entity1-1 | IN_QUEUE",
+ "STATUS | req-other-1 | ARRIVED",
+ "ACTION | req-other-1 | PROCESS",
+ "STATUS | req-other-1 | PROCESSING_SYNC",
+ "STATUS | req-entity2-1 | ARRIVED",
+ "ACTION | req-entity2-1 | HOLD | 20",
+ "STATUS | req-entity2-1 | IN_QUEUE",
+ "STATUS | req-other-2 | ARRIVED",
+ "ACTION | req-other-2 | PROCESS",
+ "STATUS | req-other-2 | PROCESSING_SYNC",
+ "STATUS | req-entity1-2 | ARRIVED",
+ "ACTION | req-entity1-1 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity1-2 | HOLD | 20",
+ "STATUS | req-entity1-2 | IN_QUEUE",
+ "STATUS | req-entity2-2 | ARRIVED",
+ "ACTION | req-entity2-1 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity2-2 | HOLD | 20",
+ "STATUS | req-entity2-2 | IN_QUEUE",
+ "STATUS | req-entity1-3 | ARRIVED",
+ "ACTION | req-entity1-2 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity1-3 | HOLD | 20",
+ "STATUS | req-entity1-3 | IN_QUEUE",
+ "STATUS | req-other-3 | ARRIVED",
+ "ACTION | req-other-3 | PROCESS",
+ "STATUS | req-other-3 | PROCESSING_SYNC",
+ "STATUS | req-entity2-3 | ARRIVED",
+ "ACTION | req-entity2-2 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity2-3 | HOLD | 20",
+ "STATUS | req-entity2-3 | IN_QUEUE",
+ "STATUS | req-entity1-4 | ARRIVED",
+ "ACTION | req-entity1-3 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity1-4 | HOLD | 20",
+ "STATUS | req-entity1-4 | IN_QUEUE",
+ "STATUS | req-entity2-4 | ARRIVED",
+ "ACTION | req-entity2-3 | RETURN_COMPLETE | SKIPPED",
+ "ACTION | req-entity2-4 | HOLD | 20",
+ "STATUS | req-entity2-4 | IN_QUEUE",
+ "STATUS | req-other-4 | ARRIVED",
+ "ACTION | req-other-4 | PROCESS",
+ "STATUS | req-other-4 | PROCESSING_SYNC",
+ "STATUS | req-entity1-1 | COMPLETED",
+ "ACTION | req-other-1 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-other-1 | COMPLETED",
+ "STATUS | req-entity2-1 | COMPLETED",
+ "ACTION | req-other-2 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-other-2 | COMPLETED",
+ "STATUS | req-entity1-2 | COMPLETED",
+ "STATUS | req-entity2-2 | COMPLETED",
+ "STATUS | req-entity1-3 | COMPLETED",
+ "ACTION | req-other-3 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-other-3 | COMPLETED",
+ "STATUS | req-entity2-3 | COMPLETED",
+ "ACTION | req-other-4 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-other-4 | COMPLETED",
+ "ACTION | req-entity1-4 | PROCESS",
+ "ACTION | req-entity2-4 | PROCESS",
+ "STATUS | req-entity1-4 | PROCESSING_SYNC",
+ "STATUS | req-entity2-4 | PROCESSING_SYNC",
+ "ACTION | req-entity1-4 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-entity1-4 | COMPLETED",
+ "ACTION | req-entity2-4 | RETURN_COMPLETE | PROCESSED",
+ "STATUS | req-entity2-4 | COMPLETED"
+ ]
+ ]
+ }
+ ]
+}
diff --git a/lib/doorman/src/test/resources/it/tc2/test.json b/lib/doorman/src/test/resources/it/tc2/test.json
new file mode 100644
index 000000000..82a0546ac
--- /dev/null
+++ b/lib/doorman/src/test/resources/it/tc2/test.json
@@ -0,0 +1,202 @@
+{
+ "handler_list": [
+ {
+ "queue_type": "Cluster",
+ "handler_class": "Handler"
+ }
+ ],
+ "request_list": [
+ {
+ "request_param": {
+ "request_id": "req-entity1-1",
+ "sequence_number": 1,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity1.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 100,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-other-1",
+ "sequence_number": 2,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_other.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 200,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity2-1",
+ "sequence_number": 3,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity2.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 300,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-other-2",
+ "sequence_number": 4,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_other.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 400,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity1-2",
+ "sequence_number": 5,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity1.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 500,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity2-2",
+ "sequence_number": 6,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity2.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 600,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity1-3",
+ "sequence_number": 7,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity1.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 700,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-other-3",
+ "sequence_number": 8,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_other.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 800,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity2-3",
+ "sequence_number": 9,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity2.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 900,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity1-4",
+ "sequence_number": 10,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity1.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 3100,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-entity2-4",
+ "sequence_number": 11,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_entity2.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 3200,
+ "process_time": 5000
+ },
+ {
+ "request_param": {
+ "request_id": "req-other-4",
+ "sequence_number": 12,
+ "queue_type": "Cluster",
+ "queue_id": "Cluster",
+ "http_method": "POST"
+ },
+ "request_body_file": "request_other.txt",
+ "response_param": {
+ "http_code": 200
+ },
+ "response_body_file": "response.txt",
+ "start_time": 3300,
+ "process_time": 5000
+ }
+ ]
+}
diff --git a/lib/doorman/src/test/resources/schema.sql b/lib/doorman/src/test/resources/schema.sql
new file mode 100644
index 000000000..d110e64ca
--- /dev/null
+++ b/lib/doorman/src/test/resources/schema.sql
@@ -0,0 +1,58 @@
+CREATE TABLE IF NOT EXISTS `resource_lock` (
+ `resource_lock_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `resource_name` varchar(256),
+ `lock_holder` varchar(100) NOT NULL,
+ `lock_count` smallint(6) NOT NULL,
+ `lock_time` datetime NOT NULL,
+ `expiration_time` datetime NOT NULL,
+ PRIMARY KEY (`resource_lock_id`),
+ UNIQUE KEY `IX1_RESOURCE_LOCK` (`resource_name`)
+);
+
+CREATE TABLE IF NOT EXISTS `message` (
+ `message_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `ext_message_id` varchar(64),
+ `request_param` TEXT NOT NULL,
+ `request_body` TEXT NOT NULL,
+ `arrived_timestamp` datetime NOT NULL,
+ `started_timestamp` datetime,
+ `completed_timestamp` datetime,
+ `response_timestamp` datetime,
+ `response_param` TEXT,
+ `response_body` TEXT,
+ `resolution` varchar(20),
+ `queue_type` varchar(64),
+ `queue_id` varchar(256),
+ PRIMARY KEY (`message_id`)
+);
+
+CREATE INDEX IF NOT EXISTS `ix1_message`
+ON message(queue_type, queue_id);
+
+CREATE TABLE IF NOT EXISTS `message_status` (
+ `message_status_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `message_id` bigint(20) unsigned NOT NULL REFERENCES message(message_id),
+ `status` varchar(20) NOT NULL,
+ `status_timestamp` datetime NOT NULL,
+ PRIMARY KEY (`message_status_id`)
+);
+
+CREATE INDEX IF NOT EXISTS `ix1_message_status`
+ON message_status(message_id);
+
+CREATE TABLE IF NOT EXISTS `message_action` (
+ `message_action_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `message_id` bigint(20) unsigned NOT NULL REFERENCES message(message_id),
+ `action` varchar(20) NOT NULL,
+ `action_status` varchar(20) NOT NULL,
+ `resolution` varchar(20),
+ `action_timestamp` datetime NOT NULL,
+ `done_timestamp` datetime,
+ `hold_time` int,
+ `response_param` TEXT,
+ `response_body` TEXT,
+ PRIMARY KEY (`message_action_id`)
+);
+
+CREATE INDEX IF NOT EXISTS `ix1_message_action`
+ON message_action(message_id);
diff --git a/lib/doorman/src/test/resources/test1.json b/lib/doorman/src/test/resources/test1.json
new file mode 100644
index 000000000..820675c7e
--- /dev/null
+++ b/lib/doorman/src/test/resources/test1.json
@@ -0,0 +1,36 @@
+{
+ "struct": {
+ "simple-list": [
+ "val1",
+ "val2",
+ null,
+ false,
+ true,
+ 123,
+ 0.123,
+ 1.2334e-5
+ ],
+ "list": [
+ {
+ "name1": "val1",
+ "name2": "val2"
+ },
+ {
+ "name1": "val1",
+ "name2": "val2"
+ },
+ {
+ "integer": 34,
+ "fraction": 0.2145,
+ "exponent": 6.61789e+0,
+ "boolean": true
+ },
+ [ "val1", "val2", "blah \"string\" \t\t\t\n" ] ]
+ },
+ "types": {
+ "integer": 34,
+ "fraction": 0.2145,
+ "exponent": 6.61789e+0,
+ "boolean": true
+ }
+}