f291c4e8916d7c88adef9cdff457a7f4d977392a
[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.io.Closeable;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.stream.Collectors;
35 import org.apache.commons.collections4.CollectionUtils;
36 import org.apache.commons.collections4.MapUtils;
37 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
38 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
39 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
40 import org.onap.policy.models.base.PfModelException;
41 import org.onap.policy.models.base.PfModelRuntimeException;
42 import org.onap.policy.models.provider.PolicyModelsProvider;
43 import org.onap.policy.models.provider.PolicyModelsProviderFactory;
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityType;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates;
53 import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
54 import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
55 import org.springframework.stereotype.Component;
56
57 /**
58  * This class provides the create, read and delete actions on Commissioning of Control Loop concepts in the database to
59  * the callers.
60  */
61 @Component
62 public class CommissioningProvider implements Closeable {
63     public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop";
64
65     private final PolicyModelsProvider modelsProvider;
66     private final ControlLoopProvider clProvider;
67
68     private static final Object lockit = new Object();
69
70     /**
71      * Create a commissioning provider.
72      *
73      * @param controlLoopParameters the parameters for access to the database
74      * @throws PfModelRuntimeException on errors creating the database provider
75      */
76     public CommissioningProvider(ClRuntimeParameterGroup controlLoopParameters) {
77         try {
78             modelsProvider = new PolicyModelsProviderFactory()
79                     .createPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters());
80         } catch (PfModelException e) {
81             throw new PfModelRuntimeException(e);
82         }
83
84         try {
85             clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters());
86         } catch (PfModelException e) {
87             throw new PfModelRuntimeException(e);
88         }
89     }
90
91     @Override
92     public void close() throws IOException {
93         try {
94             modelsProvider.close();
95             clProvider.close();
96         } catch (PfModelException e) {
97             throw new IOException("error closing modelsProvider", e);
98         }
99     }
100
101     /**
102      * Create control loops from a service template.
103      *
104      * @param serviceTemplate the service template
105      * @return the result of the commissioning operation
106      * @throws PfModelException on creation errors
107      */
108     public CommissioningResponse createControlLoopDefinitions(ToscaServiceTemplate serviceTemplate)
109             throws PfModelException {
110         synchronized (lockit) {
111             modelsProvider.createServiceTemplate(serviceTemplate);
112         }
113
114         var response = new CommissioningResponse();
115         // @formatter:off
116         response.setAffectedControlLoopDefinitions(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
117                 .values()
118                 .stream()
119                 .map(template -> template.getKey().asIdentifier())
120                 .collect(Collectors.toList()));
121         // @formatter:on
122
123         return response;
124     }
125
126     /**
127      * Delete the control loop definition with the given name and version.
128      *
129      * @param name the name of the control loop definition to delete
130      * @param version the version of the control loop to delete
131      * @return the result of the deletion
132      * @throws PfModelException on deletion errors
133      */
134     public CommissioningResponse deleteControlLoopDefinition(String name, String version) throws PfModelException {
135         synchronized (lockit) {
136             modelsProvider.deleteServiceTemplate(name, version);
137         }
138
139         var response = new CommissioningResponse();
140         response.setAffectedControlLoopDefinitions(
141                 Collections.singletonList(new ToscaConceptIdentifier(name, version)));
142
143         return response;
144     }
145
146     /**
147      * Get control loop node templates.
148      *
149      * @param clName the name of the control loop, null for all
150      * @param clVersion the version of the control loop, null for all
151      * @return list of control loop node templates
152      * @throws PfModelException on errors getting control loop definitions
153      */
154     public List<ToscaNodeTemplate> getControlLoopDefinitions(String clName, String clVersion) throws PfModelException {
155
156         // @formatter:off
157         ToscaTypedEntityFilter<ToscaNodeTemplate> nodeTemplateFilter = ToscaTypedEntityFilter
158                 .<ToscaNodeTemplate>builder()
159                 .name(clName)
160                 .version(clVersion)
161                 .type(CONTROL_LOOP_NODE_TYPE)
162                 .build();
163         // @formatter:on
164
165         return clProvider.getFilteredNodeTemplates(nodeTemplateFilter);
166     }
167
168     /**
169      * Get the control loop elements from a control loop node template.
170      *
171      * @param controlLoopNodeTemplate the control loop node template
172      * @return a list of the control loop element node templates in a control loop node template
173      * @throws PfModelException on errors get control loop element node templates
174      */
175     public List<ToscaNodeTemplate> getControlLoopElementDefinitions(ToscaNodeTemplate controlLoopNodeTemplate)
176             throws PfModelException {
177         if (!CONTROL_LOOP_NODE_TYPE.equals(controlLoopNodeTemplate.getType())) {
178             return Collections.emptyList();
179         }
180
181         if (MapUtils.isEmpty(controlLoopNodeTemplate.getProperties())) {
182             return Collections.emptyList();
183         }
184
185         @SuppressWarnings("unchecked")
186         List<Map<String, String>> controlLoopElements =
187                 (List<Map<String, String>>) controlLoopNodeTemplate.getProperties().get("elements");
188
189         if (CollectionUtils.isEmpty(controlLoopElements)) {
190             return Collections.emptyList();
191         }
192
193         List<ToscaNodeTemplate> controlLoopElementList = new ArrayList<>();
194         // @formatter:off
195         controlLoopElementList.addAll(
196                 controlLoopElements
197                         .stream()
198                         .map(elementMap -> clProvider.getNodeTemplates(elementMap.get("name"),
199                                 elementMap.get("version")))
200                         .flatMap(List::stream)
201                         .collect(Collectors.toList())
202         );
203         // @formatter:on
204
205         return controlLoopElementList;
206     }
207
208     /**
209      * Get the requested control loop definitions.
210      *
211      * @param name the name of the definition to get, null for all definitions
212      * @param version the version of the definition to get, null for all definitions
213      * @return the control loop definitions
214      * @throws PfModelException on errors getting control loop definitions
215      */
216     public ToscaServiceTemplate getToscaServiceTemplate(String name, String version) throws PfModelException {
217         var serviceTemplates = new ToscaServiceTemplates();
218         serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
219         return serviceTemplates.getServiceTemplates().get(0);
220     }
221
222     /**
223      * Get the requested json schema.
224      *
225      * @param section section of the tosca service template to get schema for
226      * @return the specified tosca service template or section Json Schema
227      * @throws PfModelException on errors with retrieving the classes
228      * @throws JsonProcessingException on errors generating the schema
229      */
230     public String getToscaServiceTemplateSchema(String section) throws PfModelException, JsonProcessingException {
231         ObjectMapper mapper = new ObjectMapper();
232         mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
233         SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
234
235         switch (section) {
236             case "data_types":
237                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaDataType.class), visitor);
238                 break;
239             case "capability_types":
240                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaCapabilityType.class), visitor);
241                 break;
242             case "node_types":
243                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaNodeType.class), visitor);
244                 break;
245             case "relationship_types":
246                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaRelationshipType.class), visitor);
247                 break;
248             case "policy_types":
249                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaPolicyType.class), visitor);
250                 break;
251             case "topology_template":
252                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaTopologyTemplate.class), visitor);
253                 break;
254             case "node_templates":
255                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaNodeTemplate.class), visitor);
256                 break;
257             default:
258                 mapper.acceptJsonFormatVisitor(mapper.constructType(ToscaServiceTemplate.class), visitor);
259         }
260
261         JsonSchema jsonSchema = visitor.finalSchema();
262         String response = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema);
263
264         return response;
265     }
266 }