d9dee50bc1d05c1a691b7a50a70837dea86d6606
[policy/clamp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2021 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.clamp.controlloop.runtime.commissioning;
22
23 import com.fasterxml.jackson.core.JsonProcessingException;
24 import com.fasterxml.jackson.databind.ObjectMapper;
25 import com.fasterxml.jackson.databind.PropertyNamingStrategies;
26 import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
27 import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.stream.Collectors;
33 import org.apache.commons.collections4.CollectionUtils;
34 import org.apache.commons.collections4.MapUtils;
35 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
36 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
37 import org.onap.policy.models.base.PfModelException;
38 import org.onap.policy.models.provider.PolicyModelsProvider;
39 import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityType;
40 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
42 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
43 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
50 import org.springframework.stereotype.Component;
51
52 /**
53  * This class provides the create, read and delete actions on Commissioning of Control Loop concepts in the database to
54  * the callers.
55  */
56 @Component
57 public class CommissioningProvider {
58     public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop";
59
60     private final PolicyModelsProvider modelsProvider;
61     private final ControlLoopProvider clProvider;
62
63     private static final Object lockit = new Object();
64
65     /**
66      * Create a commissioning provider.
67      *
68      * @param modelsProvider the PolicyModelsProvider
69      * @param clProvider the ControlLoopProvider
70      */
71     public CommissioningProvider(PolicyModelsProvider modelsProvider, ControlLoopProvider clProvider) {
72         this.modelsProvider = modelsProvider;
73         this.clProvider = clProvider;
74     }
75
76     /**
77      * Create control loops from a service template.
78      *
79      * @param serviceTemplate the service template
80      * @return the result of the commissioning operation
81      * @throws PfModelException on creation errors
82      */
83     public CommissioningResponse createControlLoopDefinitions(ToscaServiceTemplate serviceTemplate)
84             throws PfModelException {
85         synchronized (lockit) {
86             modelsProvider.createServiceTemplate(serviceTemplate);
87         }
88
89         var response = new CommissioningResponse();
90         // @formatter:off
91         response.setAffectedControlLoopDefinitions(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
92                 .values()
93                 .stream()
94                 .map(template -> template.getKey().asIdentifier())
95                 .collect(Collectors.toList()));
96         // @formatter:on
97
98         return response;
99     }
100
101     /**
102      * Delete the control loop definition with the given name and version.
103      *
104      * @param name the name of the control loop definition to delete
105      * @param version the version of the control loop to delete
106      * @return the result of the deletion
107      * @throws PfModelException on deletion errors
108      */
109     public CommissioningResponse deleteControlLoopDefinition(String name, String version) throws PfModelException {
110         synchronized (lockit) {
111             modelsProvider.deleteServiceTemplate(name, version);
112         }
113
114         var response = new CommissioningResponse();
115         response.setAffectedControlLoopDefinitions(
116                 Collections.singletonList(new ToscaConceptIdentifier(name, version)));
117
118         return response;
119     }
120
121     /**
122      * Get control loop node templates.
123      *
124      * @param clName the name of the control loop, null for all
125      * @param clVersion the version of the control loop, null for all
126      * @return list of control loop node templates
127      * @throws PfModelException on errors getting control loop definitions
128      */
129     public List<ToscaNodeTemplate> getControlLoopDefinitions(String clName, String clVersion) throws PfModelException {
130
131         // @formatter:off
132         ToscaTypedEntityFilter<ToscaNodeTemplate> nodeTemplateFilter = ToscaTypedEntityFilter
133                 .<ToscaNodeTemplate>builder()
134                 .name(clName)
135                 .version(clVersion)
136                 .type(CONTROL_LOOP_NODE_TYPE)
137                 .build();
138         // @formatter:on
139
140         return clProvider.getFilteredNodeTemplates(nodeTemplateFilter);
141     }
142
143     /**
144      * Get the control loop elements from a control loop node template.
145      *
146      * @param controlLoopNodeTemplate the control loop node template
147      * @return a list of the control loop element node templates in a control loop node template
148      * @throws PfModelException on errors get control loop element node templates
149      */
150     public List<ToscaNodeTemplate> getControlLoopElementDefinitions(ToscaNodeTemplate controlLoopNodeTemplate)
151             throws PfModelException {
152         if (!CONTROL_LOOP_NODE_TYPE.equals(controlLoopNodeTemplate.getType())) {
153             return Collections.emptyList();
154         }
155
156         if (MapUtils.isEmpty(controlLoopNodeTemplate.getProperties())) {
157             return Collections.emptyList();
158         }
159
160         @SuppressWarnings("unchecked")
161         List<Map<String, String>> controlLoopElements =
162                 (List<Map<String, String>>) controlLoopNodeTemplate.getProperties().get("elements");
163
164         if (CollectionUtils.isEmpty(controlLoopElements)) {
165             return Collections.emptyList();
166         }
167
168         List<ToscaNodeTemplate> controlLoopElementList = new ArrayList<>();
169         // @formatter:off
170         controlLoopElementList.addAll(
171                 controlLoopElements
172                         .stream()
173                         .map(elementMap -> clProvider.getNodeTemplates(elementMap.get("name"),
174                                 elementMap.get("version")))
175                         .flatMap(List::stream)
176                         .collect(Collectors.toList())
177         );
178         // @formatter:on
179
180         return controlLoopElementList;
181     }
182
183     /**
184      * Get the requested control loop definitions.
185      *
186      * @param name the name of the definition to get, null for all definitions
187      * @param version the version of the definition to get, null for all definitions
188      * @return the control loop definitions
189      * @throws PfModelException on errors getting control loop definitions
190      */
191     public ToscaServiceTemplate getToscaServiceTemplate(String name, String version) throws PfModelException {
192         var serviceTemplates = new ToscaServiceTemplates();
193         serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
194         return serviceTemplates.getServiceTemplates().get(0);
195     }
196
197     /**
198      * Get the requested json schema.
199      *
200      * @param section section of the tosca service template to get schema for
201      * @return the specified tosca service template or section Json Schema
202      * @throws PfModelException on errors with retrieving the classes
203      * @throws JsonProcessingException on errors generating the schema
204      */
205     public String getToscaServiceTemplateSchema(String section) throws PfModelException, JsonProcessingException {
206         ObjectMapper mapper = new ObjectMapper();
207         mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
208         SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
209
210         switch (section) {
211             case "data_types":
212                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaDataType.class), visitor);
213                 break;
214             case "capability_types":
215                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaCapabilityType.class), visitor);
216                 break;
217             case "node_types":
218                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaNodeType.class), visitor);
219                 break;
220             case "relationship_types":
221                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaRelationshipType.class), visitor);
222                 break;
223             case "policy_types":
224                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaPolicyType.class), visitor);
225                 break;
226             case "topology_template":
227                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaTopologyTemplate.class), visitor);
228                 break;
229             case "node_templates":
230                 mapper.acceptJsonFormatVisitor(mapper.getTypeFactory()
231                     .constructCollectionType(List.class, ToscaNodeTemplate.class), visitor);
232                 break;
233             default:
234                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaServiceTemplate.class), visitor);
235         }
236
237         JsonSchema jsonSchema = visitor.finalSchema();
238         String response = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema);
239
240         return response;
241     }
242 }