27ef1132043314bea508761e036316fe889e33c5
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.model.impl.zusammen;
21
22 import static org.openecomp.core.zusammen.api.ZusammenUtil.buildElement;
23 import static org.openecomp.core.zusammen.api.ZusammenUtil.buildStructuralElement;
24
25 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
26 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
27 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
28 import com.amdocs.zusammen.datatypes.Id;
29 import com.amdocs.zusammen.datatypes.SessionContext;
30 import com.amdocs.zusammen.datatypes.item.Action;
31 import com.amdocs.zusammen.datatypes.item.ElementContext;
32 import com.amdocs.zusammen.datatypes.item.Info;
33 import java.io.ByteArrayInputStream;
34 import java.util.Collection;
35 import java.util.Map;
36 import java.util.Objects;
37 import java.util.Optional;
38 import java.util.stream.Collectors;
39 import org.apache.commons.io.IOUtils;
40 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
41 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
42 import org.openecomp.core.model.dao.ServiceModelDao;
43 import org.openecomp.core.model.errors.RetrieveServiceTemplateFromDbErrorBuilder;
44 import org.openecomp.core.model.types.ServiceElement;
45 import org.openecomp.core.utilities.file.FileContentHandler;
46 import org.openecomp.core.zusammen.api.ZusammenAdaptor;
47 import org.openecomp.core.zusammen.api.ZusammenUtil;
48 import org.openecomp.sdc.common.errors.CoreException;
49 import org.openecomp.sdc.datatypes.model.ElementType;
50 import org.openecomp.sdc.logging.api.Logger;
51 import org.openecomp.sdc.logging.api.LoggerFactory;
52 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
53 import org.openecomp.sdc.versioning.dao.types.Version;
54 import org.openecomp.types.ElementPropertyName;
55
56 public class ServiceModelDaoZusammenImpl implements ServiceModelDao<ToscaServiceModel, ServiceElement> {
57
58     private static final String BASE_PROPERTY = "base";
59     private static final Logger logger = LoggerFactory.getLogger(ServiceModelDaoZusammenImpl.class);
60     protected ZusammenAdaptor zusammenAdaptor;
61     protected ElementType elementType;
62
63     public ServiceModelDaoZusammenImpl(ZusammenAdaptor zusammenAdaptor) {
64         this.zusammenAdaptor = zusammenAdaptor;
65         this.elementType = ElementType.ServiceModel;
66     }
67
68     @Override
69     public void registerVersioning(String versionableEntityType) {
70     }
71
72     @Override
73     public ToscaServiceModel getServiceModel(String vspId, Version version) {
74         SessionContext context = ZusammenUtil.createSessionContext();
75         ElementContext elementContext = new ElementContext(vspId, version.getId());
76         Optional<ElementInfo> serviceModel = getServiceModelElementInfo(context, elementContext);
77         if (!serviceModel.isPresent()) {
78             return null;
79         }
80         Id serviceModelElementId = serviceModel.get().getId();
81         Map<String, ServiceTemplate> serviceTemplates = getTemplates(context, elementContext, serviceModelElementId);
82         if (serviceTemplates == null) {
83             return null;
84         }
85         FileContentHandler artifacts = getArtifacts(context, elementContext, serviceModelElementId);
86         String entryDefinitionServiceTemplate = serviceModel.get().getInfo().getProperty(BASE_PROPERTY);
87         return new ToscaServiceModel(artifacts, serviceTemplates, entryDefinitionServiceTemplate);
88     }
89
90     @Override
91     public void storeServiceModel(String vspId, Version version, ToscaServiceModel serviceModel) {
92         logger.info("Storing service model for VendorSoftwareProduct id -> {}", vspId);
93         ZusammenElement templatesElement = buildStructuralElement(ElementType.Templates, Action.UPDATE);
94         serviceModel.getServiceTemplates().forEach((key, value) -> templatesElement
95             .addSubElement(buildServiceTemplateElement(key, value, serviceModel.getEntryDefinitionServiceTemplate(), Action.CREATE)));
96         ZusammenElement artifactsElement = buildStructuralElement(ElementType.Artifacts, Action.UPDATE);
97         if (Objects.nonNull(serviceModel.getArtifactFiles())) {
98             serviceModel.getArtifactFiles().getFiles()
99                 .forEach((key, value) -> artifactsElement.addSubElement(buildArtifactElement(key, value, Action.CREATE)));
100         }
101         ZusammenElement serviceModelElement = buildServiceModelElement(serviceModel.getEntryDefinitionServiceTemplate());
102         serviceModelElement.addSubElement(templatesElement);
103         serviceModelElement.addSubElement(artifactsElement);
104         ZusammenElement vspModel = buildStructuralElement(ElementType.VspModel, Action.IGNORE);
105         vspModel.addSubElement(serviceModelElement);
106         SessionContext context = ZusammenUtil.createSessionContext();
107         ElementContext elementContext = new ElementContext(vspId, version.getId());
108         zusammenAdaptor.saveElement(context, elementContext, vspModel, "Store service model");
109         logger.info("Finished storing {} for VendorSoftwareProduct id -> {}", elementType.name(), vspId);
110     }
111
112     @Override
113     public ServiceElement getServiceModelInfo(String vspId, Version version, String name) {
114         return null;
115     }
116
117     @Override
118     public void deleteAll(String vspId, Version version) {
119         logger.info("Started deleting content of Templates and Artifacts of {} of vsp {} version {}", elementType.name(), vspId, version.getId());
120         SessionContext context = ZusammenUtil.createSessionContext();
121         ElementContext elementContext = new ElementContext(vspId, version.getId());
122         Optional<ElementInfo> serviceModel = getServiceModelElementInfo(context, elementContext);
123         if (!serviceModel.isPresent()) {
124             logger.info("{} of vsp {} version {} does not exist - nothing to delete", elementType.name(), vspId, version.getId());
125             return;
126         }
127         ZusammenElement serviceModelElement = buildElement(serviceModel.get().getId(), Action.IGNORE);
128         for (Id serviceModelSubElementId : serviceModel.get().getSubElements().stream().map(ElementInfo::getId).collect(Collectors.toSet())) {
129             ElementInfo serviceModelSubElementInfo = zusammenAdaptor.getElementInfo(context, elementContext, serviceModelSubElementId).orElseThrow(
130                 () -> new IllegalStateException(String
131                     .format("Element %s declared as sub element of element %s (%s) does not exist", serviceModelSubElementId.getValue(),
132                         serviceModel.get().getId().getValue(), elementType.name())));
133             if (ElementType.Templates.name().equals(serviceModelSubElementInfo.getInfo().getName()) || ElementType.Artifacts.name()
134                 .equals(serviceModelSubElementInfo.getInfo().getName())) {
135                 ZusammenElement serviceModelSubElement = buildElement(serviceModelSubElementId, Action.IGNORE);
136                 serviceModelSubElement.setSubElements(
137                     serviceModelSubElementInfo.getSubElements().stream().map(elementInfo -> buildElement(elementInfo.getId(), Action.DELETE))
138                         .collect(Collectors.toSet()));
139                 serviceModelElement.addSubElement(serviceModelSubElement);
140             }
141         }
142         zusammenAdaptor.saveElement(context, elementContext, serviceModelElement,
143             String.format("Delete content of Templates and Artifacts of %s", elementType.name()));
144         logger.info("Finished deleting content of Templates and Artifacts of {} of vsp {} version {}", elementType.name(), vspId, version.getId());
145     }
146
147     @Override
148     public void overrideServiceModel(String vspId, Version version, ToscaServiceModel serviceModel) {
149         SessionContext context = ZusammenUtil.createSessionContext();
150         ElementContext elementContext = new ElementContext(vspId, version.getId());
151         Optional<ElementInfo> origServiceModel = getServiceModelElementInfo(context, elementContext);
152         if (!origServiceModel.isPresent()) {
153             return;
154         }
155         Id serviceModelElementId = origServiceModel.get().getId();
156         ZusammenElement serviceModelElement = buildServiceModelElement(serviceModel.getEntryDefinitionServiceTemplate());
157         serviceModelElement.setElementId(serviceModelElementId);
158         overrideServiceTemplates(serviceModelElementId, serviceModel, context, elementContext, serviceModelElement);
159         zusammenAdaptor.saveElement(context, elementContext, serviceModelElement, "Override service model");
160     }
161
162     private void overrideServiceTemplates(Id serviceModelElementId, ToscaServiceModel serviceModel, SessionContext context,
163                                           ElementContext elementContext, ZusammenElement serviceModelElement) {
164         Optional<ElementInfo> elementInfo = zusammenAdaptor
165             .getElementInfoByName(context, elementContext, serviceModelElementId, ElementType.Templates.name());
166         if (!elementInfo.isPresent()) {
167             return;
168         }
169         ZusammenElement templateElement = buildStructuralElement(ElementType.Templates, Action.UPDATE);
170         templateElement.setElementId(elementInfo.get().getId());
171         serviceModel.getServiceTemplates().forEach((templateName, serviceTemplate) -> templateElement.addSubElement(
172             buildServiceTemplateElement(templateName, serviceTemplate, serviceModel.getEntryDefinitionServiceTemplate(), Action.UPDATE)));
173         serviceModelElement.addSubElement(templateElement);
174     }
175
176     private Optional<ElementInfo> getServiceModelElementInfo(SessionContext context, ElementContext elementContext) {
177         Collection<ElementInfo> vspModelSubs = zusammenAdaptor.listElementsByName(context, elementContext, null, ElementType.VspModel.name());
178         return vspModelSubs.stream()
179             .filter(elementInfo -> elementInfo.getInfo() != null && elementType.name().equals(elementInfo.getInfo().getName())).findFirst();
180     }
181
182     private Map<String, ServiceTemplate> getTemplates(SessionContext context, ElementContext elementContext, Id serviceModelElementId) {
183         Optional<ElementInfo> templatesElementInfo = zusammenAdaptor
184             .getElementInfoByName(context, elementContext, serviceModelElementId, ElementType.Templates.name());
185         if (templatesElementInfo.isPresent()) {
186             Collection<Element> elements = zusammenAdaptor.listElementData(context, elementContext, templatesElementInfo.get().getId());
187             return elements.stream().collect(Collectors.toMap(element -> element.getInfo().getName(), this::elementToServiceTemplate));
188         }
189         return null;
190     }
191
192     private FileContentHandler getArtifacts(SessionContext context, ElementContext elementContext, Id serviceModelElementId) {
193         Optional<ElementInfo> artifactsElement = zusammenAdaptor
194             .getElementInfoByName(context, elementContext, serviceModelElementId, ElementType.Artifacts.name());
195         if (artifactsElement.isPresent()) {
196             Collection<Element> elements = zusammenAdaptor.listElementData(context, elementContext, artifactsElement.get().getId());
197             FileContentHandler fileContentHandler = new FileContentHandler();
198             elements.forEach(element -> fileContentHandler.addFile(element.getInfo().getName(), element.getData()));
199             return fileContentHandler;
200         }
201         return null;
202     }
203
204     private ZusammenElement buildServiceModelElement(String entryDefinitionServiceTemplate) {
205         ZusammenElement serviceModelElement = buildStructuralElement(elementType, Action.UPDATE);
206         serviceModelElement.getInfo().addProperty(BASE_PROPERTY, entryDefinitionServiceTemplate);
207         return serviceModelElement;
208     }
209
210     private Element buildServiceTemplateElement(String name, ServiceTemplate serviceTemplate, String entryDefinitionServiceTemplate, Action action) {
211         ZusammenElement zusammenElement = buildElement(null, action);
212         Info info = new Info();
213         info.setName(name);
214         info.setDescription(serviceTemplate.getDescription());
215         info.addProperty(ElementPropertyName.elementType.name(), ElementType.ServiceTemplate.name());
216         info.addProperty(BASE_PROPERTY, entryDefinitionServiceTemplate);
217         String yaml = new ToscaExtensionYamlUtil().objectToYaml(serviceTemplate);
218         zusammenElement.setData(new ByteArrayInputStream(yaml.getBytes()));
219         zusammenElement.setInfo(info);
220         return zusammenElement;
221     }
222
223     protected ZusammenElement buildArtifactElement(String name, byte[] artifact, Action action) {
224         ZusammenElement artifactElement = buildElement(null, action);
225         Info info = new Info();
226         info.setName(name);
227         info.addProperty(ElementPropertyName.elementType.name(), ElementType.Artifact.name());
228         artifactElement.setInfo(info);
229         artifactElement.setData(new ByteArrayInputStream(artifact));
230         return artifactElement;
231     }
232
233     private ServiceTemplate elementToServiceTemplate(Element element) {
234         try {
235             String yamlContent = IOUtils.toString(element.getData());
236             return new ToscaExtensionYamlUtil().yamlToObject(yamlContent, ServiceTemplate.class);
237         } catch (Exception e) {
238             throw new CoreException(new RetrieveServiceTemplateFromDbErrorBuilder(element.getInfo().getName(), e.getMessage()).build());
239         }
240     }
241 }