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=========================================================
21 package org.openecomp.sdcrests.item.rest.services;
23 import org.openecomp.sdc.activitylog.ActivityLogManager;
24 import org.openecomp.sdc.activitylog.ActivityLogManagerFactory;
25 import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity;
26 import org.openecomp.sdc.activitylog.dao.type.ActivityType;
27 import org.openecomp.sdc.common.errors.CoreException;
28 import org.openecomp.sdc.common.errors.Messages;
29 import org.openecomp.sdc.conflicts.ConflictsManager;
30 import org.openecomp.sdc.conflicts.ConflictsManagerFactory;
31 import org.openecomp.sdc.itempermissions.ItemPermissionsManager;
32 import org.openecomp.sdc.itempermissions.ItemPermissionsManagerFactory;
33 import org.openecomp.sdc.logging.api.Logger;
34 import org.openecomp.sdc.logging.api.LoggerFactory;
35 import org.openecomp.sdc.notification.dtos.Event;
36 import org.openecomp.sdc.notification.factories.NotificationPropagationManagerFactory;
37 import org.openecomp.sdc.notification.services.NotificationPropagationManager;
38 import org.openecomp.sdc.versioning.ItemManager;
39 import org.openecomp.sdc.versioning.ItemManagerFactory;
40 import org.openecomp.sdc.versioning.VersioningManager;
41 import org.openecomp.sdc.versioning.VersioningManagerFactory;
42 import org.openecomp.sdc.versioning.dao.types.Revision;
43 import org.openecomp.sdc.versioning.dao.types.SynchronizationState;
44 import org.openecomp.sdc.versioning.dao.types.Version;
45 import org.openecomp.sdc.versioning.errors.RevisionIdNotFoundErrorBuilder;
46 import org.openecomp.sdc.versioning.types.NotificationEventTypes;
47 import org.openecomp.sdcrests.item.rest.Versions;
48 import org.openecomp.sdcrests.item.rest.mapping.MapActivityLogEntityToDto;
49 import org.openecomp.sdcrests.item.rest.mapping.MapRevisionToDto;
50 import org.openecomp.sdcrests.item.rest.mapping.MapVersionToDto;
51 import org.openecomp.sdcrests.item.types.ActivityLogDto;
52 import org.openecomp.sdcrests.item.types.CommitRequestDto;
53 import org.openecomp.sdcrests.item.types.RevisionDto;
54 import org.openecomp.sdcrests.item.types.RevisionRequestDto;
55 import org.openecomp.sdcrests.item.types.VersionActionRequestDto;
56 import org.openecomp.sdcrests.item.types.VersionDto;
57 import org.openecomp.sdcrests.item.types.VersionRequestDto;
58 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
59 import org.springframework.context.annotation.Scope;
60 import org.springframework.stereotype.Service;
62 import javax.inject.Named;
63 import javax.ws.rs.core.Response;
64 import java.util.HashMap;
65 import java.util.List;
68 import static org.openecomp.sdc.itempermissions.notifications.NotificationConstants.PERMISSION_USER;
69 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.ITEM_ID;
70 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.ITEM_NAME;
71 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.SUBMIT_DESCRIPTION;
72 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.VERSION_ID;
73 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.VERSION_NAME;
77 @Scope(value = "prototype")
78 public class VersionsImpl implements Versions {
80 private static final String COMMIT_ITEM_ACTION = "Commit_Item";
81 private static final Logger LOGGER = LoggerFactory.getLogger(VersionsImpl.class);
83 private ItemPermissionsManager permissionsManager =
84 ItemPermissionsManagerFactory.getInstance().createInterface();
85 private ItemManager itemManager =
86 ItemManagerFactory.getInstance().createInterface();
87 private VersioningManager versioningManager =
88 VersioningManagerFactory.getInstance().createInterface();
89 private ConflictsManager conflictsManager =
90 ConflictsManagerFactory.getInstance().createInterface();
91 private ActivityLogManager activityLogManager =
92 ActivityLogManagerFactory.getInstance().createInterface();
93 private NotificationPropagationManager notifier =
94 NotificationPropagationManagerFactory.getInstance().createInterface();
97 public Response list(String itemId, String user) {
98 GenericCollectionWrapper<VersionDto> results = new GenericCollectionWrapper<>();
99 MapVersionToDto mapper = new MapVersionToDto();
101 versioningManager.list(itemId)
102 .forEach(version -> results.add(mapper.applyMapping(version, VersionDto.class)));
103 return Response.ok(results).build();
107 public Response create(VersionRequestDto request, String itemId, String baseVersionId,
109 Version version = new Version();
110 version.setBaseId(baseVersionId);
111 version.setDescription(request.getDescription());
113 version = versioningManager.create(itemId, version, request.getCreationMethod());
115 VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
117 activityLogManager.logActivity(new ActivityLogEntity(itemId, version,
118 ActivityType.Create_Version, user, true, "", ""));
120 return Response.ok(versionDto).build();
124 public Response get(String itemId, String versionId, String user) {
125 Version version = getVersion(itemId, new Version(versionId));
126 VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
127 return Response.ok(versionDto).build();
131 public Response getActivityLog(String itemId, String versionId, String user) {
132 GenericCollectionWrapper<ActivityLogDto> results = new GenericCollectionWrapper<>();
133 MapActivityLogEntityToDto mapper = new MapActivityLogEntityToDto();
135 activityLogManager.listLoggedActivities(itemId, new Version(versionId))
136 .forEach(loggedActivity -> results
137 .add(mapper.applyMapping(loggedActivity, ActivityLogDto.class)));
139 return Response.ok(results).build();
143 public Response listRevisions(String itemId, String versionId, String user) {
144 List<Revision> revisions = versioningManager.listRevisions(itemId, new Version(versionId));
145 filterRevisions(revisions);
147 GenericCollectionWrapper<RevisionDto> results = new GenericCollectionWrapper<>();
148 MapRevisionToDto mapper = new MapRevisionToDto();
149 revisions.forEach(revision -> results.add(mapper.applyMapping(revision, RevisionDto.class)));
150 return Response.ok(results).build();
154 public Response actOn(VersionActionRequestDto request, String itemId, String versionId,
156 Version version = new Version(versionId);
157 switch (request.getAction()) {
159 sync(itemId, version);
162 if (!permissionsManager.isAllowed(itemId, user, COMMIT_ITEM_ACTION)) {
163 return Response.status(Response.Status.FORBIDDEN)
164 .entity(new Exception(Messages.PERMISSIONS_ERROR.getErrorMessage())).build();
166 commit(request.getCommitRequest(), itemId, version, user);
169 revert(request.getRevisionRequest(), itemId, versionId);
172 throw new UnsupportedOperationException("Action reset not supported.");
175 return Response.ok().build();
178 private Version getVersion(String itemId, Version version) {
179 Version retrievedVersion = versioningManager.get(itemId, version);
181 if (retrievedVersion.getState().getSynchronizationState() != SynchronizationState.Merging &&
182 // looks for sdc applicative conflicts
183 conflictsManager.isConflicted(itemId, retrievedVersion)) {
184 retrievedVersion.getState().setSynchronizationState(SynchronizationState.Merging);
186 return retrievedVersion;
189 private void sync(String itemId, Version version) {
190 versioningManager.sync(itemId, version);
191 conflictsManager.finalizeMerge(itemId, version);
194 private void commit(CommitRequestDto request, String itemId, Version version, String user) {
196 String message = request == null ? "" : request.getMessage();
198 versioningManager.publish(itemId, version, message);
199 notifyUsers(itemId, version, message, user, NotificationEventTypes.COMMIT);
201 activityLogManager.logActivity(new ActivityLogEntity(itemId, version,
202 ActivityType.Commit, user, true, "", message));
205 private void revert(RevisionRequestDto request, String itemId, String versionId) {
206 if (request.getRevisionId() == null) {
207 throw new CoreException(new RevisionIdNotFoundErrorBuilder().build());
210 versioningManager.revert(itemId, new Version(versionId), request.getRevisionId());
213 private void filterRevisions(List<Revision> revisions) {
214 /* When creating a new item an initial version is created with invalid data.
215 This revision is not an applicable revision. The logic of identifying this revision is:
216 1- only the first version of item has this issue
217 2- only in the first item version there are 2 revisions created
218 3- the second revision is in format "Initial <vlm/vsp>: <name of the vlm/vsp>"
219 4- only if a revision in this format exists we remove the first revision. */
220 int numOfRevisions = revisions.size();
221 if (numOfRevisions > 1 &&
223 revisions.get(numOfRevisions - 2).getMessage().matches("Initial .*:.*")) {
224 revisions.remove(numOfRevisions - 1);
228 private void notifyUsers(String itemId, Version version, String message,
229 String userName, NotificationEventTypes eventType) {
230 Map<String, Object> eventProperties = new HashMap<>();
231 eventProperties.put(ITEM_NAME, itemManager.get(itemId).getName());
232 eventProperties.put(ITEM_ID, itemId);
234 Version ver = versioningManager.get(itemId, version);
235 eventProperties.put(VERSION_NAME, ver.getName());
236 eventProperties.put(VERSION_ID, ver.getId());
238 eventProperties.put(SUBMIT_DESCRIPTION, message);
239 eventProperties.put(PERMISSION_USER, userName);
241 Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
243 notifier.notifySubscribers(syncEvent, userName);
244 } catch (Exception e) {
245 LOGGER.error("Failed to send sync notification to users subscribed o item '" + itemId);
249 private class SyncEvent implements Event {
250 private String eventType;
251 private String originatorId;
252 private Map<String, Object> attributes;
254 private String entityId;
256 public SyncEvent(String eventType, String originatorId,
257 Map<String, Object> attributes, String entityId) {
258 this.eventType = eventType;
259 this.originatorId = originatorId;
260 this.attributes = attributes;
261 this.entityId = entityId;
265 public String getEventType() {
270 public String getOriginatorId() {
275 public Map<String, Object> getAttributes() {
280 public String getEntityId() {