b4a735409c8a1904ab8ff7429a50d0a21d79f640
[sdc.git] /
1 /*
2  * Copyright © 2016-2017 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.openecomp.activityspec.be.impl;
18
19 import static org.openecomp.activityspec.api.rest.types.ActivitySpecAction.CERTIFY;
20 import static org.openecomp.activityspec.api.rest.types.ActivitySpecAction.DELETE;
21 import static org.openecomp.activityspec.api.rest.types.ActivitySpecAction.DEPRECATE;
22 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Certified;
23 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Deleted;
24 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Deprecated;
25 import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Draft;
26
27 import java.util.Collection;
28 import java.util.Collections;
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 org.openecomp.activityspec.api.rest.types.ActivitySpecAction;
35 import org.openecomp.activityspec.be.ActivitySpecManager;
36 import org.openecomp.activityspec.be.dao.ActivitySpecDao;
37 import org.openecomp.activityspec.be.dao.types.ActivitySpecEntity;
38 import org.openecomp.activityspec.be.datatypes.ItemType;
39 import org.openecomp.activityspec.utils.ActivitySpecConstant;
40 import org.openecomp.core.dao.UniqueValueDao;
41 import org.openecomp.core.util.UniqueValueUtil;
42 import org.openecomp.sdc.common.errors.CoreException;
43 import org.openecomp.sdc.common.errors.ErrorCategory;
44 import org.openecomp.sdc.common.errors.ErrorCode;
45 import org.openecomp.sdc.common.errors.SdcRuntimeException;
46 import org.openecomp.sdc.logging.api.Logger;
47 import org.openecomp.sdc.logging.api.LoggerFactory;
48 import org.openecomp.sdc.versioning.ItemManager;
49 import org.openecomp.sdc.versioning.VersioningManager;
50 import org.openecomp.sdc.versioning.dao.types.Version;
51 import org.openecomp.sdc.versioning.dao.types.VersionStatus;
52 import org.openecomp.sdc.versioning.types.Item;
53 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
54
55 public class ActivitySpecManagerImpl implements ActivitySpecManager {
56
57   private static final Map<VersionStatus, Transition> TRANSITIONS;
58
59   static {
60     TRANSITIONS = new EnumMap<>(VersionStatus.class);
61     TRANSITIONS.put(Certified, new Transition("Certify", Draft));
62     TRANSITIONS.put(Deprecated, new Transition("Deprecate", Certified));
63     TRANSITIONS.put(Deleted, new Transition("Delete", Deprecated));
64   }
65
66   private final ItemManager itemManager;
67   private final VersioningManager versioningManager;
68   private final ActivitySpecDao activitySpecDao;
69   private final UniqueValueUtil uniqueValueUtil;
70   private static final String ACTIVITY_SPEC_NAME = "ActivitySpec.Name";
71   private static final Logger LOGGER =
72       LoggerFactory.getLogger(ActivitySpecManagerImpl.class);
73
74   public ActivitySpecManagerImpl(ItemManager itemManager,
75                                  VersioningManager versioningManager,
76                                  ActivitySpecDao activitySpecDao,
77                                  UniqueValueDao uniqueValueDao) {
78     this.itemManager = itemManager;
79     this.versioningManager = versioningManager;
80     this.activitySpecDao = activitySpecDao;
81     this.uniqueValueUtil = new UniqueValueUtil(uniqueValueDao);
82   }
83
84   @Override
85   public ActivitySpecEntity createActivitySpec(ActivitySpecEntity activitySpecEntity) {
86
87     validateUniqueValue(activitySpecEntity);
88
89     Item item = getActivitySpecItem(activitySpecEntity);
90     item = itemManager.create(item);
91
92     Version version = getActivitySpecVersion(activitySpecEntity);
93     versioningManager.create(item.getId(), version, VersionCreationMethod.major);
94
95     enrichActivitySpec(item, version, activitySpecEntity);
96     activitySpecDao.create(activitySpecEntity);
97
98     uniqueValueUtil.createUniqueValue(ACTIVITY_SPEC_NAME, activitySpecEntity.getName());
99     return activitySpecEntity;
100   }
101
102   private void validateUniqueValue(ActivitySpecEntity activitySpecEntity) {
103     try {
104       uniqueValueUtil.validateUniqueValue(ACTIVITY_SPEC_NAME, activitySpecEntity.getName());
105     } catch (CoreException exception) {
106       throw new CoreException(new ErrorCode.ErrorCodeBuilder()
107           .withCategory(ErrorCategory.APPLICATION)
108           .withId(exception.code().id())
109           .withMessage("name already in use").build());
110     }
111   }
112
113   private Version getActivitySpecVersion(ActivitySpecEntity activitySpecEntity) {
114     return activitySpecEntity.getVersion() == null ? new Version()
115         : activitySpecEntity.getVersion();
116
117   }
118
119   @Override
120   public ActivitySpecEntity get(ActivitySpecEntity activitySpec) {
121     activitySpec.setVersion(calculateLatestVersion(activitySpec.getId(),activitySpec.getVersion()
122         ));
123     ActivitySpecEntity retrieved = null;
124     try {
125       retrieved = activitySpecDao.get(activitySpec);
126     } catch (SdcRuntimeException runtimeException) {
127       LOGGER.error("Failed to retrieve activity spec for activitySpecId: " + activitySpec.getId()
128           + " and version: "
129           + activitySpec.getVersion().getId(), runtimeException);
130       validateActivitySpecExistence(activitySpec.getId(), activitySpec.getVersion());
131     }
132     if (retrieved != null) {
133       final Version retrievedVersion = versioningManager.get(activitySpec.getId(),
134           activitySpec.getVersion());
135       retrieved.setStatus(Objects.nonNull(retrievedVersion) ? retrievedVersion.getStatus().name()
136           : null);
137     }
138     return retrieved;
139   }
140
141   @Override
142   public void update(ActivitySpecEntity activitySpec) {
143
144     ActivitySpecEntity previousActivitySpec = get(activitySpec);
145
146     if (!activitySpec.getName().equals(previousActivitySpec.getName())) {
147       validateUniqueValue(activitySpec);
148     }
149
150     activitySpecDao.update(activitySpec);
151
152     if (!activitySpec.getName().equals(previousActivitySpec.getName())) {
153       uniqueValueUtil.createUniqueValue(ACTIVITY_SPEC_NAME, activitySpec.getName());
154       itemManager.updateName(activitySpec.getId(), activitySpec.getName());
155       uniqueValueUtil.deleteUniqueValue(ACTIVITY_SPEC_NAME, previousActivitySpec.getName());
156     }
157   }
158
159   @Override
160   public void actOnAction(String activitySpecId, String versionId, ActivitySpecAction action) {
161     Version version = new Version(versionId);
162     version = calculateLatestVersion(activitySpecId, version);
163     if (action == CERTIFY) {
164       version.setStatus(Certified);
165     }
166     if (action == DEPRECATE) {
167       version.setStatus(Deprecated);
168     }
169     if (action == DELETE) {
170       version.setStatus(Deleted);
171     }
172
173     updateVersionStatus(activitySpecId, action, version);
174     if (action == DELETE) {
175       ActivitySpecEntity entity = new ActivitySpecEntity();
176       entity.setId(activitySpecId);
177       entity.setVersion(version);
178       final ActivitySpecEntity activitySpecEntity = get(entity);
179       uniqueValueUtil.deleteUniqueValue(ACTIVITY_SPEC_NAME, activitySpecEntity.getName());
180     }
181   }
182
183   private void updateVersionStatus(String activitySpecId, ActivitySpecAction action,
184       Version version) {
185     VersionStatus prevVersionStatus = null;
186     Version retrievedVersion = null;
187     try {
188       retrievedVersion = versioningManager.get(activitySpecId, version);
189     } catch (SdcRuntimeException exception) {
190       LOGGER.error("Failed to get version for activitySpecId: " + activitySpecId
191               + " and version: " + version.getId(), exception);
192       validateActivitySpecExistence(activitySpecId, version);
193
194     }
195
196     VersionStatus status = version.getStatus();
197     Transition transition = TRANSITIONS.get(status);
198     if (transition != null) {
199       String errMsg = String.format("Activity Spec is in an invalid state",
200           transition.action, activitySpecId, transition.prevStatus);
201       validateStatus(Objects.nonNull(retrievedVersion) ? retrievedVersion.getStatus() : null,
202           transition.prevStatus, errMsg);
203       prevVersionStatus = transition.prevStatus;
204     }
205
206     if (Objects.nonNull(retrievedVersion)) {
207       retrievedVersion.setStatus(status);
208       versioningManager.updateVersion(activitySpecId, retrievedVersion);
209       itemManager.updateVersionStatus(activitySpecId, status, prevVersionStatus);
210       versioningManager.publish(activitySpecId, retrievedVersion, "actionOnActivitySpec :"
211           + action.name());
212     }
213   }
214
215   private void validateActivitySpecExistence(String activitySpecId, Version version) {
216     throw new CoreException(new ErrorCode.ErrorCodeBuilder()
217         .withCategory(ErrorCategory.APPLICATION)
218         .withId("ACTIVITYSPEC_NOT_FOUND")
219         .withMessage("No Activity Spec found for the given identifiers")
220         .build());
221   }
222
223   private void validateStatus(VersionStatus retrievedVersionStatus,
224       VersionStatus expectedVersionStatus, String errorMessage) {
225     if (retrievedVersionStatus != expectedVersionStatus) {
226       throw new CoreException(new ErrorCode.ErrorCodeBuilder()
227           .withCategory(ErrorCategory.APPLICATION)
228           .withId("STATUS_NOT_" + expectedVersionStatus.name().toUpperCase())
229           .withMessage(errorMessage).build());
230     }
231   }
232
233   private Version calculateLatestVersion(String activitySpecId, Version version) {
234     if (ActivitySpecConstant.VERSION_ID_DEFAULT_VALUE.equalsIgnoreCase(version.getId())) {
235       List<Version> list = null;
236       try {
237         list = versioningManager.list(activitySpecId);
238       } catch (SdcRuntimeException runtimeException) {
239         LOGGER.error("Failed to list versions for activitySpecId "
240             + activitySpecId, runtimeException);
241         validateActivitySpecExistence(activitySpecId, version);
242       }
243       if (Objects.nonNull(list) && !list.isEmpty()) {
244         return list.get(0);
245       }
246     }
247     return version;
248   }
249
250   @Override
251   public Collection<Item> list(String versionStatus) {
252     Predicate<Item> itemPredicate;
253     if (Objects.nonNull(versionStatus)) {
254
255       VersionStatus statusEnumValue;
256
257       try {
258         statusEnumValue = VersionStatus.valueOf(versionStatus);
259       } catch (IllegalArgumentException e) {
260         LOGGER.debug("Unexpected value of VersionStatus {}", versionStatus);
261         return Collections.emptyList();
262       }
263
264       itemPredicate = item -> ItemType.ACTIVITYSPEC.name().equals(item.getType())
265           && item.getVersionStatusCounters().containsKey(statusEnumValue);
266
267     } else {
268       itemPredicate = item -> ItemType.ACTIVITYSPEC.name().equals(item.getType());
269     }
270
271     return itemManager.list(itemPredicate);
272   }
273
274   private void enrichActivitySpec(Item item, Version version,
275                                   ActivitySpecEntity activitySpecEntity) {
276     activitySpecEntity.setId(item.getId());
277     activitySpecEntity.setVersion(version);
278   }
279
280   private Item getActivitySpecItem(ActivitySpecEntity activitySpecEntity) {
281     Item item = new Item();
282     item.setType(ItemType.ACTIVITYSPEC.name());
283     item.setName(activitySpecEntity.getName());
284     if (activitySpecEntity.getId() != null) {
285       item.setId(activitySpecEntity.getId());
286     }
287     item.addProperty(ActivitySpecConstant.CATEGORY_ATTRIBUTE_NAME,
288         activitySpecEntity.getCategoryList());
289     return item;
290   }
291
292   private static class Transition {
293
294     private final String action;
295     private final VersionStatus prevStatus;
296
297     private Transition(String action, VersionStatus prevStatus) {
298       this.action = action;
299       this.prevStatus = prevStatus;
300     }
301   }
302
303 }