diff options
6 files changed, 284 insertions, 23 deletions
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java index f291c4e89..e5dccde7b 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java @@ -252,7 +252,8 @@ public class CommissioningProvider implements Closeable { mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaTopologyTemplate.class), visitor); break; case "node_templates": - mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaNodeTemplate.class), visitor); + mapper.acceptJsonFormatVisitor(mapper.getTypeFactory() + .constructCollectionType(List.class, ToscaNodeTemplate.class), visitor); break; default: mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaServiceTemplate.class), visitor); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java index b50e7a0ed..74548e724 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java @@ -23,8 +23,6 @@ package org.onap.policy.clamp.controlloop.runtime.main.rest; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.module.jsonSchema.JsonSchema; -import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; @@ -347,15 +345,24 @@ public class CommissioningController extends AbstractRestController { required = false) String version) { try { - return ResponseEntity.ok().body(provider.getToscaServiceTemplate(name, version)); + ObjectMapper mapper = new ObjectMapper(); + mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); + String response = mapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(provider.getToscaServiceTemplate(name, version)); + + return ResponseEntity.ok().body(response); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Get of tosca service template failed", e); var resp = new CommissioningResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); + } catch (JsonProcessingException e) { + LOGGER.warn("Get of tosca service template failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getMessage()); + return ResponseEntity.status(Status.BAD_REQUEST.getStatusCode()).body(resp); } - } /** diff --git a/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml b/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml index 8a7523c2b..3addb55f8 100644 --- a/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml +++ b/runtime/src/main/resources/clds/camel/rest/clamp-api-v2.xml @@ -1475,7 +1475,7 @@ <constant>application/json</constant> </setHeader> <setProperty name="raiseHttpExceptionFlag"> - <simple resultType="java.lang.Boolean">true</simple> + <simple resultType="java.lang.Boolean">false</simple> </setProperty> <to uri="direct:get-service-template"/> <to @@ -1509,7 +1509,7 @@ <route> <removeHeaders pattern="*"/> <setProperty name="raiseHttpExceptionFlag"> - <simple resultType="java.lang.Boolean">true</simple> + <simple resultType="java.lang.Boolean">false</simple> </setProperty> <setHeader name="Content-Type"> <constant>application/json</constant> @@ -1543,6 +1543,50 @@ </route> </post> + <delete uri="/v2/toscaControlLoop/decommissionToscaTemplate" + type="java.lang.String" + consumes="plain/text" + outType="java.lang.String" + produces="application/json" + bindingMode="off"> + <route> + <removeHeaders pattern="*" + excludePattern="name|version|requestId"/> + <setProperty name="raiseHttpExceptionFlag"> + <simple resultType="java.lang.Boolean">true</simple> + </setProperty> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <doTry> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'Delete Tosca Service Template')"/> + <to + uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')"/> + <to uri="direct:decommission-service-template"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=endLog()"/> + <doCatch> + <exception>java.lang.Exception</exception> + <handled> + <constant>true</constant> + </handled> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/> + <log loggingLevel="ERROR" + message="Decommissioning of Tosca Service Template FAILED"/> + + <setHeader name="CamelHttpResponseCode"> + <constant>500</constant> + </setHeader> + <setBody> + <simple>Decommissioning Tosca Service Template FAILED</simple> + </setBody> + </doCatch> + </doTry> + </route> + </delete> + <get uri="/v2/toscaControlLoop/getToscaInstantiation" outType="java.lang.String" bindingMode="off" produces="application/json"> <route> <doTry> @@ -1610,6 +1654,76 @@ </route> </get> + <get uri="/v2/toscaControlLoop/getElementDefinitions" outType="java.lang.String" bindingMode="off" produces="application/json"> + <route> + <removeHeaders pattern="*" + excludePattern="name|version|requestId"/> + <doTry> + <to uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'GET Json Schema ')"/> + <to uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','read')"/> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <setProperty name="raiseHttpExceptionFlag"> + <simple resultType="java.lang.Boolean">true</simple> + </setProperty> + <to uri="direct:get-element-definitions"/> + <to uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=endLog()"/> + <doCatch> + <exception>java.lang.Exception</exception> + <handled> + <constant>true</constant> + </handled> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/> + <log loggingLevel="ERROR" + message="GET Element Definitions request failed: ${exception.stacktrace}"/> + <setHeader name="CamelHttpResponseCode"> + <constant>500</constant> + </setHeader> + <setBody> + <simple>GET JSON Schema FAILED</simple> + </setBody> + </doCatch> + </doTry> + </route> + </get> + + <get uri="/v2/toscaControlLoop/getControlLoopDefinitions" outType="java.lang.String" bindingMode="off" produces="application/json"> + <route> + <removeHeaders pattern="*" + excludePattern="name|version|requestId"/> + <doTry> + <to uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=startLog(*, 'GET Json Schema ')"/> + <to uri="bean:org.onap.policy.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','read')"/> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <setProperty name="raiseHttpExceptionFlag"> + <simple resultType="java.lang.Boolean">true</simple> + </setProperty> + <to uri="direct:get-control-loop-definitions"/> + <to uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=endLog()"/> + <doCatch> + <exception>java.lang.Exception</exception> + <handled> + <constant>true</constant> + </handled> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=errorLog()"/> + <log loggingLevel="ERROR" + message="GET Control Loop Definitions request failed: ${exception.stacktrace}"/> + <setHeader name="CamelHttpResponseCode"> + <constant>500</constant> + </setHeader> + <setBody> + <simple>GET Control Loop Definitions FAILED</simple> + </setBody> + </doCatch> + </doTry> + </route> + </get> + <post uri="/v2/toscaControlLoop/postToscaInstantiation" type="java.lang.String" consumes="plain/text" diff --git a/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml b/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml index a888d6bf0..c33aa5924 100644 --- a/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml +++ b/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml @@ -54,6 +54,37 @@ </doFinally> </doTry> </route> + <route id="decommission-service-template"> + <from uri="direct:decommission-service-template"/> + <doTry> + <log loggingLevel="INFO" + message="Decommissioning the tosca service template"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('Controlloop', 'Decommissioning the tosca service template')"/> + <setHeader name="CamelHttpMethod"> + <constant>DELETE</constant> + </setHeader> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <setProperty name="name"> + <simple>${header.name}</simple> + </setProperty> + <setProperty name="version"> + <simple>${header.version}</simple> + </setProperty> + <log loggingLevel="INFO" + message="Endpoint to send Tosca Service Template: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission"></log> + <toD + uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission?name=${exchangeProperty[name]}&version=${exchangeProperty[version]}&bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.controlloop.runtime.userName}}&authPassword={{clamp.config.controlloop.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> + <convertBodyTo type="java.lang.String"/> + <doFinally> + <to uri="direct:reset-raise-http-exception-flag"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeReturnLog()"/> + </doFinally> + </doTry> + </route> <route id="get-tosca-instantiation"> <from uri="direct:get-tosca-instantiation"/> <doTry> @@ -132,4 +163,54 @@ </doFinally> </doTry> </route> + <route id="get-element-definitions"> + <from uri="direct:get-element-definitions"/> + <doTry> + <log loggingLevel="INFO" + message="Getting the Control Loop Element Definitions"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('ControlLoop', 'Getting the Controlloop Element Definitions')"/> + <setHeader name="CamelHttpMethod"> + <constant>GET</constant> + </setHeader> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <log loggingLevel="INFO" + message="Endpoint to get Json Schema: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission/elements"></log> + <toD + uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission/elements?bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.controlloop.runtime.userName}}&authPassword={{clamp.config.controlloop.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> + <convertBodyTo type="java.lang.String"/> + <doFinally> + <to uri="direct:reset-raise-http-exception-flag"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeReturnLog()"/> + </doFinally> + </doTry> + </route> + <route id="get-control-loop-definitions"> + <from uri="direct:get-control-loop-definitions"/> + <doTry> + <log loggingLevel="INFO" + message="Getting the Control Loop Definitions"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('ControlLoop', 'Getting the Controlloop Element Definitions')"/> + <setHeader name="CamelHttpMethod"> + <constant>GET</constant> + </setHeader> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <log loggingLevel="INFO" + message="Endpoint to get Json Schema: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission/elements"></log> + <toD + uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission? bridgeEndpoint=true&useSystemProperties=true&throwExceptionOnFailure=${exchangeProperty[raiseHttpExceptionFlag]}&authMethod=Basic&authUsername={{clamp.config.controlloop.runtime.userName}}&authPassword={{clamp.config.controlloop.runtime.password}}&authenticationPreemptive=true&connectionClose=true"/> + <convertBodyTo type="java.lang.String"/> + <doFinally> + <to uri="direct:reset-raise-http-exception-flag"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeReturnLog()"/> + </doFinally> + </doTry> + </route> </routes> diff --git a/runtime/src/test/java/org/onap/policy/clamp/runtime/RuntimeCommissioningResponseTestItCase.java b/runtime/src/test/java/org/onap/policy/clamp/runtime/RuntimeCommissioningResponseTestItCase.java index 7616d7a49..a1eaf27d0 100644 --- a/runtime/src/test/java/org/onap/policy/clamp/runtime/RuntimeCommissioningResponseTestItCase.java +++ b/runtime/src/test/java/org/onap/policy/clamp/runtime/RuntimeCommissioningResponseTestItCase.java @@ -102,4 +102,49 @@ public class RuntimeCommissioningResponseTestItCase { assertThat(HttpStatus.valueOf((Integer) exchangeResponse.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)) .is2xxSuccessful()).isTrue(); } + + @Test + public void testDecommissioningOfToscaServiceTemplateStatus() { + ProducerTemplate prodTemplate = camelContext.createProducerTemplate(); + + Exchange exchangeResponse = + prodTemplate.send("direct:decommission-service-template", ExchangeBuilder.anExchange(camelContext) + .withProperty("name", "ToscaServiceTemplate") + .withProperty("version", "1.0.0") + .withProperty("raiseHttpExceptionFlag", "true") + .build()); + + assertThat(HttpStatus.valueOf((Integer) exchangeResponse.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)) + .is2xxSuccessful()).isTrue(); + } + + @Test + public void testGetControlLoopDefinitions() { + ProducerTemplate prodTemplate = camelContext.createProducerTemplate(); + + Exchange exchangeResponse = + prodTemplate.send("direct:get-control-loop-definitions", ExchangeBuilder.anExchange(camelContext) + .withProperty("name", "ToscaServiceTemplate") + .withProperty("version", "1.0.0") + .withProperty("raiseHttpExceptionFlag", "true") + .build()); + + assertThat(HttpStatus.valueOf((Integer) exchangeResponse.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)) + .is2xxSuccessful()).isTrue(); + } + + @Test + public void testGetControlLoopElementDefinitions() { + ProducerTemplate prodTemplate = camelContext.createProducerTemplate(); + + Exchange exchangeResponse = + prodTemplate.send("direct:get-element-definitions", ExchangeBuilder.anExchange(camelContext) + .withProperty("name", "ToscaServiceTemplate") + .withProperty("version", "1.0.0") + .withProperty("raiseHttpExceptionFlag", "true") + .build()); + + assertThat(HttpStatus.valueOf((Integer) exchangeResponse.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)) + .is2xxSuccessful()).isTrue(); + } } diff --git a/runtime/src/test/resources/http-cache/third_party_proxy.py b/runtime/src/test/resources/http-cache/third_party_proxy.py index 1aaf4024d..2a28c65d3 100644 --- a/runtime/src/test/resources/http-cache/third_party_proxy.py +++ b/runtime/src/test/resources/http-cache/third_party_proxy.py @@ -107,6 +107,15 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): def _get_cached_header_file_name(self,cached_file_folder): return "%s/.header" % (cached_file_folder,) + def _create_cache(self, generated_json, cached_file_folder, cached_file_header, cached_file_content): + print "jsonGenerated: " + generated_json + if not os.path.exists(cached_file_folder): + os.makedirs(cached_file_folder, 0775) + with open(cached_file_header, 'w+') as f: + f.write("{\"Content-Length\": \"" + str(len(generated_json)) + "\", \"Content-Type\": \"application/json\"}") + with open(cached_file_content, 'w+') as f: + f.write(generated_json) + def _execute_content_generated_cases(self,http_type): print("Testing special cases, cache files will be sent to :" +TMP_ROOT) cached_file_folder = self._get_cached_file_folder_name(TMP_ROOT) @@ -274,14 +283,7 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): print ("cached file folder for onap is %s: ", cached_file_folder) print "self.path start with /onap/controlloop/v2/commission/, generating response json..." jsonGenerated = "{\"tosca_definitions_version\": \"tosca_simple_yaml_1_1_0\",\"data_types\": {},\"node_types\": {}, \"policy_types\": {}, \"topology_template\": {}, \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\", \"metadata\": {}}" - print "jsonGenerated: " + jsonGenerated - if not os.path.exists(cached_file_folder): - os.makedirs(cached_file_folder, 0777) - - with open(cached_file_header, 'w+') as f: - f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") - with open(cached_file_content, 'w+') as f: - f.write(jsonGenerated) + self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission/toscaServiceTemplateSchema")) and http_type == "GET": if not _file_available: @@ -289,14 +291,19 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): print ("cached file folder for onap is %s: ", cached_file_folder) print "self.path start with /onap/controlloop/v2/commission/, generating response json..." jsonGenerated = "{\"tosca_definitions_version\": \"tosca_simple_yaml_1_1_0\",\"data_types\": {},\"node_types\": {}, \"policy_types\": {}, \"topology_template\": {}, \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\", \"metadata\": {}}" - print "jsonGenerated: " + jsonGenerated - if not os.path.exists(cached_file_folder): - os.makedirs(cached_file_folder, 0777) - - with open(cached_file_header, 'w+') as f: - f.write("{\"Content-Length\": \"" + str(len(jsonGenerated)) + "\", \"Content-Type\": \"application/json\"}") - with open(cached_file_content, 'w+') as f: - f.write(jsonGenerated) + self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) + return True + elif (self.path.startswith("/onap/controlloop/v2/commission/elements")) and http_type == "GET": + print "self.path start with /commission/elements Control Loop Elements, generating response json..." + #jsondata = json.loads(self.data_string) + jsonGenerated = "[{\"name\": ,\"org.onap.domain.pmsh.PMSH_DCAEMicroservice\": [{ \"version\": \"1.2.3\", \"derived_from\": null }]}]" + self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) + return True + elif (self.path.startswith("/onap/controlloop/v2/commission")) and http_type == "GET": + print "self.path start with /commission control loop definition, generating response json..." + #jsondata = json.loads(self.data_string) + jsonGenerated = "[{\"name\": ,\"org.onap.domain.pmsh.PMSHControlLoopDefinition\": [{ \"version\": \"1.2.3\", \"derived_from\": null }]}]" + self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) return True elif (self.path.startswith("/onap/controlloop/v2/commission")) and http_type == "POST": print "self.path start with POST /onap/controlloop/v2/commission, copying body to response ..." @@ -307,6 +314,12 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): with open(cached_file_content, 'w+') as f: f.write(self.data_string) return True + elif (self.path.startswith("/onap/controlloop/v2/commission")) and http_type == "DELETE": + print "self.path start with /commission Decommissioning, generating response json..." + jsonGenerated = "{\"errorDetails\": null,\"affectedControlLoopDefinitions\": [{ \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\" }]}" + self._create_cache(jsonGenerated, cached_file_folder, cached_file_header, cached_file_content) + + return True else: return False |