2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.components.impl;
22 import fj.data.Either;
23 import java.util.Collections;
24 import java.util.List;
26 import java.util.Optional;
27 import java.util.stream.Collectors;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.components.impl.model.ToscaTypeImportData;
31 import org.openecomp.sdc.be.config.BeEcompErrorManager;
32 import org.openecomp.sdc.be.dao.api.ActionStatus;
33 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
34 import org.openecomp.sdc.be.impl.ComponentsUtils;
35 import org.openecomp.sdc.be.model.CapabilityDefinition;
36 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
37 import org.openecomp.sdc.be.model.GroupTypeDefinition;
38 import org.openecomp.sdc.be.model.Model;
39 import org.openecomp.sdc.be.model.PropertyDefinition;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
41 import org.openecomp.sdc.be.model.normatives.ElementTypeEnum;
42 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
43 import org.openecomp.sdc.be.model.operations.impl.GroupTypeOperation;
44 import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
45 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
46 import org.openecomp.sdc.be.model.utils.TypeCompareUtils;
47 import org.openecomp.sdc.be.utils.TypeUtils;
48 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
49 import org.openecomp.sdc.common.log.wrappers.Logger;
50 import org.openecomp.sdc.exception.ResponseFormat;
51 import org.springframework.stereotype.Component;
53 @Component("groupTypeImportManager")
54 public class GroupTypeImportManager {
56 private static final Logger log = Logger.getLogger(GroupTypeImportManager.class);
57 private final GroupTypeOperation groupTypeOperation;
58 private final ComponentsUtils componentsUtils;
59 private final ToscaOperationFacade toscaOperationFacade;
60 private final CommonImportManager commonImportManager;
61 private final ModelOperation modelOperation;
63 public GroupTypeImportManager(GroupTypeOperation groupTypeOperation, ComponentsUtils componentsUtils, ToscaOperationFacade toscaOperationFacade,
64 CommonImportManager commonImportManager, ModelOperation modelOperation) {
65 this.groupTypeOperation = groupTypeOperation;
66 this.componentsUtils = componentsUtils;
67 this.toscaOperationFacade = toscaOperationFacade;
68 this.commonImportManager = commonImportManager;
69 this.modelOperation = modelOperation;
72 public Either<List<ImmutablePair<GroupTypeDefinition, Boolean>>, ResponseFormat> createGroupTypes(ToscaTypeImportData toscaTypeImportData,
73 String modelName, final boolean includeToModelDefaultImports) {
74 final Either<List<ImmutablePair<GroupTypeDefinition, Boolean>>, ResponseFormat> elementTypes = commonImportManager.createElementTypes(
75 toscaTypeImportData, this::createGroupTypesFromYml, this::upsertGroupTypesByDao, modelName);
76 if (includeToModelDefaultImports && StringUtils.isNotEmpty(modelName)) {
77 commonImportManager.addTypesToDefaultImports(ElementTypeEnum.GROUP_TYPE, toscaTypeImportData.getToscaTypesYml(), modelName);
82 private Either<List<GroupTypeDefinition>, ActionStatus> createGroupTypesFromYml(String groupTypesYml, String modelName) {
83 Either<List<GroupTypeDefinition>, ActionStatus> groupTypes = commonImportManager.createElementTypesFromYml(groupTypesYml,
84 this::createGroupType);
85 if (groupTypes.isLeft() && StringUtils.isNotEmpty(modelName)) {
86 final Optional<Model> modelOptional = modelOperation.findModelByName(modelName);
87 if (modelOptional.isPresent()) {
88 groupTypes.left().value().forEach(groupType -> groupType.setModel(modelName));
91 return Either.right(ActionStatus.INVALID_MODEL);
96 private Either<List<ImmutablePair<GroupTypeDefinition, Boolean>>, ResponseFormat> upsertGroupTypesByDao(
97 List<GroupTypeDefinition> groupTypesToCreate, String modelName) {
98 return commonImportManager.createElementTypesWithVersionByDao(groupTypesToCreate, this::validateGroupType,
99 groupType -> new ImmutablePair<>(ElementTypeEnum.GROUP_TYPE, UniqueIdBuilder.buildGroupTypeUid(groupType.getModel(),
100 groupType.getType(), groupType.getVersion(), NodeTypeEnum.GroupType.getName()).toLowerCase()),
101 groupTypeOperation::getLatestGroupTypeByType,
102 groupTypeOperation::addGroupType, this::updateGroupType, modelName);
105 private Either<GroupTypeDefinition, StorageOperationStatus> updateGroupType(GroupTypeDefinition newGroupType, GroupTypeDefinition oldGroupType) {
106 Either<GroupTypeDefinition, StorageOperationStatus> validationRes = groupTypeOperation.validateUpdateProperties(newGroupType);
107 if (validationRes.isRight()) {
108 log.error("#updateGroupType - One or all properties of group type {} not valid. status is {}", newGroupType,
109 validationRes.right().value());
110 return validationRes;
112 if (TypeCompareUtils.isGroupTypesEquals(newGroupType, oldGroupType)) {
113 return TypeCompareUtils.typeAlreadyExists();
115 return groupTypeOperation.updateGroupType(newGroupType, oldGroupType);
118 private Either<ActionStatus, ResponseFormat> validateGroupType(GroupTypeDefinition groupType) {
119 Either<ActionStatus, ResponseFormat> result = Either.left(ActionStatus.OK);
120 if (groupType.getMembers() != null) {
121 if (groupType.getMembers().isEmpty()) {
122 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_MEMBER_EMPTY, groupType.getType());
123 result = Either.right(responseFormat);
125 for (String member : groupType.getMembers()) {
126 // Verify that such Resource exist
127 Either<org.openecomp.sdc.be.model.Resource, StorageOperationStatus> eitherMemberExist = toscaOperationFacade
128 .getLatestByToscaResourceName(member, groupType.getModel());
129 if (eitherMemberExist.isRight()) {
130 StorageOperationStatus operationStatus = eitherMemberExist.right().value();
131 log.debug("Error when fetching parent resource {}, error: {}", member, operationStatus);
132 ActionStatus convertFromStorageResponse = componentsUtils.convertFromStorageResponse(operationStatus);
133 BeEcompErrorManager.getInstance().logBeComponentMissingError("Import GroupType", "resource", member);
134 result = Either.right(componentsUtils.getResponseFormat(convertFromStorageResponse, member));
143 private GroupTypeDefinition createGroupType(String groupTypeName, Map<String, Object> toscaJson) {
144 GroupTypeDefinition groupType = new GroupTypeDefinition();
145 if (toscaJson != null) {
147 commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName(), groupType::setDescription);
149 commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName(), groupType::setDerivedFrom);
151 CommonImportManager.setProperties(toscaJson, groupType::setProperties);
153 commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.METADATA.getElementName(), groupType::setMetadata);
155 Map<String, CapabilityDefinition> capabilities = createCapabilities(toscaJson);
156 groupType.setCapabilities(capabilities);
158 commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.MEMBERS.getElementName(), groupType::setMembers);
159 groupType.setType(groupTypeName);
160 groupType.setHighestVersion(true);
161 groupType.setVersion(TypeUtils.getFirstCertifiedVersionVersion());
170 private Map<String, CapabilityDefinition> createCapabilities(Map<String, Object> toscaJson) {
171 CapabilityTypeToscaJsonHolder capabilityTypeToscaJsonHolder = new CapabilityTypeToscaJsonHolder();
172 commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.CAPABILITIES.getElementName(),
173 capabilityTypeToscaJsonHolder::setCapabilityTypeToscaJson);
174 Map<String, CapabilityDefinition> capabilities;
175 if (capabilityTypeToscaJsonHolder.isEmpty()) {
176 capabilities = Collections.emptyMap();
178 capabilities = commonImportManager
179 .createElementTypesMapFromToscaJsonMap(this::createCapability, capabilityTypeToscaJsonHolder.getCapabilityTypeToscaJson());
184 private CapabilityDefinition createCapability(String capabilityName, Map<String, Object> toscaJson) {
185 CapabilityDefinition capability = new CapabilityDefinition();
186 capability.setName(capabilityName);
187 commonImportManager.setField(toscaJson, ToscaTagNamesEnum.TYPE.getElementName(), capability::setType);
189 CommonImportManager.setProperties(toscaJson, pl -> capability.setProperties(map(pl)));
197 private List<ComponentInstanceProperty> map(List<PropertyDefinition> pl) {
198 return pl.stream().map(ComponentInstanceProperty::new).collect(Collectors.toList());
201 private class CapabilityTypeToscaJsonHolder {
203 private Map<String, Object> capabilityTypeToscaJson;
205 public Map<String, Object> getCapabilityTypeToscaJson() {
206 return capabilityTypeToscaJson;
209 public void setCapabilityTypeToscaJson(Map<String, Object> capabilityTypeToscaJson) {
210 this.capabilityTypeToscaJson = capabilityTypeToscaJson;
213 public boolean isEmpty() {
214 return capabilityTypeToscaJson == null;