2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021-2022 Nordix Foundation.
4 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.clamp.acm.runtime.commissioning;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.stream.Collectors;
30 import javax.ws.rs.core.Response.Status;
31 import org.apache.commons.collections4.CollectionUtils;
32 import org.apache.commons.collections4.MapUtils;
33 import org.apache.commons.lang3.StringUtils;
34 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler;
35 import org.onap.policy.clamp.models.acm.concepts.Participant;
36 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
37 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
38 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
39 import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
40 import org.onap.policy.common.utils.coder.Coder;
41 import org.onap.policy.common.utils.coder.CoderException;
42 import org.onap.policy.common.utils.coder.StandardCoder;
43 import org.onap.policy.models.base.PfModelException;
44 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
46 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
47 import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter;
48 import org.springframework.stereotype.Service;
49 import org.springframework.transaction.annotation.Transactional;
52 * This class provides the create, read and delete actions on Commissioning of automation composition concepts in the
53 * database to the callers.
57 public class CommissioningProvider {
58 public static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition";
59 private static final String HYPHEN = "-";
61 private final ServiceTemplateProvider serviceTemplateProvider;
62 private final AutomationCompositionProvider acProvider;
63 private static final Coder CODER = new StandardCoder();
64 private final ParticipantProvider participantProvider;
65 private final SupervisionHandler supervisionHandler;
68 * Create a commissioning provider.
70 * @param serviceTemplateProvider the ServiceTemplate Provider
71 * @param acProvider the AutomationComposition Provider
72 * @param supervisionHandler the Supervision Handler
73 * @param participantProvider the Participant Provider
75 public CommissioningProvider(ServiceTemplateProvider serviceTemplateProvider,
76 AutomationCompositionProvider acProvider, SupervisionHandler supervisionHandler,
77 ParticipantProvider participantProvider) {
78 this.serviceTemplateProvider = serviceTemplateProvider;
79 this.acProvider = acProvider;
80 this.supervisionHandler = supervisionHandler;
81 this.participantProvider = participantProvider;
85 * Create automation compositions from a service template.
87 * @param serviceTemplate the service template
88 * @return the result of the commissioning operation
89 * @throws PfModelException on creation errors
91 public CommissioningResponse createAutomationCompositionDefinitions(ToscaServiceTemplate serviceTemplate)
92 throws PfModelException {
94 if (verifyIfInstancePropertiesExists()) {
95 throw new PfModelException(Status.BAD_REQUEST,
96 "Delete instances, to commission automation composition definitions");
98 serviceTemplate = serviceTemplateProvider.createServiceTemplate(serviceTemplate);
99 List<Participant> participantList = participantProvider.getParticipants();
100 if (!participantList.isEmpty()) {
101 supervisionHandler.handleSendCommissionMessage(serviceTemplate.getName(), serviceTemplate.getVersion());
103 var response = new CommissioningResponse();
105 response.setAffectedAutomationCompositionDefinitions(
106 serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
109 .map(template -> template.getKey().asIdentifier())
110 .collect(Collectors.toList()));
117 * Delete the automation composition definition with the given name and version.
119 * @param name the name of the automation composition definition to delete
120 * @param version the version of the automation composition to delete
121 * @return the result of the deletion
122 * @throws PfModelException on deletion errors
124 public CommissioningResponse deleteAutomationCompositionDefinition(String name, String version)
125 throws PfModelException {
127 if (verifyIfInstancePropertiesExists()) {
128 throw new PfModelException(Status.BAD_REQUEST,
129 "Delete instances, to commission automation composition definitions");
131 List<Participant> participantList = participantProvider.getParticipants();
132 if (!participantList.isEmpty()) {
133 supervisionHandler.handleSendDeCommissionMessage();
135 serviceTemplateProvider.deleteServiceTemplate(name, version);
136 var response = new CommissioningResponse();
137 response.setAffectedAutomationCompositionDefinitions(List.of(new ToscaConceptIdentifier(name, version)));
143 * Get automation composition node templates.
145 * @param acName the name of the automation composition, null for all
146 * @param acVersion the version of the automation composition, null for all
147 * @return list of automation composition node templates
148 * @throws PfModelException on errors getting automation composition definitions
150 @Transactional(readOnly = true)
151 public List<ToscaNodeTemplate> getAutomationCompositionDefinitions(String acName, String acVersion)
152 throws PfModelException {
155 ToscaTypedEntityFilter<ToscaNodeTemplate> nodeTemplateFilter = ToscaTypedEntityFilter
156 .<ToscaNodeTemplate>builder()
159 .type(AUTOMATION_COMPOSITION_NODE_TYPE)
163 return acProvider.getFilteredNodeTemplates(nodeTemplateFilter);
167 * Get the automation composition elements from a automation composition node template.
169 * @param automationCompositionNodeTemplate the automation composition node template
170 * @return a list of the automation composition element node templates in a automation composition node template
171 * @throws PfModelException on errors get automation composition element node templates
173 @Transactional(readOnly = true)
174 public List<ToscaNodeTemplate> getAutomationCompositionElementDefinitions(
175 ToscaNodeTemplate automationCompositionNodeTemplate) throws PfModelException {
176 if (!AUTOMATION_COMPOSITION_NODE_TYPE.equals(automationCompositionNodeTemplate.getType())) {
177 return Collections.emptyList();
180 if (MapUtils.isEmpty(automationCompositionNodeTemplate.getProperties())) {
181 return Collections.emptyList();
184 @SuppressWarnings("unchecked")
185 List<Map<String, String>> automationCompositionElements =
186 (List<Map<String, String>>) automationCompositionNodeTemplate.getProperties().get("elements");
188 if (CollectionUtils.isEmpty(automationCompositionElements)) {
189 return Collections.emptyList();
192 List<ToscaNodeTemplate> automationCompositionElementList = new ArrayList<>();
194 automationCompositionElementList.addAll(
195 automationCompositionElements
197 .map(elementMap -> acProvider.getNodeTemplates(elementMap.get("name"),
198 elementMap.get("version")))
199 .flatMap(List::stream)
200 .collect(Collectors.toList())
204 return automationCompositionElementList;
208 * Get the requested automation composition definitions.
210 * @param name the name of the definition to get, null for all definitions
211 * @param version the version of the definition to get, null for all definitions
212 * @return the automation composition definitions
213 * @throws PfModelException on errors getting automation composition definitions
215 @Transactional(readOnly = true)
216 public ToscaServiceTemplate getToscaServiceTemplate(String name, String version) throws PfModelException {
217 return serviceTemplateProvider.getToscaServiceTemplate(name, version);
221 * Get All the requested automation composition definitions.
223 * @return the automation composition definitions
224 * @throws PfModelException on errors getting automation composition definitions
226 @Transactional(readOnly = true)
227 public List<ToscaServiceTemplate> getAllToscaServiceTemplate() throws PfModelException {
228 return serviceTemplateProvider.getAllServiceTemplates();
232 * Get the tosca service template with only required sections.
234 * @param name the name of the template to get, null for all definitions
235 * @param version the version of the template to get, null for all definitions
236 * @param instanceName automation composition name
237 * @return the tosca service template
238 * @throws PfModelException on errors getting tosca service template
240 @Transactional(readOnly = true)
241 public String getToscaServiceTemplateReduced(
242 final String name, final String version, final String instanceName)
243 throws PfModelException {
245 var serviceTemplateList = serviceTemplateProvider.getServiceTemplateList(name, version);
247 List<ToscaServiceTemplate> filteredServiceTemplateList =
248 filterToscaNodeTemplateInstance(serviceTemplateList, instanceName);
250 if (filteredServiceTemplateList.isEmpty()) {
251 throw new PfModelException(Status.BAD_REQUEST, "Invalid Service Template");
254 ToscaServiceTemplate fullTemplate = filteredServiceTemplateList.get(0);
256 var template = new HashMap<String, Object>();
257 template.put("tosca_definitions_version", fullTemplate.getToscaDefinitionsVersion());
258 template.put("data_types", fullTemplate.getDataTypes());
259 template.put("policy_types", fullTemplate.getPolicyTypes());
260 template.put("node_types", fullTemplate.getNodeTypes());
261 template.put("topology_template", fullTemplate.getToscaTopologyTemplate());
264 return CODER.encode(template);
266 } catch (CoderException e) {
267 throw new PfModelException(Status.BAD_REQUEST, "Converion to Json Schema failed", e);
272 * Filters service templates if is not an instantiation type.
274 * @param serviceTemplates tosca service template
275 * @param instanceName automation composition name
276 * @return List of tosca service templates
278 private List<ToscaServiceTemplate> filterToscaNodeTemplateInstance(
279 List<ToscaServiceTemplate> serviceTemplates, String instanceName) {
281 List<ToscaServiceTemplate> toscaServiceTemplates = new ArrayList<>();
283 serviceTemplates.forEach(serviceTemplate -> {
285 Map<String, ToscaNodeTemplate> toscaNodeTemplates = new HashMap<>();
287 serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().forEach((key, nodeTemplate) -> {
288 if (StringUtils.isNotEmpty(instanceName) && nodeTemplate.getName().contains(instanceName)) {
289 toscaNodeTemplates.put(key, nodeTemplate);
290 } else if (!nodeTemplate.getName().contains(HYPHEN)) {
291 toscaNodeTemplates.put(key, nodeTemplate);
295 serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().clear();
296 serviceTemplate.getToscaTopologyTemplate().setNodeTemplates(toscaNodeTemplates);
298 toscaServiceTemplates.add(serviceTemplate);
301 return toscaServiceTemplates;
305 * Validates to see if there is any instance properties saved.
307 * @return true if exists instance properties
309 private boolean verifyIfInstancePropertiesExists() {
310 return acProvider.getAllNodeTemplates().stream()
311 .anyMatch(nodeTemplate -> nodeTemplate.getKey().getName().contains(HYPHEN));