Add collaboration feature
[sdc.git] / openecomp-be / api / openecomp-sdc-rest-webapp / item-rest / item-rest-services / src / main / java / org / openecomp / sdcrests / item / rest / services / VersionsImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
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
21 package org.openecomp.sdcrests.item.rest.services;
22
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.logging.context.MdcUtil;
36 import org.openecomp.sdc.logging.types.LoggerServiceName;
37 import org.openecomp.sdc.notification.dtos.Event;
38 import org.openecomp.sdc.notification.factories.NotificationPropagationManagerFactory;
39 import org.openecomp.sdc.notification.services.NotificationPropagationManager;
40 import org.openecomp.sdc.versioning.ItemManager;
41 import org.openecomp.sdc.versioning.ItemManagerFactory;
42 import org.openecomp.sdc.versioning.VersioningManager;
43 import org.openecomp.sdc.versioning.VersioningManagerFactory;
44 import org.openecomp.sdc.versioning.dao.types.SynchronizationState;
45 import org.openecomp.sdc.versioning.dao.types.Version;
46 import org.openecomp.sdc.versioning.errors.RevisionIdNotFoundErrorBuilder;
47 import org.openecomp.sdc.versioning.types.NotificationEventTypes;
48 import org.openecomp.sdcrests.item.rest.Versions;
49 import org.openecomp.sdcrests.item.rest.mapping.MapActivityLogEntityToDto;
50 import org.openecomp.sdcrests.item.rest.mapping.MapRevisionToDto;
51 import org.openecomp.sdcrests.item.rest.mapping.MapVersionToDto;
52 import org.openecomp.sdcrests.item.types.ActivityLogDto;
53 import org.openecomp.sdcrests.item.types.CommitRequestDto;
54 import org.openecomp.sdcrests.item.types.RevisionDto;
55 import org.openecomp.sdcrests.item.types.RevisionRequestDto;
56 import org.openecomp.sdcrests.item.types.VersionActionRequestDto;
57 import org.openecomp.sdcrests.item.types.VersionDto;
58 import org.openecomp.sdcrests.item.types.VersionRequestDto;
59 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
60 import org.springframework.context.annotation.Scope;
61 import org.springframework.stereotype.Service;
62
63 import javax.inject.Named;
64 import javax.ws.rs.core.Response;
65 import java.util.HashMap;
66 import java.util.Map;
67
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;
74
75 @Named
76 @Service("versions")
77 @Scope(value = "prototype")
78 public class VersionsImpl implements Versions {
79
80   private static final String COMMIT_ITEM_ACTION = "Commit_Item";
81   private static final Logger LOGGER = LoggerFactory.getLogger(VersionsImpl.class);
82
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();
95
96   @Override
97   public Response list(String itemId, String user) {
98     GenericCollectionWrapper<VersionDto> results = new GenericCollectionWrapper<>();
99     MapVersionToDto mapper = new MapVersionToDto();
100
101     versioningManager.list(itemId)
102         .forEach(version -> results.add(mapper.applyMapping(version, VersionDto.class)));
103     return Response.ok(results).build();
104   }
105
106   @Override
107   public Response create(VersionRequestDto request, String itemId, String baseVersionId,
108                          String user) {
109     Version version = new Version();
110     version.setBaseId(baseVersionId);
111     version.setDescription(request.getDescription());
112
113     version = versioningManager.create(itemId, version, request.getCreationMethod());
114
115     VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
116
117     activityLogManager.logActivity(new ActivityLogEntity(itemId, version,
118         ActivityType.Create_Version, user, true, "", ""));
119
120     return Response.ok(versionDto).build();
121   }
122
123   @Override
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();
128   }
129
130   @Override
131   public Response getActivityLog(String itemId, String versionId, String user) {
132     MdcUtil.initMdc(LoggerServiceName.Get_List_Activity_Log.toString());
133
134     GenericCollectionWrapper<ActivityLogDto> results = new GenericCollectionWrapper<>();
135     MapActivityLogEntityToDto mapper = new MapActivityLogEntityToDto();
136
137     activityLogManager.listLoggedActivities(itemId, new Version(versionId))
138         .forEach(loggedActivity -> results
139             .add(mapper.applyMapping(loggedActivity, ActivityLogDto.class)));
140
141     return Response.ok(results).build();
142   }
143
144   @Override
145   public Response listRevisions(String itemId, String versionId, String user) {
146     GenericCollectionWrapper<RevisionDto> results = new GenericCollectionWrapper<>();
147     MapRevisionToDto mapper = new MapRevisionToDto();
148
149     versioningManager.listRevisions(itemId, new Version(versionId))
150         .forEach(revision -> results.add(mapper.applyMapping(revision, RevisionDto.class)));
151     return Response.ok(results).build();
152   }
153
154   @Override
155   public Response actOn(VersionActionRequestDto request, String itemId, String versionId,
156                         String user) {
157     Version version = new Version(versionId);
158     switch (request.getAction()) {
159       case Sync:
160         sync(itemId, version);
161         break;
162       case Commit:
163         if (!permissionsManager.isAllowed(itemId, user, COMMIT_ITEM_ACTION)) {
164           return Response.status(Response.Status.FORBIDDEN)
165               .entity(new Exception(Messages.PERMISSIONS_ERROR.getErrorMessage())).build();
166         }
167         commit(request.getCommitRequest(), itemId, version, user);
168         break;
169       case Revert:
170         revert(request.getRevisionRequest(), itemId, versionId);
171         break;
172       case Reset:
173         throw new UnsupportedOperationException("Action reset not supported.");
174       default:
175     }
176     return Response.ok().build();
177   }
178
179
180   private void revert(RevisionRequestDto request, String itemId, String versionId) {
181     if (request.getRevisionId() == null) {
182       throw new CoreException(new RevisionIdNotFoundErrorBuilder().build());
183     }
184
185     versioningManager.revert(itemId, new Version(versionId), request.getRevisionId());
186   }
187
188   private void sync(String itemId, Version version) {
189     versioningManager.sync(itemId, version);
190     conflictsManager.finalizeMerge(itemId, version);
191   }
192
193   private void commit(CommitRequestDto request, String itemId, Version version, String user) {
194
195     String message = request == null ? "" : request.getMessage();
196
197     versioningManager.publish(itemId, version, message);
198     notifyUsers(itemId, version, message, user, NotificationEventTypes.COMMIT);
199
200     activityLogManager.logActivity(new ActivityLogEntity(itemId, version,
201         ActivityType.Commit, user, true, "", message));
202   }
203
204   private void notifyUsers(String itemId, Version version, String message,
205                            String userName, NotificationEventTypes eventType) {
206     Map<String, Object> eventProperties = new HashMap<>();
207     eventProperties.put(ITEM_NAME, itemManager.get(itemId).getName());
208     eventProperties.put(ITEM_ID, itemId);
209
210     Version ver = versioningManager.get(itemId, version);
211     eventProperties.put(VERSION_NAME, ver.getName());
212     eventProperties.put(VERSION_ID, ver.getId());
213
214     eventProperties.put(SUBMIT_DESCRIPTION, message);
215     eventProperties.put(PERMISSION_USER, userName);
216
217     Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
218     try {
219       notifier.notifySubscribers(syncEvent, userName);
220     } catch (Exception e) {
221       LOGGER.error("Failed to send sync notification to users subscribed o item '" + itemId);
222     }
223   }
224
225   private class SyncEvent implements Event {
226
227     private String eventType;
228     private String originatorId;
229     private Map<String, Object> attributes;
230     private String entityId;
231
232     public SyncEvent(String eventType, String originatorId,
233                      Map<String, Object> attributes, String entityId) {
234       this.eventType = eventType;
235       this.originatorId = originatorId;
236       this.attributes = attributes;
237       this.entityId = entityId;
238     }
239
240     @Override
241     public String getEventType() {
242       return eventType;
243     }
244
245     @Override
246     public String getOriginatorId() {
247       return originatorId;
248     }
249
250     @Override
251     public Map<String, Object> getAttributes() {
252       return attributes;
253     }
254
255     @Override
256     public String getEntityId() {
257       return entityId;
258     }
259   }
260
261   private Version getVersion(String itemId, Version version) {
262     version = versioningManager.get(itemId, version);
263
264     if (version.getState().getSynchronizationState() != SynchronizationState.Merging &&
265         conflictsManager.isConflicted(itemId, version)) { // looks for sdc applicative conflicts
266       version.getState().setSynchronizationState(SynchronizationState.Merging);
267     }
268     return version;
269   }
270 }