cd6364f145d0ad2bb154cf3fe24c62582e446e3b
[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  * 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.openecomp.sdcrests.item.rest.services;
18
19 import org.openecomp.sdc.activitylog.ActivityLogManager;
20 import org.openecomp.sdc.activitylog.ActivityLogManagerFactory;
21 import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity;
22 import org.openecomp.sdc.activitylog.dao.type.ActivityType;
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.common.errors.Messages;
25 import org.openecomp.sdc.conflicts.ConflictsManager;
26 import org.openecomp.sdc.conflicts.ConflictsManagerFactory;
27 import org.openecomp.sdc.itempermissions.PermissionsManager;
28 import org.openecomp.sdc.itempermissions.PermissionsManagerFactory;
29 import org.openecomp.sdc.logging.api.Logger;
30 import org.openecomp.sdc.logging.api.LoggerFactory;
31 import org.openecomp.sdc.notification.dtos.Event;
32 import org.openecomp.sdc.notification.factories.NotificationPropagationManagerFactory;
33 import org.openecomp.sdc.notification.services.NotificationPropagationManager;
34 import org.openecomp.sdc.versioning.AsdcItemManager;
35 import org.openecomp.sdc.versioning.AsdcItemManagerFactory;
36 import org.openecomp.sdc.versioning.VersioningManager;
37 import org.openecomp.sdc.versioning.VersioningManagerFactory;
38 import org.openecomp.sdc.versioning.dao.types.Revision;
39 import org.openecomp.sdc.versioning.dao.types.SynchronizationState;
40 import org.openecomp.sdc.versioning.dao.types.Version;
41 import org.openecomp.sdc.versioning.errors.RevisionIdNotFoundErrorBuilder;
42 import org.openecomp.sdc.versioning.types.NotificationEventTypes;
43 import org.openecomp.sdc.versioning.types.VersionCreationMethod;
44 import org.openecomp.sdcrests.item.rest.Versions;
45 import org.openecomp.sdcrests.item.rest.mapping.MapActivityLogEntityToDto;
46 import org.openecomp.sdcrests.item.rest.mapping.MapRevisionToDto;
47 import org.openecomp.sdcrests.item.rest.mapping.MapVersionToDto;
48 import org.openecomp.sdcrests.item.types.*;
49 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
50 import org.springframework.context.annotation.Scope;
51 import org.springframework.stereotype.Service;
52
53 import javax.inject.Named;
54 import javax.ws.rs.core.Response;
55 import java.util.HashMap;
56 import java.util.List;
57 import java.util.Map;
58
59 import static org.openecomp.sdc.itempermissions.notifications.NotificationConstants.PERMISSION_USER;
60 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.*;
61
62 @Named
63 @Service("versions")
64 @Scope(value = "prototype")
65 public class VersionsImpl implements Versions {
66
67     private static final String COMMIT_ITEM_ACTION = "Commit_Item";
68     private static final Logger LOGGER = LoggerFactory.getLogger(VersionsImpl.class);
69
70     private PermissionsManager permissionsManager = PermissionsManagerFactory.getInstance().createInterface();
71     private AsdcItemManager asdcItemManager = AsdcItemManagerFactory.getInstance().createInterface();
72     private VersioningManager versioningManager = VersioningManagerFactory.getInstance().createInterface();
73     private ConflictsManager conflictsManager = ConflictsManagerFactory.getInstance().createInterface();
74     private ActivityLogManager activityLogManager = ActivityLogManagerFactory.getInstance().createInterface();
75     private NotificationPropagationManager notifier =
76             NotificationPropagationManagerFactory.getInstance().createInterface();
77
78     @Override
79     public Response list(String itemId, String user) {
80         GenericCollectionWrapper<VersionDto> results = new GenericCollectionWrapper<>();
81         MapVersionToDto mapper = new MapVersionToDto();
82
83         versioningManager.list(itemId).forEach(version -> results.add(mapper.applyMapping(version, VersionDto.class)));
84         return Response.ok(results).build();
85     }
86
87     @Override
88     public Response create(VersionRequestDto request, String itemId, String baseVersionId, String user) {
89         Version version = new Version();
90         version.setBaseId(baseVersionId);
91         version.setDescription(request.getDescription());
92
93         version = versioningManager
94                           .create(itemId, version, VersionCreationMethod.valueOf(request.getCreationMethod().name()));
95
96         VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
97
98         activityLogManager
99                 .logActivity(new ActivityLogEntity(itemId, version, ActivityType.Create_Version, user, true, "", ""));
100
101         return Response.ok(versionDto).build();
102     }
103
104     @Override
105     public Response get(String itemId, String versionId, String user) {
106         Version version = getVersion(itemId, new Version(versionId));
107         VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
108         return Response.ok(versionDto).build();
109     }
110
111     @Override
112     public Response getActivityLog(String itemId, String versionId, String user) {
113         GenericCollectionWrapper<ActivityLogDto> results = new GenericCollectionWrapper<>();
114         MapActivityLogEntityToDto mapper = new MapActivityLogEntityToDto();
115
116         activityLogManager.listLoggedActivities(itemId, new Version(versionId))
117                 .forEach(loggedActivity -> results.add(mapper.applyMapping(loggedActivity, ActivityLogDto.class)));
118
119         return Response.ok(results).build();
120     }
121
122     @Override
123     public Response listRevisions(String itemId, String versionId, String user) {
124         List<Revision> revisions = versioningManager.listRevisions(itemId, new Version(versionId));
125         filterRevisions(revisions);
126
127         GenericCollectionWrapper<RevisionDto> results = new GenericCollectionWrapper<>();
128         MapRevisionToDto mapper = new MapRevisionToDto();
129         revisions.forEach(revision -> results.add(mapper.applyMapping(revision, RevisionDto.class)));
130         return Response.ok(results).build();
131     }
132
133     @Override
134     public Response actOn(VersionActionRequestDto request, String itemId, String versionId, String user) {
135         Version version = new Version(versionId);
136         switch (request.getAction()) {
137             case Sync:
138                 sync(itemId, version);
139                 break;
140             case Commit:
141                 if (!permissionsManager.isAllowed(itemId, user, COMMIT_ITEM_ACTION)) {
142                     return Response.status(Response.Status.FORBIDDEN)
143                                    .entity(new Exception(Messages.PERMISSIONS_ERROR.getErrorMessage())).build();
144                 }
145                 commit(request.getCommitRequest(), itemId, version, user);
146                 break;
147             case Revert:
148                 revert(request.getRevisionRequest(), itemId, versionId);
149                 break;
150             case Clean:
151                 versioningManager.clean(itemId, version);
152                 break;
153             default:
154                 throw new UnsupportedOperationException(String.format("Action %s not supported.", request.getAction()));
155         }
156         return Response.ok().build();
157     }
158
159     private Version getVersion(String itemId, Version version) {
160         Version retrievedVersion = versioningManager.get(itemId, version);
161
162         if (retrievedVersion.getState().getSynchronizationState() != SynchronizationState.Merging &&
163                     // looks for sdc applicative conflicts
164                     conflictsManager.isConflicted(itemId, retrievedVersion)) {
165             retrievedVersion.getState().setSynchronizationState(SynchronizationState.Merging);
166         }
167         return retrievedVersion;
168     }
169
170     private void sync(String itemId, Version version) {
171         versioningManager.sync(itemId, version);
172         conflictsManager.finalizeMerge(itemId, version);
173     }
174
175     private void commit(CommitRequestDto request, String itemId, Version version, String user) {
176
177         String message = request == null ? "" : request.getMessage();
178
179         versioningManager.publish(itemId, version, message);
180         notifyUsers(itemId, version, message, user, NotificationEventTypes.COMMIT);
181         activityLogManager
182                 .logActivity(new ActivityLogEntity(itemId, version, ActivityType.Commit, user, true, "", message));
183     }
184
185     private void revert(RevisionRequestDto request, String itemId, String versionId) {
186         if (request.getRevisionId() == null) {
187             throw new CoreException(new RevisionIdNotFoundErrorBuilder().build());
188         }
189
190         versioningManager.revert(itemId, new Version(versionId), request.getRevisionId());
191     }
192
193     private void filterRevisions(List<Revision> revisions) {
194   /* When creating a new item an initial version is created with invalid data.
195      This revision is not an applicable revision. The logic of identifying this revision is:
196      1- only the first version of item has this issue
197      2- only in the first item version there are 2 revisions created
198      3- the second revision is in format "Initial <vlm/vsp>: <name of the vlm/vsp>"
199      4- only if a revision in this format exists we remove the first revision. */
200         int numOfRevisions = revisions.size();
201         if (numOfRevisions > 1 &&
202
203                     revisions.get(numOfRevisions - 2).getMessage().matches("Initial .*:.*")) {
204             revisions.remove(numOfRevisions - 1);
205         }
206     }
207
208     private void notifyUsers(String itemId, Version version, String message, String userName,
209             NotificationEventTypes eventType) {
210         Map<String, Object> eventProperties = new HashMap<>();
211         eventProperties.put(ITEM_NAME, asdcItemManager.get(itemId).getName());
212         eventProperties.put(ITEM_ID, itemId);
213
214         Version ver = versioningManager.get(itemId, version);
215         eventProperties.put(VERSION_NAME, ver.getName());
216         eventProperties.put(VERSION_ID, ver.getId());
217
218         eventProperties.put(SUBMIT_DESCRIPTION, message);
219         eventProperties.put(PERMISSION_USER, userName);
220
221         Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
222         try {
223             notifier.notifySubscribers(syncEvent, userName);
224         } catch (Exception e) {
225             LOGGER.error("Failed to send sync notification to users subscribed o item '" + itemId);
226         }
227     }
228
229     private class SyncEvent implements Event {
230
231         private String eventType;
232         private String originatorId;
233         private Map<String, Object> attributes;
234
235         private String entityId;
236
237         public SyncEvent(String eventType, String originatorId, Map<String, Object> attributes, String entityId) {
238             this.eventType = eventType;
239             this.originatorId = originatorId;
240             this.attributes = attributes;
241             this.entityId = entityId;
242         }
243
244         @Override
245         public String getEventType() {
246             return eventType;
247         }
248
249         @Override
250         public String getOriginatorId() {
251             return originatorId;
252         }
253
254         @Override
255         public Map<String, Object> getAttributes() {
256             return attributes;
257         }
258
259         @Override
260         public String getEntityId() {
261             return entityId;
262         }
263
264     }
265 }