1 package org.openecomp.core.zusammen.plugin.collaboration;
3 import com.amdocs.zusammen.datatypes.Id;
4 import com.amdocs.zusammen.datatypes.SessionContext;
5 import com.amdocs.zusammen.datatypes.item.Action;
6 import com.amdocs.zusammen.datatypes.item.ElementContext;
7 import com.amdocs.zusammen.datatypes.response.ReturnCode;
8 import com.amdocs.zusammen.datatypes.response.ZusammenException;
9 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
10 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationPublishResult;
11 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
12 import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
13 import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
15 import java.util.Collection;
16 import java.util.Date;
18 import java.util.Optional;
19 import java.util.UUID;
21 import static com.amdocs.zusammen.datatypes.response.Module.ZCSP;
22 import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
23 import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementChange;
24 import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionChange;
25 import static org.openecomp.core.zusammen.plugin.collaboration.ErrorCode.NO_CHANGES_TO_PUBLISH;
27 public class PublishService {
28 // TODO: 6/29/2017 throw ZusammenException with ReturnCode when needed.
29 private static final String PUSH_NON_EXISTING_VERSION =
30 "Item Id %s, version Id %s: Non existing version cannot be pushed.";
32 private VersionPublicStore versionPublicStore;
33 private VersionPrivateStore versionPrivateStore;
34 private ElementPublicStore elementPublicStore;
35 private ElementPrivateStore elementPrivateStore;
37 public PublishService(VersionPublicStore versionPublicStore,
38 VersionPrivateStore versionPrivateStore,
39 ElementPublicStore elementPublicStore,
40 ElementPrivateStore elementPrivateStore) {
41 this.versionPublicStore = versionPublicStore;
42 this.versionPrivateStore = versionPrivateStore;
43 this.elementPublicStore = elementPublicStore;
44 this.elementPrivateStore = elementPrivateStore;
47 public CollaborationPublishResult publish(SessionContext context, Id itemId, Id versionId,
49 CollaborationPublishResult result = new CollaborationPublishResult();
50 result.setChange(new CollaborationMergeChange());
52 Date publishTime = new Date();
53 Id revisionId = new Id(UUID.randomUUID().toString());
54 boolean versionFirstPublication = publishVersion(context, itemId, versionId, revisionId,
56 if (versionFirstPublication) {
57 publishAllElements(context, new ElementContext(itemId, versionId, revisionId), publishTime,
60 publishDirtyElements(context, new ElementContext(itemId, versionId, revisionId), publishTime,
66 private boolean publishVersion(SessionContext context, Id itemId, Id versionId, Id revisionId,
67 Date publishTime, String message) {
68 SynchronizationStateEntity privateVersionSyncState =
69 versionPrivateStore.getSynchronizationState(context, itemId, versionId)
70 .orElseThrow(() -> new IllegalArgumentException(
71 String.format(PUSH_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
73 if (!privateVersionSyncState.isDirty()) {
74 throw new ZusammenException(new ReturnCode(NO_CHANGES_TO_PUBLISH, ZCSP,
75 String.format(Message.NO_CHANGES_TO_PUBLISH, itemId, versionId), null));
78 Optional<SynchronizationStateEntity> publicVersionSyncState =
79 versionPublicStore.getSynchronizationState(context, itemId, versionId);
81 // private must be synced with public (if public exists)
82 if (publicVersionSyncState.isPresent() &&
83 !privateVersionSyncState.getPublishTime()
84 .equals(publicVersionSyncState.get().getPublishTime())) {
85 // should not happen as it is validated in zusammen-core
86 throw new UnsupportedOperationException("Out of sync item version can not be publish");
89 boolean versionFirstPublication;
90 Map<Id, Id> versionElementIds =
91 elementPublicStore.listIds(context, new ElementContext(itemId,
93 if (publicVersionSyncState.isPresent()) {
94 versionPublicStore.update(context, itemId, new VersionEntity(versionId), revisionId,
95 versionElementIds,publishTime,message);
96 versionFirstPublication = false;
98 VersionEntity privateVersion = versionPrivateStore.get(context, itemId, versionId)
99 .orElseThrow(() -> new IllegalArgumentException(
100 String.format(PUSH_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
101 versionPublicStore.create(context, itemId, privateVersion, revisionId,versionElementIds,
102 publishTime,message);
103 versionFirstPublication = true;
105 versionPrivateStore.markAsPublished(context, itemId, versionId, publishTime);
106 return versionFirstPublication;
109 private void publishAllElements(SessionContext context, ElementContext elementContext,
110 Date publishTime, CollaborationPublishResult result) {
111 Collection<SynchronizationStateEntity> privateElementSyncStates =
112 elementPrivateStore.listSynchronizationStates(context, elementContext);
114 for (SynchronizationStateEntity privateElementSyncState : privateElementSyncStates) {
115 Optional<ElementEntity> privateElement =
116 elementPrivateStore.get(context, elementContext, privateElementSyncState.getId());
118 if (!privateElement.isPresent()) {
121 ElementEntity elementToPublish = privateElement.get();
123 elementPublicStore.create(context, elementContext, elementToPublish,
124 privateElementSyncState.isDirty() ? publishTime
125 : privateElementSyncState.getPublishTime());
127 if (privateElementSyncState.isDirty()) {
129 .markAsPublished(context, elementContext, privateElementSyncState.getId(), publishTime);
131 updateResult(elementContext, elementToPublish, Action.CREATE,
132 ROOT_ELEMENTS_PARENT_ID.equals(privateElementSyncState.getId()), result);
136 private void publishDirtyElements(SessionContext context, ElementContext elementContext,
137 Date publishTime, CollaborationPublishResult result) {
139 Id revisionId = elementContext.getRevisionId();
140 elementContext.setRevisionId(revisionId);
141 ElementContext privateElementContext = new ElementContext(elementContext.getItemId(),
142 elementContext.getVersionId(),Id.ZERO);
143 Collection<SynchronizationStateEntity> privateElementSyncStates =
144 elementPrivateStore.listSynchronizationStates(context, elementContext);
146 Collection<SynchronizationStateEntity> publicElementSyncStates =
147 elementPublicStore.listSynchronizationStates(context, elementContext);
149 for (SynchronizationStateEntity privateElementSyncState : privateElementSyncStates) {
150 if (!privateElementSyncState.isDirty()) {
154 Optional<ElementEntity> privateElement =
155 elementPrivateStore.get(context, privateElementContext, privateElementSyncState.getId());
157 ElementEntity elementToPublish;
158 Action actionOnPublic;
159 if (privateElement.isPresent()) {
160 elementToPublish = privateElement.get();
162 if (publicElementSyncStates.contains(privateElementSyncState)) {
164 elementPublicStore.update(context, elementContext, elementToPublish, publishTime);
165 actionOnPublic = Action.UPDATE;
167 elementPublicStore.create(context, elementContext, elementToPublish, publishTime);
168 actionOnPublic = Action.CREATE;
172 .markAsPublished(context, privateElementContext, privateElementSyncState.getId(), publishTime);
175 elementPublicStore.get(context, elementContext, privateElementSyncState.getId())
176 .orElseThrow(() -> new IllegalStateException(
177 "Element that should be deleted from public must exist there"));
178 elementPublicStore.delete(context, elementContext, elementToPublish, publishTime);
179 actionOnPublic = Action.DELETE;
182 .markDeletionAsPublished(context, privateElementContext, privateElementSyncState.getId(),
186 updateResult(elementContext, elementToPublish, actionOnPublic,
187 ROOT_ELEMENTS_PARENT_ID.equals(privateElementSyncState.getId()), result);
191 private void updateResult(ElementContext elementContext, ElementEntity element,
192 Action action, boolean versionDataElement,
193 CollaborationPublishResult result) {
194 if (versionDataElement) {
195 result.getChange().setChangedVersion(convertToVersionChange(elementContext, element, action));
197 result.getChange().getChangedElements()
198 .add(convertToElementChange(elementContext, element, action));