6e7703cda315ada390545dfc2081ccf4ed1da496
[sdc.git] /
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 package org.openecomp.sdcrests.item.rest.services;
17
18 import static org.openecomp.sdc.itempermissions.notifications.NotificationConstants.PERMISSION_USER;
19 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.ITEM_ID;
20 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.ITEM_NAME;
21 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.SUBMIT_DESCRIPTION;
22 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.VERSION_ID;
23 import static org.openecomp.sdc.versioning.VersioningNotificationConstansts.VERSION_NAME;
24
25 import com.google.common.annotations.VisibleForTesting;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import javax.inject.Named;
30 import javax.ws.rs.core.Response;
31 import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity;
32 import org.openecomp.sdc.activitylog.dao.type.ActivityType;
33 import org.openecomp.sdc.common.errors.CoreException;
34 import org.openecomp.sdc.common.errors.Messages;
35 import org.openecomp.sdc.logging.api.Logger;
36 import org.openecomp.sdc.logging.api.LoggerFactory;
37 import org.openecomp.sdc.notification.dtos.Event;
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.rest.models.SyncEvent;
49 import org.openecomp.sdcrests.item.types.ActivityLogDto;
50 import org.openecomp.sdcrests.item.types.CommitRequestDto;
51 import org.openecomp.sdcrests.item.types.RevisionDto;
52 import org.openecomp.sdcrests.item.types.RevisionRequestDto;
53 import org.openecomp.sdcrests.item.types.VersionActionRequestDto;
54 import org.openecomp.sdcrests.item.types.VersionDto;
55 import org.openecomp.sdcrests.item.types.VersionRequestDto;
56 import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper;
57 import org.springframework.context.annotation.Scope;
58 import org.springframework.stereotype.Service;
59
60 @Named
61 @Service("versions")
62 @Scope(value = "prototype")
63 public class VersionsImpl implements Versions {
64
65     private static final String COMMIT_ITEM_ACTION = "Commit_Item";
66     private static final Logger LOGGER = LoggerFactory.getLogger(VersionsImpl.class);
67     private ManagersProvider managersProvider;
68
69     @Override
70     public Response list(String itemId, String user) {
71         GenericCollectionWrapper<VersionDto> results = new GenericCollectionWrapper<>();
72         MapVersionToDto mapper = new MapVersionToDto();
73         getManagersProvider().getVersioningManager().list(itemId).forEach(version -> results.add(mapper.applyMapping(version, VersionDto.class)));
74         return Response.ok(results).build();
75     }
76
77     @Override
78     public Response create(VersionRequestDto request, String itemId, String baseVersionId, String user) {
79         Version version = new Version();
80         version.setBaseId(baseVersionId);
81         version.setDescription(request.getDescription());
82         version = getManagersProvider().getVersioningManager()
83             .create(itemId, version, VersionCreationMethod.valueOf(request.getCreationMethod().name()));
84         VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
85         getManagersProvider().getActivityLogManager()
86             .logActivity(new ActivityLogEntity(itemId, version, ActivityType.Create_Version, user, true, "", ""));
87         return Response.ok(versionDto).build();
88     }
89
90     @Override
91     public Response get(String itemId, String versionId, String user) {
92         Version version = getVersion(itemId, new Version(versionId));
93         VersionDto versionDto = new MapVersionToDto().applyMapping(version, VersionDto.class);
94         return Response.ok(versionDto).build();
95     }
96
97     @Override
98     public Response getActivityLog(String itemId, String versionId, String user) {
99         GenericCollectionWrapper<ActivityLogDto> results = new GenericCollectionWrapper<>();
100         MapActivityLogEntityToDto mapper = new MapActivityLogEntityToDto();
101         getManagersProvider().getActivityLogManager().listLoggedActivities(itemId, new Version(versionId))
102             .forEach(loggedActivity -> results.add(mapper.applyMapping(loggedActivity, ActivityLogDto.class)));
103         return Response.ok(results).build();
104     }
105
106     @Override
107     public Response listRevisions(String itemId, String versionId, String user) {
108         List<Revision> revisions = getManagersProvider().getVersioningManager().listRevisions(itemId, new Version(versionId));
109         filterRevisions(revisions);
110         GenericCollectionWrapper<RevisionDto> results = new GenericCollectionWrapper<>();
111         MapRevisionToDto mapper = new MapRevisionToDto();
112         revisions.forEach(revision -> results.add(mapper.applyMapping(revision, RevisionDto.class)));
113         return Response.ok(results).build();
114     }
115
116     @Override
117     public Response actOn(VersionActionRequestDto request, String itemId, String versionId, String user) {
118         Version version = new Version(versionId);
119         switch (request.getAction()) {
120             case Sync:
121                 sync(itemId, version);
122                 break;
123             case Commit:
124                 if (!getManagersProvider().getPermissionsManager().isAllowed(itemId, user, COMMIT_ITEM_ACTION)) {
125                     return Response.status(Response.Status.FORBIDDEN).entity(new Exception(Messages.PERMISSIONS_ERROR.getErrorMessage())).build();
126                 }
127                 commit(request.getCommitRequest(), itemId, version, user);
128                 break;
129             case Revert:
130                 revert(request.getRevisionRequest(), itemId, versionId);
131                 break;
132             case Clean:
133                 getManagersProvider().getVersioningManager().clean(itemId, version);
134                 break;
135             default:
136                 throw new UnsupportedOperationException(String.format("Action %s not supported.", request.getAction()));
137         }
138         return Response.ok().build();
139     }
140
141     private Version getVersion(String itemId, Version version) {
142         Version retrievedVersion = getManagersProvider().getVersioningManager().get(itemId, version);
143         if (retrievedVersion.getState().getSynchronizationState() != SynchronizationState.Merging &&
144             // looks for sdc applicative conflicts
145             getManagersProvider().getConflictsManager().isConflicted(itemId, retrievedVersion)) {
146             retrievedVersion.getState().setSynchronizationState(SynchronizationState.Merging);
147         }
148         return retrievedVersion;
149     }
150
151     private void sync(String itemId, Version version) {
152         getManagersProvider().getVersioningManager().sync(itemId, version);
153         getManagersProvider().getConflictsManager().finalizeMerge(itemId, version);
154     }
155
156     private void commit(CommitRequestDto request, String itemId, Version version, String user) {
157         String message = request == null ? "" : request.getMessage();
158         getManagersProvider().getVersioningManager().publish(itemId, version, message);
159         notifyUsers(itemId, version, message, user, NotificationEventTypes.COMMIT);
160         getManagersProvider().getActivityLogManager()
161             .logActivity(new ActivityLogEntity(itemId, version, ActivityType.Commit, user, true, "", message));
162     }
163
164     private void revert(RevisionRequestDto request, String itemId, String versionId) {
165         if (request.getRevisionId() == null) {
166             throw new CoreException(new RevisionIdNotFoundErrorBuilder().build());
167         }
168         getManagersProvider().getVersioningManager().revert(itemId, new Version(versionId), request.getRevisionId());
169     }
170
171     private void filterRevisions(List<Revision> revisions) {
172   /* When creating a new item an initial version is created with invalid data.
173      This revision is not an applicable revision. The logic of identifying this revision is:
174      1- only the first version of item has this issue
175      2- only in the first item version there are 2 revisions created
176      3- the second revision is in format "Initial <vlm/vsp>: <name of the vlm/vsp>"
177      4- only if a revision in this format exists we remove the first revision. */
178         int numOfRevisions = revisions.size();
179         if (numOfRevisions > 1 && revisions.get(numOfRevisions - 2).getMessage().matches("Initial .*:.*")) {
180             revisions.remove(numOfRevisions - 1);
181         }
182     }
183
184     private void notifyUsers(String itemId, Version version, String message, String userName, NotificationEventTypes eventType) {
185         Map<String, Object> eventProperties = new HashMap<>();
186         eventProperties.put(ITEM_NAME, getManagersProvider().getAsdcItemManager().get(itemId).getName());
187         eventProperties.put(ITEM_ID, itemId);
188         Version ver = getManagersProvider().getVersioningManager().get(itemId, version);
189         eventProperties.put(VERSION_NAME, ver.getName());
190         eventProperties.put(VERSION_ID, ver.getId());
191         eventProperties.put(SUBMIT_DESCRIPTION, message);
192         eventProperties.put(PERMISSION_USER, userName);
193         Event syncEvent = new SyncEvent(eventType.getEventName(), itemId, eventProperties, itemId);
194         try {
195             getManagersProvider().getNotificationPropagationManager().notifySubscribers(syncEvent, userName);
196         } catch (Exception e) {
197             LOGGER.error("Failed to send sync notification to users subscribed o item '" + itemId);
198         }
199     }
200
201     private ManagersProvider getManagersProvider() {
202         if (managersProvider == null) {
203             managersProvider = new ManagersProvider();
204         }
205         return managersProvider;
206     }
207
208     @VisibleForTesting
209     void setManagersProvider(ManagersProvider managersProvider) {
210         this.managersProvider = managersProvider;
211     }
212 }