Added oparent to sdc main
[sdc.git] / openecomp-be / lib / openecomp-sdc-model-lib / openecomp-sdc-model-impl / src / main / java / org / openecomp / sdc / model / impl / zusammen / ServiceModelDaoZusammenImpl.java
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
21 package org.openecomp.sdc.model.impl.zusammen;
22
23 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
24 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
25 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
26 import com.amdocs.zusammen.datatypes.Id;
27 import com.amdocs.zusammen.datatypes.SessionContext;
28 import com.amdocs.zusammen.datatypes.item.Action;
29 import com.amdocs.zusammen.datatypes.item.ElementContext;
30 import com.amdocs.zusammen.datatypes.item.Info;
31 import org.apache.commons.io.IOUtils;
32 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
33 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
34 import org.openecomp.core.model.dao.ServiceModelDao;
35 import org.openecomp.core.model.errors.RetrieveServiceTemplateFromDbErrorBuilder;
36 import org.openecomp.core.model.types.ServiceElement;
37 import org.openecomp.core.utilities.file.FileContentHandler;
38 import org.openecomp.core.zusammen.api.ZusammenAdaptor;
39 import org.openecomp.core.zusammen.api.ZusammenUtil;
40 import org.openecomp.sdc.common.errors.CoreException;
41 import org.openecomp.sdc.datatypes.model.ElementType;
42 import org.openecomp.sdc.logging.api.Logger;
43 import org.openecomp.sdc.logging.api.LoggerFactory;
44 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
45 import org.openecomp.sdc.versioning.dao.types.Version;
46 import org.openecomp.types.ElementPropertyName;
47
48 import java.io.ByteArrayInputStream;
49 import java.util.Collection;
50 import java.util.Map;
51 import java.util.Objects;
52 import java.util.Optional;
53 import java.util.stream.Collectors;
54
55 import static org.openecomp.core.zusammen.api.ZusammenUtil.buildElement;
56 import static org.openecomp.core.zusammen.api.ZusammenUtil.buildStructuralElement;
57
58 public class ServiceModelDaoZusammenImpl
59     implements ServiceModelDao<ToscaServiceModel, ServiceElement> {
60   private static final String BASE_PROPERTY = "base";
61   private static final Logger logger = LoggerFactory.getLogger(ServiceModelDaoZusammenImpl.class);
62
63   protected ZusammenAdaptor zusammenAdaptor;
64   protected ElementType elementType;
65
66   public ServiceModelDaoZusammenImpl(ZusammenAdaptor zusammenAdaptor) {
67     this.zusammenAdaptor = zusammenAdaptor;
68     this.elementType = ElementType.ServiceModel;
69   }
70
71   @Override
72   public void registerVersioning(String versionableEntityType) {
73
74   }
75
76   @Override
77   public ToscaServiceModel getServiceModel(String vspId, Version version) {
78     SessionContext context = ZusammenUtil.createSessionContext();
79     ElementContext elementContext = new ElementContext(vspId, version.getId());
80
81     Optional<ElementInfo> serviceModel = getServiceModelElementInfo(context, elementContext);
82     if (!serviceModel.isPresent()) {
83       return null;
84     }
85
86     Id serviceModelElementId = serviceModel.get().getId();
87     Map<String, ServiceTemplate> serviceTemplates =
88         getTemplates(context, elementContext, serviceModelElementId);
89     if (serviceTemplates == null) {
90       return null;
91     }
92
93     FileContentHandler artifacts = getArtifacts(context, elementContext, serviceModelElementId);
94     String entryDefinitionServiceTemplate =
95         serviceModel.get().getInfo().getProperty(BASE_PROPERTY);
96
97     return new ToscaServiceModel(artifacts, serviceTemplates, entryDefinitionServiceTemplate);
98   }
99
100   @Override
101   public void storeServiceModel(String vspId, Version version, ToscaServiceModel serviceModel) {
102     logger.info("Storing service model for VendorSoftwareProduct id -> {}", vspId);
103
104     ZusammenElement templatesElement = buildStructuralElement(ElementType.Templates, Action.UPDATE);
105     serviceModel.getServiceTemplates().forEach((key, value) -> templatesElement.addSubElement(
106             buildServiceTemplateElement(key, value, serviceModel.getEntryDefinitionServiceTemplate(), Action.CREATE)));
107
108     ZusammenElement artifactsElement = buildStructuralElement(ElementType.Artifacts, Action.UPDATE);
109     if (Objects.nonNull(serviceModel.getArtifactFiles())) {
110       serviceModel.getArtifactFiles().getFiles().forEach(
111               (key, value) -> artifactsElement.addSubElement(buildArtifactElement(key, value, Action.CREATE)));
112     }
113
114     ZusammenElement serviceModelElement = buildServiceModelElement(serviceModel.getEntryDefinitionServiceTemplate());
115
116     serviceModelElement.addSubElement(templatesElement);
117     serviceModelElement.addSubElement(artifactsElement);
118
119     ZusammenElement vspModel = buildStructuralElement(ElementType.VspModel, Action.IGNORE);
120     vspModel.addSubElement(serviceModelElement);
121
122     SessionContext context = ZusammenUtil.createSessionContext();
123     ElementContext elementContext = new ElementContext(vspId, version.getId());
124     zusammenAdaptor.saveElement(context, elementContext, vspModel, "Store service model");
125
126     logger
127         .info("Finished storing {} for VendorSoftwareProduct id -> {}", elementType.name(), vspId);
128   }
129
130   @Override
131   public ServiceElement getServiceModelInfo(String vspId, Version version, String name) {
132     return null;
133   }
134
135   @Override
136   public void deleteAll(String vspId, Version version) {
137     logger.info("Started deleting content of Templates and Artifacts of {} of vsp {} version {}",
138         elementType.name(), vspId, version.getId());
139
140     SessionContext context = ZusammenUtil.createSessionContext();
141     ElementContext elementContext = new ElementContext(vspId, version.getId());
142
143     Optional<ElementInfo> serviceModel = getServiceModelElementInfo(context, elementContext);
144     if (!serviceModel.isPresent()) {
145       logger.info("{} of vsp {} version {} does not exist - nothing to delete", elementType.name(),
146           vspId, version.getId());
147       return;
148     }
149
150     ZusammenElement serviceModelElement = buildElement(serviceModel.get().getId(), Action.IGNORE);
151     for (Id serviceModelSubElementId :
152         serviceModel.get().getSubElements().stream()
153             .map(ElementInfo::getId)
154             .collect(Collectors.toSet())) {
155       ElementInfo serviceModelSubElementInfo =
156           zusammenAdaptor.getElementInfo(context, elementContext, serviceModelSubElementId)
157               .orElseThrow(() -> new IllegalStateException(String.format(
158                   "Element %s declared as sub element of element %s (%s) does not exist",
159                   serviceModelSubElementId.getValue(),
160                   serviceModel.get().getId().getValue(),
161                   elementType.name())));
162
163       if (ElementType.Templates.name().equals(serviceModelSubElementInfo.getInfo().getName())
164           || ElementType.Artifacts.name().equals(serviceModelSubElementInfo.getInfo().getName())) {
165         ZusammenElement serviceModelSubElement =
166             buildElement(serviceModelSubElementId, Action.IGNORE);
167         serviceModelSubElement.setSubElements(serviceModelSubElementInfo.getSubElements().stream()
168             .map(elementInfo -> buildElement(elementInfo.getId(), Action.DELETE))
169             .collect(Collectors.toSet()));
170         serviceModelElement.addSubElement(serviceModelSubElement);
171       }
172     }
173
174     zusammenAdaptor.saveElement(context, elementContext, serviceModelElement,
175         String.format("Delete content of Templates and Artifacts of %s", elementType.name()));
176
177     logger.info("Finished deleting content of Templates and Artifacts of {} of vsp {} version {}",
178         elementType.name(), vspId, version.getId());
179   }
180
181   @Override
182   public void overrideServiceModel(String vspId,
183                                    Version version,
184                                    ToscaServiceModel serviceModel) {
185     SessionContext context = ZusammenUtil.createSessionContext();
186     ElementContext elementContext = new ElementContext(vspId, version.getId());
187
188     Optional<ElementInfo> origServiceModel = getServiceModelElementInfo(context, elementContext);
189     if (!origServiceModel.isPresent()) {
190       return;
191     }
192     Id serviceModelElementId = origServiceModel.get().getId();
193
194     ZusammenElement serviceModelElement = buildServiceModelElement(serviceModel.getEntryDefinitionServiceTemplate());
195     serviceModelElement.setElementId(serviceModelElementId);
196
197     overrideServiceTemplates(serviceModelElementId, serviceModel, context, elementContext, serviceModelElement);
198
199     zusammenAdaptor.saveElement(context, elementContext, serviceModelElement, "Override service model");
200   }
201
202
203   private void overrideServiceTemplates(Id serviceModelElementId,
204                                         ToscaServiceModel serviceModel,
205                                         SessionContext context,
206                                         ElementContext elementContext,
207                                         ZusammenElement serviceModelElement) {
208     Optional<ElementInfo> elementInfo = zusammenAdaptor.getElementInfoByName(
209         context, elementContext, serviceModelElementId, ElementType.Templates.name());
210     if (!elementInfo.isPresent()) {
211       return;
212     }
213     ZusammenElement templateElement = buildStructuralElement(ElementType.Templates, Action.UPDATE);
214     templateElement.setElementId(elementInfo.get().getId());
215     serviceModel.getServiceTemplates().forEach((templateName, serviceTemplate) -> templateElement.addSubElement(
216         buildServiceTemplateElement(templateName, serviceTemplate,
217             serviceModel.getEntryDefinitionServiceTemplate(), Action.UPDATE)));
218     serviceModelElement.addSubElement(templateElement);
219   }
220
221   private Optional<ElementInfo> getServiceModelElementInfo(SessionContext context,
222                                                            ElementContext elementContext) {
223     Collection<ElementInfo> vspModelSubs = zusammenAdaptor
224         .listElementsByName(context, elementContext, null, ElementType.VspModel.name());
225
226     return vspModelSubs.stream()
227         .filter(elementInfo -> elementInfo.getInfo() != null
228             && elementType.name().equals(elementInfo.getInfo().getName()))
229         .findFirst();
230   }
231
232   private Map<String, ServiceTemplate> getTemplates(SessionContext context,
233                                                     ElementContext elementContext,
234                                                     Id serviceModelElementId) {
235     Optional<ElementInfo> templatesElementInfo = zusammenAdaptor.getElementInfoByName(
236         context, elementContext, serviceModelElementId, ElementType.Templates.name());
237
238     if (templatesElementInfo.isPresent()) {
239       Collection<Element> elements = zusammenAdaptor.listElementData(context, elementContext,
240           templatesElementInfo.get().getId());
241
242       return elements.stream().collect(Collectors.toMap(
243           element -> element.getInfo().getName(),
244           this::elementToServiceTemplate));
245     }
246     return null;
247   }
248
249   private FileContentHandler getArtifacts(SessionContext context, ElementContext elementContext,
250                                           Id serviceModelElementId) {
251     Optional<ElementInfo> artifactsElement = zusammenAdaptor.getElementInfoByName(
252         context, elementContext, serviceModelElementId, ElementType.Artifacts.name());
253
254     if (artifactsElement.isPresent()) {
255
256       Collection<Element> elements = zusammenAdaptor.listElementData(context, elementContext,
257           artifactsElement.get().getId());
258       FileContentHandler fileContentHandler = new FileContentHandler();
259       elements.forEach(element -> fileContentHandler.addFile(element.getInfo().getName(),
260           element.getData()));
261       return fileContentHandler;
262     }
263
264     return null;
265   }
266
267   private ZusammenElement buildServiceModelElement(String entryDefinitionServiceTemplate) {
268     ZusammenElement serviceModelElement = buildStructuralElement(elementType, Action.UPDATE);
269     serviceModelElement.getInfo().addProperty(BASE_PROPERTY, entryDefinitionServiceTemplate);
270     return serviceModelElement;
271   }
272
273   private Element buildServiceTemplateElement(String name, ServiceTemplate serviceTemplate,
274                                               String entryDefinitionServiceTemplate,
275                                               Action action) {
276     ZusammenElement zusammenElement = buildElement(null, action);
277     Info info = new Info();
278     info.setName(name);
279     info.setDescription(serviceTemplate.getDescription());
280     info.addProperty(ElementPropertyName.elementType.name(), ElementType.ServiceTemplate.name());
281     info.addProperty(BASE_PROPERTY, entryDefinitionServiceTemplate);
282     String yaml = new ToscaExtensionYamlUtil().objectToYaml(serviceTemplate);
283     zusammenElement.setData(new ByteArrayInputStream(yaml.getBytes()));
284     zusammenElement.setInfo(info);
285     return zusammenElement;
286   }
287
288   protected ZusammenElement buildArtifactElement(String name, byte[] artifact, Action action) {
289     ZusammenElement artifactElement = buildElement(null, action);
290     Info info = new Info();
291     info.setName(name);
292     info.addProperty(ElementPropertyName.elementType.name(), ElementType.Artifact.name());
293     artifactElement.setInfo(info);
294     artifactElement.setData(new ByteArrayInputStream(artifact));
295
296     return artifactElement;
297   }
298
299
300   private ServiceTemplate elementToServiceTemplate(Element element) {
301     try {
302       String yamlContent = IOUtils.toString(element.getData());
303       return new ToscaExtensionYamlUtil().
304           yamlToObject(yamlContent, ServiceTemplate.class);
305     } catch (Exception e) {
306       throw new CoreException(
307           new RetrieveServiceTemplateFromDbErrorBuilder(
308               element.getInfo().getName(), e.getMessage()).build());
309     }
310   }
311 }