diff options
24 files changed, 837 insertions, 162 deletions
diff --git a/common/src/main/resources/tosca/CdsControlLoopElementType.yaml b/common/src/main/resources/tosca/CdsControlLoopElementType.yaml index 296324b68..c2fc66a6a 100644 --- a/common/src/main/resources/tosca/CdsControlLoopElementType.yaml +++ b/common/src/main/resources/tosca/CdsControlLoopElementType.yaml @@ -24,3 +24,4 @@ node_types: cdsBlueprint: type: string required: true + description: The CDS blueprint that this control loop element is managing. diff --git a/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml b/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml index 615fc34dd..e45a06257 100644 --- a/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml +++ b/common/src/main/resources/tosca/ControlLoopTOSCAServiceTemplateTypes.yaml @@ -34,20 +34,62 @@ node_types: provider: type: string required: false + metadata: + common: true description: Specifies the organization that provides the control loop element - participant_type: + participantType: type: onap.datatypes.ToscaConceptIdentifier required: true + metadata: + common: true description: The identity of the participant type that hosts this type of Control Loop Element - start_phase: + startPhase: type: integer required: false constraints: - greater-or-equal: 0 + metadata: + common: true description: A value indicating the start phase in which this control loop element will be started, the first start phase is zero. Control Loop Elements are started in their start_phase order and stopped in reverse start phase order. Control Loop Elements with the same start phase are started and stopped simultaneously + uninitializedToPassiveTimeout: + type: integer + required: false + constraints: + - greater-or-equal: 0 + default: 60 + metadata: + common: true + description: The maximum time in seconds to wait for a state chage from uninitialized to passive + passiveToRunningTimeout: + type: integer + required: false + constraints: + - greater-or-equal: 0 + default: 60 + metadata: + common: true + description: The maximum time in seconds to wait for a state chage from passive to running + runningToPassiveTimeout: + type: integer + required: false + constraints: + - greater-or-equal: 0 + default: 60 + metadata: + common: true + description: The maximum time in seconds to wait for a state chage from running to passive + passiveToUninitializedTimeout: + type: integer + required: false + constraints: + - greater-or-equal: 0 + default: 60 + metadata: + common: true + description: The maximum time in seconds to wait for a state chage from passive to uninitialized org.onap.policy.clamp.controlloop.ControlLoop: version: 1.0.1 derived_from: tosca.nodetypes.Root @@ -55,11 +97,15 @@ node_types: provider: type: string required: false + metadata: + common: true description: Specifies the organization that provides the control loop element elements: type: list required: true - description: Specifies a list of control loop element definitions that make up this control loop definition + metadata: + common: true entry_schema: type: onap.datatypes.ToscaConceptIdentifier + description: Specifies a list of control loop element definitions that make up this control loop definition diff --git a/common/src/main/resources/tosca/DcaeControlLoopElementType.yaml b/common/src/main/resources/tosca/DcaeControlLoopElementType.yaml index 654a09470..acf91bb92 100644 --- a/common/src/main/resources/tosca/DcaeControlLoopElementType.yaml +++ b/common/src/main/resources/tosca/DcaeControlLoopElementType.yaml @@ -26,14 +26,14 @@ data_types: name: consulUrl type: string typeVersion: 0.0.0 - description: Consul url for this entry required: true + description: Consul url for this entry consulBody: name: consulBody type: string typeVersion: 0.0.0 - description: Body of Consul entry required: true + description: Body of Consul entry node_types: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement: version: 1.0.1 @@ -42,8 +42,10 @@ node_types: dcaeBlueprint: type: string required: true + description: The DCAE blueprint for the DCAE microservice this control loop element is managing. consulInfo: type: list required: false entry_schema: type: org.onap.datatypes.policy.clamp.controlloop.DCAEControlLoopElementConsulInfo + description: The information to be sent to Consul for the microservice this control loop element is managing. diff --git a/common/src/main/resources/tosca/HttpControlLoopElementType.yaml b/common/src/main/resources/tosca/HttpControlLoopElementType.yaml index 4fdb60546..fd37040c6 100644 --- a/common/src/main/resources/tosca/HttpControlLoopElementType.yaml +++ b/common/src/main/resources/tosca/HttpControlLoopElementType.yaml @@ -24,28 +24,28 @@ data_types: restRequestId: type: onap.datatypes.ToscaConceptIdentifier typeVersion: 1.0.0 - description: The name and version of a REST request to be sent to a REST endpoint required: true + description: The name and version of a REST request to be sent to a REST endpoint httpMethod: type: string - description: The REST method to use required: true constraints: - valid_values: [POST, PUT, GET, DELETE] + description: The REST method to use path: type: string - description: The path of the REST request relative to the base URL required: true + description: The path of the REST request relative to the base URL body: type: string - description: The body of the REST request for PUT and POST requests required: false + description: The body of the REST request for PUT and POST requests expectedResponse: type: integer - description: THe expected HTTP status code for the REST request required: true constraints: - in_range: [100, 599] + description: THe expected HTTP status code for the REST request org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity: version: 1.0.0 derived_from: tosca.datatypes.Root @@ -53,14 +53,14 @@ data_types: configurationEntityId: type: onap.datatypes.ToscaConceptIdentifier typeVersion: 1.0.0 - description: The name and version of a Configuration Entity to be handled by the HTTP Control Loop Element required: true + description: The name and version of a Configuration Entity to be handled by the HTTP Control Loop Element restSequence: type: list - description: A sequence of REST commands to send to the REST endpoint entry_schema: type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest typeVersion: 1.0.0 + description: A sequence of REST commands to send to the REST endpoint node_types: org.onap.policy.clamp.controlloop.HttpControlLoopElement: version: 1.0.1 @@ -69,14 +69,17 @@ node_types: baseUrl: type: string required: true + description: The base URL to be prepended to each path, identifies the host for the REST endpoints. httpHeaders: type: map required: false entry_schema: type: string + description: HTTP headers to send on REST requests configurationEntities: type: map required: true entry_schema: type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity typeVersion: 1.0.0 + description: The connfiguration entities the Control Loop Element is managing and their associated REST requests diff --git a/common/src/main/resources/tosca/KubernetesControlLoopElementType.yaml b/common/src/main/resources/tosca/KubernetesControlLoopElementType.yaml index 7468581b5..86a8ce197 100644 --- a/common/src/main/resources/tosca/KubernetesControlLoopElementType.yaml +++ b/common/src/main/resources/tosca/KubernetesControlLoopElementType.yaml @@ -24,26 +24,26 @@ data_types: chartId: type: onap.datatypes.ToscaConceptIdentifier typeVersion: 1.0.0 - description: The name and version of the chart required: true + description: The name and version of the chart releaseName: type: string - description: The name of the release of the chart required: true + description: The name of the release of the chart repository: type: string - description: The name of the repository where the chart is stored required: false + description: The name of the repository where the chart is stored namespace: type: string - description: The name space of the chart required: true + description: The name space of the chart overrideParams: type: map - description: A map of override settings for parameters in the chart required: false entry_schema: type: string + description: A map of override settings for parameters in the chart node_types: org.onap.policy.clamp.controlloop.KubernetesControlLoopElement: version: 1.0.1 @@ -52,25 +52,25 @@ node_types: chart: type: org.onap.datatypes.policy.clamp.controlloop.kubernetesControlLoopElement.Chart typeVersion: 1.0.0 - description: The helm chart for the microservice required: true + description: The helm chart for the microservice configs: type: list - description: The configurations for the microservice required: false entry_schema: type: string + description: The configurations for the microservice requirements: type: string - description: The requirements for the microservice required: false + description: The requirements for the microservice templates: type: list - description: The templates for the microservice required: false entry_schema: type: string + description: The templates for the microservice values: type: string + required: false description: The values for the microservice - required: true diff --git a/common/src/main/resources/tosca/PolicyControlLoopElementType.yaml b/common/src/main/resources/tosca/PolicyControlLoopElementType.yaml index f2d45f1bb..e584c2fce 100644 --- a/common/src/main/resources/tosca/PolicyControlLoopElementType.yaml +++ b/common/src/main/resources/tosca/PolicyControlLoopElementType.yaml @@ -21,6 +21,13 @@ node_types: version: 1.0.1 derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement properties: - policyId: + policyType: type: onap.datatypes.ToscaConceptIdentifier required: true + description: The policy type of the policy that this control loop element is managing + policyId: + type: onap.datatypes.ToscaConceptIdentifier + required: false + description: The policy that this control loop element is managing, if the policy ID is specified, the policy + is either already in the Policy Framework database or is specified in the "policies" part of the + TOSCA service template of the Control Loop definition diff --git a/common/src/test/resources/examples/controlloop/PMSubscriptionHandling.yaml b/common/src/test/resources/examples/controlloop/PMSubscriptionHandling.yaml index f9f97420a..5c6883bee 100644 --- a/common/src/test/resources/examples/controlloop/PMSubscriptionHandling.yaml +++ b/common/src/test/resources/examples/controlloop/PMSubscriptionHandling.yaml @@ -309,24 +309,24 @@ node_types: properties: provider: type: string - requred: false + required: false org.onap.policy.clamp.controlloop.ControlLoopElement: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: provider: type: string - requred: false + required: false participant_id: type: onap.datatypes.ToscaConceptIdentifier - requred: true + required: true org.onap.policy.clamp.controlloop.ControlLoop: version: 1.0.1 derived_from: tosca.nodetypes.Root properties: provider: type: string - requred: false + required: false elements: type: list required: true @@ -338,10 +338,10 @@ node_types: properties: dcae_blueprint_id: type: onap.datatypes.ToscaConceptIdentifier - requred: false + required: false dcae_blueprint: type: onap.dcae.cloudify_blueprint - requred: false + required: false consul_info: type: list required: false @@ -353,17 +353,17 @@ node_types: properties: policy_type_id: type: onap.datatypes.ToscaConceptIdentifier - requred: true + required: true policy_id: type: onap.datatypes.ToscaConceptIdentifier - requred: false + required: false org.onap.policy.clamp.controlloop.CDSControlLoopElement: version: 1.0.1 derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement properties: cds_blueprint_id: type: onap.datatypes.ToscaConceptIdentifier - requred: true + required: true topology_template: inputs: pmsh_monitoring_policy: diff --git a/common/src/test/resources/gentleguidance/GentleGuidanceDefaultPropeties.yaml b/common/src/test/resources/gentleguidance/GentleGuidanceDefaultPropeties.yaml new file mode 100644 index 000000000..d634a1fa5 --- /dev/null +++ b/common/src/test/resources/gentleguidance/GentleGuidanceDefaultPropeties.yaml @@ -0,0 +1,115 @@ +# ============LICENSE_START======================================================= +# Copyright (C) 2021 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========================================================= +tosca_definitions_version: tosca_simple_yaml_1_3 +topology_template: + node_templates: + org.onap.domain.gentleguidance.KubernetesControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.KubernetesControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance Kubernetes Microservice + properties: + provider: Ericsson + participantType: org.onap.policy.controlloop.participant.Kubernetes:1.0.0 + startPhase: 2 + uninitializedToPassiveTimeout: 180 + chart: + chartId: GentleGuidance:1.0.0 + releaseName: Istanbul + namespace: org.onap.policy.controlloop.gentleguidance + org.onap.domain.gentleguidance.RestControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.HttpControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance Microservice REST configuration + properties: + provider: Ericsson + participantType: org.onap.policy.controlloop.participant.Http:1.0.0 + startPhase: 1 + baseUrl: https://10.10.10.10:12345/gentleguidancemicroservice + httpHeaders: + "Content-Type": "application/json" + "Accept": "application/json" + configurationEntities: + org.onap.policy.controlloop.gentleguidance.setGentleGuidanceConfig:1.0.0: + configurationEntityId: org.onap.policy.controlloop.gentleguidance.setGentleGuidanceConfig:1.0.0 + restSequence: + - restRequestId: org.onap.policy.controlloop.gentleguidance.setGentleGuidanceConfig.CreateGentle:1.0.0 + httpMethd: POST + path: "gentle/create" + body: + gentleLevel: veryGentle + gentleType: softAndFurry + expectedResponse: 200 + - restRequestId: org.onap.policy.controlloop.gentleguidance.setGentleGuidanceConfig.CreateGuidance:1.0.0 + httpMethd: POST + path: "guidance/create" + body: + guidanceLevel: high + guidanceType: subtle + expectedResponse: 200 + org.onap.policy.controlloop.gentleguidance.updateGentleGuidanceConfig:1.0.0: + configurationEntityId: org.onap.policy.controlloop.gentleguidance.updateGentleGuidanceConfig:1.0.0 + restSequence: + - restRequestId: org.onap.policy.controlloop.gentleguidance.updateGentleGuidanceConfig.CreateGentle:1.0.0 + httpMethd: PUT + path: "gentle/update]" + body: + gentleLevel: robust + gentleType: hardAndGritty + expectedResponse: 200 + - restRequestId: org.onap.policy.controlloop.gentleguidance.updateGentleGuidanceConfig.CreateGuidance:1.0.0 + httpMethd: PUT + path: "guidance/update" + body: + guidanceLevel: low + guidanceType: terse + expectedResponse: 200 + org.onap.domain.gentleguidance.PolicyControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.PolicyControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance Operational Policy + properties: + provider: Ericsson + participantType: org.onap.policy.controlloop.participant.Policy:1.0.0 + startPhase: 0 + policyType: onap.policies.controlloop.operational.common.Apex:1.0.0 + policyId: org.onap.domain.gentleguidance.policy.GentleGuidanceAssertive:1.0.0 + org.onap.domain.gentleguidance.CdsControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.CDSControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance CDS blueprint + properties: + provider: Ericsson + participantType: org.onap.policy.controlloop.participant.Cds:1.0.0 + startPhase: 0 + cdsBlueprint: "Placeholder for the CDS blueprint" + org.onap.domain.gentleguidance.ControlLoopDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.ControlLoop + type_version: 1.0.1 + description: Control loop definition for the Gentle Guidance domain + properties: + provider: Ericsson + elements: + - org.onap.domain.gentleguidance.KubernetesControlLoopElementDefinition:1.0.0 + - org.onap.domain.gentleguidance.RestControlLoopElementDefinition:1.0.0 + - org.onap.domain.gentleguidance.PolicyControlLoopElementDefinition:1.0.0 + - org.onap.domain.gentleguidance.CdsControlLoopElementDefinition:1.0.0 diff --git a/common/src/test/resources/gentleguidance/GentleGuidanceNoPropeties.yaml b/common/src/test/resources/gentleguidance/GentleGuidanceNoPropeties.yaml new file mode 100644 index 000000000..d0222617d --- /dev/null +++ b/common/src/test/resources/gentleguidance/GentleGuidanceNoPropeties.yaml @@ -0,0 +1,52 @@ +# ============LICENSE_START======================================================= +# Copyright (C) 2021 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========================================================= +tosca_definitions_version: tosca_simple_yaml_1_3 +topology_template: + node_templates: + org.onap.domain.gentleguidance.KubernetesControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.KubernetesControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance Kubernetes Microservice + org.onap.domain.gentleguidance.RestControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.HttpControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance Microservice REST configuration + org.onap.domain.gentleguidance.PolicyControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.PolicyControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance Operational Policy + org.onap.domain.gentleguidance.CdsControlLoopElementDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.CDSControlLoopElement + type_version: 1.0.1 + description: Control loop element for the Gentle Guidance CDS blueprint + org.onap.domain.gentleguidance.ControlLoopDefinition: + version: 1.0.0 + type: org.onap.policy.clamp.controlloop.ControlLoop + type_version: 1.0.1 + description: Control loop definition for the Gentle Guidance domain + properties: + provider: Ericsson + elements: + - org.onap.domain.gentleguidance.KubernetesControlLoopElementDefinition:1.0.0 + - org.onap.domain.gentleguidance.RestControlLoopElementDefinition:1.0.0 + - org.onap.domain.gentleguidance.PolicyControlLoopElementDefinition:1.0.0 + - org.onap.domain.gentleguidance.CdsControlLoopElementDefinition:1.0.0 diff --git a/packages/policy-clamp-docker/pom.xml b/packages/policy-clamp-docker/pom.xml index fc6e36085..576c95de6 100644 --- a/packages/policy-clamp-docker/pom.xml +++ b/packages/policy-clamp-docker/pom.xml @@ -149,6 +149,38 @@ </build> </image> <image> + <name>onap/kubernetes-participant</name> + <alias>onap-kubernetes-participant</alias> + <build> + <cleanup>try</cleanup> + <dockerFile>KubernetesParticipantDockerfile</dockerFile> + <tags> + <tag>${project.version}</tag> + <tag>${project.version}-${maven.build.timestamp}</tag> + <tag>${project.docker.latest.minmax.tag.version}</tag> + </tags> + <assembly> + <inline> + <dependencySets> + <dependencySet> + <includes> + <include>org.onap.policy.clamp:policy-clamp-tarball</include> + </includes> + <outputDirectory>/lib</outputDirectory> + <outputFileNameMapping>kubernetes-participant.tar.gz</outputFileNameMapping> + </dependencySet> + <dependencySet> + <includes> + <include>org.onap.policy.clamp.participant:policy-clamp-participant-impl-kubernetes</include> + </includes> + <outputFileNameMapping>app.jar</outputFileNameMapping> + </dependencySet> + </dependencySets> + </inline> + </assembly> + </build> + </image> + <image> <name>onap/dcae-participant</name> <alias>onap-dcae-participant</alias> <build> @@ -245,5 +277,10 @@ <artifactId>policy-clamp-participant-impl-dcae</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.onap.policy.clamp.participant</groupId> + <artifactId>policy-clamp-participant-impl-kubernetes</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> diff --git a/packages/policy-clamp-docker/src/main/docker/KubernetesParticipantDockerfile b/packages/policy-clamp-docker/src/main/docker/KubernetesParticipantDockerfile new file mode 100644 index 000000000..40532c002 --- /dev/null +++ b/packages/policy-clamp-docker/src/main/docker/KubernetesParticipantDockerfile @@ -0,0 +1,66 @@ +#------------------------------------------------------------------------------- +# ============LICENSE_START======================================================= +# Copyright (C) 2021 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========================================================= +#------------------------------------------------------------------------------- + +# +# Docker file to build an image that runs CLAMP on Java 11 or better in alpine +# +FROM onap/policy-jre-alpine:2.2.1 + +LABEL maintainer="Policy Team" + +ARG POLICY_LOGS=/var/log/onap/policy/clamp + +ENV POLICY_LOGS=$POLICY_LOGS +ENV POLICY_HOME=$POLICY_HOME/clamp + +RUN mkdir -p $POLICY_LOGS $POLICY_HOME $POLICY_HOME/bin && \ + chown -R policy:policy $POLICY_HOME $POLICY_LOGS && \ + mkdir /packages +COPY /maven/lib/kubernetes-participant.tar.gz /packages + +RUN tar xvfz /packages/kubernetes-participant.tar.gz --directory $POLICY_HOME && \ + rm /packages/kubernetes-participant.tar.gz && \ + rm -rf $POLICY_HOME/lib + +WORKDIR $POLICY_HOME +COPY kubernetes-participant.sh bin/. +COPY /maven/app.jar /app + +RUN chown -R policy:policy * && \ + chmod 755 bin/*.sh && \ + chown -R policy:policy /app && \ + apk update && \ + apk add wget && \ + wget https://get.helm.sh/helm-v3.5.2-linux-amd64.tar.gz && \ + tar xvf helm-v3.5.2-linux-amd64.tar.gz && \ + mv linux-amd64/helm /usr/local/bin && \ + rm -rf linux-amd64 && \ + rm helm-v3.5.2-linux-amd64.tar.gz && \ + wget https://storage.googleapis.com/kubernetes-release/release/v1.21.1/bin/linux/amd64/kubectl && \ + chmod +x kubectl && \ + mv kubectl /usr/local/bin/kubectl + +EXPOSE 8080 + +USER policy +WORKDIR $POLICY_HOME/bin +ENTRYPOINT [ "./kubernetes-participant.sh" ] + + diff --git a/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh b/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh new file mode 100644 index 000000000..195639ad3 --- /dev/null +++ b/packages/policy-clamp-docker/src/main/docker/kubernetes-participant.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env sh +# +# ============LICENSE_START======================================================= +# Copyright (C) 2021 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========================================================= +# + +JAVA_HOME=/usr/lib/jvm/java-11-openjdk/ +KEYSTORE="${KEYSTORE:-$POLICY_HOME/etc/ssl/policy-keystore}" +TRUSTSTORE="${TRUSTSTORE:-$POLICY_HOME/etc/ssl/policy-truststore}" +KEYSTORE_PASSWD="${KEYSTORE_PASSWD:-Pol1cy_0nap}" +TRUSTSTORE_PASSWD="${TRUSTSTORE_PASSWD:-Pol1cy_0nap}" + + + +if [ -f "${POLICY_HOME}/etc/mounted/policy-truststore" ]; then + echo "overriding policy-truststore" + cp -f "${POLICY_HOME}"/etc/mounted/policy-truststore "${TRUSTSTORE}" +fi + +if [ -f "${POLICY_HOME}/etc/mounted/policy-keystore" ]; then + echo "overriding policy-keystore" + cp -f "${POLICY_HOME}"/etc/mounted/policy-keystore "${KEYSTORE}" +fi + +if [ -f "${POLICY_HOME}/etc/mounted/logback.xml" ]; then + echo "overriding logback xml files" + cp -f "${POLICY_HOME}"/etc/mounted/logback*.xml "${POLICY_HOME}"/etc/ +fi + +$JAVA_HOME/bin/java -Djavax.net.ssl.keyStore="${KEYSTORE}" \ + -Djavax.net.ssl.keyStorePassword="${KEYSTORE_PASSWD}" \ + -Djavax.net.ssl.trustStore="${TRUSTSTORE}" \ + -Djavax.net.ssl.trustStorePassword="${TRUSTSTORE_PASSWD}" \ + -jar /app/app.jar diff --git a/packages/policy-clamp-tarball/pom.xml b/packages/policy-clamp-tarball/pom.xml index 559dbaa4d..4689433a7 100644 --- a/packages/policy-clamp-tarball/pom.xml +++ b/packages/policy-clamp-tarball/pom.xml @@ -47,6 +47,11 @@ <artifactId>policy-clamp-participant-impl-dcae</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.onap.policy.clamp.participant</groupId> + <artifactId>policy-clamp-participant-impl-kubernetes</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build> diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java index a96581e6c..3f5e42542 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java @@ -20,6 +20,7 @@ package org.onap.policy.clamp.controlloop.participant.dcae.endtoend; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.mockserver.model.HttpRequest.request; @@ -160,4 +161,16 @@ class PartecipantDcaeTest { assertEquals(participantHandler.getParticipantId(), participantControlLoopUpdateMsg.getParticipantId()); assertEquals(1, participantHandler.getControlLoopHandler().getControlLoops().getControlLoopList().size()); } + + @Test + void testControlLoopUpdateListenerString() throws CoderException { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.UNINITIALISED); + + assertThat(participantControlLoopUpdateMsg.toString()).contains("state=UNINITIALISED"); + ParticipantControlLoopUpdate copyParticipantControlLoopUpdateMsg = + TestListenerUtils.createCopyControlLoopUpdateMsg(participantControlLoopUpdateMsg); + assertThat(copyParticipantControlLoopUpdateMsg.toString()).contains("state=UNINITIALISED"); + assertNotEquals(participantControlLoopUpdateMsg, copyParticipantControlLoopUpdateMsg); + } } diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java index f730f36f4..f3aa17655 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java @@ -22,6 +22,7 @@ package org.onap.policy.clamp.controlloop.participant.dcae.httpclient; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; @@ -98,6 +99,17 @@ class ClampHttpClientTest { } @Test + void test_create() throws Exception { + try (ClampHttpClient client = new ClampHttpClient(parameters)) { + + assertThat(client.create(LOOP, null)).isNull(); + + } catch (Exception e) { + fail(e.getMessage()); + } + } + + @Test void test_deploy() throws Exception { try (ClampHttpClient client = new ClampHttpClient(parameters)) { @@ -128,4 +140,26 @@ class ClampHttpClientTest { void test_getStatusEmptyMap() { assertThat(ClampHttpClient.getStatusCode(new Loop())).isEqualTo(ClampHttpClient.STATUS_NOT_FOUND); } + + @Test + void test_stop() throws Exception { + try (ClampHttpClient client = new ClampHttpClient(parameters)) { + + assertFalse(client.stop(LOOP)); + + } catch (Exception e) { + fail(e.getMessage()); + } + } + + @Test + void test_delete() throws Exception { + try (ClampHttpClient client = new ClampHttpClient(parameters)) { + + assertFalse(client.delete(LOOP)); + + } catch (Exception e) { + fail(e.getMessage()); + } + } } diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandlerTest.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandlerTest.java index ab181d476..40f2f5f7b 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandlerTest.java @@ -20,6 +20,7 @@ package org.onap.policy.clamp.controlloop.participant.dcae.main.handler; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -74,10 +75,13 @@ class ControlLoopElementHandlerTest { ParticipantIntermediaryApi intermediaryApi = mock(ParticipantIntermediaryApi.class); controlLoopElementHandler.setIntermediaryApi(intermediaryApi); - controlLoopElementHandler.controlLoopElementStateChange(UUID.randomUUID(), ControlLoopState.PASSIVE, + UUID controlLoopElementId = UUID.randomUUID(); + controlLoopElementHandler.controlLoopElementStateChange(controlLoopElementId, ControlLoopState.PASSIVE, ControlLoopOrderedState.UNINITIALISED); verify(clampClient).undeploy(eq(LOOP)); + controlLoopElementHandler.handleStatistics(controlLoopElementId); + assertThat(intermediaryApi.getControlLoopElement(controlLoopElementId)).isNull(); } @Test diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java index 0b2712b7a..4579b52bf 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java @@ -183,6 +183,15 @@ public class TestListenerUtils { } /** + * Method to create a deep copy of ControlLoopUpdateMsg. + * + * @return ParticipantControlLoopUpdate message + */ + public static ParticipantControlLoopUpdate createCopyControlLoopUpdateMsg(ParticipantControlLoopUpdate cpy) { + return new ParticipantControlLoopUpdate(cpy); + } + + /** * Method to create ParticipantHealthCheck message. * * @return ParticipantHealthCheck message diff --git a/runtime-controlloop/pom.xml b/runtime-controlloop/pom.xml index 2e3b4e902..e436451ff 100644 --- a/runtime-controlloop/pom.xml +++ b/runtime-controlloop/pom.xml @@ -45,6 +45,17 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>com.fasterxml.jackson.module</groupId> + <artifactId>jackson-module-jsonSchema</artifactId> + <version>${version.jackson}</version> + <exclusions> + <exclusion> + <groupId>javax.validation</groupId> + <artifactId>validation-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> 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 22809e8c0..f291c4e89 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 @@ -20,6 +20,11 @@ package org.onap.policy.clamp.controlloop.runtime.commissioning; +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 java.io.Closeable; import java.io.IOException; import java.util.ArrayList; @@ -36,10 +41,16 @@ import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.provider.PolicyModelsProviderFactory; +import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates; +import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; import org.springframework.stereotype.Component; @@ -207,4 +218,49 @@ public class CommissioningProvider implements Closeable { serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version)); return serviceTemplates.getServiceTemplates().get(0); } + + /** + * Get the requested json schema. + * + * @param section section of the tosca service template to get schema for + * @return the specified tosca service template or section Json Schema + * @throws PfModelException on errors with retrieving the classes + * @throws JsonProcessingException on errors generating the schema + */ + public String getToscaServiceTemplateSchema(String section) throws PfModelException, JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); + SchemaFactoryWrapper visitor = new SchemaFactoryWrapper(); + + switch (section) { + case "data_types": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaDataType.class), visitor); + break; + case "capability_types": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaCapabilityType.class), visitor); + break; + case "node_types": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaNodeType.class), visitor); + break; + case "relationship_types": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaRelationshipType.class), visitor); + break; + case "policy_types": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaPolicyType.class), visitor); + break; + case "topology_template": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaTopologyTemplate.class), visitor); + break; + case "node_templates": + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaNodeTemplate.class), visitor); + break; + default: + mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaServiceTemplate.class), visitor); + } + + JsonSchema jsonSchema = visitor.finalSchema(); + String response = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema); + + return response; + } } 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 a03254272..b50e7a0ed 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 @@ -20,6 +20,11 @@ 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; @@ -30,6 +35,7 @@ import io.swagger.annotations.ExtensionProperty; import io.swagger.annotations.ResponseHeader; import java.util.List; import java.util.UUID; +import javax.ws.rs.core.Response.Status; import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; @@ -81,39 +87,39 @@ public class CommissioningController extends AbstractRestController { consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation( - value = "Commissions control loop definitions", - notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs", - response = CommissioningResponse.class, - tags = {"Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - 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 = LAST_MOD_RELEASE) - } - ) - } + value = "Commissions control loop definitions", + notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs", + response = CommissioningResponse.class, + tags = {"Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + 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 = LAST_MOD_RELEASE) + } + ) + } ) @ApiResponses( value = { @@ -152,37 +158,37 @@ public class CommissioningController extends AbstractRestController { @DeleteMapping(value = "/commission", produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Delete a commissioned control loop", - notes = "Deletes a Commissioned Control Loop, returning optional error details", - response = CommissioningResponse.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - 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 = LAST_MOD_RELEASE) - } - ) - } + notes = "Deletes a Commissioned Control Loop, returning optional error details", + response = CommissioningResponse.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + 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 = LAST_MOD_RELEASE) + } + ) + } ) @ApiResponses( value = { @@ -226,21 +232,21 @@ public class CommissioningController extends AbstractRestController { @GetMapping(value = "/commission", produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested commissioned control loop definitions", - notes = "Queries details of the requested commissioned control loop definitions, " - + "returning all control loop details", - response = ToscaNodeTemplate.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - 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)}, + notes = "Queries details of the requested commissioned control loop definitions, " + + "returning all control loop details", + response = ToscaNodeTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + 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 ( @@ -295,31 +301,31 @@ public class CommissioningController extends AbstractRestController { @GetMapping(value = "/commission/toscaservicetemplate", produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested tosca service templates", - notes = "Queries details of the requested commissioned tosca service template, " - + "returning all tosca service template details", - response = ToscaServiceTemplate.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - 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 = LAST_MOD_RELEASE) - } - ) - } + notes = "Queries details of the requested commissioned tosca service template, " + + "returning all tosca service template details", + response = ToscaServiceTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + 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 = LAST_MOD_RELEASE) + } + ) + } ) @ApiResponses( value = { @@ -353,6 +359,74 @@ public class CommissioningController extends AbstractRestController { } /** + * Retrieves the Json Schema for the specified Tosca Service Template. + * + * @param requestId request ID used in ONAP logging + * @param section section of the tosca service template to get schema for + * @return the specified tosca service template or section Json Schema + */ + // @formatter:off + @GetMapping(value = "/commission/toscaServiceTemplateSchema", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) + @ApiOperation(value = "Query details of the requested tosca service template json schema", + notes = "Queries details of the requested commissioned tosca service template json schema, " + + "returning all tosca service template json schema details", + response = ToscaServiceTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + 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 = LAST_MOD_RELEASE) + } + ) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public ResponseEntity<?> queryToscaServiceTemplateJsonSchema( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Section of Template schema is desired for", required = false) @RequestParam( + value = "section", + required = false, defaultValue = "all") String section) { + try { + return ResponseEntity.ok().body(provider.getToscaServiceTemplateSchema(section)); + + } catch (PfModelRuntimeException | PfModelException e) { + LOGGER.warn("Get of tosca service template json schema 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 json schema failed", e); + var resp = new CommissioningResponse(); + resp.setErrorDetails(e.getMessage()); + return ResponseEntity.status(Status.BAD_REQUEST.getStatusCode()).body(resp); + } + } + + /** * Queries the elements of a specific control loop. * * @param requestId request ID used in ONAP logging @@ -364,31 +438,31 @@ public class CommissioningController extends AbstractRestController { @GetMapping(value = "/commission/elements", produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested commissioned control loop element definitions", - notes = "Queries details of the requested commissioned control loop element definitions, " - + "returning all control loop elements' details", - response = ToscaNodeTemplate.class, - tags = {"Clamp Control Loop Commissioning API"}, - authorizations = @Authorization(value = AUTHORIZATION_TYPE), - 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 = LAST_MOD_RELEASE) - } - ) - } + notes = "Queries details of the requested commissioned control loop element definitions, " + + "returning all control loop elements' details", + response = ToscaNodeTemplate.class, + tags = {"Clamp Control Loop Commissioning API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + 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 = LAST_MOD_RELEASE) + } + ) + } ) @ApiResponses( value = { 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 d560db660..8a7523c2b 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 @@ -1575,6 +1575,40 @@ </doTry> </route> </get> + <get uri="/v2/toscaControlLoop/getJsonSchema" outType="java.lang.String" bindingMode="off" produces="application/json"> + <route> + <removeHeaders pattern="*" + excludePattern="section"/> + <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-json-schema"/> + <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 JSON Schema request failed: ${exception.stacktrace}"/> + <setHeader name="CamelHttpResponseCode"> + <constant>500</constant> + </setHeader> + <setBody> + <simple>GET JSON Schema FAILED</simple> + </setBody> + </doCatch> + </doTry> + </route> + </get> <post uri="/v2/toscaControlLoop/postToscaInstantiation" type="java.lang.String" 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 b7da4a743..a888d6bf0 100644 --- a/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml +++ b/runtime/src/main/resources/clds/camel/routes/controlloop-flows.xml @@ -104,4 +104,32 @@ </doFinally> </doTry> </route> + <route id="get-json-schema"> + <from uri="direct:get-json-schema"/> + <doTry> + <log loggingLevel="INFO" + message="Getting the JSON Schema"/> + <to + uri="bean:org.onap.policy.clamp.flow.log.FlowLogOperation?method=invokeLog('ControlLoop', 'Getting the JSON Schema')"/> + <setHeader name="CamelHttpMethod"> + <constant>GET</constant> + </setHeader> + <setHeader name="Content-Type"> + <constant>application/json</constant> + </setHeader> + <setProperty name="section"> + <simple>${header.section}</simple> + </setProperty> + <log loggingLevel="INFO" + message="Endpoint to get Json Schema: {{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission/toscaServiceTemplateSchema"></log> + <toD + uri="{{clamp.config.controlloop.runtime.url}}/onap/controlloop/v2/commission/toscaServiceTemplateSchema?section=${exchangeProperty[section]}&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 0ba1486bb..7616d7a49 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 @@ -47,6 +47,20 @@ public class RuntimeCommissioningResponseTestItCase { + " \"name\": \"ToscaServiceTemplateSimple\", \"version\": \"1.0.0\", \"metadata\": {}}"; @Test + public void testToscaServiceTemplateSchemaStatus() { + ProducerTemplate prodTemplate = camelContext.createProducerTemplate(); + + Exchange exchangeResponse = + prodTemplate.send("direct:get-json-schema", ExchangeBuilder.anExchange(camelContext) + .withProperty("section", "data_types") + .withProperty("raiseHttpExceptionFlag", "true") + .build()); + + assertThat(HttpStatus.valueOf((Integer) exchangeResponse.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE)) + .is2xxSuccessful()).isTrue(); + } + + @Test public void testToscaServiceTemplateStatus() { ProducerTemplate prodTemplate = camelContext.createProducerTemplate(); 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 50bd43a35..1aaf4024d 100644 --- a/runtime/src/test/resources/http-cache/third_party_proxy.py +++ b/runtime/src/test/resources/http-cache/third_party_proxy.py @@ -283,6 +283,21 @@ class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler): with open(cached_file_content, 'w+') as f: f.write(jsonGenerated) return True + elif (self.path.startswith("/onap/controlloop/v2/commission/toscaServiceTemplateSchema")) and http_type == "GET": + if not _file_available: + cached_file_folder = cached_file_folder.split('bridgeEndpoint')[0] + 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) + 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 ..." if not os.path.exists(cached_file_folder): |