Add activity spec code
[sdc/sdc-workflow-designer.git] / workflow-designer-be / src / main / java / org / onap / sdc / workflow / services / impl / ActivitySpecManagerImpl.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.sdc.workflow.services.impl;
18
19 import static org.onap.sdc.workflow.services.ActivitySpecConstant.ACTIVITY_SPEC_NOT_FOUND;
20 import static org.onap.sdc.workflow.services.ActivitySpecConstant.VERSION_ID_DEFAULT_VALUE;
21 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Certified;
22 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Deleted;
23 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Deprecated;
24 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Draft;
25
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Comparator;
29 import java.util.EnumMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Objects;
33 import java.util.function.Predicate;
34 import java.util.stream.Collectors;
35 import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecAction;
36 import org.onap.sdc.workflow.persistence.ActivitySpecRepository;
37 import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity;
38 import org.onap.sdc.workflow.services.ActivitySpecManager;
39 import org.onap.sdc.workflow.services.UniqueValueService;
40 import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException;
41 import org.onap.sdc.workflow.services.exceptions.VersionStatusModificationException;
42 import org.onap.sdc.workflow.services.impl.mappers.ActivitySpecMapper;
43 import org.openecomp.sdc.common.errors.SdcRuntimeException;
44 import org.openecomp.sdc.logging.api.Logger;
45 import org.openecomp.sdc.logging.api.LoggerFactory;
46 import org.openecomp.sdc.versioning.ItemManager;
47 import org.openecomp.sdc.versioning.VersioningManager;
48 import org.openecomp.sdc.versioning.dao.types.Version;
49 import org.openecomp.sdc.versioning.dao.types.VersionStatus;
50 import org.openecomp.sdc.versioning.types.Item;
51 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
52 import org.springframework.beans.factory.annotation.Autowired;
53 import org.springframework.beans.factory.annotation.Qualifier;
54 import org.springframework.stereotype.Service;
55
56 @Service("activitySpecManager")
57 public class ActivitySpecManagerImpl implements ActivitySpecManager {
58
59     private static final String ACTIVITY_SPEC_NAME = "ActivitySpec.Name";
60     private static final Logger LOGGER = LoggerFactory.getLogger(ActivitySpecManagerImpl.class);
61     private static final Map<VersionStatus, VersionStatus> EXPECTED_PREV_STATUS;
62
63     static {
64         EXPECTED_PREV_STATUS = new EnumMap<>(VersionStatus.class);
65         EXPECTED_PREV_STATUS.put(Certified, Draft);
66         EXPECTED_PREV_STATUS.put(Deprecated, Certified);
67         EXPECTED_PREV_STATUS.put(Deleted, Deprecated);
68     }
69
70     private final ItemManager itemManager;
71     private final VersioningManager versioningManager;
72     private final ActivitySpecRepository activitySpecDao;
73     private final UniqueValueService uniqueValueService;
74     private final ActivitySpecMapper activitySpecMapper;
75
76
77     @Autowired
78     public ActivitySpecManagerImpl(ItemManager itemManager, VersioningManager versioningManager,
79             ActivitySpecRepository activitySpecDao,
80             @Qualifier("uniqueValueService") UniqueValueService uniqueValueService,
81             ActivitySpecMapper activitySpecMapper) {
82         this.itemManager = itemManager;
83         this.versioningManager = versioningManager;
84         this.activitySpecDao = activitySpecDao;
85         this.uniqueValueService = uniqueValueService;
86         this.activitySpecMapper = activitySpecMapper;
87     }
88
89     @Override
90     public ActivitySpecEntity createActivitySpec(ActivitySpecEntity activitySpec) {
91
92         uniqueValueService.validateUniqueValue(ACTIVITY_SPEC_NAME, activitySpec.getName());
93
94         Item item = activitySpecMapper.activitySpecToItem(activitySpec);
95         item = itemManager.create(item);
96
97         Version version = getActivitySpecVersion(activitySpec);
98         versioningManager.create(item.getId(), version, VersionCreationMethod.major);
99
100         enrichActivitySpec(item, version, activitySpec);
101         activitySpecDao.create(activitySpec);
102
103         uniqueValueService.createUniqueValue(ACTIVITY_SPEC_NAME, activitySpec.getName());
104         return activitySpec;
105     }
106
107     @Override
108     public ActivitySpecEntity get(ActivitySpecEntity activitySpec) {
109         activitySpec.setVersion(calculateLatestVersion(activitySpec));
110         ActivitySpecEntity retrieved;
111         try {
112             retrieved = activitySpecDao.get(activitySpec);
113         } catch (SdcRuntimeException runtimeException) {
114             LOGGER.debug(
115                     "Failed to retrieve activity spec for activitySpecId: " + activitySpec.getId() + " and version: "
116                             + activitySpec.getVersion().getId(), runtimeException);
117             throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND);
118         }
119         if (retrieved != null) {
120             final Version retrievedVersion = versioningManager.get(activitySpec.getId(), activitySpec.getVersion());
121             retrieved.setStatus(Objects.nonNull(retrievedVersion) ? retrievedVersion.getStatus().name() : null);
122         }
123         return retrieved;
124     }
125
126     @Override
127     public void update(ActivitySpecEntity activitySpec) {
128         Item retrievedItem = itemManager.get(activitySpec.getId());
129         if (retrievedItem == null) {
130             LOGGER.error(String.format("Activity Spec with id %s was not found", activitySpec.getId()));
131             throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND);
132         }
133         uniqueValueService.updateUniqueValue(ACTIVITY_SPEC_NAME, retrievedItem.getName(), activitySpec.getName());
134
135         Item item = activitySpecMapper.activitySpecToItem(activitySpec);
136         item.setId(activitySpec.getId());
137         item.setStatus(retrievedItem.getStatus());
138         item.setVersionStatusCounters(retrievedItem.getVersionStatusCounters());
139         itemManager.update(item);
140
141         activitySpec.setVersion(calculateLatestVersion(activitySpec));
142         activitySpecDao.update(activitySpec);
143     }
144
145     @Override
146     public void actOnAction(ActivitySpecEntity activitySpec, ActivitySpecAction action) {
147         Version version = calculateLatestVersion(activitySpec);
148         if (action == ActivitySpecAction.CERTIFY) {
149             version.setStatus(Certified);
150         }
151         if (action == ActivitySpecAction.DEPRECATE) {
152             version.setStatus(Deprecated);
153         }
154         if (action == ActivitySpecAction.DELETE) {
155             version.setStatus(Deleted);
156         }
157
158         updateVersionStatus(activitySpec.getId(), action, version);
159         if (action == ActivitySpecAction.DELETE) {
160             final String activitySpecName = get(new ActivitySpecEntity(activitySpec.getId(), version)).getName();
161             uniqueValueService.deleteUniqueValue(ACTIVITY_SPEC_NAME, activitySpecName);
162         }
163     }
164
165     private void updateVersionStatus(String activitySpecId, ActivitySpecAction action, Version version) {
166         VersionStatus prevVersionStatus = null;
167         Version retrievedVersion;
168         try {
169             retrievedVersion = versioningManager.get(activitySpecId, version);
170         } catch (SdcRuntimeException exception) {
171             LOGGER.debug(
172                     "Failed to get version for activitySpecId: " + activitySpecId + " and version: " + version.getId(),
173                     exception);
174             throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND);
175
176         }
177
178         VersionStatus status = version.getStatus();
179         VersionStatus expectedPrevStatus = EXPECTED_PREV_STATUS.get(status);
180         if (expectedPrevStatus != null) {
181
182             VersionStatus retrievedStatus = Objects.nonNull(retrievedVersion) ? retrievedVersion.getStatus() : null;
183             if (retrievedStatus != expectedPrevStatus) {
184                 LOGGER.debug("Failed to " + version.getStatus() + " since activity spec is in " + retrievedStatus);
185                 throw new VersionStatusModificationException(activitySpecId, version.getId(), retrievedStatus, status);
186             }
187             prevVersionStatus = expectedPrevStatus;
188         }
189
190         if (Objects.nonNull(retrievedVersion)) {
191             retrievedVersion.setStatus(status);
192             versioningManager.updateVersion(activitySpecId, retrievedVersion);
193             itemManager.updateVersionStatus(activitySpecId, status, prevVersionStatus);
194             versioningManager.publish(activitySpecId, retrievedVersion, "actionOnActivitySpec :" + action.name());
195         }
196     }
197
198     @Override
199     public Collection<ActivitySpecEntity> list(String versionStatus) {
200         Predicate<Item> itemPredicate;
201         if (Objects.nonNull(versionStatus)) {
202             VersionStatus statusEnumValue;
203
204             try {
205                 statusEnumValue = VersionStatus.valueOf(versionStatus);
206             } catch (IllegalArgumentException e) {
207                 LOGGER.debug("Unexpected value of VersionStatus {}", versionStatus);
208                 return Collections.emptyList();
209             }
210             itemPredicate =
211                     item -> ItemType.ACTIVITYSPEC.name().equals(item.getType()) && item.getVersionStatusCounters()
212                                                                                            .containsKey(
213                                                                                                    statusEnumValue);
214         } else {
215             itemPredicate = item -> ItemType.ACTIVITYSPEC.name().equals(item.getType());
216         }
217
218         return itemManager.list(itemPredicate).stream()
219                        .sorted(Comparator.comparing(Item::getModificationTime).reversed())
220                        .map(activitySpecMapper::itemToActivitySpec).collect(Collectors.toList());
221     }
222
223     private Version calculateLatestVersion(ActivitySpecEntity activitySpec) {
224         if (VERSION_ID_DEFAULT_VALUE.equalsIgnoreCase(activitySpec.getVersion().getId())) {
225             List<Version> list;
226             try {
227                 list = versioningManager.list(activitySpec.getId());
228             } catch (SdcRuntimeException runtimeException) {
229                 LOGGER.debug("Failed to list versions for activitySpecId " + activitySpec.getId(), runtimeException);
230                 throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND);
231             }
232             if (Objects.nonNull(list) && !list.isEmpty()) {
233                 return list.get(0);
234             }
235         }
236         return activitySpec.getVersion();
237     }
238
239     private Version getActivitySpecVersion(ActivitySpecEntity activitySpecEntity) {
240         return activitySpecEntity.getVersion() == null ? new Version() : activitySpecEntity.getVersion();
241
242     }
243
244     private void enrichActivitySpec(Item item, Version version, ActivitySpecEntity activitySpecEntity) {
245         activitySpecEntity.setId(item.getId());
246         activitySpecEntity.setVersion(version);
247     }
248 }