Fix 'Data type cache not updated when data type updated'-bug
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / DataTypeBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 Fujitsu Limited. 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.be.components.impl;
21
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Optional;
26 import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
27 import org.openecomp.sdc.be.exception.supplier.DataTypeOperationExceptionSupplier;
28 import org.openecomp.sdc.be.model.Component;
29 import org.openecomp.sdc.be.model.ComponentParametersView;
30 import org.openecomp.sdc.be.model.DataTypeDefinition;
31 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
32 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
33 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
34 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
35 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
36 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
37 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
38 import org.openecomp.sdc.be.model.operations.impl.DataTypeOperation;
39 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.util.CollectionUtils;
42
43 @org.springframework.stereotype.Component("dataTypeBusinessLogic")
44 public class DataTypeBusinessLogic extends BaseBusinessLogic {
45
46     private final DataTypeImportManager dataTypeImportManager;
47     private final DataTypeOperation dataTypeOperation;
48
49     @Autowired
50     public DataTypeBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
51                                  IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
52                                  InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation,
53                                  DataTypeImportManager dataTypeImportManager,
54                                  DataTypeOperation dataTypeOperation) {
55         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
56             artifactToscaOperation);
57         this.dataTypeImportManager = dataTypeImportManager;
58         this.dataTypeOperation = dataTypeOperation;
59     }
60
61     /**
62      * Get a list of data types that the Component has.
63      *
64      * @param componentId Unique ID of the Component
65      * @return list of data types
66      */
67     public Either<List<DataTypeDefinition>, StorageOperationStatus> getPrivateDataTypes(String componentId) {
68         ComponentParametersView filter = new ComponentParametersView();
69         filter.disableAll();
70         filter.setIgnoreDataType(false);
71         // Get Component object
72         Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaElement(componentId, filter);
73         if (componentResult.isRight()) {
74             return Either.right(componentResult.right().value());
75         }
76         Component component = componentResult.left().value();
77         List<DataTypeDefinition> dataTypesToReturn = component.getDataTypes();
78         if (dataTypesToReturn == null) {
79             // this means there is no DATA_TYPES graph vertex.
80
81             // in this case, returns empty list.
82             dataTypesToReturn = new ArrayList<>();
83         }
84         return Either.left(dataTypesToReturn);
85     }
86
87     /**
88      * Get a data type in a Component
89      *
90      * @param componentId  Unique ID of the Component
91      * @param dataTypeName Data type name
92      * @return found data type
93      */
94     public Either<DataTypeDefinition, StorageOperationStatus> getPrivateDataType(String componentId, String dataTypeName) {
95         Either<List<DataTypeDefinition>, StorageOperationStatus> dataTypesResult = this.getPrivateDataTypes(componentId);
96         if (dataTypesResult.isRight()) {
97             return Either.right(dataTypesResult.right().value());
98         }
99         List<DataTypeDefinition> dataTypes = dataTypesResult.left().value();
100         Optional<DataTypeDefinition> findResult = dataTypes.stream().filter(e -> e.getName().equals(dataTypeName)).findAny();
101         return findResult.<Either<DataTypeDefinition, StorageOperationStatus>>map(Either::left)
102             .orElseGet(() -> Either.right(StorageOperationStatus.NOT_FOUND));
103     }
104
105     /**
106      * Delete a data type from the Component.
107      *
108      * @param componentId  Unique ID of the Component
109      * @param dataTypeName Data type name to be deleted
110      * @return deleted data type
111      */
112     public Either<DataTypeDefinition, StorageOperationStatus> deletePrivateDataType(String componentId, String dataTypeName) {
113         ComponentParametersView filter = new ComponentParametersView();
114         filter.disableAll();
115         filter.setIgnoreDataType(false);
116         // Get Component object
117         Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaElement(componentId, filter);
118         if (componentResult.isRight()) {
119             // not exists
120             return Either.right(componentResult.right().value());
121         }
122         return deletePrivateDataType(componentResult.left().value(), dataTypeName);
123     }
124
125     /**
126      * Delete a data type from the Component.
127      *
128      * @param component    Component object which has data types. needs to be fetched with componentParametersView.setIgnoreDataType(false)
129      * @param dataTypeName Data type name to be deleted
130      * @return deleted data type
131      */
132     public Either<DataTypeDefinition, StorageOperationStatus> deletePrivateDataType(Component component, String dataTypeName) {
133         // check the specified data type exists
134         List<DataTypeDefinition> dataTypes = component.getDataTypes();
135         if (CollectionUtils.isEmpty(dataTypes)) {
136             return Either.right(StorageOperationStatus.NOT_FOUND);
137         }
138         Optional<DataTypeDefinition> dataTypeResult = dataTypes.stream().filter(e -> e.getName().equals(dataTypeName)).findFirst();
139         if (!dataTypeResult.isPresent()) {
140             return Either.right(StorageOperationStatus.NOT_FOUND);
141         }
142         // delete it
143         StorageOperationStatus deleteResult = toscaOperationFacade.deleteDataTypeOfComponent(component, dataTypeName);
144         if (deleteResult != StorageOperationStatus.OK) {
145             return Either.right(deleteResult);
146         }
147         // return deleted data type if ok
148         return Either.left(dataTypeResult.get());
149     }
150
151     /**
152      * Creates given data types. The data types must be provided in a yaml format, where each entry is one data type object, for
153      * example:
154      * <pre>
155      * tosca.datatypes.TimeInterval:
156      *   derived_from: tosca.datatypes.Root
157      *   [...]
158      *
159      * tosca.datatypes.network.NetworkInfo:
160      *   derived_from: tosca.datatypes.Root
161      *   [...]
162      * </pre>
163      *
164      * @param dataTypesYaml                the data types to create in yaml format. It can contain multiple data types entries.
165      * @param model                        Model name to associate with data type
166      * @param includeToModelDefaultImports Add data type entry to default imports for model
167      */
168     public void createDataTypeFromYaml(final String dataTypesYaml, final String model, final boolean includeToModelDefaultImports) {
169         dataTypeImportManager.createDataTypes(dataTypesYaml, model, includeToModelDefaultImports);
170     }
171
172     public void updateApplicationDataTypeCache(final String dataTypeId) {
173         DataTypeDataDefinition dataTypeDataDefinition = dataTypeOperation.getDataTypeByUid(dataTypeId).orElseThrow(
174             DataTypeOperationExceptionSupplier.dataTypeNotFound(dataTypeId));
175         getApplicationDataTypeCache().reload(dataTypeDataDefinition.getModel(), dataTypeId);
176     }
177 }