re base code
[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.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;
48
49 import javax.inject.Named;
50 import javax.ws.rs.core.Response;
51 import java.util.HashMap;
52 import java.util.List;
53 import java.util.Map;
54
55 import static org.openecomp.sdc.itempermissions.notifications.NotificationConstants.PERMISSION_USER;
56 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.*;
57
58 @Named
59 @Service("versions")
60 @Scope(value = "prototype")
61 public class VersionsImpl implements Versions {
62
63   private static final String COMMIT_ITEM_ACTION = "Commit_Item";
64   private static final Logger LOGGER = LoggerFactory.getLogger(VersionsImpl.class);
65
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();
76
77   @Override
78   public Response list(String itemId, String user) {
79     GenericCollectionWrapper<VersionDto> results = new GenericCollectionWrapper<>();
80     MapVersionToDto mapper = new MapVersionToDto();
81
82     versioningManager.list(itemId)
83         .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,
89                          String user) {
90     Version version = new Version();
91     version.setBaseId(baseVersionId);
92     version.setDescription(request.getDescription());
93
94     version = versioningManager.create(itemId, version, VersionCreationMethod.valueOf(request
95         .getCreationMethod().name()));
96
97     VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
98
99     return Response.ok(versionDto).build();
100   }
101
102   @Override
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();
107   }
108
109   @Override
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();
114   }
115
116   @Override
117   public Response listRevisions(String itemId, String versionId, String user) {
118     List<Revision> revisions = versioningManager.listRevisions(itemId, new Version(versionId));
119     filterRevisions(revisions);
120
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();
125   }
126
127   @Override
128   public Response actOn(VersionActionRequestDto request, String itemId, String versionId,
129                         String user) {
130     Version version = new Version(versionId);
131     switch (request.getAction()) {
132       case Sync:
133         sync(itemId, version);
134         break;
135       case Commit:
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();
139         }
140         commit(request.getCommitRequest(), itemId, version, user);
141         break;
142       case Revert:
143         revert(request.getRevisionRequest(), itemId, versionId);
144         break;
145       case Clean:
146         versioningManager.clean(itemId, version);
147         break;
148       default:
149         throw new UnsupportedOperationException(String.format("Action %s not supported.", request.getAction()));
150     }
151     return Response.ok().build();
152   }
153
154   private Version getVersion(String itemId, Version version) {
155     Version retrievedVersion = versioningManager.get(itemId, version);
156
157     if (retrievedVersion.getState().getSynchronizationState() != SynchronizationState.Merging &&
158         // looks for sdc applicative conflicts
159         conflictsManager.isConflicted(itemId, retrievedVersion)) {
160       retrievedVersion.getState().setSynchronizationState(SynchronizationState.Merging);
161     }
162     return retrievedVersion;
163   }
164
165   private void sync(String itemId, Version version) {
166     versioningManager.sync(itemId, version);
167     conflictsManager.finalizeMerge(itemId, version);
168   }
169
170   private void commit(CommitRequestDto request, String itemId, Version version, String user) {
171
172     String message = request == null ? "" : request.getMessage();
173
174     versioningManager.publish(itemId, version, message);
175     notifyUsers(itemId, version, message, user, NotificationEventTypes.COMMIT);
176   }
177
178   private void revert(RevisionRequestDto request, String itemId, String versionId) {
179     if (request.getRevisionId() == null) {
180       throw new CoreException(new RevisionIdNotFoundErrorBuilder().build());
181     }
182
183     versioningManager.revert(itemId, new Version(versionId), request.getRevisionId());
184   }
185
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 &&
195
196         revisions.get(numOfRevisions - 2).getMessage().matches("Initial .*:.*")) {
197       revisions.remove(numOfRevisions - 1);
198     }
199   }
200
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);
206
207     Version ver = versioningManager.get(itemId, version);
208     eventProperties.put(VERSION_NAME, ver.getName());
209     eventProperties.put(VERSION_ID, ver.getId());
210
211     eventProperties.put(SUBMIT_DESCRIPTION, message);
212     eventProperties.put(PERMISSION_USER, userName);
213
214     Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
215     try {
216       notifier.notifySubscribers(syncEvent, userName);
217     } catch (Exception e) {
218       LOGGER.error("Failed to send sync notification to users subscribed o item '" + itemId);
219     }
220   }
221
222   private class SyncEvent implements Event {
223     private String eventType;
224     private String originatorId;
225     private Map<String, Object> attributes;
226
227     private String entityId;
228
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;
235     }
236
237     @Override
238     public String getEventType() {
239       return eventType;
240     }
241
242     @Override
243     public String getOriginatorId() {
244       return originatorId;
245     }
246
247     @Override
248     public Map<String, Object> getAttributes() {
249       return attributes;
250     }
251
252     @Override
253     public String getEntityId() {
254       return entityId;
255     }
256
257   }
258 }