aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Hernandez <jh1730@att.com>2018-03-27 00:06:19 +0000
committerGerrit Code Review <gerrit@onap.org>2018-03-27 00:06:19 +0000
commita84f47325effa7baffb0f8fed2de1fc49ec733e1 (patch)
tree3219dfac46feac0f28c72e26e253c58e2b0ec6e7
parentf6a81de0fd84186d499c39fe5f2d75c20cb0e301 (diff)
parent7150a5f7027725b5eed9c723c6224c8b3d5307dd (diff)
Merge "Add timeout to SO to wait for success"
-rw-r--r--controlloop/common/model-impl/so/pom.xml6
-rw-r--r--controlloop/common/model-impl/so/src/main/java/org/onap/policy/so/SOManager.java526
-rw-r--r--controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/DummyWorkingMemory.java314
-rw-r--r--controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSOManager.java455
-rw-r--r--controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSoDummyServer.java272
-rw-r--r--controlloop/common/simulators/pom.xml1
-rw-r--r--controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SoSimulatorJaxRs.java38
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/so.success.json10
8 files changed, 1168 insertions, 454 deletions
diff --git a/controlloop/common/model-impl/so/pom.xml b/controlloop/common/model-impl/so/pom.xml
index a026236a6..cc31464a7 100644
--- a/controlloop/common/model-impl/so/pom.xml
+++ b/controlloop/common/model-impl/so/pom.xml
@@ -60,9 +60,9 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>2.13.0</version>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-http</artifactId>
+ <version>2.25.1</version>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/controlloop/common/model-impl/so/src/main/java/org/onap/policy/so/SOManager.java b/controlloop/common/model-impl/so/src/main/java/org/onap/policy/so/SOManager.java
index 35227d310..a40a2d10f 100644
--- a/controlloop/common/model-impl/so/src/main/java/org/onap/policy/so/SOManager.java
+++ b/controlloop/common/model-impl/so/src/main/java/org/onap/policy/so/SOManager.java
@@ -20,235 +20,323 @@
package org.onap.policy.so;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
-
-import org.onap.policy.so.util.Serialization;
-import org.onap.policy.drools.system.PolicyEngine;
-import org.onap.policy.rest.RESTManager;
-import org.onap.policy.rest.RESTManager.Pair;
-import org.drools.core.WorkingMemory;
-
+import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import org.drools.core.WorkingMemory;
+import org.onap.policy.drools.system.PolicyEngine;
+import org.onap.policy.rest.RESTManager;
+import org.onap.policy.rest.RESTManager.Pair;
+import org.onap.policy.so.util.Serialization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonSyntaxException;
+/**
+ * This class handles the interface towards SO (Service Orchestrator) for the ONAP Policy Framework. The SO
+ * API is defined at this link:
+ * http://onap.readthedocs.io/en/latest/submodules/so.git/docs/SO_R1_Interface.html#get-orchestration-request
+ *
+ */
public final class SOManager {
-
- private static final Logger logger = LoggerFactory.getLogger(SOManager.class);
- private static final Logger netLogger = LoggerFactory.getLogger(org.onap.policy.drools.event.comm.Topic.NETWORK_LOGGER);
- private static ExecutorService executors = Executors.newCachedThreadPool();
-
- static final String MEDIA_TYPE = "application/json";
-
- static final String LINE_SEPARATOR = System.lineSeparator();
-
- // REST get timeout value in milliseconds
- private static final long DEFAULT_GET_REQUEST_TIMEOUT = 20000;
-
- // The REST manager used for processing REST calls for this VFC manager
- private RESTManager restManager;
-
- private long restGetTimeout = DEFAULT_GET_REQUEST_TIMEOUT;
-
- public SOManager() {
- restManager = new RESTManager();
- }
-
- public SOResponse createModuleInstance(String url, String urlBase, String username, String password, SORequest request) {
-
- //
- // Call REST
- //
- Map<String, String> headers = new HashMap<>();
- headers.put("Accept", MEDIA_TYPE);
-
- //
- // 201 - CREATED - you are done just return
- //
- String requestJson = Serialization.gsonPretty.toJson(request);
- netLogger.info("[OUT|{}|{}|{}|{}|{}|{}|]{}{}", "SO", url, username, password, headers, MEDIA_TYPE, LINE_SEPARATOR, requestJson);
- Pair<Integer, String> httpDetails = restManager.post(url, username, password, headers, MEDIA_TYPE, requestJson);
-
- if (httpDetails == null) {
- return null;
- }
-
- if (httpDetails.a != 202) {
- return null;
- }
-
- try {
- SOResponse response = Serialization.gsonPretty.fromJson(httpDetails.b, SOResponse.class);
-
- String body = Serialization.gsonPretty.toJson(response);
- logger.debug("***** Response to post:");
- logger.debug(body);
-
- String requestId = response.getRequestReferences().getRequestId();
- int attemptsLeft = 20;
-
- String urlGet = urlBase + "/orchestrationRequests/v2/" + requestId;
- SOResponse responseGet = null;
-
- while (attemptsLeft-- > 0) {
- Pair<Integer, String> httpDetailsGet = restManager.get(urlGet, username, password, headers);
- if (httpDetailsGet == null) {
- return null;
- }
-
- responseGet = Serialization.gsonPretty.fromJson(httpDetailsGet.b, SOResponse.class);
- netLogger.info("[IN|{}|{}|]{}{}", "SO", urlGet, LINE_SEPARATOR, httpDetailsGet.b);
-
- body = Serialization.gsonPretty.toJson(responseGet);
- logger.debug("***** Response to get:");
- logger.debug(body);
-
- if (httpDetailsGet.a == 200 &&
- (responseGet.getRequest().getRequestStatus().getRequestState().equalsIgnoreCase("COMPLETE")
- || responseGet.getRequest().getRequestStatus().getRequestState().equalsIgnoreCase("FAILED"))) {
- logger.debug("***** ######## VF Module Creation {}",
- responseGet.getRequest().getRequestStatus().getRequestState());
- return responseGet;
- }
- Thread.sleep(restGetTimeout);
- }
-
- if (responseGet != null && responseGet.getRequest() != null
- && responseGet.getRequest().getRequestStatus() != null
- && responseGet.getRequest().getRequestStatus().getRequestState() != null) {
- logger.warn("***** ######## VF Module Creation timeout. Status: ( {})",
- responseGet.getRequest().getRequestStatus().getRequestState());
- }
-
- return responseGet;
- }
- catch (JsonSyntaxException e) {
- logger.error("Failed to deserialize into SOResponse: ", e);
- }
- catch (InterruptedException e) {
- logger.error("Interrupted exception: ", e);
- Thread.currentThread().interrupt();
- }
-
- return null;
- }
-
- /**
- *
- * @param wm
- * @param url
- * @param urlBase
- * @param username
- * @param password
- * @param request
- *
- * This method makes an asynchronous Rest call to MSO and inserts the response into the
- * Drools working memory
- * @return
- */
- public Future<?> asyncSORestCall(String requestID, WorkingMemory wm, String serviceInstanceId, String vnfInstanceId, SORequest request) {
- return executors.submit(new AsyncSORestCallThread(requestID, wm, serviceInstanceId, vnfInstanceId, request));
- }
-
- private class AsyncSORestCallThread implements Runnable {
- final String requestID;
- final WorkingMemory wm;
- final String serviceInstanceId;
- final String vnfInstanceId;
- final SORequest request;
-
- private AsyncSORestCallThread(final String requestID, final WorkingMemory wm, final String serviceInstanceId, final String vnfInstanceId, final SORequest request) {
- this.requestID = requestID;
- this.wm = wm;
- this.serviceInstanceId = serviceInstanceId;
- this.vnfInstanceId = vnfInstanceId;
- this.request = request;
- }
-
- @Override
- public void run() {
- try {
- String serverRoot = PolicyEngine.manager.getEnvironmentProperty("so.url");
- String username = PolicyEngine.manager.getEnvironmentProperty("so.username");
- String password = PolicyEngine.manager.getEnvironmentProperty("so.password");
-
- String url = serverRoot + "/serviceInstances/v5/" + serviceInstanceId + "/vnfs/"
- + vnfInstanceId + "/vfModules";
-
- String auth = username + ":" + password;
-
- Map<String, String> headers = new HashMap<>();
- byte[] encodedBytes = Base64.getEncoder().encode(auth.getBytes());
- headers.put("Accept", MEDIA_TYPE);
- headers.put("Authorization", "Basic " + new String(encodedBytes));
-
- Gson gsonPretty =
- new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
-
- String soJson = gsonPretty.toJson(request);
-
- SOResponse so = new SOResponse();
- netLogger.info("[OUT|{}|{}|]{}{}", "SO", url, LINE_SEPARATOR, soJson);
- Pair<Integer, String> httpResponse = restManager.post(url, "policy", "policy", headers, MEDIA_TYPE, soJson);
-
- if (httpResponse != null) {
- if (httpResponse.b != null && httpResponse.a != null) {
- netLogger.info("[IN|{}|{}|]{}{}", url, "SO", LINE_SEPARATOR, httpResponse.b);
-
- Gson gson = new Gson();
- so = gson.fromJson(httpResponse.b, SOResponse.class);
- so.setHttpResponseCode(httpResponse.a);
- }
- else {
- logger.error("SO Response status/code is null.");
- so.setHttpResponseCode(999);
- }
-
- }
- else {
- logger.error("SO Response returned null.");
- so.setHttpResponseCode(999);
- }
-
- SOResponseWrapper soWrapper = new SOResponseWrapper(so, requestID);
- wm.insert(soWrapper);
- if (logger.isInfoEnabled()) {
- logger.info("SOResponse inserted " + gsonPretty.toJson(soWrapper));
- }
- }
- catch (Exception e) {
- logger.error("Error while performing asyncSORestCall: " + e.getMessage(), e);
-
- // create dummy SO object to trigger cleanup
- SOResponse so = new SOResponse();
- so.setHttpResponseCode(999);
- wm.insert(so);
- }
- }
- }
-
- /**
- * method to allow tuning of REST get timeout
- * @param restGetTimeout the timeout value
- */
- protected void setRestGetTimeout(final long restGetTimeout) {
- this.restGetTimeout = restGetTimeout;
- }
-
- /**
- * Protected setter for rest manager to allow mocked rest manager to be used for testing
- * @param restManager the test REST manager
- */
- protected void setRestManager(final RESTManager restManager) {
- this.restManager = restManager;
- }
+ private static final Logger logger = LoggerFactory.getLogger(SOManager.class);
+ private static final Logger netLogger = LoggerFactory.getLogger(org.onap.policy.drools.event.comm.Topic.NETWORK_LOGGER);
+ private static ExecutorService executors = Executors.newCachedThreadPool();
+
+ private static final int SO_RESPONSE_ERROR = 999;
+ private static final String MEDIA_TYPE = "application/json";
+ private static final String LINE_SEPARATOR = System.lineSeparator();
+
+ // REST get timeout value in milliseconds
+ private static final int GET_REQUESTS_BEFORE_TIMEOUT = 20;
+ private static final long GET_REQUEST_WAIT_INTERVAL = 20000;
+
+ // The REST manager used for processing REST calls for this VFC manager
+ private RESTManager restManager;
+
+ private long restGetTimeout = GET_REQUEST_WAIT_INTERVAL;
+
+ /**
+ * Default constructor
+ */
+ public SOManager() {
+ restManager = new RESTManager();
+ }
+
+ /**
+ * Create a service instance in SO.
+ * @param url the SO URL
+ * @param urlBase the base URL
+ * @param username user name on SO
+ * @param password password on SO
+ * @param request the request to issue to SO
+ * @return
+ */
+ public SOResponse createModuleInstance(final String url, final String urlBase, final String username, final String password, final SORequest request) {
+ // Issue the HTTP POST request to SO to create the service instance
+ String requestJson = Serialization.gsonPretty.toJson(request);
+ netLogger.info("[OUT|{}|{}|{}|{}|{}|{}|]{}{}", "SO", url, username, password, createSimpleHeaders(), MEDIA_TYPE, LINE_SEPARATOR, requestJson);
+ Pair<Integer, String> httpResponse = restManager.post(url, username, password, createSimpleHeaders(), MEDIA_TYPE, requestJson);
+
+ // Process the response from SO
+ SOResponse response = waitForSOOperationCompletion(urlBase, username, password, url, httpResponse);
+ if (SO_RESPONSE_ERROR != response.getHttpResponseCode()) {
+ return response;
+ }
+ else {
+ return null;
+ }
+ }
+
+ /**
+ * This method makes an asynchronous Rest call to MSO and inserts the response into Drools working memory.
+ * @param wm the Drools working memory
+ * @param url the URL to use on the POST request
+ * @param urlBase the SO base URL
+ * @param username user name for SO requests
+ * @param password password for SO requests
+ * @param request the SO request
+ * @return a concurrent Future for the thread that handles the request
+ */
+ public Future<SOResponse> asyncSORestCall(final String requestID, final WorkingMemory wm, final String serviceInstanceId, final String vnfInstanceId, final SORequest request) {
+ return executors.submit(new AsyncSORestCallThread(requestID, wm, serviceInstanceId, vnfInstanceId, request));
+ }
+
+ /**
+ * This class handles an asynchronous request to SO as a thread.
+ */
+ private class AsyncSORestCallThread implements Callable<SOResponse> {
+ final String requestID;
+ final WorkingMemory wm;
+ final String serviceInstanceId;
+ final String vnfInstanceId;
+ final SORequest request;
+
+ /**
+ * Constructor, sets the context of the request.
+ * @param requestID The request ID
+ * @param wm reference to the Drools working memory
+ * @param serviceInstanceId the service instance in SO to use
+ * @param vnfInstanceId the VNF instance that is the subject of the request
+ * @param request the request itself
+ */
+ private AsyncSORestCallThread(final String requestID, final WorkingMemory wm, final String serviceInstanceId, final String vnfInstanceId, final SORequest request) {
+ this.requestID = requestID;
+ this.wm = wm;
+ this.serviceInstanceId = serviceInstanceId;
+ this.vnfInstanceId = vnfInstanceId;
+ this.request = request;
+ }
+
+ /**
+ * Process the asynchronous SO request.
+ */
+ @Override
+ public SOResponse call() {
+ String urlBase = PolicyEngine.manager.getEnvironmentProperty("so.url");
+ String username = PolicyEngine.manager.getEnvironmentProperty("so.username");
+ String password = PolicyEngine.manager.getEnvironmentProperty("so.password");
+
+ // The URL of the request we will POST
+ String url = urlBase + "/serviceInstances/v5/" + serviceInstanceId + "/vnfs/"
+ + vnfInstanceId + "/vfModules";
+
+ // Create a JSON representation of the request
+ String soJson = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create().toJson(request);
+
+ netLogger.info("[OUT|{}|{}|]{}{}", "SO", url, LINE_SEPARATOR, soJson);
+ Pair<Integer, String> httpResponse = restManager.post(url, "policy", "policy", createAuthenticateHeaders(username, password), MEDIA_TYPE, soJson);
+
+ // Process the response from SO
+ SOResponse response = waitForSOOperationCompletion(urlBase, username, password, url, httpResponse);
+
+ // Return the response to Drools in its working memory
+ SOResponseWrapper soWrapper = new SOResponseWrapper(response, requestID);
+ wm.insert(soWrapper);
+
+ return response;
+ }
+
+ /**
+ * Create HTTP headers for authenticated requests to SO.
+ * @param username user name on SO
+ * @param password password on SO
+ * @return the HTTP headers
+ */
+ private Map<String, String> createAuthenticateHeaders(final String username, final String password) {
+ String auth = username + ":" + password;
+
+ Map<String, String> headers = new HashMap<>();
+ byte[] encodedBytes = Base64.getEncoder().encode(auth.getBytes());
+ headers.put("Accept", MEDIA_TYPE);
+ headers.put("Authorization", "Basic " + new String(encodedBytes));
+
+ return headers;
+ }
+ }
+
+ /**
+ * Wait for the SO operation we have ordered to complete.
+ * @param urlBaseSO The base URL for SO
+ * @param username user name on SO
+ * @param password password on SO
+ * @param initialRequestURL The URL of the initial HTTP request
+ * @param initialHTTPResponse The initial HTTP message returned from SO
+ * @return The parsed final response of SO to the request
+ */
+ private SOResponse waitForSOOperationCompletion(final String urlBaseSO, final String username, final String password,
+ final String initialRequestURL, final Pair<Integer, String> initialHTTPResponse) {
+ // Process the initial response from SO, the response to a post
+ SOResponse response = processSOResponse(initialRequestURL, initialHTTPResponse);
+ if (SO_RESPONSE_ERROR == response.getHttpResponseCode()) {
+ return response;
+ }
+
+ // The SO URL to use to get the status of orchestration requests
+ String urlGet = urlBaseSO + "/orchestrationRequests/v5/" + response.getRequestReferences().getRequestId();
+
+ // The HTTP status code of the latest response
+ Pair<Integer, String> latestHTTPResponse = initialHTTPResponse;
+
+ // Wait for the response from SO
+ for (int attemptsLeft = GET_REQUESTS_BEFORE_TIMEOUT; attemptsLeft >= 0; attemptsLeft--) {
+ // The SO request may have completed even on the first request so we check the response here before
+ // issuing any other requests
+ if (isRequestStateFinished(latestHTTPResponse, response)) {
+ return response;
+ }
+
+ // Wait for the defined interval before issuing a get
+ try {
+ Thread.sleep(restGetTimeout);
+ }
+ catch (InterruptedException e) {
+ logger.error("Interrupted exception: ", e);
+ Thread.currentThread().interrupt();
+ response.setHttpResponseCode(SO_RESPONSE_ERROR);
+ return response;
+ }
+
+ // Issue a GET to find the current status of our request
+ netLogger.info("[OUT|{}|{}|{}|{}|{}|{}|]{}", "SO", urlGet, username, password, createSimpleHeaders(), MEDIA_TYPE, LINE_SEPARATOR);
+ Pair<Integer, String> httpResponse = restManager.get(urlGet, username, password, createSimpleHeaders());
+
+ // Get our response
+ response = processSOResponse(urlGet, httpResponse);
+ if (SO_RESPONSE_ERROR == response.getHttpResponseCode()) {
+ return response;
+ }
+
+ // Our latest HTTP response code
+ latestHTTPResponse = httpResponse;
+ }
+
+ // We have timed out on the SO request
+ response.setHttpResponseCode(SO_RESPONSE_ERROR);
+ return response;
+ }
+
+ /**
+ * Parse the response message from SO into a SOResponse object.
+ * @param requestURL The URL of the HTTP request
+ * @param httpDetails The HTTP message returned from SO
+ * @return The parsed response
+ */
+ private SOResponse processSOResponse(final String requestURL, final Pair<Integer, String> httpResponse) {
+ SOResponse response = new SOResponse();
+
+ // A null httpDetails indicates a HTTP problem, a valid response from SO must be either 200 or 202
+ if (!httpResultIsNullFree(httpResponse) || (httpResponse.a != 200 && httpResponse.a != 202)) {
+ logger.error("Invalid HTTP response received from SO");
+ response.setHttpResponseCode(SO_RESPONSE_ERROR);
+ return response;
+ }
+
+ // Parse the JSON of the response into our POJO
+ try {
+ response = Serialization.gsonPretty.fromJson(httpResponse.b, SOResponse.class);
+ }
+ catch (JsonSyntaxException e) {
+ logger.error("Failed to deserialize HTTP response into SOResponse: ", e);
+ response.setHttpResponseCode(SO_RESPONSE_ERROR);
+ return response;
+ }
+
+ // Set the HTTP response code of the response if needed
+ if (response.getHttpResponseCode() == 0) {
+ response.setHttpResponseCode(httpResponse.a);
+ }
+
+ netLogger.info("[IN|{}|{}|]{}{}", "SO", requestURL, LINE_SEPARATOR, httpResponse.b);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("***** Response to SO Request to URL {}:", requestURL);
+ logger.debug(httpResponse.b);
+ }
+
+ return response;
+ }
+
+ /**
+ * Method to allow tuning of REST get timeout.
+ * @param restGetTimeout the timeout value
+ */
+ protected void setRestGetTimeout(final long restGetTimeout) {
+ this.restGetTimeout = restGetTimeout;
+ }
+
+ /**
+ * Check that the request state of a response is defined.
+ * @param response The response to check
+ * @return true if the request for the response is defined
+ */
+ private boolean isRequestStateDefined(final SOResponse response) {
+ return response != null &&
+ response.getRequest() != null &&
+ response.getRequest().getRequestStatus() != null &&
+ response.getRequest().getRequestStatus().getRequestState() != null;
+ }
+
+ /**
+ * Check that the request state of a response is finished.
+ * @param latestHTTPDetails the HTTP details of the response
+ * @param response The response to check
+ * @return true if the request for the response is finished
+ */
+ private boolean isRequestStateFinished(final Pair<Integer, String> latestHTTPDetails, final SOResponse response) {
+ if (latestHTTPDetails != null && 200 == latestHTTPDetails.a && isRequestStateDefined(response)) {
+ String requestState = response.getRequest().getRequestStatus().getRequestState();
+ return "COMPLETE".equalsIgnoreCase(requestState) || "FAILED".equalsIgnoreCase(requestState);
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Check that a HTTP operation result has no nulls.
+ * @param httpOperationResult the result to check
+ * @return true if no nulls are found
+ */
+ private boolean httpResultIsNullFree(Pair<Integer, String> httpOperationResult) {
+ return httpOperationResult != null && httpOperationResult.a != null && httpOperationResult.b != null;
+ }
+
+ /**
+ * Create simple HTTP headers for unauthenticated requests to SO.
+ * @return the HTTP headers
+ */
+ private Map<String, String> createSimpleHeaders() {
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Accept", MEDIA_TYPE);
+ return headers;
+ }
}
diff --git a/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/DummyWorkingMemory.java b/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/DummyWorkingMemory.java
new file mode 100644
index 000000000..af7ddc426
--- /dev/null
+++ b/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/DummyWorkingMemory.java
@@ -0,0 +1,314 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * so
+ * ================================================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.policy.so;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.drools.core.WorkingMemory;
+import org.drools.core.WorkingMemoryEntryPoint;
+import org.drools.core.common.InternalFactHandle;
+import org.drools.core.impl.InternalKnowledgeBase;
+import org.drools.core.spi.AsyncExceptionHandler;
+import org.drools.core.spi.GlobalResolver;
+import org.kie.api.event.kiebase.KieBaseEventListener;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+import org.kie.api.runtime.Environment;
+import org.kie.api.runtime.ObjectFilter;
+import org.kie.api.runtime.process.ProcessInstance;
+import org.kie.api.runtime.process.WorkItemManager;
+import org.kie.api.runtime.rule.Agenda;
+import org.kie.api.runtime.rule.AgendaFilter;
+import org.kie.api.runtime.rule.FactHandle;
+import org.kie.api.runtime.rule.FactHandle.State;
+import org.kie.api.runtime.rule.QueryResults;
+import org.kie.api.time.SessionClock;
+
+public class DummyWorkingMemory implements WorkingMemory {
+
+ @Override
+ public void addEventListener(RuleRuntimeEventListener listener) {
+ }
+
+ @Override
+ public void removeEventListener(RuleRuntimeEventListener listener) {
+ }
+
+ @Override
+ public Collection<RuleRuntimeEventListener> getRuleRuntimeEventListeners() {
+ return null;
+ }
+
+ @Override
+ public void addEventListener(AgendaEventListener listener) {
+ }
+
+ @Override
+ public void removeEventListener(AgendaEventListener listener) {
+ }
+
+ @Override
+ public Collection<AgendaEventListener> getAgendaEventListeners() {
+ return null;
+ }
+
+ @Override
+ public void addEventListener(KieBaseEventListener listener) {
+ }
+
+ @Override
+ public void removeEventListener(KieBaseEventListener listener) {
+ }
+
+ @Override
+ public Collection<KieBaseEventListener> getKieBaseEventListeners() {
+ return null;
+ }
+
+ @Override
+ public FactHandle insert(Object object, boolean dynamic) {
+ return null;
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public String getEntryPointId() {
+ return null;
+ }
+
+ @Override
+ public FactHandle insert(Object object) {
+ return null;
+ }
+
+ @Override
+ public void retract(FactHandle handle) {
+ }
+
+ @Override
+ public void delete(FactHandle handle) {
+ }
+
+ @Override
+ public void delete(FactHandle handle, State fhState) {
+
+
+ }
+
+ @Override
+ public void update(FactHandle handle, Object object) {
+ }
+
+ @Override
+ public void update(FactHandle handle, Object object, String... modifiedProperties) {
+ }
+
+ @Override
+ public Collection<? extends Object> getObjects() {
+ return null;
+ }
+
+ @Override
+ public Collection<? extends Object> getObjects(ObjectFilter filter) {
+ return null;
+ }
+
+ @Override
+ public <T extends FactHandle> Collection<T> getFactHandles() {
+ return null;
+ }
+
+ @Override
+ public <T extends FactHandle> Collection<T> getFactHandles(ObjectFilter filter) {
+ return null;
+ }
+
+ @Override
+ public long getFactCount() {
+ return 0;
+ }
+
+ @Override
+ public Agenda getAgenda() {
+ return null;
+ }
+
+ @Override
+ public void setGlobal(String identifier, Object value) {
+ }
+
+ @Override
+ public Object getGlobal(String identifier) {
+ return null;
+ }
+
+ @Override
+ public Environment getEnvironment() {
+ return null;
+ }
+
+ @Override
+ public void setGlobalResolver(GlobalResolver globalResolver) {
+ }
+
+ @Override
+ public GlobalResolver getGlobalResolver() {
+ return null;
+ }
+
+ @Override
+ public InternalKnowledgeBase getKnowledgeBase() {
+ return null;
+ }
+
+ @Override
+ public int fireAllRules() {
+ return 0;
+ }
+
+ @Override
+ public int fireAllRules(AgendaFilter agendaFilter) {
+ return 0;
+ }
+
+ @Override
+ public int fireAllRules(int fireLimit) {
+ return 0;
+ }
+
+ @Override
+ public int fireAllRules(AgendaFilter agendaFilter, int fireLimit) {
+ return 0;
+ }
+
+ @Override
+ public Object getObject(FactHandle handle) {
+ return null;
+ }
+
+ @Override
+ public FactHandle getFactHandle(Object object) {
+ return null;
+ }
+
+ @Override
+ public FactHandle getFactHandleByIdentity(Object object) {
+ return null;
+ }
+
+ @Override
+ public Iterator<?> iterateObjects() {
+ return null;
+ }
+
+ @Override
+ public Iterator<?> iterateObjects(ObjectFilter filter) {
+ return null;
+ }
+
+ @Override
+ public Iterator<InternalFactHandle> iterateFactHandles() {
+ return null;
+ }
+
+ @Override
+ public Iterator<InternalFactHandle> iterateFactHandles(ObjectFilter filter) {
+ return null;
+ }
+
+ @Override
+ public void setFocus(String focus) {
+ }
+
+ @Override
+ public QueryResults getQueryResults(String query, Object... arguments) {
+ return null;
+ }
+
+ @Override
+ public void setAsyncExceptionHandler(AsyncExceptionHandler handler) {
+ }
+
+ @Override
+ public void clearAgenda() {
+ }
+
+ @Override
+ public void clearAgendaGroup(String group) {
+ }
+
+ @Override
+ public void clearActivationGroup(String group) {
+ }
+
+ @Override
+ public void clearRuleFlowGroup(String group) {
+ }
+
+ @Override
+ public ProcessInstance startProcess(String processId) {
+ return null;
+ }
+
+ @Override
+ public ProcessInstance startProcess(String processId, Map<String, Object> parameters) {
+ return null;
+ }
+
+ @Override
+ public Collection<ProcessInstance> getProcessInstances() {
+ return null;
+ }
+
+ @Override
+ public ProcessInstance getProcessInstance(long id) {
+ return null;
+ }
+
+ @Override
+ public ProcessInstance getProcessInstance(long id, boolean readOnly) {
+ return null;
+ }
+
+ @Override
+ public WorkItemManager getWorkItemManager() {
+ return null;
+ }
+
+ @Override
+ public void halt() {
+ }
+
+ @Override
+ public WorkingMemoryEntryPoint getWorkingMemoryEntryPoint(String id) {
+ return null;
+ }
+
+ @Override
+ public SessionClock getSessionClock() {
+ return null;
+ }
+
+}
diff --git a/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSOManager.java b/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSOManager.java
index a2beb57b5..864362649 100644
--- a/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSOManager.java
+++ b/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSOManager.java
@@ -19,234 +19,249 @@
*/
package org.onap.policy.so;
-import static org.junit.Assert.*;
-import static org.mockito.ArgumentMatchers.anyMap;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.startsWith;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import java.io.IOException;
+import java.net.URI;
import java.util.UUID;
import java.util.concurrent.Future;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
import org.drools.core.WorkingMemory;
-import org.junit.Before;
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onap.policy.drools.system.PolicyEngine;
-import org.onap.policy.rest.RESTManager;
-import org.onap.policy.rest.RESTManager.Pair;
-import org.onap.policy.so.util.Serialization;
public class TestSOManager {
- private static WorkingMemory mockedWorkingMemory;
-
- private RESTManager mockedRESTManager;
-
- private Pair<Integer, String> httpResponsePutOK;
- private Pair<Integer, String> httpResponseGetOK;
- private Pair<Integer, String> httpResponsePostOK;
- private Pair<Integer, String> httpResponseErr;
-
- private SORequest request;
- private SOResponse response;
-
- @BeforeClass
- public static void beforeTestSOManager() {
- mockedWorkingMemory = mock(WorkingMemory.class);
- }
-
- @Before
- public void setupMockedRest() {
- mockedRESTManager = mock(RESTManager.class);
-
- httpResponsePutOK = mockedRESTManager.new Pair<>(202, Serialization.gsonPretty.toJson(response));
- httpResponseGetOK = mockedRESTManager.new Pair<>(200, Serialization.gsonPretty.toJson(response));
- httpResponsePostOK = mockedRESTManager.new Pair<>(202, Serialization.gsonPretty.toJson(response));
- httpResponseErr = mockedRESTManager.new Pair<>(200, "{");
- }
-
- @Before
- public void createRequestAndResponse() {
- request = new SORequest();
- SORequestStatus requestStatus = new SORequestStatus();
- requestStatus.setRequestState("COMPLETE");
- request.setRequestStatus(requestStatus);
- request.setRequestId(UUID.randomUUID());
-
- response = new SOResponse();
-
- SORequestReferences requestReferences = new SORequestReferences();
- String requestId = UUID.randomUUID().toString();
- requestReferences.setRequestId(requestId);
- response.setRequestReferences(requestReferences);
-
- response.setRequest(request);
- }
-
- @Test
- public void testSOInitiation() {
- assertNotNull(new SOManager());
- }
-
- @Test
- public void testCreateModuleInstance() throws InterruptedException {
- SOManager manager = new SOManager();
- manager.setRestManager(mockedRESTManager);
-
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "OK", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("Null"), anyMap(), anyString(), anyString()))
- .thenReturn(null);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "Null", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("Not202"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponseErr);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "Not202", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetNull"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetNull"), anyMap()))
- .thenReturn(null);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetNull", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetOK"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetOK"), anyMap()))
- .thenReturn(httpResponseGetOK);
- request.getRequestStatus().setRequestState("COMPLETE");
- SOResponse response = manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetOK", request);
- assertNotNull(response);
- assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
-
- response.getRequest().getRequestStatus().setRequestState("FAILED");
- Pair<Integer, String> httpResponseGetOKRequestFailed = mockedRESTManager.new Pair<>(200, Serialization.gsonPretty.toJson(response));
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetOKReqFailed"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetOKReqFailed"), anyMap()))
- .thenReturn(httpResponseGetOKRequestFailed);
- response = manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetOKReqFailed", request);
- assertNotNull(response);
- assertEquals("FAILED", response.getRequest().getRequestStatus().getRequestState());
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetBadJSON"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetBadJSON"), anyMap()))
- .thenReturn(httpResponseErr);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetBadJSON", request));
-
- response.getRequest().getRequestStatus().setRequestState("IN-PROGRESS");
- Pair<Integer, String> httpResponseGetOKRequestTimeout = mockedRESTManager.new Pair<>(200, Serialization.gsonPretty.toJson(response));
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetOKReqTimeout"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetOKReqTimeout"), anyMap()))
- .thenReturn(httpResponseGetOKRequestTimeout);
-
- manager.setRestGetTimeout(10);
- response = manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetOKReqTimeout", request);
- assertNotNull(response);
- assertEquals("IN-PROGRESS", response.getRequest().getRequestStatus().getRequestState());
- }
-
- @Test
- public void testAsyncSORestCall() throws InterruptedException {
- PolicyEngine.manager.getEnvironment().put("so.url", "http://somewhere.over.the.rainbow.null");
- PolicyEngine.manager.getEnvironment().put("so.username", "Dorothy");
- PolicyEngine.manager.getEnvironment().put("so.password", "OK");
-
- SOManager manager = new SOManager();
- manager.setRestManager(mockedRESTManager);
-
- String serviceInstanceId = UUID.randomUUID().toString();
- String vnfInstanceId = UUID.randomUUID().toString();
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow.null"), eq("policy"), eq("policy"), anyMap(), anyString(), anyString()))
- .thenReturn(null);
-
- Future<?> asyncRestCallFuture = manager.asyncSORestCall(request.getRequestId().toString(), mockedWorkingMemory, serviceInstanceId, vnfInstanceId, request);
- try {
- assertNull(asyncRestCallFuture.get());
- }
- catch (Exception e) {
- fail("test should not throw an exception");
- }
-
- PolicyEngine.manager.getEnvironment().put("so.url", "http://somewhere.over.the.rainbow.err");
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow.err"), eq("policy"), eq("policy"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponseErr);
-
- asyncRestCallFuture = manager.asyncSORestCall(request.getRequestId().toString(), mockedWorkingMemory, serviceInstanceId, vnfInstanceId, request);
- try {
- assertNull(asyncRestCallFuture.get());
- }
- catch (Exception e) {
- System.err.println(e);
- fail("test should not throw an exception");
- }
-
- PolicyEngine.manager.getEnvironment().put("so.url", "http://somewhere.over.the.rainbow.ok");
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow.ok"), eq("policy"), eq("policy"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePostOK);
-
- asyncRestCallFuture = manager.asyncSORestCall(request.getRequestId().toString(), mockedWorkingMemory, serviceInstanceId, vnfInstanceId, request);
- try {
- assertNull(asyncRestCallFuture.get());
- }
- catch (Exception e) {
- System.err.println(e);
- fail("test should not throw an exception");
- }
-/*
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("Null"), anyMap(), anyString(), anyString()))
- .thenReturn(null);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "Null", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("Not202"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponseErr);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "Not202", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetNull"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetNull"), anyMap()))
- .thenReturn(null);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetNull", request));
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetOK"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetOK"), anyMap()))
- .thenReturn(httpResponseGetOK);
- request.getRequestStatus().setRequestState("COMPLETE");
- SOResponse response = manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetOK", request);
- assertNotNull(response);
- assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
-
- response.getRequest().getRequestStatus().setRequestState("FAILED");
- Pair<Integer, String> httpResponseGetOKRequestFailed = mockedRESTManager.new Pair<>(200, Serialization.gsonPretty.toJson(response));
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetOKReqFailed"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetOKReqFailed"), anyMap()))
- .thenReturn(httpResponseGetOKRequestFailed);
- response = manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetOKReqFailed", request);
- assertNotNull(response);
- assertEquals("FAILED", response.getRequest().getRequestStatus().getRequestState());
-
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetBadJSON"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetBadJSON"), anyMap()))
- .thenReturn(httpResponseErr);
- assertNull(manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetBadJSON", request));
-
- response.getRequest().getRequestStatus().setRequestState("IN-PROGRESS");
- Pair<Integer, String> httpResponseGetOKRequestTimeout = mockedRESTManager.new Pair<>(200, Serialization.gsonPretty.toJson(response));
- when(mockedRESTManager.post(startsWith("http://somewhere.over.the.rainbow"), eq("Dorothy"), eq("PutOKGetOKReqTimeout"), anyMap(), anyString(), anyString()))
- .thenReturn(httpResponsePutOK);
- when(mockedRESTManager.get(startsWith("http://somewhere.over.the.rainbow/InOz"), eq("Dorothy"), eq("PutOKGetOKReqTimeout"), anyMap()))
- .thenReturn(httpResponseGetOKRequestTimeout);
-
- manager.setRestGetTimeout(10);
- response = manager.createModuleInstance("http://somewhere.over.the.rainbow", "http://somewhere.over.the.rainbow/InOz", "Dorothy", "PutOKGetOKReqTimeout", request);
- assertNotNull(response);
- assertEquals("FAILED", response.getRequest().getRequestStatus().getRequestState());
- */
- }
+ private static final String BASE_URI = "http://localhost:46553/TestSOManager";
+ private static final String BASE_SO_URI = BASE_URI + "/SO";
+ private static HttpServer server;
+
+ @BeforeClass
+ public static void setUp() {
+ final ResourceConfig rc = new ResourceConfig(TestSoDummyServer.class);
+ server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ server.shutdown();
+ }
+
+ @Test
+ public void testGrizzlyServer() throws ClientProtocolException, IOException {
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+ HttpGet httpGet = new HttpGet("http://localhost:46553/TestSOManager/SO/Stats");
+ CloseableHttpResponse response = httpclient.execute(httpGet);
+
+ String returnBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertTrue(returnBody.matches("^\\{\"GET\": [0-9]*,\"STAT\": [0-9]*,\"POST\": [0-9]*,\"PUT\": [0-9]*\\}$"));
+ }
+
+ @Test
+ public void testServiceInstantiation() throws IOException {
+ SOManager manager = new SOManager();
+ assertNotNull(manager);
+ manager.setRestGetTimeout(100);
+
+ SOResponse response = manager.createModuleInstance("http:/localhost:99999999", BASE_SO_URI, "sean", "citizen", null);
+ assertNull(response);
+
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", null);
+ assertNull(response);
+
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", new SORequest());
+ assertNull(response);
+
+ SORequest request = new SORequest();
+ request.setRequestId(UUID.randomUUID());
+ request.setRequestScope("Test");
+ request.setRequestType("ReturnBadJson");
+ request.setStartTime("2018-03-23 16:31");
+ request.setRequestStatus(new SORequestStatus());
+ request.getRequestStatus().setRequestState("ONGOING");
+
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNull(response);
+
+ request.setRequestType("ReturnCompleted");
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNotNull(response);
+ assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
+
+ request.setRequestType("ReturnFailed");
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNotNull(response);
+ assertEquals("FAILED", response.getRequest().getRequestStatus().getRequestState());
+
+ // Use scope to set the number of iterations we'll wait for
+
+ request.setRequestType("ReturnOnging200");
+ request.setRequestScope(new Integer(10).toString());
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNotNull(response);
+ assertNotNull(response.getRequest());
+ assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
+
+ request.setRequestType("ReturnOnging202");
+ request.setRequestScope(new Integer(20).toString());
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNotNull(response);
+ assertNotNull(response.getRequest());
+ assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
+
+ // Test timeout after 20 attempts for a response
+ request.setRequestType("ReturnOnging202");
+ request.setRequestScope(new Integer(21).toString());
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNull(response);
+
+ // Test bad response after 3 attempts for a response
+ request.setRequestType("ReturnBadAfterWait");
+ request.setRequestScope(new Integer(3).toString());
+ response = manager.createModuleInstance(BASE_SO_URI + "/serviceInstances/v5", BASE_SO_URI, "sean", "citizen", request);
+ assertNull(response);
+ }
+
+ @Test
+ public void testVfModuleCreation() throws IOException {
+ SOManager manager = new SOManager();
+ assertNotNull(manager);
+ manager.setRestGetTimeout(100);
+
+ PolicyEngine.manager.setEnvironmentProperty("so.username", "sean");
+ PolicyEngine.manager.setEnvironmentProperty("so.password", "citizen");
+
+ WorkingMemory wm = new DummyWorkingMemory();
+
+ PolicyEngine.manager.setEnvironmentProperty("so.url", "http:/localhost:99999999");
+ Future<SOResponse> asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), null);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals(999, response.getHttpResponseCode());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ PolicyEngine.manager.setEnvironmentProperty("so.url", BASE_SO_URI);
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), null);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals(999, response.getHttpResponseCode());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), new SORequest());
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals(999, response.getHttpResponseCode());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ SORequest request = new SORequest();
+ request.setRequestId(UUID.randomUUID());
+ request.setRequestScope("Test");
+ request.setRequestType("ReturnBadJson");
+ request.setStartTime("2018-03-23 16:31");
+ request.setRequestStatus(new SORequestStatus());
+ request.getRequestStatus().setRequestState("ONGOING");
+
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals(999, response.getHttpResponseCode());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ request.setRequestType("ReturnCompleted");
+
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ request.setRequestType("ReturnFailed");
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals("FAILED", response.getRequest().getRequestStatus().getRequestState());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ // Use scope to set the number of iterations we'll wait for
+
+ request.setRequestType("ReturnOnging200");
+ request.setRequestScope(new Integer(10).toString());
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertNotNull(response.getRequest());
+ assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ request.setRequestType("ReturnOnging202");
+ request.setRequestScope(new Integer(20).toString());
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertNotNull(response.getRequest());
+ assertEquals("COMPLETE", response.getRequest().getRequestStatus().getRequestState());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ // Test timeout after 20 attempts for a response
+ request.setRequestType("ReturnOnging202");
+ request.setRequestScope(new Integer(21).toString());
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals(999, response.getHttpResponseCode());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ // Test bad response after 3 attempts for a response
+ request.setRequestType("ReturnBadAfterWait");
+ request.setRequestScope(new Integer(3).toString());
+ asyncRestCallFuture = manager.asyncSORestCall(UUID.randomUUID().toString(), wm, UUID.randomUUID().toString(), UUID.randomUUID().toString(), request);
+ try {
+ SOResponse response = asyncRestCallFuture.get();
+ assertEquals(999, response.getHttpResponseCode());
+ }
+ catch (Exception e) {
+ fail("test should not throw an exception");
+ }
+ }
}
diff --git a/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSoDummyServer.java b/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSoDummyServer.java
new file mode 100644
index 000000000..907ca69bc
--- /dev/null
+++ b/controlloop/common/model-impl/so/src/test/java/org/onap/policy/so/TestSoDummyServer.java
@@ -0,0 +1,272 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * so
+ * ================================================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.so;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+
+import com.google.gson.Gson;
+
+@Path("/SO")
+public class TestSoDummyServer {
+
+ private static int postMessagesReceived = 0;
+ private static int putMessagesReceived = 0;
+ private static int statMessagesReceived = 0;
+ private static int getMessagesReceived = 0;
+
+ private static Map<String, SOResponse> ongoingRequestMap = new ConcurrentHashMap<>();
+
+ @GET
+ @Path("/Stats")
+ public Response serviceGetStats() {
+ statMessagesReceived++;
+ return Response.status(200).entity("{\"GET\": " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived + ",\"POST\": " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}").build();
+ }
+
+ @GET
+ @Path("/OneStat/{statType}")
+ public Response serviceGetStat(@PathParam("statType") final String statType) {
+ statMessagesReceived++;
+ return Response.status(200).entity("{\"TYPE\": " + statType + "}").build();
+ }
+
+ @POST
+ @Path("/serviceInstances/v5")
+ public Response servicePostRequest(final String jsonString) {
+ postMessagesReceived++;
+
+ if (jsonString == null) {
+ return Response.status(400).build();
+ }
+
+ SORequest request = null;
+ try {
+ request = new Gson().fromJson(jsonString, SORequest.class);
+ }
+ catch (Exception e) {
+ return Response.status(400).build();
+ }
+
+ if (request == null) {
+ return Response.status(400).build();
+ }
+
+ if (request.getRequestType() == null) {
+ return Response.status(400).build();
+ }
+
+ if ("ReturnBadJson".equals(request.getRequestType())) {
+ return Response.status(200)
+ .entity("{\"GET\": , " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived + ",\"POST\": , " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}")
+ .build();
+ }
+
+ SOResponse response = new SOResponse();
+ response.setRequest(request);
+ response.setRequestReferences(new SORequestReferences());
+ response.getRequestReferences().setRequestId(request.getRequestId().toString());
+
+ if ("ReturnCompleted".equals(request.getRequestType())) {
+ response.getRequest().getRequestStatus().setRequestState("COMPLETE");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ if ("ReturnFailed".equals(request.getRequestType())) {
+ response.getRequest().getRequestStatus().setRequestState("FAILED");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ if ("ReturnOnging202".equals(request.getRequestType())) {
+ ongoingRequestMap.put(request.getRequestId().toString(), response);
+
+ response.getRequest().getRequestStatus().setRequestState("ONGOING");
+ response.setHttpResponseCode(202);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ if ("ReturnOnging200".equals(request.getRequestType())) {
+ ongoingRequestMap.put(request.getRequestId().toString(), response);
+
+ response.getRequest().getRequestStatus().setRequestState("ONGOING");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+
+ if ("ReturnBadAfterWait".equals(request.getRequestType())) {
+ ongoingRequestMap.put(request.getRequestId().toString(), response);
+
+ response.getRequest().getRequestStatus().setRequestState("ONGOING");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ return null;
+ }
+
+ @POST
+ @Path("/serviceInstances/v5/{serviceInstanceId}/vnfs/{vnfInstanceId}/vfModules")
+ public Response servicePostRequestVfModules(
+ @PathParam("serviceInstanceId") final String serviceInstanceId,
+ @PathParam("vnfInstanceId") final String vnfInstanceId,
+ final String jsonString) {
+ postMessagesReceived++;
+
+ if (jsonString == null) {
+ return Response.status(400).build();
+ }
+
+ SORequest request = null;
+ try {
+ request = new Gson().fromJson(jsonString, SORequest.class);
+ }
+ catch (Exception e) {
+ return Response.status(400).build();
+ }
+
+ if (request == null) {
+ return Response.status(400).build();
+ }
+
+ if (request.getRequestType() == null) {
+ return Response.status(400).build();
+ }
+
+ if ("ReturnBadJson".equals(request.getRequestType())) {
+ return Response.status(200)
+ .entity("{\"GET\": , " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived + ",\"POST\": , " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}")
+ .build();
+ }
+
+ SOResponse response = new SOResponse();
+ response.setRequest(request);
+ response.setRequestReferences(new SORequestReferences());
+ response.getRequestReferences().setRequestId(request.getRequestId().toString());
+
+ if ("ReturnCompleted".equals(request.getRequestType())) {
+ response.getRequest().getRequestStatus().setRequestState("COMPLETE");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ if ("ReturnFailed".equals(request.getRequestType())) {
+ response.getRequest().getRequestStatus().setRequestState("FAILED");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ if ("ReturnOnging202".equals(request.getRequestType())) {
+ ongoingRequestMap.put(request.getRequestId().toString(), response);
+
+ response.getRequest().getRequestStatus().setRequestState("ONGOING");
+ response.setHttpResponseCode(202);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ if ("ReturnOnging200".equals(request.getRequestType())) {
+ ongoingRequestMap.put(request.getRequestId().toString(), response);
+
+ response.getRequest().getRequestStatus().setRequestState("ONGOING");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+
+ if ("ReturnBadAfterWait".equals(request.getRequestType())) {
+ ongoingRequestMap.put(request.getRequestId().toString(), response);
+
+ response.getRequest().getRequestStatus().setRequestState("ONGOING");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ return null;
+ }
+
+ @GET
+ @Path("/orchestrationRequests/v5/{nsInstanceId}")
+ public Response soRequestStatus(@PathParam("nsInstanceId") final String nsInstanceId) {
+
+ SOResponse response = ongoingRequestMap.get(nsInstanceId);
+
+ int iterationsLeft = Integer.valueOf(response.getRequest().getRequestScope());
+ if (--iterationsLeft > 0) {
+ response.getRequest().setRequestScope(new Integer(iterationsLeft).toString());
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+
+ ongoingRequestMap.remove(nsInstanceId);
+
+ if ("ReturnBadAfterWait".equals(response.getRequest().getRequestType())) {
+ return Response.status(400).build();
+ }
+
+ response.getRequest().getRequestStatus().setRequestState("COMPLETE");
+ response.getRequest().setRequestScope("0");
+ response.setHttpResponseCode(200);
+ String responseString = new Gson().toJson(response, SOResponse.class);
+ return Response.status(response.getHttpResponseCode())
+ .entity(responseString)
+ .build();
+ }
+}
diff --git a/controlloop/common/simulators/pom.xml b/controlloop/common/simulators/pom.xml
index c256d13ac..1c613eaba 100644
--- a/controlloop/common/simulators/pom.xml
+++ b/controlloop/common/simulators/pom.xml
@@ -51,7 +51,6 @@
<groupId>org.onap.policy.drools-applications.controlloop.common.model-impl</groupId>
<artifactId>so</artifactId>
<version>${project.version}</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.onap.policy.drools-applications.controlloop.common.model-impl</groupId>
diff --git a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SoSimulatorJaxRs.java b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SoSimulatorJaxRs.java
index 1547fd41f..9b623a646 100644
--- a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SoSimulatorJaxRs.java
+++ b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SoSimulatorJaxRs.java
@@ -20,6 +20,8 @@
package org.onap.policy.simulators;
+import java.util.UUID;
+
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -27,10 +29,17 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import org.onap.policy.so.SORequest;
+import org.onap.policy.so.SORequestReferences;
+import org.onap.policy.so.SORequestStatus;
+import org.onap.policy.so.SOResponse;
+
+import com.att.aft.dme2.internal.gson.Gson;
+
@Path("/serviceInstances")
public class SoSimulatorJaxRs {
-
- /**
+
+ /**
* SO post query.
*
* @param serviceInstanceId the service instance Id
@@ -41,14 +50,23 @@ public class SoSimulatorJaxRs {
@Path("/v5/{serviceInstanceId}/vnfs/{vnfInstanceId}/vfModules")
@Consumes(MediaType.APPLICATION_JSON)
@Produces("application/json")
- public String soPostQuery(@PathParam("serviceInstanceId") String serviceInstanceId,
- @PathParam("vnfInstanceId") String vnfInstanceId) {
-
- // the requestID contained in the SO Response is a newly generated requestID
- // with no relation to the requestID in Policy controlLoopEvent
- return "{\"requestReferences\": {\"instanceId\": \"ff305d54-75b4-ff1b-bdb2-eb6b9e5460ff\", \"requestId\": \""
- + "rq1234d1-5a33-ffdf-23ab-12abad84e331\" }}";
+ public String soPostQuery(@PathParam("serviceInstanceId") String serviceInstanceId, @PathParam("vnfInstanceId") String vnfInstanceId)
+ {
+ SORequest request = new SORequest();
+ SORequestStatus requestStatus = new SORequestStatus();
+ requestStatus.setRequestState("COMPLETE");
+ request.setRequestStatus(requestStatus);
+ request.setRequestId(UUID.randomUUID());
+
+ SOResponse response = new SOResponse();
+
+ SORequestReferences requestReferences = new SORequestReferences();
+ String requestId = UUID.randomUUID().toString();
+ requestReferences.setRequestId(requestId);
+ response.setRequestReferences(requestReferences);
+
+ response.setRequest(request);
+ return new Gson().toJson(response);
}
-
}
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/so.success.json b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/so.success.json
index 8f3387e4d..6d617b4bf 100644
--- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/so.success.json
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/so.success.json
@@ -3,5 +3,13 @@
"instanceId": "ff305d54-75b4-ff1b-bdb2-eb6b9e5460ff",
"requestId": "e4f95e0c-a013-4530-8e59-c5c5f9e539b6"
},
+ "request": {
+ "requestId": "e4f95e0c-a013-4530-8e59-c5c5f9e539b6",
+ "requestStatus": {
+ "percentProgress": 100,
+ "requestState": "COMPLETE",
+ "wasRolledBack": false
+ }
+ },
"httpResponseCode": 200
-} \ No newline at end of file
+}