Add REST Apis for Tosca Node template operations 10/127210/2
authorrameshiyer27 <ramesh.murugan.iyer@est.tech>
Thu, 17 Feb 2022 17:14:15 +0000 (17:14 +0000)
committerrameshiyer27 <ramesh.murugan.iyer@est.tech>
Mon, 21 Feb 2022 19:44:46 +0000 (19:44 +0000)
Statistics handling for the new Apis are not added
as it is going to be handled via spring actuators as part of spring
migration.Please suggest if manual stats handling is required.

Issue-ID: POLICY-3832
Signed-off-by: zrrmmua <ramesh.murugan.iyer@est.tech>
Change-Id: I1eeaec9e617fd586238e7ff9e96d40a75c517885

main/src/main/java/org/onap/policy/api/main/rest/ApiRestController.java
main/src/main/java/org/onap/policy/api/main/rest/CommonRestController.java
main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java [new file with mode: 0644]
main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/api/main/rest/TestApiRestServer.java
main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java [new file with mode: 0644]
main/src/test/java/org/onap/policy/api/main/rest/utils/CommonTestRestController.java [new file with mode: 0644]
main/src/test/resources/nodetemplates/nodetemplates.metadatasets.input.tosca.json [new file with mode: 0644]
main/src/test/resources/nodetemplates/nodetemplates.metadatasets.invalid.nodetype.json [new file with mode: 0644]
main/src/test/resources/nodetemplates/nodetemplates.metadatasets.no.nodetemplate.json [new file with mode: 0644]
main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json [new file with mode: 0644]

index 263345a..c564dbe 100644 (file)
@@ -4,7 +4,7 @@
  * ================================================================================\r
  * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.\r
  * Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.\r
- * Modifications Copyright (C) 2020 Nordix Foundation.\r
+ * Modifications Copyright (C) 2020,2022 Nordix Foundation.\r
  * Modifications Copyright (C) 2020-2022 Bell Canada. All rights reserved.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
@@ -61,7 +61,6 @@ import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;\r
 import org.springframework.http.ResponseEntity;\r
 import org.springframework.web.bind.annotation.DeleteMapping;\r
-import org.springframework.web.bind.annotation.ExceptionHandler;\r
 import org.springframework.web.bind.annotation.GetMapping;\r
 import org.springframework.web.bind.annotation.PathVariable;\r
 import org.springframework.web.bind.annotation.PostMapping;\r
@@ -95,43 +94,6 @@ import org.springframework.web.bind.annotation.RestController;
     securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))\r
 public class ApiRestController extends CommonRestController {\r
 \r
-    private static final Logger LOGGER = LoggerFactory.getLogger(ApiRestController.class);\r
-\r
-    private static final String ERROR_MESSAGE_NO_POLICIES_FOUND = "No policies found";\r
-\r
-    private static final String EXTENSION_NAME = "interface info";\r
-\r
-    private static final String API_VERSION_NAME = "api-version";\r
-    private static final String API_VERSION = "1.0.0";\r
-\r
-    private static final String LAST_MOD_NAME = "last-mod-release";\r
-\r
-    private static final String AUTHORIZATION_TYPE = "basicAuth";\r
-\r
-    private static final String VERSION_MINOR_NAME = "X-MinorVersion";\r
-    private static final String VERSION_MINOR_DESCRIPTION =\r
-        "Used to request or communicate a MINOR version back from the client"\r
-            + " to the server, and from the server back to the client";\r
-\r
-    private static final String VERSION_PATCH_NAME = "X-PatchVersion";\r
-    private static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for"\r
-        + " troubleshooting purposes only, and will not be provided by" + " the client on request";\r
-\r
-    private static final String VERSION_LATEST_NAME = "X-LatestVersion";\r
-    private static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version";\r
-\r
-    private static final String REQUEST_ID_NAME = "X-ONAP-RequestID";\r
-    private static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose";\r
-    private static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction";\r
-\r
-    private static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error";\r
-    private static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error";\r
-    private static final String SERVER_ERROR_MESSAGE = "Internal Server Error";\r
-    private static final String NOT_FOUND_MESSAGE = "Resource Not Found";\r
-    private static final String INVALID_BODY_MESSAGE = "Invalid Body";\r
-    private static final String INVALID_PAYLOAD_MESSAGE = "Not Acceptable Payload";\r
-    private static final String HTTP_CONFLICT_MESSAGE = "Delete Conflict, Rule Violation";\r
-\r
     private enum Target {\r
         POLICY,\r
         POLICY_TYPE,\r
@@ -1090,13 +1052,6 @@ public class ApiRestController extends CommonRestController {
         }\r
     }\r
 \r
-    @ExceptionHandler(value = {PolicyApiRuntimeException.class})\r
-    protected ResponseEntity<Object> handleException(PolicyApiRuntimeException ex) {\r
-        LOGGER.warn(ex.getMessage(), ex.getCause());\r
-        return makeErrorResponse(ex.getRequestId(), ex.getErrorResponse(),\r
-            ex.getErrorResponse().getResponseCode().getStatusCode());\r
-    }\r
-\r
     private void updateApiStatisticsCounter(Target target, HttpStatus result, HttpMethod http) {\r
         mgr.updateTotalApiCallCount();\r
         switch (target) {\r
index 0389e0f..5e4c3ee 100644 (file)
@@ -4,6 +4,7 @@
  * ================================================================================\r
  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
  * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.\r
+ * Modifications Copyright (C) 2022 Nordix Foundation.\r
  * ================================================================================\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -24,6 +25,7 @@
 package org.onap.policy.api.main.rest;\r
 \r
 import java.util.UUID;\r
+import org.onap.policy.api.main.exception.PolicyApiRuntimeException;\r
 import org.onap.policy.common.utils.coder.Coder;\r
 import org.onap.policy.common.utils.coder.CoderException;\r
 import org.onap.policy.common.utils.coder.StandardCoder;\r
@@ -31,6 +33,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;\r
 import org.springframework.http.HttpHeaders;\r
 import org.springframework.http.ResponseEntity;\r
+import org.springframework.web.bind.annotation.ExceptionHandler;\r
 \r
 /**\r
  * Super class from which REST controllers are derived.\r
@@ -39,7 +42,41 @@ public class CommonRestController {
 \r
     private static final Logger LOGGER = LoggerFactory.getLogger(CommonRestController.class);\r
 \r
-    private final Coder coder = new StandardCoder();\r
+    protected static final String EXTENSION_NAME = "interface info";\r
+\r
+    protected static final String API_VERSION_NAME = "api-version";\r
+    protected static final String API_VERSION = "1.0.0";\r
+\r
+    protected static final String LAST_MOD_NAME = "last-mod-release";\r
+\r
+    protected static final String AUTHORIZATION_TYPE = "basicAuth";\r
+\r
+    protected static final String VERSION_MINOR_NAME = "X-MinorVersion";\r
+    protected static final String VERSION_MINOR_DESCRIPTION =\r
+        "Used to request or communicate a MINOR version back from the client"\r
+            + " to the server, and from the server back to the client";\r
+\r
+    protected static final String VERSION_PATCH_NAME = "X-PatchVersion";\r
+    protected static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a "\r
+        + "response for troubleshooting purposes only, and will not be provided by" + " the client on request";\r
+\r
+    protected static final String VERSION_LATEST_NAME = "X-LatestVersion";\r
+    protected static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version";\r
+\r
+    protected static final String REQUEST_ID_NAME = "X-ONAP-RequestID";\r
+    protected static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose";\r
+    protected static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction";\r
+\r
+    protected static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error";\r
+    protected static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error";\r
+    protected static final String SERVER_ERROR_MESSAGE = "Internal Server Error";\r
+    protected static final String NOT_FOUND_MESSAGE = "Resource Not Found";\r
+    protected static final String INVALID_BODY_MESSAGE = "Invalid Body";\r
+    protected static final String INVALID_PAYLOAD_MESSAGE = "Not Acceptable Payload";\r
+    protected static final String HTTP_CONFLICT_MESSAGE = "Delete Conflict, Rule Violation";\r
+    protected static final String ERROR_MESSAGE_NO_POLICIES_FOUND = "No policies found";\r
+\r
+    protected final Coder coder = new StandardCoder();\r
 \r
     protected <T> ResponseEntity<T> makeOkResponse(UUID requestId, T respEntity) {\r
         HttpHeaders headers = new HttpHeaders();\r
@@ -89,4 +126,11 @@ public class CommonRestController {
             return null;\r
         }\r
     }\r
+\r
+    @ExceptionHandler(value = {PolicyApiRuntimeException.class})\r
+    protected ResponseEntity<Object> handleException(PolicyApiRuntimeException ex) {\r
+        LOGGER.warn(ex.getMessage(), ex.getCause());\r
+        return makeErrorResponse(ex.getRequestId(), ex.getErrorResponse(),\r
+            ex.getErrorResponse().getResponseCode().getStatusCode());\r
+    }\r
 }
\ No newline at end of file
diff --git a/main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java b/main/src/main/java/org/onap/policy/api/main/rest/NodeTemplateController.java
new file mode 100644 (file)
index 0000000..90e03da
--- /dev/null
@@ -0,0 +1,346 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy API
+ * ================================================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.api.main.rest;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.Authorization;
+import io.swagger.annotations.BasicAuthDefinition;
+import io.swagger.annotations.Extension;
+import io.swagger.annotations.ExtensionProperty;
+import io.swagger.annotations.Info;
+import io.swagger.annotations.ResponseHeader;
+import io.swagger.annotations.SecurityDefinition;
+import io.swagger.annotations.SwaggerDefinition;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.UUID;
+import org.onap.policy.api.main.exception.PolicyApiRuntimeException;
+import org.onap.policy.api.main.rest.provider.NodeTemplateProvider;
+import org.onap.policy.common.endpoints.event.comm.Topic;
+import org.onap.policy.common.endpoints.utils.NetLoggerUtil;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Class to provide REST API services for Tosca Node templates.
+ */
+@RestController
+@RequestMapping(path = "/policy/api/v1", produces = { "application/json", "application/yaml" })
+@Api(value = "Tosca Node template Design API")
+@SwaggerDefinition(
+    info = @Info(
+        description = "Tosca Node template Design API is publicly exposed for clients to Create/Read/Update/Delete"
+            + " node templates which can be recognized"
+            + " and executable by incorporated policy engines. It is an"
+            + " independent component running rest service that takes all node templates design API calls"
+            + " from clients and then assign them to different API working functions.",
+        version = "1.0.0", title = "Tosca Node template Design",
+        extensions = {@Extension(properties = {@ExtensionProperty(name = "planned-retirement-date", value = "tbd"),
+            @ExtensionProperty(name = "component", value = "Policy Framework")})}),
+    schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS},
+    securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")}))
+public class NodeTemplateController extends CommonRestController {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(NodeTemplateController.class);
+
+    @Autowired
+    private NodeTemplateProvider provider;
+
+    /**
+     * Creates one or more new tosca node templates in one call.
+     *
+     * @param body the body of the node templates in TOSCA definition
+     *
+     * @return the Response object containing the results of the API operation
+     */
+    @PostMapping("/nodetemplates")
+    @ApiOperation(value = "Create one or more new node templates",
+        notes = "Client should provide TOSCA body of the new node templates",
+        authorizations = @Authorization(value = AUTHORIZATION_TYPE), tags = {"nodeTemplate", },
+        response = ToscaServiceTemplate.class,
+        responseHeaders = {
+            @ResponseHeader(name = VERSION_MINOR_NAME,
+                description = VERSION_MINOR_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_PATCH_NAME,
+                description = VERSION_PATCH_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = REQUEST_ID_NAME,
+                description = REQUEST_ID_HDR_DESCRIPTION, response = UUID.class)},
+        extensions = {
+            @Extension(name = EXTENSION_NAME, properties = {
+                @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+                @ExtensionProperty(name = LAST_MOD_NAME, value = "Jakarta")})})
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpURLConnection.HTTP_BAD_REQUEST, message = INVALID_BODY_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = AUTHENTICATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = AUTHORIZATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = NOT_FOUND_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_ACCEPTABLE, message = INVALID_PAYLOAD_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = SERVER_ERROR_MESSAGE)})
+    public ResponseEntity<ToscaServiceTemplate> createToscaNodeTemplates(
+        @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+        @RequestBody @ApiParam(value = "Entity body of tosca node templates", required = true)
+            ToscaServiceTemplate body) {
+
+        if (NetLoggerUtil.getNetworkLogger().isInfoEnabled()) {
+            NetLoggerUtil.log(NetLoggerUtil.EventType.IN, Topic.CommInfrastructure.REST, "/nodetemplates",
+                toJson(body));
+        }
+        try {
+            ToscaServiceTemplate nodeTemplates = provider.createNodeTemplates(body);
+            return makeOkResponse(requestId, nodeTemplates);
+        } catch (PfModelException | PfModelRuntimeException pfme) {
+            final var msg = "POST /nodetemplates";
+            throw new PolicyApiRuntimeException(msg, pfme.getCause(), pfme.getErrorResponse(), requestId);
+        }
+    }
+
+
+    /**
+     * Updates one or more node templates in one call.
+     *
+     * @param body the body of the node templates in TOSCA definition
+     *
+     * @return the Response object containing the results of the API operation
+     */
+    @PutMapping("/nodetemplates")
+    @ApiOperation(value = "Updates one or more new node templates",
+        notes = "Client should provide TOSCA body of the updated node templates",
+        authorizations = @Authorization(value = AUTHORIZATION_TYPE), tags = {"nodeTemplate", },
+        response = ToscaServiceTemplate.class,
+        responseHeaders = {
+            @ResponseHeader(name = VERSION_MINOR_NAME,
+                description = VERSION_MINOR_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_PATCH_NAME,
+                description = VERSION_PATCH_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = REQUEST_ID_NAME,
+                description = REQUEST_ID_HDR_DESCRIPTION, response = UUID.class)},
+        extensions = {
+            @Extension(name = EXTENSION_NAME, properties = {
+                @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+                @ExtensionProperty(name = LAST_MOD_NAME, value = "Jakarta")})})
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpURLConnection.HTTP_BAD_REQUEST, message = INVALID_BODY_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = AUTHENTICATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = AUTHORIZATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = NOT_FOUND_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_ACCEPTABLE, message = INVALID_PAYLOAD_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = SERVER_ERROR_MESSAGE)})
+    public ResponseEntity<ToscaServiceTemplate> updateToscaNodeTemplates(
+        @RequestHeader(name = REQUEST_ID_NAME, required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId,
+        @RequestBody @ApiParam(value = "Entity body of tosca node templates", required = true)
+            ToscaServiceTemplate body) {
+
+        if (NetLoggerUtil.getNetworkLogger().isInfoEnabled()) {
+            NetLoggerUtil.log(NetLoggerUtil.EventType.IN, Topic.CommInfrastructure.REST, "/nodetemplates",
+                toJson(body));
+        }
+        try {
+            ToscaServiceTemplate nodeTemplates = provider.updateToscaNodeTemplates(body);
+            return makeOkResponse(requestId, nodeTemplates);
+        } catch (PfModelException | PfModelRuntimeException pfme) {
+            final var msg = "PUT /nodetemplates";
+            throw new PolicyApiRuntimeException(msg, pfme.getCause(), pfme.getErrorResponse(), requestId);
+        }
+    }
+
+
+    /**
+     * Deletes a node template with specific name and version.
+     *
+     * @param name  the name of node template
+     * @param version the version of node template
+     * @return the Response object containing the results of the API operation
+     */
+    @DeleteMapping("/nodetemplates/{name}/versions/{version}")
+    @ApiOperation(value = "Updates one or more new node templates",
+        notes = "Client should provide TOSCA body of the updated node templates",
+        authorizations = @Authorization(value = AUTHORIZATION_TYPE), tags = {"nodeTemplate", },
+        response = ToscaServiceTemplate.class,
+        responseHeaders = {
+            @ResponseHeader(name = VERSION_MINOR_NAME,
+                description = VERSION_MINOR_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_PATCH_NAME,
+                description = VERSION_PATCH_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = REQUEST_ID_NAME,
+                description = REQUEST_ID_HDR_DESCRIPTION, response = UUID.class)},
+        extensions = {
+            @Extension(name = EXTENSION_NAME, properties = {
+                @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+                @ExtensionProperty(name = LAST_MOD_NAME, value = "Jakarta")})})
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpURLConnection.HTTP_BAD_REQUEST, message = INVALID_BODY_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = AUTHENTICATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = AUTHORIZATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = NOT_FOUND_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_ACCEPTABLE, message = INVALID_PAYLOAD_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = SERVER_ERROR_MESSAGE)})
+    public ResponseEntity<ToscaServiceTemplate> deleteToscaNodeTemplates(
+        @PathVariable("name") @ApiParam(value = "Name of the node template", required = true) String name,
+        @PathVariable("version") @ApiParam(value = "Version of the node template",
+            required = true) String version,
+        @RequestHeader(name = REQUEST_ID_NAME, required = false)
+        @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId) {
+        try {
+            ToscaServiceTemplate nodeTemplates = provider.deleteToscaNodeTemplate(name, version);
+            return makeOkResponse(requestId, nodeTemplates);
+        } catch (PfModelException | PfModelRuntimeException pfme) {
+            final var msg = String.format("DELETE /nodetemplates/%s/versions/%s", name, version);
+            throw new PolicyApiRuntimeException(msg, pfme.getCause(), pfme.getErrorResponse(), requestId);
+        }
+    }
+
+
+    /**
+     * Retrieves the specified version of a node template.
+     *
+     * @param name the name of the node template
+     * @param version the version of the node template
+     *
+     * @return the Response object containing the results of the API operation
+     */
+    @GetMapping("/nodetemplates/{name}/versions/{version}")
+    @ApiOperation(value = "Retrieve one version of a tosca node template",
+        notes = "Returns a particular version of a node template",
+        response = ToscaNodeTemplate.class,
+        responseContainer = "List",
+        responseHeaders = {
+            @ResponseHeader(name = VERSION_MINOR_NAME,
+                description = VERSION_MINOR_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_PATCH_NAME,
+                description = VERSION_PATCH_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = REQUEST_ID_NAME,
+                description = REQUEST_ID_HDR_DESCRIPTION, response = UUID.class)},
+        authorizations = @Authorization(value = AUTHORIZATION_TYPE), tags = {"nodeTemplates", },
+        extensions = {
+            @Extension(name = EXTENSION_NAME, properties = {
+                @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+                @ExtensionProperty(name = LAST_MOD_NAME, value = "Jakarta")
+            })
+        }
+    )
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = AUTHENTICATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = AUTHORIZATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = NOT_FOUND_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = SERVER_ERROR_MESSAGE)
+    })
+    public ResponseEntity<List<ToscaNodeTemplate>> getSpecificVersionOfNodeTemplate(
+        @PathVariable("name") @ApiParam(value = "Name of the node template", required = true) String name,
+        @PathVariable("version") @ApiParam(value = "Version of the node template",
+            required = true) String version,
+        @RequestHeader(name = REQUEST_ID_NAME, required = false)
+        @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId) {
+        try {
+            List<ToscaNodeTemplate> nodeTemplates = provider.fetchToscaNodeTemplates(name, version);
+            return makeOkResponse(requestId, nodeTemplates);
+        } catch (PfModelException | PfModelRuntimeException pfme) {
+            var msg = String.format("GET /nodetemplates/%s/versions/%s", name, version);
+            throw new PolicyApiRuntimeException(msg, pfme.getCause(), pfme.getErrorResponse(), requestId);
+        }
+    }
+
+
+    /**
+     * Retrieves all the node templates from the tosca service template.
+     *
+     * @return the Response object containing the results of the API operation
+     */
+    @GetMapping("/nodetemplates")
+    @ApiOperation(value = "Retrieve all the available tosca node templates",
+        notes = "Returns all the node templates from the service template",
+        response = ToscaNodeTemplate.class,
+        responseContainer = "List",
+        responseHeaders = {
+            @ResponseHeader(name = VERSION_MINOR_NAME,
+                description = VERSION_MINOR_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_PATCH_NAME,
+                description = VERSION_PATCH_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION,
+                response = String.class),
+            @ResponseHeader(name = REQUEST_ID_NAME,
+                description = REQUEST_ID_HDR_DESCRIPTION, response = UUID.class)},
+        authorizations = @Authorization(value = AUTHORIZATION_TYPE), tags = {"nodeTemplates", },
+        extensions = {
+            @Extension(name = EXTENSION_NAME, properties = {
+                @ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION),
+                @ExtensionProperty(name = LAST_MOD_NAME, value = "Jakarta")
+            })
+        }
+    )
+    @ApiResponses(value = {
+        @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = AUTHENTICATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = AUTHORIZATION_ERROR_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = NOT_FOUND_MESSAGE),
+        @ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = SERVER_ERROR_MESSAGE)
+    })
+    public ResponseEntity<List<ToscaNodeTemplate>> getAllNodeTemplates(
+        @RequestHeader(name = REQUEST_ID_NAME, required = false)
+        @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId) {
+        try {
+            List<ToscaNodeTemplate> nodeTemplates = provider.fetchToscaNodeTemplates(null, null);
+            return makeOkResponse(requestId, nodeTemplates);
+        } catch (PfModelException | PfModelRuntimeException pfme) {
+            var msg = "GET /nodetemplates";
+            throw new PolicyApiRuntimeException(msg, pfme.getCause(), pfme.getErrorResponse(), requestId);
+        }
+    }
+
+}
diff --git a/main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java b/main/src/main/java/org/onap/policy/api/main/rest/provider/NodeTemplateProvider.java
new file mode 100644 (file)
index 0000000..2ff5024
--- /dev/null
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy API
+ * ================================================================================
+ * Copyright (C) 2022 Nordix Foundation. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.api.main.rest.provider;
+
+import java.util.List;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class NodeTemplateProvider extends CommonModelProvider {
+
+    /**
+     * Default constructor.
+     */
+    @Autowired
+    public NodeTemplateProvider(PolicyModelsProvider modelsProvider) throws PfModelException {
+        super(modelsProvider);
+    }
+
+
+    /**
+     * Retrieves a node template matching specified ID and version.
+     *
+     * @param name the name of the node template, null to return all entries
+     * @param version the version of node template, null to return all entries
+     *
+     * @return the List of node templates
+     *
+     * @throws PfModelException the PfModel parsing exception
+     */
+    public List<ToscaNodeTemplate> fetchToscaNodeTemplates(final String name, final String version)
+        throws PfModelException {
+
+        return modelsProvider.getToscaNodeTemplate(name, version);
+    }
+
+
+    /**
+     * Creates one or more new node templates.
+     *
+     * @param serviceTemplate service template containing node template definitions
+     *
+     * @return the ToscaServiceTemplate object
+     *
+     * @throws PfModelException the PfModel parsing exception
+     */
+    public ToscaServiceTemplate createNodeTemplates(ToscaServiceTemplate serviceTemplate)
+        throws PfModelException {
+
+        return modelsProvider.createToscaNodeTemplates(serviceTemplate);
+    }
+
+
+    /**
+     * Update one or more node templates.
+     *
+     * @param serviceTemplate service template with updated node templates
+     * @return the ToscaServiceTemplate object
+     *
+     * @throws PfModelException the PfModel parsing exception
+     */
+    public ToscaServiceTemplate updateToscaNodeTemplates(ToscaServiceTemplate serviceTemplate)
+        throws PfModelException {
+
+        return modelsProvider.updateToscaNodeTemplates(serviceTemplate);
+    }
+
+
+    /**
+     * Deletes the node template matching specified ID and version.
+     *
+     * @param name the name of the node template
+     * @param version the version of the node template
+     *
+     * @return the ToscaServiceTemplate object
+     *
+     * @throws PfModelException the PfModel parsing exception
+     */
+    public ToscaServiceTemplate deleteToscaNodeTemplate(String name, String version)
+        throws PfModelException {
+
+        return modelsProvider.deleteToscaNodeTemplate(name, version);
+    }
+
+
+}
index ae654c6..a22a0a0 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.
  *  Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
- *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ *  Modifications Copyright (C) 2019-2020,2022 Nordix Foundation.
  *  Modifications Copyright (C) 2020-2022 Bell Canada. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,27 +31,17 @@ import static org.junit.Assert.assertNull;
 
 import java.io.File;
 import java.io.IOException;
-import java.security.SecureRandom;
 import java.util.List;
 import java.util.Map;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.Invocation;
-import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.onap.policy.api.main.PolicyApiApplication;
-import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
+import org.onap.policy.api.main.rest.utils.CommonTestRestController;
 import org.onap.policy.common.endpoints.report.HealthCheckReport;
-import org.onap.policy.common.gson.GsonMessageBodyHandler;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.coder.StandardYamlCoder;
 import org.onap.policy.common.utils.network.NetworkUtil;
@@ -79,7 +69,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 @SpringBootTest(classes = PolicyApiApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 @ActiveProfiles("test")
 @DirtiesContext(classMode = ClassMode.AFTER_CLASS)
-public class TestApiRestServer {
+public class TestApiRestServer extends CommonTestRestController {
 
     private static final String ALIVE = "alive";
     private static final String SELF = NetworkUtil.getHostname();
@@ -196,7 +186,7 @@ public class TestApiRestServer {
     @Test
     public void testCreatePolicyTypes() throws Exception {
         for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
             ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
             assertNotNull(response);
@@ -204,12 +194,12 @@ public class TestApiRestServer {
         }
 
         // Send a policy type with a null value to trigger an error
-        Response rawResponse = readResource(POLICYTYPES, APP_JSON);
+        Response rawResponse = readResource(POLICYTYPES, APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
         String firstPolicyType = response.getPolicyTypes().keySet().iterator().next();
         response.getPolicyTypes().put(firstPolicyType, null);
-        Response rawResponse2 = createResource(POLICYTYPES, standardCoder.encode(response));
+        Response rawResponse2 = createResource(POLICYTYPES, standardCoder.encode(response), apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse2.getStatus());
         ErrorResponse errorResponse = rawResponse2.readEntity(ErrorResponse.class);
         assertEquals("no policy types specified on service template", errorResponse.getErrorMessage());
@@ -218,7 +208,7 @@ public class TestApiRestServer {
     @Test
     public void testCreatePolicies() throws Exception {
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         }
 
@@ -232,7 +222,8 @@ public class TestApiRestServer {
         TextFileUtils.putStringAsTextFile(toscaPolicy, "src/test/resources/policies/BadTestPolicy.yaml");
 
         Response rawResponse2 =
-                createResource(POLICYTYPES_TCA_POLICIES, "src/test/resources/policies/BadTestPolicy.yaml");
+                createResource(POLICYTYPES_TCA_POLICIES,
+                    "src/test/resources/policies/BadTestPolicy.yaml", apiPort);
         assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), rawResponse2.getStatus());
         ErrorResponse errorResponse = rawResponse2.readEntity(ErrorResponse.class);
         assertThat(errorResponse.getErrorMessage())
@@ -242,7 +233,7 @@ public class TestApiRestServer {
     @Test
     public void testSimpleCreatePolicies() throws Exception {
         for (String resrcName : TOSCA_POLICIES_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICIES, resrcName);
+            Response rawResponse = createResource(POLICIES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         }
 
@@ -256,7 +247,8 @@ public class TestApiRestServer {
         toscaPolicy = toscaPolicy.replaceAll("onap.restart.tca", "onap.restart.tca.IDontExist");
         TextFileUtils.putStringAsTextFile(toscaPolicy, "src/test/resources/policies/BadTestPolicy.yaml");
 
-        Response rawResponse2 = createResource(POLICIES, "src/test/resources/policies/BadTestPolicy.yaml");
+        Response rawResponse2 =
+            createResource(POLICIES, "src/test/resources/policies/BadTestPolicy.yaml", apiPort);
         ErrorResponse errorResponse = rawResponse2.readEntity(ErrorResponse.class);
         assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), rawResponse2.getStatus());
         assertThat(errorResponse.getErrorMessage())
@@ -266,31 +258,31 @@ public class TestApiRestServer {
     @SuppressWarnings("unchecked")
     @Test
     public void testToscaCompliantOpDroolsPolicies() throws Exception {
-        Response rawResponse = createResource(POLICYTYPES, TOSCA_POLICYTYPE_OP_RESOURCE);
+        Response rawResponse = createResource(POLICYTYPES, TOSCA_POLICYTYPE_OP_RESOURCE, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS_VERSION, APP_JSON);
+        rawResponse = readResource(POLICYTYPES_DROOLS_VERSION, APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = createResource(POLICIES, TOSCA_POLICY_OP_DROOLS_VCPE_RESOURSE_JSON);
+        rawResponse = createResource(POLICIES, TOSCA_POLICY_OP_DROOLS_VCPE_RESOURSE_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = createResource(POLICIES, TOSCA_POLICY_OP_DROOLS_VCPE_RESOURSE_YAML);
+        rawResponse = createResource(POLICIES, TOSCA_POLICY_OP_DROOLS_VCPE_RESOURSE_YAML, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON);
+        rawResponse = readResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = deleteResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON);
+        rawResponse = deleteResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = createResource(POLICIES, TOSCA_POLICY_OP_DROOLS_VCPE_RESOURSE_YAML);
+        rawResponse = createResource(POLICIES, TOSCA_POLICY_OP_DROOLS_VCPE_RESOURSE_YAML, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON);
+        rawResponse = readResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_YAML);
+        rawResponse = readResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_YAML, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         ToscaServiceTemplate toscaVcpeSt = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -311,7 +303,7 @@ public class TestApiRestServer {
         assertEquals("APPC", operation.get("actor"));
         assertEquals("Restart", operation.get("operation"));
 
-        rawResponse = deleteResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON);
+        rawResponse = deleteResource(POLICYTYPES_DROOLS_POLICIES_VCPE_VERSION, APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
     }
 
@@ -326,7 +318,7 @@ public class TestApiRestServer {
     }
 
     private void testHealthCheckSuccess(String mediaType) throws Exception {
-        final Invocation.Builder invocationBuilder = sendHttpsRequest(HEALTHCHECK_ENDPOINT, mediaType);
+        final Invocation.Builder invocationBuilder = sendHttpsRequest(HEALTHCHECK_ENDPOINT, mediaType, apiPort);
         final HealthCheckReport report = invocationBuilder.get(HealthCheckReport.class);
         validateHealthCheckReport(NAME, SELF, true, 200, ALIVE, report);
     }
@@ -342,11 +334,11 @@ public class TestApiRestServer {
     }
 
     private void testApiStatistics_200(String mediaType) throws Exception {
-        Invocation.Builder invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT, mediaType);
+        Invocation.Builder invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT, mediaType, apiPort);
         StatisticsReport report = invocationBuilder.get(StatisticsReport.class);
         validateStatisticsReport(report, 200);
         updateApiStatistics();
-        invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT, mediaType);
+        invocationBuilder = sendHttpsRequest(STATISTICS_ENDPOINT, mediaType, apiPort);
         report = invocationBuilder.get(StatisticsReport.class);
         validateStatisticsReport(report, 200);
         // ApiStatisticsManager.resetAllStatistics();
@@ -363,46 +355,48 @@ public class TestApiRestServer {
     }
 
     private void testReadPolicyTypes(String mediaType) throws Exception {
-        Response rawResponse = readResource("policytypes/onap.policies.optimization.resource.HpaPolicy", mediaType);
+        Response rawResponse =
+            readResource("policytypes/onap.policies.optimization.resource.HpaPolicy", mediaType,
+                apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         ToscaServiceTemplate namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
         assertNotNull(namingServiceTemplate);
         assertEquals(3, namingServiceTemplate.getPolicyTypesAsMap().size());
         assertEquals(5, namingServiceTemplate.getDataTypesAsMap().size());
 
-        rawResponse = readResource(POLICYTYPES, mediaType);
+        rawResponse = readResource(POLICYTYPES, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
         assertFalse(response.getPolicyTypes().isEmpty());
 
-        rawResponse = readResource(POLICYTYPES_TCA, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_TCA_VERSION, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_VERSION, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_TCA_LATEST, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_LATEST, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_COLLECTOR, mediaType);
+        rawResponse = readResource(POLICYTYPES_COLLECTOR, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_COLLECTOR_VERSION, mediaType);
+        rawResponse = readResource(POLICYTYPES_COLLECTOR_VERSION, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_COLLECTOR_LATEST, mediaType);
+        rawResponse = readResource(POLICYTYPES_COLLECTOR_LATEST, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS, mediaType);
+        rawResponse = readResource(POLICYTYPES_DROOLS, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS_VERSION, mediaType);
+        rawResponse = readResource(POLICYTYPES_DROOLS_VERSION, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_DROOLS_VERSION_LATEST, mediaType);
+        rawResponse = readResource(POLICYTYPES_DROOLS_VERSION_LATEST, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_NAMING_VERSION, mediaType);
+        rawResponse = readResource(POLICYTYPES_NAMING_VERSION, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
     }
 
@@ -417,19 +411,23 @@ public class TestApiRestServer {
     }
 
     private void testDeletePolicyType(String mediaType) throws Exception {
-        Response rawResponse = deleteResource("policytypes/onap.policies.IDoNotExist/versions/1.0.0", mediaType);
+        Response rawResponse = deleteResource("policytypes/onap.policies.IDoNotExist/versions/1.0.0",
+            mediaType, apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = createResource(POLICYTYPES, "policytypes/onap.policies.Test.yaml");
+        rawResponse = createResource(POLICYTYPES, "policytypes/onap.policies.Test.yaml", apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource("policytypes/onap.policies.Test/versions/1.0.0", mediaType);
+        rawResponse =
+            readResource("policytypes/onap.policies.Test/versions/1.0.0", mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = deleteResource("policytypes/onap.policies.Test/versions/1.0.0", mediaType);
+        rawResponse =
+            deleteResource("policytypes/onap.policies.Test/versions/1.0.0", mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource("policytypes/onap.policies.Test/versions/1.0.0", mediaType);
+        rawResponse =
+            readResource("policytypes/onap.policies.Test/versions/1.0.0", mediaType, apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
     }
 
@@ -445,23 +443,23 @@ public class TestApiRestServer {
 
     private void testReadPolicies(String mediaType) throws Exception {
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         }
 
-        Response rawResponse = readResource(POLICYTYPES_TCA_POLICIES, mediaType);
+        Response rawResponse = readResource(POLICYTYPES_TCA_POLICIES, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_LATEST, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_LATEST, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType);
+        rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
     }
@@ -470,11 +468,11 @@ public class TestApiRestServer {
     public void testNamingPolicyGet() throws Exception {
 
         Response rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/"
-                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/1.0.0", APP_JSON);
+                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/1.0.0", APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/"
-                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/1.0.0?mode=referenced", APP_JSON);
+                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/1.0.0?mode=referenced", APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         ToscaServiceTemplate namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -483,7 +481,7 @@ public class TestApiRestServer {
         assertEquals(3, namingServiceTemplate.getDataTypesAsMap().size());
 
         rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/"
-                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/latest?mode=referenced", APP_JSON);
+                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/latest?mode=referenced", APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -491,8 +489,8 @@ public class TestApiRestServer {
         assertEquals(1, namingServiceTemplate.getPolicyTypesAsMap().size());
         assertEquals(3, namingServiceTemplate.getDataTypesAsMap().size());
 
-        rawResponse =
-                readResource("policytypes/onap.policies.Naming/versions/1.0.0/policies?mode=referenced", APP_JSON);
+        rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/policies"
+                + "?mode=referenced", APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -501,7 +499,7 @@ public class TestApiRestServer {
         assertEquals(3, namingServiceTemplate.getDataTypesAsMap().size());
 
         rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/"
-                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/1.0.0", APP_JSON);
+                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/1.0.0", APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -511,7 +509,7 @@ public class TestApiRestServer {
         assertNull(namingServiceTemplate.getDataTypes());
 
         rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/"
-                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/latest", APP_JSON);
+                + "policies/SDNC_Policy.ONAP_NF_NAMING_TIMESTAMP/versions/latest", APP_JSON, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -519,7 +517,9 @@ public class TestApiRestServer {
         assertNull(namingServiceTemplate.getPolicyTypes());
         assertNull(namingServiceTemplate.getDataTypes());
 
-        rawResponse = readResource("policytypes/onap.policies.Naming/versions/1.0.0/policies", APP_JSON);
+        rawResponse =
+            readResource("policytypes/onap.policies.Naming/versions/1.0.0/policies", APP_JSON,
+                apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
         namingServiceTemplate = rawResponse.readEntity(ToscaServiceTemplate.class);
@@ -539,7 +539,7 @@ public class TestApiRestServer {
     }
 
     private void testDeletePolicies(String mediaType) throws Exception {
-        Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType);
+        Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType, apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
         ErrorResponse error = rawResponse.readEntity(ErrorResponse.class);
         assertEquals("policy onap.restart.tca:1.0.0 not found", error.getErrorMessage());
@@ -557,30 +557,30 @@ public class TestApiRestServer {
 
     private void testDeletePolicyVersion(String mediaType) throws Exception {
         for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
             ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
             assertNotNull(response);
             assertFalse(response.getPolicyTypes().isEmpty());
         }
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         }
-        Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType);
+        Response rawResponse = deleteResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
 
-        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_VERSION1, mediaType, apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
         ErrorResponse errorResponse = rawResponse.readEntity(ErrorResponse.class);
         assertEquals("policies for onap.restart.tca:1.0.0 do not exist", errorResponse.getErrorMessage());
 
-        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE, mediaType, apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
         errorResponse = rawResponse.readEntity(ErrorResponse.class);
         assertEquals("policies for onap.restart.tca:null do not exist", errorResponse.getErrorMessage());
 
-        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_LATEST, mediaType);
+        rawResponse = readResource(POLICYTYPES_TCA_POLICIES_VCPE_LATEST, mediaType, apiPort);
         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
         errorResponse = rawResponse.readEntity(ErrorResponse.class);
         assertEquals("policies for onap.restart.tca:null do not exist", errorResponse.getErrorMessage());
@@ -598,17 +598,17 @@ public class TestApiRestServer {
 
     private void testGetAllVersionOfPolicy(String mediaType) throws Exception {
         for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
             ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
             assertNotNull(response);
             assertFalse(response.getPolicyTypes().isEmpty());
         }
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
         }
-        Response rawResponse = readResource(POLICYTYPES_TCA_POLICIES, mediaType);
+        Response rawResponse = readResource(POLICYTYPES_TCA_POLICIES, mediaType, apiPort);
         assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
     }
 
@@ -624,17 +624,17 @@ public class TestApiRestServer {
 
     private void getPolicies(String mediaType) throws Exception {
         for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES, resrcName, apiPort);
             assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
             ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
             assertThat(response).isNotNull();
             assertThat(response.getPolicyTypes()).isNotEmpty();
         }
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
         }
-        Response rawResponse = readResource(POLICIES, mediaType);
+        Response rawResponse = readResource(POLICIES, mediaType, apiPort);
         assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
         ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
         assertThat(response.getToscaTopologyTemplate().getPolicies()).isNotEmpty();
@@ -652,17 +652,17 @@ public class TestApiRestServer {
 
     private void getSpecificPolicy(String mediaType) throws Exception {
         for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES, resrcName, apiPort);
             assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
             ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
             assertThat(response).isNotNull();
             assertThat(response.getPolicyTypes()).isNotEmpty();
         }
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            Response rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
         }
-        Response rawResponse = readResource(POLICIES_VCPE_VERSION1, mediaType);
+        Response rawResponse = readResource(POLICIES_VCPE_VERSION1, mediaType, apiPort);
         assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
         ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
         assertThat(response.getToscaTopologyTemplate().getPolicies()).hasSize(1);
@@ -672,102 +672,32 @@ public class TestApiRestServer {
     public void testDeleteSpecificPolicy() throws Exception {
         Response rawResponse;
         for (String resrcName : TOSCA_POLICYTYPE_RESOURCE_NAMES) {
-            rawResponse = createResource(POLICYTYPES, resrcName);
+            rawResponse = createResource(POLICYTYPES, resrcName, apiPort);
             assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
             ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
             assertThat(response).isNotNull();
             assertThat(response.getPolicyTypes()).isNotEmpty();
         }
         for (String resrcName : TOSCA_POLICY_RESOURCE_NAMES) {
-            rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName);
+            rawResponse = createResource(POLICYTYPES_TCA_POLICIES, resrcName, apiPort);
             assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
         }
 
-        rawResponse = readResource(POLICIES_VCPE_VERSION1, APP_JSON);
+        rawResponse = readResource(POLICIES_VCPE_VERSION1, APP_JSON, apiPort);
         assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
 
         // delete a particular policy
-        rawResponse = deleteResource(POLICIES_VCPE_VERSION1, APP_JSON);
+        rawResponse = deleteResource(POLICIES_VCPE_VERSION1, APP_JSON, apiPort);
         assertThat(rawResponse.getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
 
-        rawResponse = readResource(POLICIES_VCPE_VERSION1, APP_JSON);
+        rawResponse = readResource(POLICIES_VCPE_VERSION1, APP_JSON, apiPort);
         assertThat(rawResponse.getStatus()).isEqualTo(Status.NOT_FOUND.getStatusCode());
 
-        rawResponse = deleteResource(POLICIES_VCPE_VERSION1, APP_JSON);
+        rawResponse = deleteResource(POLICIES_VCPE_VERSION1, APP_JSON, apiPort);
         assertThat(rawResponse.getStatus()).isEqualTo(Status.NOT_FOUND.getStatusCode());
 
     }
 
-
-    private Response createResource(String endpoint, String resourceName) throws Exception {
-
-        String mediaType = APP_JSON; // default media type
-        ToscaServiceTemplate rawServiceTemplate = new ToscaServiceTemplate();
-        if (resourceName.endsWith(".json")) {
-            rawServiceTemplate =
-                    standardCoder.decode(ResourceUtils.getResourceAsString(resourceName), ToscaServiceTemplate.class);
-        } else if (resourceName.endsWith(".yaml") || resourceName.endsWith(".yml")) {
-            mediaType = APP_YAML;
-            rawServiceTemplate = standardYamlCoder.decode(ResourceUtils.getResourceAsString(resourceName),
-                    ToscaServiceTemplate.class);
-        }
-
-        final Invocation.Builder invocationBuilder;
-
-        invocationBuilder = sendHttpsRequest(endpoint, mediaType);
-
-        Entity<ToscaServiceTemplate> entity = Entity.entity(rawServiceTemplate, mediaType);
-        return invocationBuilder.post(entity);
-    }
-
-    private Response readResource(String endpoint, String mediaType) throws Exception {
-
-        final Invocation.Builder invocationBuilder;
-
-        invocationBuilder = sendHttpsRequest(endpoint, mediaType);
-
-        return invocationBuilder.get();
-
-    }
-
-    private Response deleteResource(String endpoint, String mediaType) throws Exception {
-
-        final Invocation.Builder invocationBuilder;
-
-        invocationBuilder = sendHttpsRequest(endpoint, mediaType);
-
-        return invocationBuilder.delete();
-    }
-
-    private Invocation.Builder sendHttpsRequest(final String endpoint, String mediaType) throws Exception {
-
-        final TrustManager[] noopTrustManager = NetworkUtil.getAlwaysTrustingManager();
-
-        final SSLContext sc = SSLContext.getInstance("TLSv1.2");
-        sc.init(null, noopTrustManager, new SecureRandom());
-        final ClientBuilder clientBuilder =
-                ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true);
-        final Client client = clientBuilder.build();
-        final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("policyadmin", "zb!XztG34");
-        client.register(feature);
-
-        client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
-        if (APP_JSON.equalsIgnoreCase(mediaType)) {
-            client.register(GsonMessageBodyHandler.class);
-        } else if (APP_YAML.equalsIgnoreCase(mediaType)) {
-            client.register(YamlMessageBodyHandler.class);
-        }
-
-        final WebTarget webTarget = client.target("https://localhost:" + apiPort + "/policy/api/v1/" + endpoint);
-
-        final Invocation.Builder invocationBuilder = webTarget.request(mediaType);
-
-        if (!NetworkUtil.isTcpPortOpen("localhost", apiPort, 60, 1000L)) {
-            throw new IllegalStateException("cannot connect to port " + apiPort);
-        }
-        return invocationBuilder;
-    }
-
     private void updateApiStatistics() {
         mgr.updateTotalApiCallCount();
         mgr.updateApiCallSuccessCount();
diff --git a/main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java b/main/src/test/java/org/onap/policy/api/main/rest/TestNodeTemplateController.java
new file mode 100644 (file)
index 0000000..5244f3c
--- /dev/null
@@ -0,0 +1,223 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy API
+ * ================================================================================
+ * Copyright (C) 2022 Nordix Foundation. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.api.main.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.List;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.policy.api.main.PolicyApiApplication;
+import org.onap.policy.api.main.rest.provider.NodeTemplateProvider;
+import org.onap.policy.api.main.rest.utils.CommonTestRestController;
+import org.onap.policy.common.utils.security.SelfSignedKeyStore;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.errors.concepts.ErrorResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * Class to perform unit test of {@link NodeTemplateController}.
+ *
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = PolicyApiApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("test")
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+public class TestNodeTemplateController extends CommonTestRestController {
+
+    private static final String TOSCA_NODE_TEMPLATE_RESOURCE =
+        "nodetemplates/nodetemplates.metadatasets.input.tosca.json";
+    private static final String TOSCA_INVALID_NODE_TYPE =
+        "nodetemplates/nodetemplates.metadatasets.invalid.nodetype.json";
+    private static final String TOSCA_INVALID_TEMPLATE =
+        "nodetemplates/nodetemplates.metadatasets.no.nodetemplate.json";
+    private static final String TOSCA_UPDATE_NODE_TEMPLATES = "nodetemplates/nodetemplates.metadatasets.update.json";
+
+    private static final String NODE_TEMPLATES = "nodetemplates";
+    private static final String SPECIFIC_NODE_TEMPLATE = "nodetemplates/apexMetadata_adaptive/versions/1.0.0";
+    private static final String INVALID_NODE_TEMPLATE_ID = "nodetemplates/invalid_template/versions/1.0.0";
+
+    private static final List<String> nodeTemplateKeys =
+        List.of("apexMetadata_grpc", "apexMetadata_adaptive", "apexMetadata_decisionMaker");
+
+    protected static final String APP_JSON = "application/json";
+
+    private static SelfSignedKeyStore keystore;
+
+    @LocalServerPort
+    private int apiPort;
+
+    @Autowired
+    private NodeTemplateProvider provider;
+
+    /**
+     * Initializes parameters and set up test environment.
+     *
+     * @throws IOException on I/O exceptions
+     * @throws InterruptedException if interrupted
+     */
+    @BeforeClass
+    public static void setupParameters() throws IOException, InterruptedException {
+        keystore = new SelfSignedKeyStore();
+    }
+
+    /**
+     * Clean up the database.
+     *
+     */
+    @After
+    public void clearDb() {
+        for (String name : nodeTemplateKeys) {
+            try {
+                provider.deleteToscaNodeTemplate(name, "1.0.0");
+            } catch (PfModelException | PfModelRuntimeException e) {
+                //do nothing
+            }
+        }
+    }
+
+    @DynamicPropertySource
+    static void registerPgProperties(DynamicPropertyRegistry registry) {
+        registry.add("server.ssl.enabled", () -> "true");
+        registry.add("server.ssl.key-store", () -> keystore.getKeystoreName());
+        registry.add("server.ssl.key-store-password", () -> SelfSignedKeyStore.KEYSTORE_PASSWORD);
+        registry.add("server.ssl.key-store-type", () -> "PKCS12");
+        registry.add("server.ssl.key-alias", () -> "policy@policy.onap.org");
+        registry.add("server.ssl.key-password", () -> SelfSignedKeyStore.PRIVATE_KEY_PASSWORD);
+    }
+
+
+    @Test
+    public void testCreateToscaNodeTemplates() throws Exception {
+        Response rawResponse = createResource(NODE_TEMPLATES, TOSCA_NODE_TEMPLATE_RESOURCE, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
+        assertNotNull(response);
+        assertFalse(response.getToscaTopologyTemplate().getNodeTemplates().isEmpty());
+
+        // Send a node type with a invalid value to trigger an error
+        rawResponse = createResource(NODE_TEMPLATES, TOSCA_INVALID_NODE_TYPE, apiPort);
+        assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), rawResponse.getStatus());
+        ErrorResponse response2 = rawResponse.readEntity(ErrorResponse.class);
+        assertThat(response2.getErrorMessage())
+            .containsPattern("^NODE_TYPE .* for toscaNodeTemplate .* does not exist$");
+
+        // Send invalid tosca template with no node templates
+        rawResponse = createResource(NODE_TEMPLATES, TOSCA_INVALID_TEMPLATE, apiPort);
+        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
+        response2 = rawResponse.readEntity(ErrorResponse.class);
+        assertEquals("node templates not present on the service template", response2.getErrorMessage());
+    }
+
+
+    @Test
+    public void testReadNodeTemplates() throws Exception {
+        Response rawResponse = readResource(NODE_TEMPLATES, APP_JSON, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        List<?> nodeTemplates = rawResponse.readEntity(List.class);
+        assertNotNull(nodeTemplates);
+        assertEquals(0, nodeTemplates.size());
+
+        createResource(NODE_TEMPLATES, TOSCA_NODE_TEMPLATE_RESOURCE, apiPort);
+        rawResponse = readResource(NODE_TEMPLATES, APP_JSON, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        nodeTemplates = rawResponse.readEntity(List.class);
+        assertNotNull(nodeTemplates);
+        assertEquals(3, nodeTemplates.size());
+
+        rawResponse = readResource(SPECIFIC_NODE_TEMPLATE, APP_JSON, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        List<ToscaNodeTemplate> retrievedTemplate =
+            rawResponse.readEntity(new GenericType<List<ToscaNodeTemplate>>() {});
+        assertNotNull(nodeTemplates);
+        assertEquals(1, retrievedTemplate.size());
+        String retrievedTemplateName = retrievedTemplate.get(0).getName();
+        assertEquals("apexMetadata_adaptive", retrievedTemplateName);
+    }
+
+    @Test
+    public void testUpdateNodeTemplates() throws Exception {
+        createResource(NODE_TEMPLATES, TOSCA_NODE_TEMPLATE_RESOURCE, apiPort);
+        Response rawResponse = updateResource(NODE_TEMPLATES, TOSCA_UPDATE_NODE_TEMPLATES, APP_JSON, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
+        assertNotNull(response);
+        assertFalse(response.getToscaTopologyTemplate().getNodeTemplates().isEmpty());
+        String updatedValue = "" + response.getToscaTopologyTemplate().getNodeTemplates().get("apexMetadata_grpc")
+            .getMetadata().get("state");
+        assertEquals("passive", updatedValue);
+
+        rawResponse = updateResource(NODE_TEMPLATES, TOSCA_INVALID_NODE_TYPE, APP_JSON, apiPort);
+        assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), rawResponse.getStatus());
+        ErrorResponse response2 = rawResponse.readEntity(ErrorResponse.class);
+        assertThat(response2.getErrorMessage())
+            .containsPattern("^NODE_TYPE .* for toscaNodeTemplate .* does not exist$");
+
+        // Send invalid tosca template with no node templates
+        rawResponse = updateResource(NODE_TEMPLATES, TOSCA_INVALID_TEMPLATE, APP_JSON, apiPort);
+        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
+        ErrorResponse response3 = rawResponse.readEntity(ErrorResponse.class);
+        assertEquals("node templates not present on the service template", response3.getErrorMessage());
+    }
+
+    @Test
+    public void testDeleteNodeTemplates() throws Exception {
+        createResource(NODE_TEMPLATES, TOSCA_NODE_TEMPLATE_RESOURCE, apiPort);
+        Response rawResponse = deleteResource(SPECIFIC_NODE_TEMPLATE, APP_JSON, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        ToscaServiceTemplate response = rawResponse.readEntity(ToscaServiceTemplate.class);
+        assertNotNull(response);
+        assertFalse(response.getToscaTopologyTemplate().getNodeTemplates().isEmpty());
+
+        rawResponse = readResource(NODE_TEMPLATES, APP_JSON, apiPort);
+        assertEquals(Response.Status.OK.getStatusCode(), rawResponse.getStatus());
+        List<?> nodeTemplates = rawResponse.readEntity(List.class);
+        assertNotNull(nodeTemplates);
+        assertEquals(2, nodeTemplates.size());
+
+        // Send invalid id
+        rawResponse = deleteResource(INVALID_NODE_TEMPLATE_ID, APP_JSON, apiPort);
+        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rawResponse.getStatus());
+        ErrorResponse response3 = rawResponse.readEntity(ErrorResponse.class);
+        assertThat(response3.getErrorMessage()).containsPattern("^node template .* not found$");
+    }
+
+}
diff --git a/main/src/test/java/org/onap/policy/api/main/rest/utils/CommonTestRestController.java b/main/src/test/java/org/onap/policy/api/main/rest/utils/CommonTestRestController.java
new file mode 100644 (file)
index 0000000..9289adb
--- /dev/null
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy API
+ * ================================================================================
+ * Copyright (C) 2022 Nordix Foundation. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.api.main.rest.utils;
+
+import java.security.SecureRandom;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.StandardYamlCoder;
+import org.onap.policy.common.utils.network.NetworkUtil;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * Util class to perform REST unit tests.
+ *
+ */
+public class CommonTestRestController {
+
+    protected static final String APP_JSON = "application/json";
+    protected static final String APP_YAML = "application/yaml";
+
+    protected static final StandardCoder standardCoder = new StandardCoder();
+    protected static StandardYamlCoder standardYamlCoder = new StandardYamlCoder();
+
+
+    protected Response createResource(String endpoint, String resourceName, int apiPort)
+        throws Exception {
+
+        ToscaServiceTemplate rawServiceTemplate = getRawServiceTemplate(resourceName);
+        String mediaType = getMediaType(resourceName);
+        mediaType = mediaType == null ?  APP_JSON : mediaType;
+
+        final Invocation.Builder invocationBuilder;
+        invocationBuilder = sendHttpsRequest(endpoint, mediaType, apiPort);
+        Entity<ToscaServiceTemplate> entity = Entity.entity(rawServiceTemplate, mediaType);
+        return invocationBuilder.post(entity);
+    }
+
+    protected Response readResource(String endpoint, String mediaType, int apiPort) throws Exception {
+
+        final Invocation.Builder invocationBuilder;
+        invocationBuilder = sendHttpsRequest(endpoint, mediaType, apiPort);
+        return invocationBuilder.get();
+    }
+
+    protected Response deleteResource(String endpoint, String mediaType, int apiPort) throws Exception {
+
+        final Invocation.Builder invocationBuilder;
+        invocationBuilder = sendHttpsRequest(endpoint, mediaType, apiPort);
+        return invocationBuilder.delete();
+    }
+
+    protected Response updateResource(String endpoint, String resourceName, String mediaType, int apiPort)
+        throws Exception {
+
+        ToscaServiceTemplate rawServiceTemplate = getRawServiceTemplate(resourceName);
+
+        final Invocation.Builder invocationBuilder;
+        invocationBuilder = sendHttpsRequest(endpoint, mediaType, apiPort);
+        Entity<ToscaServiceTemplate> entity = Entity.entity(rawServiceTemplate, mediaType);
+        return invocationBuilder.put(entity);
+    }
+
+    protected ToscaServiceTemplate decodeJson(String resourceName) throws CoderException {
+        return standardCoder.decode(ResourceUtils.getResourceAsString(resourceName), ToscaServiceTemplate.class);
+    }
+
+    protected ToscaServiceTemplate decodeYaml(String resourceName) throws CoderException {
+        return standardYamlCoder.decode(ResourceUtils.getResourceAsString(resourceName), ToscaServiceTemplate.class);
+    }
+
+    protected Invocation.Builder sendHttpsRequest(final String endpoint, String mediaType, int apiPort)
+        throws Exception {
+
+        final TrustManager[] noopTrustManager = NetworkUtil.getAlwaysTrustingManager();
+
+        final SSLContext sc = SSLContext.getInstance("TLSv1.2");
+        sc.init(null, noopTrustManager, new SecureRandom());
+        final ClientBuilder clientBuilder =
+            ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier((host, session) -> true);
+        final Client client = clientBuilder.build();
+        final HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("policyadmin", "zb!XztG34");
+        client.register(feature);
+
+        client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+        if (APP_JSON.equalsIgnoreCase(mediaType)) {
+            client.register(GsonMessageBodyHandler.class);
+        } else if (APP_YAML.equalsIgnoreCase(mediaType)) {
+            client.register(YamlMessageBodyHandler.class);
+        }
+
+        final WebTarget webTarget = client.target("https://localhost:" + apiPort + "/policy/api/v1/" + endpoint);
+
+        final Invocation.Builder invocationBuilder = webTarget.request(mediaType);
+
+        if (!NetworkUtil.isTcpPortOpen("localhost", apiPort, 60, 1000L)) {
+            throw new IllegalStateException("cannot connect to port " + apiPort);
+        }
+        return invocationBuilder;
+    }
+
+    private ToscaServiceTemplate getRawServiceTemplate(String resourceName) throws CoderException {
+        ToscaServiceTemplate rawServiceTemplate = new ToscaServiceTemplate();
+        if (APP_JSON.equals(getMediaType(resourceName))) {
+            rawServiceTemplate = decodeJson(resourceName);
+        } else if (APP_YAML.equals(getMediaType(resourceName))) {
+            rawServiceTemplate = decodeYaml(resourceName);
+        }
+        return  rawServiceTemplate;
+    }
+
+    private String getMediaType(String resourceName) {
+        if (resourceName.endsWith(".json")) {
+            return APP_JSON;
+        } else if (resourceName.endsWith(".yaml") || resourceName.endsWith(".yml")) {
+            return APP_YAML;
+        }
+        return null;
+    }
+
+}
diff --git a/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.input.tosca.json b/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.input.tosca.json
new file mode 100644 (file)
index 0000000..88d69b3
--- /dev/null
@@ -0,0 +1,1578 @@
+{
+  "tosca_definitions_version": "tosca_simple_yaml_1_1_0",
+  "node_types": {
+    "org.onap.nodetypes.policy.MetadataSet": {
+      "derived_from": "tosca.nodetypes.Root",
+      "version": "1.0.0"
+    }
+  },
+
+  "topology_template": {
+    "node_templates": {
+      "apexMetadata_grpc": {
+        "version": "1.0.0",
+        "type": "org.onap.nodetypes.policy.MetadataSet",
+        "type_version": "1.0.0",
+        "description": "Metadata set for GRPC",
+        "metadata": {
+          "policyModel": {
+            "key": {
+              "name": "GrpcPolicyModel",
+              "version": "1.0.1"
+            }
+          },
+          "threshold": 3.14,
+          "state": "active"
+        }
+      },
+      "apexMetadata_adaptive": {
+        "version": "1.0.0",
+        "type": "org.onap.nodetypes.policy.MetadataSet",
+        "type_version": "1.0.0",
+        "description": "Metadata set for an Adaptive Policy",
+        "metadata": {
+          "policyModel": {
+            "key": {
+              "name": "AdaptivePolicyModel",
+              "version": "1.2.1"
+            }
+          },
+          "radius": 1.23,
+          "height": 2.13,
+          "length": 45
+        }
+      },
+      "apexMetadata_decisionMaker": {
+        "version": "1.0.0",
+        "type": "org.onap.nodetypes.policy.MetadataSet",
+        "type_version": "1.0.0",
+        "description": "Metadata set for an Adaptive Policy",
+        "metadata": {
+          "policyModel": {
+            "key": {
+              "name": "DecisionMakerPolicyModel",
+              "version": "1.0.0"
+            },
+            "keyInformation": {
+              "key": {
+                "name": "DecisionMakerPolicyModel_KeyInfo",
+                "version": "0.0.1"
+              },
+              "keyInfoMap": {
+                "entry": [
+                  {
+                    "key": {
+                      "name": "AnswerAlbum",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerAlbum",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "4ea21a2c-5dc7-337f-ba13-f427a4ae79a1",
+                      "description": "Generated description for concept referred to by key \"AnswerAlbum:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "AnswerEvent",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerEvent",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "ce2233b8-bb89-3c5e-a18f-1d13089d2bb6",
+                      "description": "Generated description for concept referred to by key \"AnswerEvent:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "AnswerInitPolicy",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerInitPolicy",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "c8254064-b171-3ccb-85c0-29b5719ee8fc",
+                      "description": "Generated description for concept referred to by key \"AnswerInitPolicy:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "AnswerInitTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerInitTask",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "28fb33d2-a4e0-3046-8302-7baf9a2056d1",
+                      "description": "Generated description for concept referred to by key \"AnswerInitTask:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionEvent",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionEvent",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "487acc75-b5a1-3285-90cf-98ecd6fb3500",
+                      "description": "Generated description for concept referred to by key \"DecisionEvent:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicy",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicy",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "9e8dda9a-6f85-311d-842b-00b5b5578edd",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicy:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "d7789464-e4d1-382e-8481-fba53fa7b9a9",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel_Albums",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel_Albums",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "e5dfbadd-5229-3ad9-996c-eda030ef5dc1",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel_Albums:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel_Events",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel_Events",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "b4248202-ff8e-3d45-8b3d-0ed0fd2eaed4",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel_Events:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel_KeyInfo",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel_KeyInfo",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "693b1b29-c4c6-34ba-98e1-bc1a7576f0f8",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel_KeyInfo:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel_Policies",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel_Policies",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "2dee1e42-9caa-32b1-9298-784dcdcb9cae",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel_Policies:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel_Schemas",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel_Schemas",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "c256f102-2681-3f35-bbbd-1f4948587e15",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel_Schemas:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicyModel_Tasks",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionMakerPolicyModel_Tasks",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "660cbdba-687d-3a05-ba26-69daf93a8158",
+                      "description": "Generated description for concept referred to by key \"DecisionMakerPolicyModel_Tasks:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DitheringAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DitheringAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "da31cee8-2e84-39d2-9337-9ee3bf347c98",
+                      "description": "Generated description for concept referred to by key \"DitheringAnswerTask:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "LastAnswerAlbum",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "LastAnswerAlbum",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "21399145-3fbe-39a5-b863-8a59a8add4a8",
+                      "description": "Generated description for concept referred to by key \"LastAnswerAlbum:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "MakeDecisionEvent",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "MakeDecisionEvent",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "02ec632a-aeae-31fe-8f6d-656e1875749f",
+                      "description": "Generated description for concept referred to by key \"MakeDecisionEvent:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "OptimisticAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "OptimisticAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "818e6b9e-0109-31f5-a95c-17f6fb016027",
+                      "description": "Generated description for concept referred to by key \"OptimisticAnswerTask:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "PessimisticAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "PessimisticAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "8f4a707e-0d8b-3e09-b921-332f6f81f302",
+                      "description": "Generated description for concept referred to by key \"PessimisticAnswerTask:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "RandomAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "RandomAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "bfb0af88-b454-3b08-911f-7ff2475350bf",
+                      "description": "Generated description for concept referred to by key \"RandomAnswerTask:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "RoundRobinAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "RoundRobinAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "eac6fb59-8aca-3011-b7ba-69875f1db4b6",
+                      "description": "Generated description for concept referred to by key \"RoundRobinAnswerTask:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "SimpleIntegerType",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "SimpleIntegerType",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "ab00a5b8-7edd-340f-8140-4d14f571edfb",
+                      "description": "Generated description for concept referred to by key \"SimpleIntegerType:0.0.1\""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "SimpleStringType",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "SimpleStringType",
+                        "version": "0.0.1"
+                      },
+                      "UUID": "8a4957cf-9493-3a76-8c22-a208e23259af",
+                      "description": "Generated description for concept referred to by key \"SimpleStringType:0.0.1\""
+                    }
+                  }
+                ]
+              }
+            },
+            "policies": {
+              "key": {
+                "name": "DecisionMakerPolicyModel_Policies",
+                "version": "0.0.1"
+              },
+              "policyMap": {
+                "entry": [
+                  {
+                    "key": {
+                      "name": "AnswerInitPolicy",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "policyKey": {
+                        "name": "AnswerInitPolicy",
+                        "version": "0.0.1"
+                      },
+                      "template": "freestyle",
+                      "state": {
+                        "entry": [
+                          {
+                            "key": "AnswerInitState",
+                            "value": {
+                              "stateKey": {
+                                "parentKeyName": "AnswerInitPolicy",
+                                "parentKeyVersion": "0.0.1",
+                                "parentLocalName": "NULL",
+                                "localName": "AnswerInitState"
+                              },
+                              "trigger": {
+                                "name": "AnswerEvent",
+                                "version": "0.0.1"
+                              },
+                              "stateOutputs": {
+                                "entry": [
+                                  {
+                                    "key": "AnswerInitOutput",
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "AnswerInitPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "AnswerInitState",
+                                        "localName": "AnswerInitOutput"
+                                      },
+                                      "outgoingEvent": {
+                                        "name": "AnswerEvent",
+                                        "version": "0.0.1"
+                                      },
+                                      "outgoingEventReference": [
+                                        {
+                                          "name": "AnswerEvent",
+                                          "version": "0.0.1"
+                                        }
+                                      ],
+                                      "nextState": {
+                                        "parentKeyName": "NULL",
+                                        "parentKeyVersion": "0.0.0",
+                                        "parentLocalName": "NULL",
+                                        "localName": "NULL"
+                                      }
+                                    }
+                                  }
+                                ]
+                              },
+                              "contextAlbumReference": [],
+                              "taskSelectionLogic": {
+                                "key": "NULL",
+                                "logicFlavour": "UNDEFINED",
+                                "logic": ""
+                              },
+                              "stateFinalizerLogicMap": {
+                                "entry": []
+                              },
+                              "defaultTask": {
+                                "name": "AnswerInitTask",
+                                "version": "0.0.1"
+                              },
+                              "taskReferences": {
+                                "entry": [
+                                  {
+                                    "key": {
+                                      "name": "AnswerInitTask",
+                                      "version": "0.0.1"
+                                    },
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "AnswerInitPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "AnswerInitState",
+                                        "localName": "AnswerInitPolicy"
+                                      },
+                                      "outputType": "DIRECT",
+                                      "output": {
+                                        "parentKeyName": "AnswerInitPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "AnswerInitState",
+                                        "localName": "AnswerInitOutput"
+                                      }
+                                    }
+                                  }
+                                ]
+                              }
+                            }
+                          }
+                        ]
+                      },
+                      "firstState": "AnswerInitState"
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionMakerPolicy",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "policyKey": {
+                        "name": "DecisionMakerPolicy",
+                        "version": "0.0.1"
+                      },
+                      "template": "freestyle",
+                      "state": {
+                        "entry": [
+                          {
+                            "key": "MakeDecisionState",
+                            "value": {
+                              "stateKey": {
+                                "parentKeyName": "DecisionMakerPolicy",
+                                "parentKeyVersion": "0.0.1",
+                                "parentLocalName": "NULL",
+                                "localName": "MakeDecisionState"
+                              },
+                              "trigger": {
+                                "name": "MakeDecisionEvent",
+                                "version": "0.0.1"
+                              },
+                              "stateOutputs": {
+                                "entry": [
+                                  {
+                                    "key": "DecisionFinalOutput",
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionFinalOutput"
+                                      },
+                                      "outgoingEvent": {
+                                        "name": "DecisionEvent",
+                                        "version": "0.0.1"
+                                      },
+                                      "outgoingEventReference": [
+                                        {
+                                          "name": "DecisionEvent",
+                                          "version": "0.0.1"
+                                        }
+                                      ],
+                                      "nextState": {
+                                        "parentKeyName": "NULL",
+                                        "parentKeyVersion": "0.0.0",
+                                        "parentLocalName": "NULL",
+                                        "localName": "NULL"
+                                      }
+                                    }
+                                  }
+                                ]
+                              },
+                              "contextAlbumReference": [],
+                              "taskSelectionLogic": {
+                                "key": "TaskSelectionLogic",
+                                "logicFlavour": "JAVASCRIPT",
+                                "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nif (executor.inFields.get(\"mode\").equals(\"random\")) {\n    executor.subject.getTaskKey(\"RandomAnswerTask\").copyTo(executor.selectedTask);\n}\nelse if (executor.inFields.get(\"mode\").equals(\"pessimistic\")) {\n    executor.subject.getTaskKey(\"PessimisticAnswerTask\").copyTo(executor.selectedTask);\n}\nelse if (executor.inFields.get(\"mode\").equals(\"optimistic\")) {\n    executor.subject.getTaskKey(\"OptimisticAnswerTask\").copyTo(executor.selectedTask);\n}\nelse if (executor.inFields.get(\"mode\").equals(\"dithering\")) {\n    executor.subject.getTaskKey(\"DitheringAnswerTask\").copyTo(executor.selectedTask);\n}\nelse if (executor.inFields.get(\"mode\").equals(\"roundrobin\")) {\n    executor.subject.getTaskKey(\"RoundRobinAnswerTask\").copyTo(executor.selectedTask);\n}\n\nexecutor.logger.info(\"Answer Selected Task:\" + executor.selectedTask);\n\ntrue;"
+                              },
+                              "stateFinalizerLogicMap": {
+                                "entry": []
+                              },
+                              "defaultTask": {
+                                "name": "RandomAnswerTask",
+                                "version": "0.0.1"
+                              },
+                              "taskReferences": {
+                                "entry": [
+                                  {
+                                    "key": {
+                                      "name": "DitheringAnswerTask",
+                                      "version": "0.0.1"
+                                    },
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionMakerPolicy"
+                                      },
+                                      "outputType": "DIRECT",
+                                      "output": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionFinalOutput"
+                                      }
+                                    }
+                                  },
+                                  {
+                                    "key": {
+                                      "name": "OptimisticAnswerTask",
+                                      "version": "0.0.1"
+                                    },
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionMakerPolicy"
+                                      },
+                                      "outputType": "DIRECT",
+                                      "output": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionFinalOutput"
+                                      }
+                                    }
+                                  },
+                                  {
+                                    "key": {
+                                      "name": "PessimisticAnswerTask",
+                                      "version": "0.0.1"
+                                    },
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionMakerPolicy"
+                                      },
+                                      "outputType": "DIRECT",
+                                      "output": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionFinalOutput"
+                                      }
+                                    }
+                                  },
+                                  {
+                                    "key": {
+                                      "name": "RandomAnswerTask",
+                                      "version": "0.0.1"
+                                    },
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionMakerPolicy"
+                                      },
+                                      "outputType": "DIRECT",
+                                      "output": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionFinalOutput"
+                                      }
+                                    }
+                                  },
+                                  {
+                                    "key": {
+                                      "name": "RoundRobinAnswerTask",
+                                      "version": "0.0.1"
+                                    },
+                                    "value": {
+                                      "key": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionMakerPolicy"
+                                      },
+                                      "outputType": "DIRECT",
+                                      "output": {
+                                        "parentKeyName": "DecisionMakerPolicy",
+                                        "parentKeyVersion": "0.0.1",
+                                        "parentLocalName": "MakeDecisionState",
+                                        "localName": "DecisionFinalOutput"
+                                      }
+                                    }
+                                  }
+                                ]
+                              }
+                            }
+                          }
+                        ]
+                      },
+                      "firstState": "MakeDecisionState"
+                    }
+                  }
+                ]
+              }
+            },
+            "tasks": {
+              "key": {
+                "name": "DecisionMakerPolicyModel_Tasks",
+                "version": "0.0.1"
+              },
+              "taskMap": {
+                "entry": [
+                  {
+                    "key": {
+                      "name": "AnswerInitTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerInitTask",
+                        "version": "0.0.1"
+                      },
+                      "inputEvent": {
+                        "key": {
+                          "name": "AnswerEvent",
+                          "version": "0.0.1"
+                        },
+                        "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                        "source": "DCAE",
+                        "target": "apex",
+                        "parameter": {
+                          "entry": [
+                            {
+                              "key": "a0",
+                              "value": {
+                                "key": "a0",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            },
+                            {
+                              "key": "a1",
+                              "value": {
+                                "key": "a1",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            },
+                            {
+                              "key": "a2",
+                              "value": {
+                                "key": "a2",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            },
+                            {
+                              "key": "a3",
+                              "value": {
+                                "key": "a3",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            },
+                            {
+                              "key": "a4",
+                              "value": {
+                                "key": "a4",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            },
+                            {
+                              "key": "a5",
+                              "value": {
+                                "key": "a5",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            },
+                            {
+                              "key": "a6",
+                              "value": {
+                                "key": "a6",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            }
+                          ]
+                        },
+                        "toscaPolicyState": ""
+                      },
+                      "outputEvents": {
+                        "entry": [
+                          {
+                            "key": "AnswerEvent",
+                            "value": {
+                              "key": {
+                                "name": "AnswerEvent",
+                                "version": "0.0.1"
+                              },
+                              "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                              "source": "DCAE",
+                              "target": "apex",
+                              "parameter": {
+                                "entry": [
+                                  {
+                                    "key": "a0",
+                                    "value": {
+                                      "key": "a0",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  },
+                                  {
+                                    "key": "a1",
+                                    "value": {
+                                      "key": "a1",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  },
+                                  {
+                                    "key": "a2",
+                                    "value": {
+                                      "key": "a2",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  },
+                                  {
+                                    "key": "a3",
+                                    "value": {
+                                      "key": "a3",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  },
+                                  {
+                                    "key": "a4",
+                                    "value": {
+                                      "key": "a4",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  },
+                                  {
+                                    "key": "a5",
+                                    "value": {
+                                      "key": "a5",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  },
+                                  {
+                                    "key": "a6",
+                                    "value": {
+                                      "key": "a6",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  }
+                                ]
+                              },
+                              "toscaPolicyState": ""
+                            }
+                          }
+                        ]
+                      },
+                      "taskParameters": {
+                        "entry": []
+                      },
+                      "contextAlbumReference": [
+                        {
+                          "name": "AnswerAlbum",
+                          "version": "0.0.1"
+                        },
+                        {
+                          "name": "LastAnswerAlbum",
+                          "version": "0.0.1"
+                        }
+                      ],
+                      "taskLogic": {
+                        "key": "TaskLogic",
+                        "logicFlavour": "JAVASCRIPT",
+                        "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar answerAlbum = executor.getContextAlbum(\"AnswerAlbum\");\n\nanswerAlbum.put(\"a0\", executor.inFields.get(\"a0\"));\nanswerAlbum.put(\"a1\", executor.inFields.get(\"a1\"));\nanswerAlbum.put(\"a2\", executor.inFields.get(\"a2\"));\nanswerAlbum.put(\"a3\", executor.inFields.get(\"a3\"));\nanswerAlbum.put(\"a4\", executor.inFields.get(\"a4\"));\nanswerAlbum.put(\"a5\", executor.inFields.get(\"a5\"));\nanswerAlbum.put(\"a6\", executor.inFields.get(\"a6\"));\n\nvar lastAnswerAlbum = executor.getContextAlbum(\"LastAnswerAlbum\");\nlastAnswerAlbum.put(\"lastAnswer\", answerAlbum.size() - 1);\n\nexecutor.outFields.put(\"a0\", answerAlbum.get(\"a0\"));\nexecutor.outFields.put(\"a1\", answerAlbum.get(\"a1\"));\nexecutor.outFields.put(\"a2\", answerAlbum.get(\"a2\"));\nexecutor.outFields.put(\"a3\", answerAlbum.get(\"a3\"));\nexecutor.outFields.put(\"a4\", answerAlbum.get(\"a4\"));\nexecutor.outFields.put(\"a5\", answerAlbum.get(\"a5\"));\nexecutor.outFields.put(\"a6\", answerAlbum.get(\"a6\"));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+                      }
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DitheringAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DitheringAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "inputEvent": {
+                        "key": {
+                          "name": "MakeDecisionEvent",
+                          "version": "0.0.1"
+                        },
+                        "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                        "source": "DCAE",
+                        "target": "apex",
+                        "parameter": {
+                          "entry": [
+                            {
+                              "key": "mode",
+                              "value": {
+                                "key": "mode",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            }
+                          ]
+                        },
+                        "toscaPolicyState": ""
+                      },
+                      "outputEvents": {
+                        "entry": [
+                          {
+                            "key": "DecisionEvent",
+                            "value": {
+                              "key": {
+                                "name": "DecisionEvent",
+                                "version": "0.0.1"
+                              },
+                              "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                              "source": "DCAE",
+                              "target": "apex",
+                              "parameter": {
+                                "entry": [
+                                  {
+                                    "key": "decision",
+                                    "value": {
+                                      "key": "decision",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  }
+                                ]
+                              },
+                              "toscaPolicyState": ""
+                            }
+                          }
+                        ]
+                      },
+                      "taskParameters": {
+                        "entry": []
+                      },
+                      "contextAlbumReference": [
+                        {
+                          "name": "AnswerAlbum",
+                          "version": "0.0.1"
+                        }
+                      ],
+                      "taskLogic": {
+                        "key": "TaskLogic",
+                        "logicFlavour": "JAVASCRIPT",
+                        "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar size = executor.getContextAlbum(\"AnswerAlbum\").size();\n\nvar selection = 2 + Math.floor(Math.random() * 3);\n\nvar selectionA = \"a\" + selection;\n\nexecutor.logger.info(size);\nexecutor.logger.info(selectionA);\n\nexecutor.outFields.put(\"decision\", executor.getContextAlbum(\"AnswerAlbum\").get(selectionA));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+                      }
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "OptimisticAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "OptimisticAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "inputEvent": {
+                        "key": {
+                          "name": "MakeDecisionEvent",
+                          "version": "0.0.1"
+                        },
+                        "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                        "source": "DCAE",
+                        "target": "apex",
+                        "parameter": {
+                          "entry": [
+                            {
+                              "key": "mode",
+                              "value": {
+                                "key": "mode",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            }
+                          ]
+                        },
+                        "toscaPolicyState": ""
+                      },
+                      "outputEvents": {
+                        "entry": [
+                          {
+                            "key": "DecisionEvent",
+                            "value": {
+                              "key": {
+                                "name": "DecisionEvent",
+                                "version": "0.0.1"
+                              },
+                              "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                              "source": "DCAE",
+                              "target": "apex",
+                              "parameter": {
+                                "entry": [
+                                  {
+                                    "key": "decision",
+                                    "value": {
+                                      "key": "decision",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  }
+                                ]
+                              },
+                              "toscaPolicyState": ""
+                            }
+                          }
+                        ]
+                      },
+                      "taskParameters": {
+                        "entry": []
+                      },
+                      "contextAlbumReference": [
+                        {
+                          "name": "AnswerAlbum",
+                          "version": "0.0.1"
+                        }
+                      ],
+                      "taskLogic": {
+                        "key": "TaskLogic",
+                        "logicFlavour": "JAVASCRIPT",
+                        "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar size = executor.getContextAlbum(\"AnswerAlbum\").size();\n\nvar selection = size - Math.floor(Math.random() * size / 2) - 1;\n\nvar selectionA = \"a\" + selection;\n\nexecutor.logger.info(size);\nexecutor.logger.info(selectionA);\n\nexecutor.outFields.put(\"decision\", executor.getContextAlbum(\"AnswerAlbum\").get(selectionA));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+                      }
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "PessimisticAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "PessimisticAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "inputEvent": {
+                        "key": {
+                          "name": "MakeDecisionEvent",
+                          "version": "0.0.1"
+                        },
+                        "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                        "source": "DCAE",
+                        "target": "apex",
+                        "parameter": {
+                          "entry": [
+                            {
+                              "key": "mode",
+                              "value": {
+                                "key": "mode",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            }
+                          ]
+                        },
+                        "toscaPolicyState": ""
+                      },
+                      "outputEvents": {
+                        "entry": [
+                          {
+                            "key": "DecisionEvent",
+                            "value": {
+                              "key": {
+                                "name": "DecisionEvent",
+                                "version": "0.0.1"
+                              },
+                              "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                              "source": "DCAE",
+                              "target": "apex",
+                              "parameter": {
+                                "entry": [
+                                  {
+                                    "key": "decision",
+                                    "value": {
+                                      "key": "decision",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  }
+                                ]
+                              },
+                              "toscaPolicyState": ""
+                            }
+                          }
+                        ]
+                      },
+                      "taskParameters": {
+                        "entry": []
+                      },
+                      "contextAlbumReference": [
+                        {
+                          "name": "AnswerAlbum",
+                          "version": "0.0.1"
+                        }
+                      ],
+                      "taskLogic": {
+                        "key": "TaskLogic",
+                        "logicFlavour": "JAVASCRIPT",
+                        "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar size = executor.getContextAlbum(\"AnswerAlbum\").size();\n\nvar selection = Math.floor(Math.random() * size / 2);\n\nvar selectionA = \"a\" + selection;\n\nexecutor.logger.info(size);\nexecutor.logger.info(selectionA);\n\nexecutor.outFields.put(\"decision\", executor.getContextAlbum(\"AnswerAlbum\").get(selectionA));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+                      }
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "RandomAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "RandomAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "inputEvent": {
+                        "key": {
+                          "name": "MakeDecisionEvent",
+                          "version": "0.0.1"
+                        },
+                        "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                        "source": "DCAE",
+                        "target": "apex",
+                        "parameter": {
+                          "entry": [
+                            {
+                              "key": "mode",
+                              "value": {
+                                "key": "mode",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            }
+                          ]
+                        },
+                        "toscaPolicyState": ""
+                      },
+                      "outputEvents": {
+                        "entry": [
+                          {
+                            "key": "DecisionEvent",
+                            "value": {
+                              "key": {
+                                "name": "DecisionEvent",
+                                "version": "0.0.1"
+                              },
+                              "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                              "source": "DCAE",
+                              "target": "apex",
+                              "parameter": {
+                                "entry": [
+                                  {
+                                    "key": "decision",
+                                    "value": {
+                                      "key": "decision",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  }
+                                ]
+                              },
+                              "toscaPolicyState": ""
+                            }
+                          }
+                        ]
+                      },
+                      "taskParameters": {
+                        "entry": []
+                      },
+                      "contextAlbumReference": [
+                        {
+                          "name": "AnswerAlbum",
+                          "version": "0.0.1"
+                        }
+                      ],
+                      "taskLogic": {
+                        "key": "TaskLogic",
+                        "logicFlavour": "JAVASCRIPT",
+                        "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar size = executor.getContextAlbum(\"AnswerAlbum\").size();\n\nvar selection = Math.floor(Math.random() * size);\n\nvar selectionA = \"a\" + selection;\n\nexecutor.logger.info(size);\nexecutor.logger.info(selectionA);\n\nexecutor.outFields.put(\"decision\", executor.getContextAlbum(\"AnswerAlbum\").get(selectionA));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+                      }
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "RoundRobinAnswerTask",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "RoundRobinAnswerTask",
+                        "version": "0.0.1"
+                      },
+                      "inputEvent": {
+                        "key": {
+                          "name": "MakeDecisionEvent",
+                          "version": "0.0.1"
+                        },
+                        "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                        "source": "DCAE",
+                        "target": "apex",
+                        "parameter": {
+                          "entry": [
+                            {
+                              "key": "mode",
+                              "value": {
+                                "key": "mode",
+                                "fieldSchemaKey": {
+                                  "name": "SimpleStringType",
+                                  "version": "0.0.1"
+                                },
+                                "optional": false
+                              }
+                            }
+                          ]
+                        },
+                        "toscaPolicyState": ""
+                      },
+                      "outputEvents": {
+                        "entry": [
+                          {
+                            "key": "DecisionEvent",
+                            "value": {
+                              "key": {
+                                "name": "DecisionEvent",
+                                "version": "0.0.1"
+                              },
+                              "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                              "source": "DCAE",
+                              "target": "apex",
+                              "parameter": {
+                                "entry": [
+                                  {
+                                    "key": "decision",
+                                    "value": {
+                                      "key": "decision",
+                                      "fieldSchemaKey": {
+                                        "name": "SimpleStringType",
+                                        "version": "0.0.1"
+                                      },
+                                      "optional": false
+                                    }
+                                  }
+                                ]
+                              },
+                              "toscaPolicyState": ""
+                            }
+                          }
+                        ]
+                      },
+                      "taskParameters": {
+                        "entry": []
+                      },
+                      "contextAlbumReference": [
+                        {
+                          "name": "AnswerAlbum",
+                          "version": "0.0.1"
+                        },
+                        {
+                          "name": "LastAnswerAlbum",
+                          "version": "0.0.1"
+                        }
+                      ],
+                      "taskLogic": {
+                        "key": "TaskLogic",
+                        "logicFlavour": "JAVASCRIPT",
+                        "logic": "/*\n * ============LICENSE_START=======================================================\n *  Copyright (C) 2016-2018 Ericsson. All rights reserved.\n *  Modifications Copyright (C) 2020 Nordix Foundation.\n * ================================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * SPDX-License-Identifier: Apache-2.0\n * ============LICENSE_END=========================================================\n */\n\nexecutor.logger.info(executor.subject.id);\nexecutor.logger.info(executor.inFields);\n\nvar size = executor.getContextAlbum(\"AnswerAlbum\").size();\nvar lastAnswer = executor.getContextAlbum(\"LastAnswerAlbum\").get(\"lastAnswer\");\n\nexecutor.logger.info(size);\nexecutor.logger.info(lastAnswer);\n\nvar answer = ++lastAnswer;\nif (answer >= size) {\n    answer = 0;\n}\n\nexecutor.getContextAlbum(\"LastAnswerAlbum\").put(\"lastAnswer\", answer)\n\nvar selectionA = \"a\" + answer;\n\nexecutor.logger.info(selectionA);\n\nexecutor.outFields.put(\"decision\", executor.getContextAlbum(\"AnswerAlbum\").get(selectionA));\n\nexecutor.logger.info(executor.outFields);\n\ntrue;"
+                      }
+                    }
+                  }
+                ]
+              }
+            },
+            "events": {
+              "key": {
+                "name": "DecisionMakerPolicyModel_Events",
+                "version": "0.0.1"
+              },
+              "eventMap": {
+                "entry": [
+                  {
+                    "key": {
+                      "name": "AnswerEvent",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerEvent",
+                        "version": "0.0.1"
+                      },
+                      "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                      "source": "DCAE",
+                      "target": "apex",
+                      "parameter": {
+                        "entry": [
+                          {
+                            "key": "a0",
+                            "value": {
+                              "key": "a0",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          },
+                          {
+                            "key": "a1",
+                            "value": {
+                              "key": "a1",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          },
+                          {
+                            "key": "a2",
+                            "value": {
+                              "key": "a2",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          },
+                          {
+                            "key": "a3",
+                            "value": {
+                              "key": "a3",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          },
+                          {
+                            "key": "a4",
+                            "value": {
+                              "key": "a4",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          },
+                          {
+                            "key": "a5",
+                            "value": {
+                              "key": "a5",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          },
+                          {
+                            "key": "a6",
+                            "value": {
+                              "key": "a6",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          }
+                        ]
+                      },
+                      "toscaPolicyState": ""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "DecisionEvent",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "DecisionEvent",
+                        "version": "0.0.1"
+                      },
+                      "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                      "source": "DCAE",
+                      "target": "apex",
+                      "parameter": {
+                        "entry": [
+                          {
+                            "key": "decision",
+                            "value": {
+                              "key": "decision",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          }
+                        ]
+                      },
+                      "toscaPolicyState": ""
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "MakeDecisionEvent",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "MakeDecisionEvent",
+                        "version": "0.0.1"
+                      },
+                      "nameSpace": "org.onap.policy.apex.domains.decisionmaker",
+                      "source": "DCAE",
+                      "target": "apex",
+                      "parameter": {
+                        "entry": [
+                          {
+                            "key": "mode",
+                            "value": {
+                              "key": "mode",
+                              "fieldSchemaKey": {
+                                "name": "SimpleStringType",
+                                "version": "0.0.1"
+                              },
+                              "optional": false
+                            }
+                          }
+                        ]
+                      },
+                      "toscaPolicyState": ""
+                    }
+                  }
+                ]
+              }
+            },
+            "albums": {
+              "key": {
+                "name": "DecisionMakerPolicyModel_Albums",
+                "version": "0.0.1"
+              },
+              "albums": {
+                "entry": [
+                  {
+                    "key": {
+                      "name": "AnswerAlbum",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "AnswerAlbum",
+                        "version": "0.0.1"
+                      },
+                      "scope": "policy",
+                      "isWritable": true,
+                      "itemSchema": {
+                        "name": "SimpleStringType",
+                        "version": "0.0.1"
+                      }
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "LastAnswerAlbum",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "LastAnswerAlbum",
+                        "version": "0.0.1"
+                      },
+                      "scope": "policy",
+                      "isWritable": true,
+                      "itemSchema": {
+                        "name": "SimpleIntegerType",
+                        "version": "0.0.1"
+                      }
+                    }
+                  }
+                ]
+              }
+            },
+            "schemas": {
+              "key": {
+                "name": "DecisionMakerPolicyModel_Schemas",
+                "version": "0.0.1"
+              },
+              "schemas": {
+                "entry": [
+                  {
+                    "key": {
+                      "name": "SimpleIntegerType",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "SimpleIntegerType",
+                        "version": "0.0.1"
+                      },
+                      "schemaFlavour": "Java",
+                      "schemaDefinition": "java.lang.Integer"
+                    }
+                  },
+                  {
+                    "key": {
+                      "name": "SimpleStringType",
+                      "version": "0.0.1"
+                    },
+                    "value": {
+                      "key": {
+                        "name": "SimpleStringType",
+                        "version": "0.0.1"
+                      },
+                      "schemaFlavour": "Java",
+                      "schemaDefinition": "java.lang.String"
+                    }
+                  }
+                ]
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.invalid.nodetype.json b/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.invalid.nodetype.json
new file mode 100644 (file)
index 0000000..9d63e2c
--- /dev/null
@@ -0,0 +1,25 @@
+{
+  "tosca_definitions_version": "tosca_simple_yaml_1_1_0",
+  "topology_template": {
+    "node_templates": {
+      "apexMetadata_adaptive": {
+        "version": "1.0.0",
+        "type": "org.onap.nodetypes.policy.invalid",
+        "type_version": "1.0.1",
+        "description": "Metadata set for an Adaptive Policy",
+        "metadata": {
+          "policyModel": {
+            "key": {
+              "name": "AdaptivePolicyModel",
+              "version": "1.2.2"
+            }
+          },
+          "radius": 1.23,
+          "height": 2.13,
+          "length": 46
+        }
+      }
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.no.nodetemplate.json b/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.no.nodetemplate.json
new file mode 100644 (file)
index 0000000..6aea446
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "tosca_definitions_version": "tosca_simple_yaml_1_1_0",
+  "topology_template": {
+  }
+}
\ No newline at end of file
diff --git a/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json b/main/src/test/resources/nodetemplates/nodetemplates.metadatasets.update.json
new file mode 100644 (file)
index 0000000..767f1fb
--- /dev/null
@@ -0,0 +1,30 @@
+{
+  "tosca_definitions_version": "tosca_simple_yaml_1_1_0",
+  "node_types": {
+    "org.onap.nodetypes.policy.MetadataSet": {
+      "derived_from": "tosca.nodetypes.Root",
+      "version": "1.0.0"
+    }
+  },
+
+  "topology_template": {
+    "node_templates": {
+      "apexMetadata_grpc": {
+        "version": "1.0.0",
+        "type": "org.onap.nodetypes.policy.MetadataSet",
+        "type_version": "1.0.0",
+        "description": "Metadata set for GRPC",
+        "metadata": {
+          "policyModel": {
+            "key": {
+              "name": "GrpcPolicyModel",
+              "version": "1.0.2"
+            }
+          },
+          "threshold": 3.15,
+          "state": "passive"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file