Catalog alignment
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / ecomp / converters / AssetMetadataConverter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 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.be.ecomp.converters;
22
23 import fj.data.Either;
24 import org.apache.commons.collections.MapUtils;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
26 import org.openecomp.sdc.be.dao.api.ActionStatus;
27 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
28 import org.openecomp.sdc.be.distribution.servlet.DistributionCatalogServlet;
29 import org.openecomp.sdc.be.externalapi.servlet.representation.ArtifactMetadata;
30 import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata;
31 import org.openecomp.sdc.be.externalapi.servlet.representation.ResourceAssetDetailedMetadata;
32 import org.openecomp.sdc.be.externalapi.servlet.representation.ResourceAssetMetadata;
33 import org.openecomp.sdc.be.externalapi.servlet.representation.ResourceInstanceMetadata;
34 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceAssetDetailedMetadata;
35 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceAssetMetadata;
36 import org.openecomp.sdc.be.impl.ComponentsUtils;
37 import org.openecomp.sdc.be.model.ArtifactDefinition;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.ComponentInstance;
40 import org.openecomp.sdc.be.model.Resource;
41 import org.openecomp.sdc.be.model.Service;
42 import org.openecomp.sdc.be.model.category.CategoryDefinition;
43 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
44 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
45 import org.openecomp.sdc.common.log.wrappers.Logger;
46 import org.openecomp.sdc.exception.ResponseFormat;
47 import org.springframework.beans.factory.annotation.Autowired;
48
49 import java.util.Collection;
50 import java.util.HashMap;
51 import java.util.LinkedList;
52 import java.util.List;
53 import java.util.Map;
54
55 @org.springframework.stereotype.Component("asset-metadata-utils")
56 public class AssetMetadataConverter {
57     private static final Logger log = Logger.getLogger(DistributionCatalogServlet.class);
58
59     @Autowired
60     private ComponentsUtils componentsUtils;
61
62     @Autowired
63     protected ToscaOperationFacade toscaOperationFacade;
64
65     /*
66      * Relative asset’s URL. Should be used in REST GET API to download the asset’s CSAR. https://{serverBaseURL}/{csarPath} can be obtained from (HttpServletRequest)request.getServerName()
67      */
68     public Either<List<? extends AssetMetadata>, ResponseFormat> convertToAssetMetadata(List<? extends Component> componentList, String serverBaseURL, boolean detailed) {
69         if (componentList == null || componentList.isEmpty()) {
70             return Either.left(new LinkedList<>());
71         }
72         List<AssetMetadata> retResList = new LinkedList<>();
73
74         for (Component curr : componentList) {
75             Either<? extends AssetMetadata, ResponseFormat> resMetaData = convertToSingleAssetMetadata(curr, serverBaseURL, detailed);
76             if (resMetaData.isRight()) {
77                 return Either.right(resMetaData.right().value());
78             }
79             retResList.add(resMetaData.left().value());
80         }
81
82         return Either.left(retResList);
83
84     }
85
86     public <T extends Component> Either<? extends AssetMetadata, ResponseFormat> convertToSingleAssetMetadata(T component, String serverBaseURL, boolean detailed) {
87         ComponentTypeEnum componentType = component.getComponentType();
88         Either<? extends AssetMetadata, ResponseFormat> resMetaData = convertToMetadata(componentType, serverBaseURL, detailed, component);
89
90         if (resMetaData.isRight()) {
91             return Either.right(resMetaData.right().value());
92         }
93         else{
94             return Either.left(resMetaData.left().value());
95         }
96
97     }
98
99     private Either<? extends AssetMetadata, ResponseFormat> convertToMetadata(ComponentTypeEnum componentType, String serverBaseURL, boolean detailed, Component curr) {
100
101         switch (componentType) {
102
103         case RESOURCE:
104
105             return generateResourceMeatdata(serverBaseURL, detailed, curr);
106
107         case SERVICE:
108
109             return generateServiceMetadata(serverBaseURL, detailed, curr);
110
111         default:
112
113             ResponseFormat responseFormat = componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.COMPONENT_INVALID_CATEGORY);
114             return Either.right(responseFormat);
115         }
116     }
117
118     private Either<? extends AssetMetadata, ResponseFormat> generateResourceMeatdata(String serverBaseURL, boolean detailed, Component curr) {
119         AssetMetadata metaData;
120         metaData = createMetadaObject(detailed, curr.getComponentType());
121         metaData = convertToResourceMetadata((ResourceAssetMetadata) metaData, (Resource) curr, serverBaseURL, detailed);
122
123         if (detailed) {
124             Either<ResourceAssetDetailedMetadata, StorageOperationStatus> converted = convertToResourceDetailedMetadata((ResourceAssetDetailedMetadata) metaData, (Resource) curr, serverBaseURL);
125             if (converted.isRight()) {
126                 ActionStatus storageResponse = componentsUtils.convertFromStorageResponse(converted.right().value(), ComponentTypeEnum.RESOURCE);
127                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(storageResponse);
128                 return Either.right(responseFormat);
129             }
130         }
131
132         return Either.left(metaData);
133     }
134
135     private AssetMetadata createMetadaObject(boolean detailed, ComponentTypeEnum type) {
136         AssetMetadata metaData = null;
137         switch (type) {
138         case SERVICE:
139             if (!detailed) {
140                 metaData = new ServiceAssetMetadata();
141             } else {
142                 metaData = new ServiceAssetDetailedMetadata();
143             }
144             break;
145         case RESOURCE:
146             if (!detailed) {
147                 metaData = new ResourceAssetMetadata();
148             } else {
149                 metaData = new ResourceAssetDetailedMetadata();
150             }
151             break;
152         default:
153             break;
154         }
155         return metaData;
156     }
157
158     private Either<? extends AssetMetadata, ResponseFormat> generateServiceMetadata(String serverBaseURL, boolean detailed, Component curr) {
159         AssetMetadata metaData = createMetadaObject(detailed, curr.getComponentType());
160
161         metaData = convertToServiceAssetMetadata((ServiceAssetMetadata) metaData, (Service) curr, serverBaseURL, detailed);
162
163         if (detailed) {
164             Either<ServiceAssetDetailedMetadata, StorageOperationStatus> converted = convertToServiceDetailedMetadata((ServiceAssetDetailedMetadata) metaData, (Service) curr);
165             if (converted.isRight()) {
166                 ActionStatus storageResponse = componentsUtils.convertFromStorageResponse(converted.right().value(), ComponentTypeEnum.RESOURCE);
167                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(storageResponse);
168                 return Either.right(responseFormat);
169             }
170         }
171
172         return Either.left(metaData);
173     }
174
175     private <U extends AssetMetadata, T extends Component> U convertToAsset(U asset, T component, String serverBaseURL, boolean detailed) {
176         asset.setUuid(component.getUUID());
177         asset.setInvariantUUID(component.getInvariantUUID());
178         asset.setName(component.getName());
179         asset.setVersion(component.getVersion());
180         if (!detailed) {
181             asset.setToscaModelURL(serverBaseURL + "/" + component.getUUID() + "/toscaModel");
182         } else {
183             String toscaModelUrl = (new String(serverBaseURL)).replace("metadata", "toscaModel");
184             asset.setToscaModelURL(toscaModelUrl);
185         }
186
187         return asset;
188     }
189
190     private <T extends ResourceAssetMetadata> T convertToResourceMetadata(T assetToPopulate, Resource resource, String serverBaseURL, boolean detailed) {
191         assetToPopulate = convertToAsset(assetToPopulate, resource, serverBaseURL, detailed);
192         if(resource.getCategories() != null && !resource.getCategories().isEmpty()){
193             CategoryDefinition categoryDefinition = resource.getCategories().get(0);
194             assetToPopulate.setCategory(categoryDefinition.getName());
195             assetToPopulate.setSubCategory(categoryDefinition.getSubcategories().get(0).getName());
196         }
197         assetToPopulate.setResourceType(resource.getResourceType().name());
198         assetToPopulate.setLifecycleState(resource.getLifecycleState().name());
199         assetToPopulate.setLastUpdaterUserId(resource.getLastUpdaterUserId());
200
201         return (T) assetToPopulate;
202     }
203
204     private <T extends ServiceAssetMetadata> T convertToServiceAssetMetadata(T assetToPopulate, Service service, String serverBaseURL, boolean detailed) {
205         assetToPopulate = convertToAsset(assetToPopulate, service, serverBaseURL, detailed);
206
207         if(service.getCategories() != null && !service.getCategories().isEmpty()){
208             CategoryDefinition categoryDefinition = service.getCategories().get(0);
209             assetToPopulate.setCategory(categoryDefinition.getName());
210         }
211
212         assetToPopulate.setLifecycleState(service.getLifecycleState().name());
213         assetToPopulate.setLastUpdaterUserId(service.getLastUpdaterUserId());
214         assetToPopulate.setDistributionStatus(service.getDistributionStatus().name());
215
216         return (T) assetToPopulate;
217     }
218
219     private <T extends ResourceAssetDetailedMetadata> Either<T, StorageOperationStatus> convertToResourceDetailedMetadata(T assetToPopulate, Resource resource, String serverBaseURL) {
220
221         List<ComponentInstance> componentInstances = resource.getComponentInstances();
222
223         if (componentInstances != null) {
224             Either<List<ResourceInstanceMetadata>, StorageOperationStatus> resourceInstanceMetadata = convertToResourceInstanceMetadata(componentInstances, ComponentTypeEnum.RESOURCE_PARAM_NAME, resource.getUUID());
225             if (resourceInstanceMetadata.isRight()) {
226                 return Either.right(resourceInstanceMetadata.right().value());
227             }
228
229             assetToPopulate.setResources(resourceInstanceMetadata.left().value());
230         }
231
232         Map<String, ArtifactDefinition> deploymentArtifacts = resource.getDeploymentArtifacts();
233         assetToPopulate = populateResourceWithArtifacts(assetToPopulate, resource, deploymentArtifacts);
234
235         assetToPopulate.setLastUpdaterFullName(resource.getLastUpdaterFullName());
236         assetToPopulate.setToscaResourceName(resource.getToscaResourceName());
237         assetToPopulate.setDescription(resource.getDescription());
238         return Either.left(assetToPopulate);
239     }
240
241     private <T extends ServiceAssetDetailedMetadata> Either<T, StorageOperationStatus> convertToServiceDetailedMetadata(T assetToPopulate, Service service) {
242
243         List<ComponentInstance> componentInstances = service.getComponentInstances();
244
245         if (componentInstances != null) {
246             Either<List<ResourceInstanceMetadata>, StorageOperationStatus> resourceInstanceMetadata = convertToResourceInstanceMetadata(componentInstances, ComponentTypeEnum.SERVICE_PARAM_NAME, service.getUUID());
247             if (resourceInstanceMetadata.isRight()) {
248                 return Either.right(resourceInstanceMetadata.right().value());
249             }
250
251             assetToPopulate.setResources(resourceInstanceMetadata.left().value());
252         }
253
254         Map<String, ArtifactDefinition> deploymentArtifacts = service.getDeploymentArtifacts();
255         assetToPopulate = populateServiceWithArtifacts(assetToPopulate, service, deploymentArtifacts);
256
257         assetToPopulate.setLastUpdaterFullName(service.getLastUpdaterFullName());
258
259         return Either.left(assetToPopulate);
260     }
261
262     private <T extends ResourceAssetDetailedMetadata> T populateResourceWithArtifacts(T asset, Resource resource, Map<String, ArtifactDefinition> artifacts) {
263
264         List<ArtifactMetadata> artifactMetaList = populateAssetWithArtifacts(resource, artifacts);
265
266         asset.setArtifacts(artifactMetaList);
267
268         return asset;
269     }
270
271     private <T extends ServiceAssetDetailedMetadata> T populateServiceWithArtifacts(T asset, Service service, Map<String, ArtifactDefinition> artifacts) {
272
273         List<ArtifactMetadata> artifactMetaList = populateAssetWithArtifacts(service, artifacts);
274
275         asset.setArtifacts(artifactMetaList);
276
277         return asset;
278     }
279
280     private List<ArtifactMetadata> populateAssetWithArtifacts(Component component, Map<String, ArtifactDefinition> artifacts) {
281         List<ArtifactMetadata> artifactMetaList =  new LinkedList<>();
282         if (artifacts != null) {
283             Collection<ArtifactDefinition> artefactDefList = artifacts.values();
284
285             for (ArtifactDefinition artifactDefinition : artefactDefList) {
286                 if (artifactDefinition.getEsId() != null && !artifactDefinition.getEsId().isEmpty()) {
287                     ArtifactMetadata convertedArtifactMetadata = convertToArtifactMetadata(artifactDefinition, ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUUID(), null);
288                     artifactMetaList.add(convertedArtifactMetadata);
289                 }
290             }
291         }
292         return artifactMetaList.isEmpty() ? null : artifactMetaList;
293     }
294
295     private ArtifactMetadata convertToArtifactMetadata(ArtifactDefinition artifact, String componentType, String componentUUID, String resourceInstanceName) {
296         final String COMPONENT_ARTIFACT_URL = "/sdc/v1/catalog/%s/%s/artifacts/%s";
297
298         final String RESOURCE_INSTANCE_ARTIFACT_URL = "/sdc/v1/catalog/%s/%s/resourceInstances/%s/artifacts/%s";
299
300         ArtifactMetadata metadata = new ArtifactMetadata();
301
302         metadata.setArtifactName(artifact.getArtifactName());
303         metadata.setArtifactType(artifact.getArtifactType());
304
305         if (resourceInstanceName == null || resourceInstanceName.isEmpty()) {
306             metadata.setArtifactURL(String.format(COMPONENT_ARTIFACT_URL, componentType, componentUUID, artifact.getArtifactUUID()));
307         } else {
308             metadata.setArtifactURL(String.format(RESOURCE_INSTANCE_ARTIFACT_URL, componentType, componentUUID, resourceInstanceName, artifact.getArtifactUUID()));
309         }
310
311         metadata.setArtifactDescription(artifact.getDescription());
312         metadata.setArtifactTimeout(artifact.getTimeout() != null && artifact.getTimeout() > 0 ? artifact.getTimeout() : null);
313         metadata.setArtifactChecksum(artifact.getArtifactChecksum());
314         metadata.setArtifactUUID(artifact.getArtifactUUID());
315         metadata.setArtifactVersion(artifact.getArtifactVersion());
316         metadata.setGeneratedFromUUID(artifact.getGeneratedFromId());
317         metadata.setArtifactLabel(artifact.getArtifactLabel());
318         metadata.setArtifactGroupType(artifact.getArtifactGroupType().getType());
319         return metadata;
320     }
321
322     private Either<List<ResourceInstanceMetadata>, StorageOperationStatus> convertToResourceInstanceMetadata(List<ComponentInstance> componentInstances, String componentType, String componentUUID) {
323         List<ResourceInstanceMetadata> retList = new LinkedList<>();
324         Map<String, ImmutablePair<String, String>> uuidDuplicatesMap = new HashMap<>();
325
326         for (ComponentInstance componentInstance : componentInstances) {
327             ResourceInstanceMetadata metadata = new ResourceInstanceMetadata();
328             String componentUid = componentInstance.getComponentUid();
329             String invariantUUID, resourceUUID;
330
331             if (!uuidDuplicatesMap.containsKey(componentUid)) {
332                 Either<Resource, StorageOperationStatus> eitherResource = toscaOperationFacade.getToscaElement(componentInstance.getComponentUid());
333                 if (eitherResource.isRight()) {
334                     log.debug("convertToResourceInstanceMetadata: Failed getting resource with Uid: {}", componentInstance.getComponentUid());
335                     return Either.right(eitherResource.right().value());
336                 } else {
337                     final Resource resource = eitherResource.left().value();
338                     invariantUUID = resource.getInvariantUUID();
339                     resourceUUID = resource.getUUID();
340                     ImmutablePair<String, String> uuidInvariantUUIDPair = new ImmutablePair<>(resourceUUID, invariantUUID);
341                     uuidDuplicatesMap.put(componentUid, uuidInvariantUUIDPair);
342                 }
343             } else {
344                 invariantUUID = uuidDuplicatesMap.get(componentUid).getRight();
345                 resourceUUID =  uuidDuplicatesMap.get(componentUid).getLeft();
346             }
347
348             metadata.setResourceInvariantUUID(invariantUUID);
349             metadata.setResourceUUID(resourceUUID);
350             metadata.setResourceInstanceName(componentInstance.getName());
351             metadata.setResourceName(componentInstance.getComponentName());
352             metadata.setResourceVersion(componentInstance.getComponentVersion());
353             metadata.setResoucreType(componentInstance.getOriginType().getValue());
354
355             if(MapUtils.isNotEmpty(componentInstance.getDeploymentArtifacts())){
356                 LinkedList<ArtifactMetadata> artifactMetaList = new LinkedList<>();
357                 Collection<ArtifactDefinition> values = componentInstance.getDeploymentArtifacts().values();
358                 for (ArtifactDefinition artifactDefinition : values) {
359                     ArtifactMetadata converted = convertToArtifactMetadata(artifactDefinition, componentType, componentUUID, componentInstance.getNormalizedName());
360                     artifactMetaList.add(converted);
361                 }
362                 metadata.setArtifacts(artifactMetaList);
363             }
364             retList.add(metadata);
365         }
366         return Either.left(retList);
367     }
368
369 }