diff options
author | sb5356 <sb5356@att.com> | 2020-03-30 13:14:46 -0400 |
---|---|---|
committer | sb5356 <sb5356@att.com> | 2020-03-30 15:16:27 -0400 |
commit | 1c1791c5498dad7b7fd6b1591e0c5844d4c6c601 (patch) | |
tree | c4d718094ae13779ba2a858739b34945b48a8dde /lib/doorman/src/test | |
parent | 30691263393c3862ed0707220afeb1a9a44d7773 (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')
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 + } +} |