2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.openecomp.sdcrests.item.rest.services;
19 import org.openecomp.sdc.common.errors.CoreException;
20 import org.openecomp.sdc.common.errors.Messages;
21 import org.openecomp.sdc.conflicts.ConflictsManager;
22 import org.openecomp.sdc.conflicts.ConflictsManagerFactory;
23 import org.openecomp.sdc.itempermissions.PermissionsManager;
24 import org.openecomp.sdc.itempermissions.PermissionsManagerFactory;
25 import org.openecomp.sdc.logging.api.Logger;
26 import org.openecomp.sdc.logging.api.LoggerFactory;
27 import org.openecomp.sdc.notification.dtos.Event;
28 import org.openecomp.sdc.notification.factories.NotificationPropagationManagerFactory;
29 import org.openecomp.sdc.notification.services.NotificationPropagationManager;
30 import org.openecomp.sdc.versioning.AsdcItemManager;
31 import org.openecomp.sdc.versioning.AsdcItemManagerFactory;
32 import org.openecomp.sdc.versioning.VersioningManager;
33 import org.openecomp.sdc.versioning.VersioningManagerFactory;
34 import org.openecomp.sdc.versioning.dao.types.Revision;
35 import org.openecomp.sdc.versioning.dao.types.SynchronizationState;
36 import org.openecomp.sdc.versioning.dao.types.Version;
37 import org.openecomp.sdc.versioning.errors.RevisionIdNotFoundErrorBuilder;
38 import org.openecomp.sdc.versioning.types.NotificationEventTypes;
39 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
40 import org.openecomp.sdcrests.item.rest.Versions;
41 import org.openecomp.sdcrests.item.rest.mapping.MapActivityLogEntityToDto;
42 import org.openecomp.sdcrests.item.rest.mapping.MapRevisionToDto;
43 import org.openecomp.sdcrests.item.rest.mapping.MapVersionToDto;
44 import org.openecomp.sdcrests.item.types.*;
45 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
46 import org.springframework.context.annotation.Scope;
47 import org.springframework.stereotype.Service;
49 import javax.inject.Named;
50 import javax.ws.rs.core.Response;
51 import java.util.HashMap;
52 import java.util.List;
55 import static org.openecomp.sdc.itempermissions.notifications.NotificationConstants.PERMISSION_USER;
56 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.*;
60 @Scope(value = "prototype")
61 public class VersionsImpl implements Versions {
63 private static final String COMMIT_ITEM_ACTION = "Commit_Item";
64 private static final Logger LOGGER = LoggerFactory.getLogger(VersionsImpl.class);
66 private PermissionsManager permissionsManager =
67 PermissionsManagerFactory.getInstance().createInterface();
68 private AsdcItemManager asdcItemManager =
69 AsdcItemManagerFactory.getInstance().createInterface();
70 private VersioningManager versioningManager =
71 VersioningManagerFactory.getInstance().createInterface();
72 private ConflictsManager conflictsManager =
73 ConflictsManagerFactory.getInstance().createInterface();
74 private NotificationPropagationManager notifier =
75 NotificationPropagationManagerFactory.getInstance().createInterface();
78 public Response list(String itemId, String user) {
79 GenericCollectionWrapper<VersionDto> results = new GenericCollectionWrapper<>();
80 MapVersionToDto mapper = new MapVersionToDto();
82 versioningManager.list(itemId)
83 .forEach(version -> results.add(mapper.applyMapping(version, VersionDto.class)));
84 return Response.ok(results).build();
88 public Response create(VersionRequestDto request, String itemId, String baseVersionId,
90 Version version = new Version();
91 version.setBaseId(baseVersionId);
92 version.setDescription(request.getDescription());
94 version = versioningManager.create(itemId, version, VersionCreationMethod.valueOf(request
95 .getCreationMethod().name()));
97 VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
99 return Response.ok(versionDto).build();
103 public Response get(String itemId, String versionId, String user) {
104 Version version = getVersion(itemId, new Version(versionId));
105 VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
106 return Response.ok(versionDto).build();
110 public Response getActivityLog(String itemId, String versionId, String user) {
111 GenericCollectionWrapper<ActivityLogDto> results = new GenericCollectionWrapper<>();
112 MapActivityLogEntityToDto mapper = new MapActivityLogEntityToDto();
113 return Response.ok(results).build();
117 public Response listRevisions(String itemId, String versionId, String user) {
118 List<Revision> revisions = versioningManager.listRevisions(itemId, new Version(versionId));
119 filterRevisions(revisions);
121 GenericCollectionWrapper<RevisionDto> results = new GenericCollectionWrapper<>();
122 MapRevisionToDto mapper = new MapRevisionToDto();
123 revisions.forEach(revision -> results.add(mapper.applyMapping(revision, RevisionDto.class)));
124 return Response.ok(results).build();
128 public Response actOn(VersionActionRequestDto request, String itemId, String versionId,
130 Version version = new Version(versionId);
131 switch (request.getAction()) {
133 sync(itemId, version);
136 if (!permissionsManager.isAllowed(itemId, user, COMMIT_ITEM_ACTION)) {
137 return Response.status(Response.Status.FORBIDDEN)
138 .entity(new Exception(Messages.PERMISSIONS_ERROR.getErrorMessage())).build();
140 commit(request.getCommitRequest(), itemId, version, user);
143 revert(request.getRevisionRequest(), itemId, versionId);
146 versioningManager.clean(itemId, version);
149 throw new UnsupportedOperationException(String.format("Action %s not supported.", request.getAction()));
151 return Response.ok().build();
154 private Version getVersion(String itemId, Version version) {
155 Version retrievedVersion = versioningManager.get(itemId, version);
157 if (retrievedVersion.getState().getSynchronizationState() != SynchronizationState.Merging &&
158 // looks for sdc applicative conflicts
159 conflictsManager.isConflicted(itemId, retrievedVersion)) {
160 retrievedVersion.getState().setSynchronizationState(SynchronizationState.Merging);
162 return retrievedVersion;
165 private void sync(String itemId, Version version) {
166 versioningManager.sync(itemId, version);
167 conflictsManager.finalizeMerge(itemId, version);
170 private void commit(CommitRequestDto request, String itemId, Version version, String user) {
172 String message = request == null ? "" : request.getMessage();
174 versioningManager.publish(itemId, version, message);
175 notifyUsers(itemId, version, message, user, NotificationEventTypes.COMMIT);
178 private void revert(RevisionRequestDto request, String itemId, String versionId) {
179 if (request.getRevisionId() == null) {
180 throw new CoreException(new RevisionIdNotFoundErrorBuilder().build());
183 versioningManager.revert(itemId, new Version(versionId), request.getRevisionId());
186 private void filterRevisions(List<Revision> revisions) {
187 /* When creating a new item an initial version is created with invalid data.
188 This revision is not an applicable revision. The logic of identifying this revision is:
189 1- only the first version of item has this issue
190 2- only in the first item version there are 2 revisions created
191 3- the second revision is in format "Initial <vlm/vsp>: <name of the vlm/vsp>"
192 4- only if a revision in this format exists we remove the first revision. */
193 int numOfRevisions = revisions.size();
194 if (numOfRevisions > 1 &&
196 revisions.get(numOfRevisions - 2).getMessage().matches("Initial .*:.*")) {
197 revisions.remove(numOfRevisions - 1);
201 private void notifyUsers(String itemId, Version version, String message,
202 String userName, NotificationEventTypes eventType) {
203 Map<String, Object> eventProperties = new HashMap<>();
204 eventProperties.put(ITEM_NAME, asdcItemManager.get(itemId).getName());
205 eventProperties.put(ITEM_ID, itemId);
207 Version ver = versioningManager.get(itemId, version);
208 eventProperties.put(VERSION_NAME, ver.getName());
209 eventProperties.put(VERSION_ID, ver.getId());
211 eventProperties.put(SUBMIT_DESCRIPTION, message);
212 eventProperties.put(PERMISSION_USER, userName);
214 Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
216 notifier.notifySubscribers(syncEvent, userName);
217 } catch (Exception e) {
218 LOGGER.error("Failed to send sync notification to users subscribed o item '" + itemId);
222 private class SyncEvent implements Event {
223 private String eventType;
224 private String originatorId;
225 private Map<String, Object> attributes;
227 private String entityId;
229 public SyncEvent(String eventType, String originatorId,
230 Map<String, Object> attributes, String entityId) {
231 this.eventType = eventType;
232 this.originatorId = originatorId;
233 this.attributes = attributes;
234 this.entityId = entityId;
238 public String getEventType() {
243 public String getOriginatorId() {
248 public Map<String, Object> getAttributes() {
253 public String getEntityId() {