aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin')
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml27
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java222
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java100
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java119
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java48
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java23
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java35
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java20
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java5
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java6
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java201
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java161
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java384
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java110
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java38
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java29
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java18
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java269
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java189
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java133
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java117
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java135
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java39
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java29
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java34
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java14
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java21
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java14
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java15
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java16
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java29
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java13
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java9
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java13
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java18
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java14
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java375
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/CassandraDaoUtils.java (renamed from openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraDaoUtils.java)4
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryFactoryImpl.java (renamed from openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java)6
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java565
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java31
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java423
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java33
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java209
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java15
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java185
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java15
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java82
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java33
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java137
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java22
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java60
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java116
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java23
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java21
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java45
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java441
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java114
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json7
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java64
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java237
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java167
62 files changed, 5414 insertions, 683 deletions
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml
index fba7d568e3..f8cfcfdc9b 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml
@@ -33,5 +33,32 @@
<artifactId>zusammen-state-store-cassandra-plugin</artifactId>
<version>${zusammen-state-store.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>${testng.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>${mockito.all.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.amdocs.zusammen</groupId>
+ <artifactId>zusammen-commons-utils</artifactId>
+ <version>${zusammen.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdc.core</groupId>
+ <artifactId>openecomp-facade-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdc.core</groupId>
+ <artifactId>openecomp-session-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java
index 59afa70e9a..a973590eb5 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java
@@ -19,13 +19,30 @@ package org.openecomp.core.zusammen.plugin;
import com.amdocs.zusammen.datatypes.Id;
import com.amdocs.zusammen.datatypes.SessionContext;
import com.amdocs.zusammen.datatypes.Space;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionChange;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.ItemVersionDataConflict;
import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElement;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementConflict;
+import com.amdocs.zusammen.sdk.state.types.StateElement;
+import com.amdocs.zusammen.sdk.types.ElementDescriptor;
import com.amdocs.zusammen.utils.fileutils.FileUtils;
+import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.Date;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
public class ZusammenPluginUtil {
@@ -34,7 +51,7 @@ public class ZusammenPluginUtil {
case PUBLIC:
return ZusammenPluginConstants.PUBLIC_SPACE;
case PRIVATE:
- return ZusammenPluginUtil.getPrivateSpaceName(context);
+ return getPrivateSpaceName(context);
default:
throw new IllegalArgumentException(String.format("Space %s is not supported.", space));
}
@@ -44,14 +61,54 @@ public class ZusammenPluginUtil {
return context.getUser().getUserName();
}
- public static ElementEntity getElementEntity(CollaborationElement element) {
+ public static ElementContext getPrivateElementContext(ElementContext elementContext) {
+ return new ElementContext(elementContext.getItemId(),elementContext.getVersionId(),Id.ZERO);
+ }
+
+
+ public static VersionEntity convertToVersionEntity(Id versionId, Id baseVersionId,
+ Date creationTime,
+ Date modificationTime) {
+
+ return convertToVersionEntity(versionId, null, baseVersionId,
+ creationTime, modificationTime);
+ }
+
+ public static VersionEntity convertToVersionEntity(Id versionId, Id revisionId, Id baseVersionId,
+ Date creationTime,
+ Date modificationTime) {
+ VersionEntity version = new VersionEntity(versionId);
+ version.setBaseId(baseVersionId);
+ version.setCreationTime(creationTime);
+ version.setModificationTime(modificationTime);
+ return version;
+ }
+
+ public static ItemVersion convertToItemVersion(VersionEntity versionEntity,
+ ItemVersionData itemVersionData) {
+ ItemVersion itemVersion = new ItemVersion();
+ itemVersion.setId(versionEntity.getId());
+
+ itemVersion.setBaseId(versionEntity.getBaseId());
+ itemVersion.setCreationTime(versionEntity.getCreationTime());
+ itemVersion.setModificationTime(versionEntity.getModificationTime());
+ itemVersion.setData(itemVersionData);
+ return itemVersion;
+ }
+
+ public static ElementEntity convertToElementEntity(CollaborationElement element) {
+
ElementEntity elementEntity = new ElementEntity(element.getId());
elementEntity.setNamespace(element.getNamespace());
elementEntity.setParentId(element.getParentId() == null
- ? ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID
+ ? ROOT_ELEMENTS_PARENT_ID
: element.getParentId());
+
+
elementEntity.setInfo(element.getInfo());
+
elementEntity.setRelations(element.getRelations());
+
if (element.getData() != null) {
elementEntity.setData(ByteBuffer.wrap(FileUtils.toByteArray(element.getData())));
}
@@ -63,21 +120,29 @@ public class ZusammenPluginUtil {
elementEntity.setVisualization(
ByteBuffer.wrap(FileUtils.toByteArray(element.getVisualization())));
}
+ elementEntity.setElementHash(new Id(calculateElementHash(elementEntity)));
+
return elementEntity;
}
- public static CollaborationElement getCollaborationElement(
- ElementEntityContext elementEntityContext, ElementEntity elementEntity) {
- Id parentId =
- ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID.equals(elementEntity.getParentId())
- ? null
- : elementEntity.getParentId();
- CollaborationElement element = new CollaborationElement(elementEntityContext.getItemId(),
- elementEntityContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
+ public static ElementDescriptor convertToElementDescriptor(
+ ElementContext elementContext, ElementEntity elementEntity) {
+ if (elementEntity == null) {
+ return null;
+ }
+ ElementDescriptor element = new ElementDescriptor(elementContext.getItemId(),
+ elementContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
- element.setParentId(parentId);
- element.setInfo(elementEntity.getInfo());
- element.setRelations(elementEntity.getRelations());
+ mapElementEntityToDescriptor(elementEntity, element);
+ return element;
+ }
+
+ public static CollaborationElement convertToCollaborationElement(
+ ElementContext elementContext, ElementEntity elementEntity) {
+ CollaborationElement element = new CollaborationElement(elementContext.getItemId(),
+ elementContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
+
+ mapElementEntityToDescriptor(elementEntity, element);
if (elementEntity.getData() != null) {
element.setData(new ByteArrayInputStream(elementEntity.getData().array()));
@@ -89,7 +154,134 @@ public class ZusammenPluginUtil {
if (elementEntity.getVisualization() != null) {
element.setVisualization(new ByteArrayInputStream(elementEntity.getVisualization().array()));
}
+ return element;
+ }
+
+ public static CollaborationElementChange convertToElementChange(
+ ElementContext changedElementContext, ElementEntity changedElement, Action action) {
+ CollaborationElementChange elementChange = new CollaborationElementChange();
+ elementChange.setElement(convertToCollaborationElement(changedElementContext, changedElement));
+ elementChange.setAction(action);
+ return elementChange;
+ }
+
+ public static ItemVersionChange convertToVersionChange(ElementContext elementContext,
+ ElementEntity versionDataElement,
+ Action action) {
+ ItemVersionChange versionChange = new ItemVersionChange();
+
+ ItemVersion itemVersion = new ItemVersion();
+ itemVersion.setId(elementContext.getVersionId());
+
+ itemVersion.setData(convertToVersionData(versionDataElement));
+
+ versionChange.setItemVersion(itemVersion);
+ versionChange.setAction(action);
+ return versionChange;
+ }
+
+ public static ItemVersionDataConflict getVersionConflict(ElementEntity localVesionData,
+ ElementEntity remoteVersionData) {
+ ItemVersionDataConflict versionConflict = new ItemVersionDataConflict();
+ versionConflict.setLocalData(convertToVersionData(localVesionData));
+ versionConflict.setRemoteData(convertToVersionData(remoteVersionData));
+ return versionConflict;
+ }
+
+ public static CollaborationElementConflict getElementConflict(ElementContext elementContext,
+ ElementEntity localElement,
+ ElementEntity remoteElement) {
+ CollaborationElementConflict elementConflict = new CollaborationElementConflict();
+ elementConflict
+ .setLocalElement(convertToCollaborationElement(elementContext, localElement));
+ elementConflict.setRemoteElement(
+ convertToCollaborationElement(elementContext, remoteElement));
+ return elementConflict;
+ }
+
+ public static ItemVersionData convertToVersionData(ElementEntity versionDataElement) {
+ ItemVersionData versionData = new ItemVersionData();
+ versionData.setInfo(versionDataElement.getInfo());
+ versionData.setRelations(versionDataElement.getRelations());
+ return versionData;
+ }
+
+ private static void mapElementEntityToDescriptor(ElementEntity elementEntity,
+ ElementDescriptor elementDescriptor) {
+ Id parentId = ROOT_ELEMENTS_PARENT_ID.equals(elementEntity.getParentId())
+ ? null
+ : elementEntity.getParentId();
+
+ elementDescriptor.setParentId(parentId);
+ elementDescriptor.setInfo(elementEntity.getInfo());
+ elementDescriptor.setRelations(elementEntity.getRelations());
+ elementDescriptor.setSubElements(elementEntity.getSubElementIds());
+ }
+
+ public static String calculateElementHash(ElementEntity elementEntity) {
+ StringBuffer elementHash = new StringBuffer();
+ if (elementEntity.getData() != null) {
+ elementHash.append(calculateSHA1(elementEntity.getData().array()));
+ } else {
+ elementHash.append("0");
+ }
+ elementHash.append("_");
+ if (elementEntity.getVisualization() != null) {
+ elementHash.append(calculateSHA1(elementEntity.getVisualization().array()));
+ } else {
+ elementHash.append("0");
+ }
+ elementHash.append("_");
+
+ if (elementEntity.getSearchableData() != null) {
+ elementHash.append(calculateSHA1(elementEntity.getSearchableData().array()));
+ } else {
+ elementHash.append("0");
+ }
+ elementHash.append("_");
+
+ if (elementEntity.getInfo() != null) {
+ elementHash.append(calculateSHA1(JsonUtil.object2Json(elementEntity.getInfo()).getBytes()));
+ } else {
+ elementHash.append("0");
+ }
+ elementHash.append("_");
+
+ if (elementEntity.getRelations() != null) {
+ elementHash
+ .append(calculateSHA1(JsonUtil.object2Json(elementEntity.getRelations()).getBytes()));
+ } else {
+ elementHash.append("0");
+ }
+
+ return elementHash.toString();
+ }
+
+ private static String calculateSHA1(byte[] content2Convert) {
+ MessageDigest md = null;
+ try {
+ md = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ return Base64.getEncoder().encodeToString(md.digest(content2Convert));
+ }
+
+
+ public static StateElement getStateElement(ElementContext elementContext, ElementEntity
+ elementEntity) {
+ Id parentId = ROOT_ELEMENTS_PARENT_ID.equals(elementEntity.getParentId())
+ ? null
+ : elementEntity.getParentId();
+ StateElement element = new StateElement(elementContext.getItemId(),
+ elementContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
+
+ element.setParentId(parentId);
+ element.setInfo(elementEntity.getInfo());
+ element.setRelations(elementEntity.getRelations());
element.setSubElements(elementEntity.getSubElementIds());
return element;
}
+
+
}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java
new file mode 100644
index 0000000000..45d5769e9c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java
@@ -0,0 +1,100 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public class CommitStagingService {
+
+ private VersionPrivateStore versionPrivateStore;
+ private VersionStageStore versionStageStore;
+ private ElementPrivateStore elementPrivateStore;
+ private ElementStageStore elementStageStore;
+
+ public CommitStagingService(VersionPrivateStore versionPrivateStore,
+ VersionStageStore versionStageStore,
+ ElementPrivateStore elementPrivateStore,
+ ElementStageStore elementStageStore) {
+ this.versionPrivateStore = versionPrivateStore;
+ this.versionStageStore = versionStageStore;
+ this.elementPrivateStore = elementPrivateStore;
+ this.elementStageStore = elementStageStore;
+ }
+
+ public void commitStaging(SessionContext context, Id itemId, Id versionId) {
+ Optional<StageEntity<VersionEntity>> versionStage =
+ versionStageStore.get(context, itemId, new VersionEntity(versionId));
+
+ final ElementContext elementContext = new ElementContext(itemId, versionId, Id.ZERO);
+ Collection<ElementEntity> stagedElementIds = elementStageStore.listIds(context, elementContext);
+
+ if ((!versionStage.isPresent() && stagedElementIds.isEmpty()) ||
+ elementStageStore.hasConflicts(context, elementContext)) {
+ return;
+ }
+
+ versionStage.ifPresent(verStage -> commitVersionStage(context, itemId, verStage));
+ commitElementsStage(context, elementContext, stagedElementIds);
+ }
+
+ private void commitVersionStage(SessionContext context, Id itemId,
+ StageEntity<VersionEntity> versionStage) {
+ switch (versionStage.getAction()) {
+ case CREATE:
+ versionPrivateStore.commitStagedCreate(context, itemId, versionStage.getEntity(),
+ versionStage.getPublishTime());
+ break;
+ case UPDATE:
+ versionPrivateStore.commitStagedUpdate(context, itemId, versionStage.getEntity(),
+ versionStage.getPublishTime());
+ break;
+ case IGNORE:
+ versionPrivateStore.commitStagedIgnore(context, itemId, versionStage.getEntity(),
+ versionStage.getPublishTime());
+ break;
+ default:
+ throw new UnsupportedOperationException(
+ "Version change other then Create/Update/Ignore is not supported");
+ }
+
+ versionStageStore.delete(context, itemId, versionStage.getEntity());
+ }
+
+ private void commitElementsStage(SessionContext context, ElementContext elementContext,
+ Collection<ElementEntity> stagedElementIds) {
+ for (ElementEntity stagedElementId : stagedElementIds) {
+ StageEntity<ElementEntity> stagedElement =
+ elementStageStore.get(context, elementContext, stagedElementId)
+ .orElseThrow(
+ () -> new IllegalStateException("Element id returned by list must exist"));
+ switch (stagedElement.getAction()) {
+ case CREATE:
+ elementPrivateStore.commitStagedCreate(context, elementContext, stagedElement.getEntity(),
+ stagedElement.getPublishTime());
+ break;
+ case UPDATE:
+ elementPrivateStore.commitStagedUpdate(context, elementContext, stagedElement.getEntity(),
+ stagedElement.getPublishTime());
+ break;
+ case DELETE:
+ elementPrivateStore
+ .commitStagedDelete(context, elementContext, stagedElement.getEntity());
+ break;
+ case IGNORE:
+ elementPrivateStore.commitStagedIgnore(context, elementContext, stagedElement.getEntity(),
+ stagedElement.getPublishTime());
+ break;
+ default:
+ throw new UnsupportedOperationException(
+ "Element change other then Create/Update/Delete/Ignore is not supported");
+ }
+ elementStageStore.delete(context, elementContext, stagedElement.getEntity());
+ }
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java
deleted file mode 100644
index ac103c0fbf..0000000000
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.openecomp.core.zusammen.plugin.collaboration;
-
-import com.amdocs.zusammen.datatypes.Id;
-import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.item.ElementContext;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
-import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElement;
-import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
-import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
-import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Optional;
-
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getCollaborationElement;
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
-
-
-public class ElementCollaborationStore {
-
- private static final String SUB_ELEMENT_NOT_EXIST_ERROR_MSG =
- "List sub elements error: item %s, version %s - " +
- "element %s, which appears as sub element of element %s, does not exist";
-
- public Collection<CollaborationElement> listElements(SessionContext context,
- ElementContext elementContext,
- Id elementId) {
- ElementEntityContext elementEntityContext =
- new ElementEntityContext(ZusammenPluginUtil.getPrivateSpaceName(context), elementContext);
-
- if (elementId == null) {
- elementId = ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
- }
-
- ElementRepository elementRepository = getElementRepository(context);
- String elementIdValue = elementId.getValue();
- String versionIdValue = elementContext.getChangeRef() == null
- ? elementContext.getVersionId().getValue()
- : elementContext.getChangeRef();
- Collection<CollaborationElement> subElements = new ArrayList<>();
-
- Optional<ElementEntity> element =
- elementRepository.get(context, elementEntityContext, new ElementEntity(elementId));
- if (element.isPresent() && element.get().getSubElementIds() != null) {
- for (Id subElementId : element.get().getSubElementIds()) {
- ElementEntity subElement =
- elementRepository.get(context, elementEntityContext, new ElementEntity(subElementId))
- .orElseThrow(
- () -> new IllegalStateException(String.format(SUB_ELEMENT_NOT_EXIST_ERROR_MSG,
- elementContext.getItemId().getValue(), versionIdValue,
- subElementId.getValue(), elementIdValue)));
- subElements.add(getCollaborationElement(elementEntityContext, subElement));
- }
- }
- return subElements;
- }
-
- public CollaborationElement getElement(SessionContext context, ElementContext elementContext,
- Id elementId) {
- ElementEntityContext elementEntityContext =
- new ElementEntityContext(ZusammenPluginUtil.getPrivateSpaceName(context), elementContext);
- return getElementRepository(context)
- .get(context, elementEntityContext, new ElementEntity(elementId))
- .map(elementEntity -> getCollaborationElement(elementEntityContext, elementEntity))
- .orElse(null);
- }
-
- public void createElement(SessionContext context, CollaborationElement element) {
- getElementRepository(context)
- .create(context,
- new ElementEntityContext(getSpaceName(context, element.getSpace()),
- element.getItemId(), element.getVersionId()),
- ZusammenPluginUtil.getElementEntity(element));
- }
-
- public void updateElement(SessionContext context, CollaborationElement element) {
- getElementRepository(context)
- .update(context,
- new ElementEntityContext(getSpaceName(context, element.getSpace()),
- element.getItemId(), element.getVersionId()),
- ZusammenPluginUtil.getElementEntity(element));
- }
-
- public void deleteElement(SessionContext context, CollaborationElement element) {
- deleteElementHierarchy(getElementRepository(context),
- context,
- new ElementEntityContext(getSpaceName(context, element.getSpace()),
- element.getItemId(), element.getVersionId()),
- ZusammenPluginUtil.getElementEntity(element));
- }
-
- public boolean checkHealth(SessionContext sessionContext) {
- return getElementRepository(sessionContext).checkHealth(sessionContext);
- }
-
- private void deleteElementHierarchy(ElementRepository elementRepository, SessionContext context,
- ElementEntityContext elementEntityContext,
- ElementEntity elementEntity) {
- Optional<ElementEntity> retrieved =
- elementRepository.get(context, elementEntityContext, elementEntity);
- if (!retrieved.isPresent()) {
- return;
- }
- retrieved.get().getSubElementIds().stream()
- .map(ElementEntity::new)
- .forEach(subElementEntity -> deleteElementHierarchy(
- elementRepository, context, elementEntityContext, subElementEntity));
-
- // only for the first one the parentId will populated (so it'll be removed from its parent)
- elementRepository.delete(context, elementEntityContext, elementEntity);
- }
-
- protected ElementRepository getElementRepository(SessionContext context) {
- return ElementRepositoryFactory.getInstance().createInterface(context);
- }
-}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java
new file mode 100644
index 0000000000..045def2561
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java
@@ -0,0 +1,48 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+public interface ElementPrivateStore extends ElementStore {
+
+ Map<Id, Id> listIds(SessionContext context, ElementContext elementContext);
+
+ Collection<ElementEntity> listSubs(SessionContext context, ElementContext elementContext,
+ Id elementId);
+
+ Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+ ElementContext elementContext,
+ Id elementId);
+
+ void create(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+ boolean update(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+ void delete(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+ void markAsPublished(SessionContext context, ElementContext elementContext, Id elementId,
+ Date publishTime);
+
+ void markDeletionAsPublished(SessionContext context, ElementContext elementContext, Id elementId,
+ Date publishTime);
+
+ void commitStagedCreate(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime);
+
+ void commitStagedUpdate(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime);
+
+ void commitStagedDelete(SessionContext context, ElementContext elementContext,
+ ElementEntity element);
+
+ void commitStagedIgnore(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java
new file mode 100644
index 0000000000..0f1790a1bf
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java
@@ -0,0 +1,23 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+
+import java.util.Date;
+import java.util.Map;
+
+public interface ElementPublicStore extends ElementStore {
+
+ void create(SessionContext context, ElementContext elementContext, ElementEntity element,
+ Date publishTime);
+
+ void update(SessionContext context, ElementContext elementContext, ElementEntity element,
+ Date publishTime);
+
+ void delete(SessionContext context, ElementContext elementContext, ElementEntity element,
+ Date publishTime);
+
+ Map<Id,Id> listIds(SessionContext context, ElementContext elementContext);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java
new file mode 100644
index 0000000000..a9236247f9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java
@@ -0,0 +1,35 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface ElementStageStore {
+
+ Collection<ElementEntity> listIds(SessionContext context, ElementContext elementContext);
+
+ boolean hasConflicts(SessionContext context, ElementContext elementContext);
+
+ Collection<StageEntity<ElementEntity>> listConflictedDescriptors(SessionContext context,
+ ElementContext elementContext);
+
+ Optional<StageEntity<ElementEntity>> get(SessionContext context, ElementContext elementContext,
+ ElementEntity element);
+
+ Optional<StageEntity<ElementEntity>> getConflicted(SessionContext context,
+ ElementContext elementContext,
+ ElementEntity element);
+
+ void create(SessionContext context, ElementContext elementContext,
+ StageEntity<ElementEntity> elementStage);
+
+ void delete(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+ void resolveConflict(SessionContext context, ElementContext elementContext, ElementEntity element,
+ Resolution resolution);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java
new file mode 100644
index 0000000000..1c26a817ae
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java
@@ -0,0 +1,20 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface ElementStore {
+ Optional<ElementEntity> get(SessionContext context, ElementContext elementContext, Id elementId);
+
+ Optional<ElementEntity> getDescriptor(SessionContext context, ElementContext elementContext,
+ Id elementId);
+
+ Collection<SynchronizationStateEntity> listSynchronizationStates(SessionContext context,
+ ElementContext elementContext);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java
new file mode 100644
index 0000000000..3d0910072c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java
@@ -0,0 +1,5 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+public class ErrorCode {
+ public static final int NO_CHANGES_TO_PUBLISH = 60000;
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java
new file mode 100644
index 0000000000..2816974307
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java
@@ -0,0 +1,6 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+public class Message {
+ public static final String NO_CHANGES_TO_PUBLISH =
+ "Item Id %s, version Id %s: There are no changes to publish.";
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java
new file mode 100644
index 0000000000..7b043c830f
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java
@@ -0,0 +1,201 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.response.ReturnCode;
+import com.amdocs.zusammen.datatypes.response.ZusammenException;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationPublishResult;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import static com.amdocs.zusammen.datatypes.response.Module.ZCSP;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementChange;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionChange;
+import static org.openecomp.core.zusammen.plugin.collaboration.ErrorCode.NO_CHANGES_TO_PUBLISH;
+
+public class PublishService {
+ // TODO: 6/29/2017 throw ZusammenException with ReturnCode when needed.
+ private static final String PUSH_NON_EXISTING_VERSION =
+ "Item Id %s, version Id %s: Non existing version cannot be pushed.";
+
+ private VersionPublicStore versionPublicStore;
+ private VersionPrivateStore versionPrivateStore;
+ private ElementPublicStore elementPublicStore;
+ private ElementPrivateStore elementPrivateStore;
+
+ public PublishService(VersionPublicStore versionPublicStore,
+ VersionPrivateStore versionPrivateStore,
+ ElementPublicStore elementPublicStore,
+ ElementPrivateStore elementPrivateStore) {
+ this.versionPublicStore = versionPublicStore;
+ this.versionPrivateStore = versionPrivateStore;
+ this.elementPublicStore = elementPublicStore;
+ this.elementPrivateStore = elementPrivateStore;
+ }
+
+ public CollaborationPublishResult publish(SessionContext context, Id itemId, Id versionId,
+ String message) {
+ CollaborationPublishResult result = new CollaborationPublishResult();
+ result.setChange(new CollaborationMergeChange());
+
+ Date publishTime = new Date();
+ Id revisionId = new Id(UUID.randomUUID().toString());
+ boolean versionFirstPublication = publishVersion(context, itemId, versionId, revisionId,
+ publishTime,message);
+ if (versionFirstPublication) {
+ publishAllElements(context, new ElementContext(itemId, versionId, revisionId), publishTime,
+ result);
+ } else {
+ publishDirtyElements(context, new ElementContext(itemId, versionId, revisionId), publishTime,
+ result);
+ }
+ return result;
+ }
+
+ private boolean publishVersion(SessionContext context, Id itemId, Id versionId, Id revisionId,
+ Date publishTime, String message) {
+ SynchronizationStateEntity privateVersionSyncState =
+ versionPrivateStore.getSynchronizationState(context, itemId, versionId)
+ .orElseThrow(() -> new IllegalArgumentException(
+ String.format(PUSH_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
+
+ if (!privateVersionSyncState.isDirty()) {
+ throw new ZusammenException(new ReturnCode(NO_CHANGES_TO_PUBLISH, ZCSP,
+ String.format(Message.NO_CHANGES_TO_PUBLISH, itemId, versionId), null));
+ }
+
+ Optional<SynchronizationStateEntity> publicVersionSyncState =
+ versionPublicStore.getSynchronizationState(context, itemId, versionId);
+
+ // private must be synced with public (if public exists)
+ if (publicVersionSyncState.isPresent() &&
+ !privateVersionSyncState.getPublishTime()
+ .equals(publicVersionSyncState.get().getPublishTime())) {
+ // should not happen as it is validated in zusammen-core
+ throw new UnsupportedOperationException("Out of sync item version can not be publish");
+ }
+
+ boolean versionFirstPublication;
+ Map<Id, Id> versionElementIds =
+ elementPublicStore.listIds(context, new ElementContext(itemId,
+ versionId));
+ if (publicVersionSyncState.isPresent()) {
+ versionPublicStore.update(context, itemId, new VersionEntity(versionId), revisionId,
+ versionElementIds,publishTime,message);
+ versionFirstPublication = false;
+ } else {
+ VersionEntity privateVersion = versionPrivateStore.get(context, itemId, versionId)
+ .orElseThrow(() -> new IllegalArgumentException(
+ String.format(PUSH_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
+ versionPublicStore.create(context, itemId, privateVersion, revisionId,versionElementIds,
+ publishTime,message);
+ versionFirstPublication = true;
+ }
+ versionPrivateStore.markAsPublished(context, itemId, versionId, publishTime);
+ return versionFirstPublication;
+ }
+
+ private void publishAllElements(SessionContext context, ElementContext elementContext,
+ Date publishTime, CollaborationPublishResult result) {
+ Collection<SynchronizationStateEntity> privateElementSyncStates =
+ elementPrivateStore.listSynchronizationStates(context, elementContext);
+
+ for (SynchronizationStateEntity privateElementSyncState : privateElementSyncStates) {
+ Optional<ElementEntity> privateElement =
+ elementPrivateStore.get(context, elementContext, privateElementSyncState.getId());
+
+ if (!privateElement.isPresent()) {
+ continue;
+ }
+ ElementEntity elementToPublish = privateElement.get();
+
+ elementPublicStore.create(context, elementContext, elementToPublish,
+ privateElementSyncState.isDirty() ? publishTime
+ : privateElementSyncState.getPublishTime());
+
+ if (privateElementSyncState.isDirty()) {
+ elementPrivateStore
+ .markAsPublished(context, elementContext, privateElementSyncState.getId(), publishTime);
+ }
+ updateResult(elementContext, elementToPublish, Action.CREATE,
+ ROOT_ELEMENTS_PARENT_ID.equals(privateElementSyncState.getId()), result);
+ }
+ }
+
+ private void publishDirtyElements(SessionContext context, ElementContext elementContext,
+ Date publishTime, CollaborationPublishResult result) {
+
+ Id revisionId = elementContext.getRevisionId();
+ elementContext.setRevisionId(revisionId);
+ ElementContext privateElementContext = new ElementContext(elementContext.getItemId(),
+ elementContext.getVersionId(),Id.ZERO);
+ Collection<SynchronizationStateEntity> privateElementSyncStates =
+ elementPrivateStore.listSynchronizationStates(context, elementContext);
+
+ Collection<SynchronizationStateEntity> publicElementSyncStates =
+ elementPublicStore.listSynchronizationStates(context, elementContext);
+
+ for (SynchronizationStateEntity privateElementSyncState : privateElementSyncStates) {
+ if (!privateElementSyncState.isDirty()) {
+ continue;
+ }
+
+ Optional<ElementEntity> privateElement =
+ elementPrivateStore.get(context, privateElementContext, privateElementSyncState.getId());
+
+ ElementEntity elementToPublish;
+ Action actionOnPublic;
+ if (privateElement.isPresent()) {
+ elementToPublish = privateElement.get();
+
+ if (publicElementSyncStates.contains(privateElementSyncState)) {
+
+ elementPublicStore.update(context, elementContext, elementToPublish, publishTime);
+ actionOnPublic = Action.UPDATE;
+ } else {
+ elementPublicStore.create(context, elementContext, elementToPublish, publishTime);
+ actionOnPublic = Action.CREATE;
+ }
+
+ elementPrivateStore
+ .markAsPublished(context, privateElementContext, privateElementSyncState.getId(), publishTime);
+ } else {
+ elementToPublish =
+ elementPublicStore.get(context, elementContext, privateElementSyncState.getId())
+ .orElseThrow(() -> new IllegalStateException(
+ "Element that should be deleted from public must exist there"));
+ elementPublicStore.delete(context, elementContext, elementToPublish, publishTime);
+ actionOnPublic = Action.DELETE;
+
+ elementPrivateStore
+ .markDeletionAsPublished(context, privateElementContext, privateElementSyncState.getId(),
+ publishTime);
+ }
+
+ updateResult(elementContext, elementToPublish, actionOnPublic,
+ ROOT_ELEMENTS_PARENT_ID.equals(privateElementSyncState.getId()), result);
+ }
+ }
+
+ private void updateResult(ElementContext elementContext, ElementEntity element,
+ Action action, boolean versionDataElement,
+ CollaborationPublishResult result) {
+ if (versionDataElement) {
+ result.getChange().setChangedVersion(convertToVersionChange(elementContext, element, action));
+ } else {
+ result.getChange().getChangedElements()
+ .add(convertToElementChange(elementContext, element, action));
+ }
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java
new file mode 100644
index 0000000000..0d2ea2c0d8
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java
@@ -0,0 +1,161 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class RevertService {
+
+ private ElementPublicStore elementPublicStore;
+ private ElementPrivateStore elementPrivateStore;
+
+ public RevertService(ElementPublicStore elementPublicStore,
+ ElementPrivateStore elementPrivateStore) {
+ this.elementPublicStore = elementPublicStore;
+ this.elementPrivateStore = elementPrivateStore;
+ }
+
+ public void revert(SessionContext context, Id itemId, Id versionId, Id revisionId) {
+ ElementContext targetContext = new ElementContext(itemId, versionId);
+ ElementContext sourceContext = new ElementContext(itemId, versionId, revisionId);
+ copyElementsFromPublic(context, sourceContext, targetContext);
+ }
+
+ private void copyElementsFromPublic(SessionContext context, ElementContext sourceContext,
+ ElementContext targetContext) {
+ Collection<RevertElementAction> revertElementActions =
+ evaluateRevertElementActions(context, sourceContext, targetContext);
+
+ revertElementActions.forEach(revertElementAction -> revertElementAction.run(context));
+ }
+
+ private Collection<RevertElementAction> evaluateRevertElementActions(SessionContext context,
+ ElementContext sourceContext,
+ ElementContext targetContext) {
+
+ Map<Id, Id> sourceElements = elementPublicStore.listIds(context, sourceContext);
+ Map<Id, Id> targetPublicElements = elementPublicStore.listIds(context, targetContext);
+ Collection<SynchronizationStateEntity> synchronizationStateEntities =
+ elementPrivateStore.listSynchronizationStates(context, targetContext);
+
+ Map<Id, Id> targetElements =
+ evaluateTargetElements(targetPublicElements, synchronizationStateEntities);
+
+
+ Collection<RevertElementAction> revertElementActions = new ArrayList<>();
+
+ sourceElements.entrySet().forEach(entry -> {
+ Id sourceElementId = entry.getKey();
+ Id sourceElementRevisionId = entry.getValue();
+
+ if (!targetElements.containsKey(sourceElementId)) {
+ revertElementActions
+ .add(new RevertElementAction(sourceContext, sourceElementId, commands[CREATE]));
+ } else if (!targetElements.get(sourceElementId).equals(sourceElementRevisionId)) {
+ revertElementActions
+ .add(new RevertElementAction(sourceContext, sourceElementId, commands[UPDATE]));
+ }
+ });
+
+ targetElements.entrySet().forEach(entry -> {
+ Id targetElementId = entry.getKey();
+ if (!sourceElements.containsKey(targetElementId)) {
+ revertElementActions
+ .add(new RevertElementAction(targetContext, targetElementId, commands[DELETE]));
+ }
+ });
+
+ return revertElementActions;
+ }
+
+ private Map<Id, Id> evaluateTargetElements(Map<Id, Id> targetPublicElements,
+ Collection<SynchronizationStateEntity> syncStates) {
+ Map<Id, Id> targetElements = new HashMap<>(targetPublicElements);
+ syncStates.stream()
+ .filter(SynchronizationStateEntity::isDirty)
+ .forEach(syncState -> targetElements.put(syncState.getId(), Id.ZERO));
+ return targetElements;
+ }
+
+ private static class RevertElementAction {
+ private ElementContext elementContext;
+ private Id elementId;
+ private ActionCommand command;
+
+ private RevertElementAction(ElementContext elementContext, Id elementId,
+ ActionCommand command) {
+ this.elementContext = elementContext;
+ this.elementId = elementId;
+ this.command = command;
+ }
+
+ public ElementContext getElementContext() {
+ return elementContext;
+ }
+
+ public Id getElementId() {
+ return elementId;
+ }
+
+ public void run(SessionContext context) {
+ command.run(context, elementContext, elementId);
+ }
+ }
+
+ private interface ActionCommand {
+ void run(SessionContext context, ElementContext elementContext, Id elementId);
+ }
+
+ private static int CREATE = 0;
+ private static int UPDATE = 1;
+ private static int DELETE = 2;
+
+ private ActionCommand[] commands = {new ActionCommand() {
+ @Override
+ public void run(SessionContext context, ElementContext elementContext, Id elementId) {
+ //create
+ Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
+ if (!element.isPresent()) {
+ throw getMissingElementException(elementContext, elementId);
+ }
+ elementPrivateStore.create(context, elementContext, element.get());
+ }
+ }, new ActionCommand() {
+ @Override
+ public void run(SessionContext context, ElementContext elementContext, Id elementId) {
+ //update
+ Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
+ if (!element.isPresent()) {
+ throw getMissingElementException(elementContext, elementId);
+ }
+ elementPrivateStore.update(context, elementContext, element.get());
+ }
+ }, new ActionCommand() {
+ @Override
+ public void run(SessionContext context, ElementContext elementContext, Id elementId) {
+ //delete
+ Optional<ElementEntity> element = elementPrivateStore.get(context, elementContext, elementId);
+ if (!element.isPresent()) {
+ return; // deleted by parent when hierarchy was deleted
+ }
+ elementPrivateStore.delete(context, elementContext, element.get());
+ }
+ }};
+
+ private RuntimeException getMissingElementException(ElementContext elementContext,
+ Id elementId) {
+ return new IllegalStateException(
+ String.format("Item Id %s, version Id %s, revision Id %s: Missing element with Id %s",
+ elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue(), elementId.getValue())
+ );
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java
new file mode 100644
index 0000000000..04a7e9ffb1
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java
@@ -0,0 +1,384 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeConflict;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeResult;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+
+public class SyncService {
+ private static final String PULL_NON_EXISTING_VERSION =
+ "Item Id %s, version Id %s: Non existing version cannot be synced.";
+ private static final String PUBLIC_SYNC_STATE_EXISTS_WITHOUT_ELEMENT =
+ "Item Id %s, version Id %s: Sync state of element with Id %s " +
+ "exists in public space while the element does not";
+ private static final String PRIVATE_UNPUBLISHED_SYNC_STATE_EXISTS_WITHOUT_ELEMENT =
+ "Item Id %s, version Id %s: Sync state of unpublished element with Id %s " +
+ "exists in private space while the element does not";
+
+ private VersionPublicStore versionPublicStore;
+ private VersionPrivateStore versionPrivateStore;
+ private VersionStageStore versionStageStore;
+ private ElementPublicStore elementPublicStore;
+ private ElementPrivateStore elementPrivateStore;
+ private ElementStageStore elementStageStore;
+
+ public SyncService(VersionPublicStore versionPublicStore,
+ VersionPrivateStore versionPrivateStore,
+ VersionStageStore versionStageStore,
+ ElementPublicStore elementPublicStore,
+ ElementPrivateStore elementPrivateStore,
+ ElementStageStore elementStageStore) {
+ this.versionPublicStore = versionPublicStore;
+ this.versionPrivateStore = versionPrivateStore;
+ this.versionStageStore = versionStageStore;
+ this.elementPublicStore = elementPublicStore;
+ this.elementPrivateStore = elementPrivateStore;
+ this.elementStageStore = elementStageStore;
+ }
+
+ public CollaborationMergeResult sync(SessionContext context, Id itemId, Id versionId,
+ boolean force) {
+ SynchronizationStateEntity publicVersionSyncState =
+ versionPublicStore.getSynchronizationState(context, itemId, versionId)
+ .orElseThrow(() -> new IllegalStateException(
+ String.format(PULL_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
+
+ Date publishTime = publicVersionSyncState.getPublishTime();
+
+ Optional<SynchronizationStateEntity> privateVersionSyncState =
+ versionPrivateStore.getSynchronizationState(context, itemId, versionId);
+
+ if (force || !privateVersionSyncState.isPresent() ||
+ !publishTime.equals(privateVersionSyncState.get().getPublishTime())) {
+ ElementContext elementContext =
+ new ElementContext(itemId, versionId, publicVersionSyncState.getRevisionId());
+
+ Collection<SynchronizationStateEntity> publicSyncStates =
+ elementPublicStore.listSynchronizationStates(context, elementContext);
+ Collection<SynchronizationStateEntity> privateSyncStates =
+ elementPrivateStore.listSynchronizationStates(context, elementContext);
+ Map<Id, SynchronizationStateEntity> publicSyncStateById = toMapById(publicSyncStates);
+
+ Set<Id> syncedElements = new HashSet<>();
+ if (force) {
+ List<SynchronizationStateEntity> dirtyPrivateSyncStates = privateSyncStates.stream()
+ .filter(SynchronizationStateEntity::isDirty)
+ .collect(Collectors.toList());
+
+ forceSyncDirtyElements(context, elementContext, dirtyPrivateSyncStates, publicSyncStateById,
+ syncedElements);
+ }
+
+ if (!privateVersionSyncState.isPresent() ||
+ !publishTime.equals(privateVersionSyncState.get().getPublishTime())) {
+ syncVersion(context, itemId, versionId, publishTime, privateVersionSyncState.isPresent());
+ syncElements(context, elementContext,
+ privateVersionSyncState.map(SynchronizationStateEntity::getPublishTime).orElse(null),
+ publicSyncStates, privateSyncStates, publicSyncStateById, syncedElements);
+ }
+ }
+
+ return createResult();
+ }
+
+ private CollaborationMergeResult createResult() {
+ CollaborationMergeResult result = new CollaborationMergeResult();
+ result.setChange(new CollaborationMergeChange());
+ result.setConflict(new CollaborationMergeConflict());
+ return result;
+ }
+
+ private void syncVersion(SessionContext context, Id itemId, Id versionId, Date publishTime,
+ boolean versionExistOnPrivate) {
+ if (versionExistOnPrivate) {
+ stageVersion(context, itemId, new VersionEntity(versionId), Action.UPDATE, publishTime);
+ } else {
+ stageVersion(context, itemId, versionPublicStore.get(context, itemId, versionId)
+ .orElseThrow(() -> new IllegalArgumentException(String
+ .format(PULL_NON_EXISTING_VERSION, itemId.toString(), versionId.toString()))),
+ Action.CREATE, publishTime);
+ }
+ }
+
+ private void syncElements(SessionContext context, ElementContext elementContext,
+ Date previousSyncedPublishTime,
+ Collection<SynchronizationStateEntity> publicSyncStates,
+ Collection<SynchronizationStateEntity> privateSyncStates,
+ Map<Id, SynchronizationStateEntity> publicSyncStateById,
+ Set<Id> syncedElements) {
+ Map<Id, SynchronizationStateEntity> privateSyncStateById = toMapById(privateSyncStates);
+
+ Collection<SynchronizationStateEntity> updatedPublicSyncStates =
+ previousSyncedPublishTime == null
+ ? publicSyncStates
+ : publicSyncStates.stream()
+ .filter(syncState -> syncState.getPublishTime().after(previousSyncedPublishTime))
+ .collect(Collectors.toList());
+
+ syncPublicUpdatedElements(context, elementContext, updatedPublicSyncStates,
+ publicSyncStateById, privateSyncStateById, syncedElements);
+
+ List<SynchronizationStateEntity> onlyOnPrivatePublishedSyncStates =
+ privateSyncStates.stream()
+ .filter(syncState -> !publicSyncStateById.containsKey(syncState.getId()) &&
+ syncState.getPublishTime() != null)
+ .collect(Collectors.toList());
+
+ syncPublicDeletedElements(context, elementContext, onlyOnPrivatePublishedSyncStates,
+ publicSyncStateById, privateSyncStateById, syncedElements);
+ }
+
+ private void syncPublicUpdatedElements(SessionContext context, ElementContext elementContext,
+ Collection<SynchronizationStateEntity> updatedPublicSyncStates,
+ Map<Id, SynchronizationStateEntity> publicSyncStateById,
+ Map<Id, SynchronizationStateEntity> privateSyncStateById,
+ Set<Id> syncedElements) {
+ for (SynchronizationStateEntity publicSyncState : updatedPublicSyncStates) {
+ if (syncedElements.contains(publicSyncState.getId())) {
+ continue;
+ }
+
+ ElementEntity publicElement =
+ elementPublicStore.get(context, elementContext, publicSyncState.getId()).orElseThrow(
+ () -> new IllegalStateException(String
+ .format(PUBLIC_SYNC_STATE_EXISTS_WITHOUT_ELEMENT,
+ elementContext.getItemId().getValue(),
+ elementContext.getVersionId().getValue(),
+ publicSyncState.getId().getValue())));
+
+ SynchronizationStateEntity privateSyncState =
+ privateSyncStateById.get(publicSyncState.getId());
+
+ if (privateSyncState != null) {
+ if (!privateSyncState.isDirty()) {
+ // not changed on private
+ stageElement(context, elementContext, publicElement,
+ publicSyncState.getPublishTime(),
+ Action.UPDATE, false, null);
+ syncedElements.add(publicSyncState.getId());
+ } else {
+ Optional<ElementEntity> privateElement =
+ elementPrivateStore.get(context, elementContext, publicSyncState.getId());
+
+ if (privateElement.isPresent()) {
+ // updated on private - conflict if it has different hash
+ stageElement(context, elementContext, publicElement,
+ publicSyncState.getPublishTime(), Action.UPDATE,
+ !publicElement.getElementHash().equals(privateElement.get().getElementHash()),
+ null);
+
+ syncedElements.add(publicSyncState.getId());
+ } else {
+ // deleted on private - conflict tree
+ Set<Id> changeTreeElementIds =
+ stagePublicElementTree(context, elementContext, publicElement, publicSyncStateById,
+ (treeElementIds) -> true);
+ syncedElements.addAll(changeTreeElementIds);
+ }
+ }
+ } else {
+ // not existing on private - new creation on public
+ Set<Id> changeTreeElementIds =
+ stagePublicElementTree(context, elementContext, publicElement, publicSyncStateById,
+ (treeElementIds) -> containsDirty(treeElementIds, privateSyncStateById));
+ syncedElements.addAll(changeTreeElementIds);
+ }
+ }
+ }
+
+ private void syncPublicDeletedElements(
+ SessionContext context, ElementContext elementContext,
+ Collection<SynchronizationStateEntity> onlyOnPrivatePublishedSyncStates,
+ Map<Id, SynchronizationStateEntity> publicSyncStateById,
+ Map<Id, SynchronizationStateEntity> privateSyncStateById,
+ Set<Id> syncedElements) {
+ for (SynchronizationStateEntity privateSyncState : onlyOnPrivatePublishedSyncStates) {
+ if (syncedElements.contains(privateSyncState.getId())) {
+ continue;
+ }
+
+ Optional<ElementEntity> privateElement =
+ elementPrivateStore.get(context, elementContext, privateSyncState.getId());
+
+ if (!privateElement.isPresent()) {
+ // deleted on private as well
+ stageElement(context, elementContext, new ElementEntity(privateSyncState.getId()),
+ null, Action.DELETE, false, null);
+ syncedElements.add(privateSyncState.getId());
+ } else {
+ Set<Id> changeTreeElementIds =
+ stageElementTree(context, elementContext, privateElement.get(),
+ elementPrivateStore, publicSyncStateById::containsKey,
+ (treeElementIds) -> containsDirty(treeElementIds, privateSyncStateById),
+ (elementId) -> null, Action.DELETE);
+ syncedElements.addAll(changeTreeElementIds);
+ }
+ }
+ }
+
+ private void forceSyncDirtyElements(SessionContext context, ElementContext elementContext,
+ List<SynchronizationStateEntity> dirtyPrivateSyncStates,
+ Map<Id, SynchronizationStateEntity> publicSyncStateById,
+ Set<Id> syncedElements) {
+ for (SynchronizationStateEntity privateSyncState : dirtyPrivateSyncStates) {
+ Optional<ElementEntity> privateElement =
+ elementPrivateStore.get(context, elementContext, privateSyncState.getId());
+ if (privateSyncState.getPublishTime() == null) {
+ stageElement(context, elementContext,
+ privateElement.orElseThrow(() -> new IllegalStateException(
+ String.format(PRIVATE_UNPUBLISHED_SYNC_STATE_EXISTS_WITHOUT_ELEMENT,
+ elementContext.getItemId().getValue(),
+ elementContext.getVersionId().getValue(),
+ privateSyncState.getId().getValue()))),
+ null, Action.DELETE, false, null);
+ } else {
+ SynchronizationStateEntity publicSyncState =
+ publicSyncStateById.get(privateSyncState.getId());
+ if (publicSyncState != null) {
+ ElementEntity publicElement =
+ elementPublicStore.get(context, elementContext, privateSyncState.getId()).orElseThrow(
+ () -> new IllegalStateException(String
+ .format(PUBLIC_SYNC_STATE_EXISTS_WITHOUT_ELEMENT,
+ elementContext.getItemId().getValue(),
+ elementContext.getVersionId().getValue(),
+ privateSyncState.getId().getValue())));
+
+ stageElement(context, elementContext, publicElement, publicSyncState.getPublishTime(),
+ privateElement.isPresent() ? Action.UPDATE : Action.CREATE, false, null);
+ } else {
+ stageElement(context, elementContext, privateElement.isPresent()
+ ? privateElement.get()
+ : new ElementEntity(privateSyncState.getId()),
+ null, Action.DELETE, false, null);
+ }
+ }
+ syncedElements.add(privateSyncState.getId());
+ }
+ }
+
+ private Set<Id> stagePublicElementTree(SessionContext context,
+ ElementContext elementContext,
+ ElementEntity publicElement,
+ Map<Id, SynchronizationStateEntity> publicSyncStateById,
+ Predicate<Set<Id>> isElementTreeConflicted) {
+
+
+ return stageElementTree(context, elementContext, publicElement,
+ elementPublicStore,
+ (elementId) -> elementPrivateStore.getDescriptor(context, elementContext, elementId)
+ .isPresent(),
+ isElementTreeConflicted,
+ (elementId) -> publicSyncStateById.get(elementId).getPublishTime(),
+ Action.CREATE);
+ }
+
+ private Set<Id> stageElementTree(SessionContext context, ElementContext elementContext,
+ ElementEntity element,
+ ElementStore elementStore,
+ Predicate<Id> isElementExist,
+ Predicate<Set<Id>> isElementTreeConflicted,
+ Function<Id, Date> stagePublishTimeGetter,
+ Action stageAction) {
+ ElementEntity elementTreeRoot = findRootElementOfChange(context, elementContext,
+ elementStore, isElementExist, element);
+
+ Set<Id> elementTreeIds = new HashSet<>();
+ elementTreeIds.add(elementTreeRoot.getId());
+
+ Set<Id> subElementIds = stageElementSubs(context, elementContext, elementStore, elementTreeRoot,
+ stagePublishTimeGetter, stageAction);
+ elementTreeIds.addAll(subElementIds);
+
+ boolean conflicted = isElementTreeConflicted.test(elementTreeIds);
+ stageElement(context, elementContext, elementTreeRoot,
+ stagePublishTimeGetter.apply(elementTreeRoot.getId()), stageAction, conflicted,
+ conflicted ? subElementIds : null);
+ return elementTreeIds;
+ }
+
+ private ElementEntity findRootElementOfChange(SessionContext context,
+ ElementContext elementContext,
+ ElementStore elementStore,
+ Predicate<Id> isElementExistOnOppositeStore,
+ ElementEntity element) {
+ return element.getId().equals(ROOT_ELEMENTS_PARENT_ID) ||
+ isElementExistOnOppositeStore.test(element.getParentId())
+ ? element
+ : findRootElementOfChange(context, elementContext, elementStore,
+ isElementExistOnOppositeStore,
+ elementStore.get(context, elementContext, element.getParentId())
+ .orElseThrow(() -> new IllegalStateException(
+ String.format("Element %s exists while its parent element %s does not",
+ element.getId(), element.getParentId()))));
+ }
+
+ private boolean containsDirty(Set<Id> elementIds,
+ Map<Id, SynchronizationStateEntity> syncStateById) {
+ return elementIds.stream().anyMatch(elementId -> {
+ SynchronizationStateEntity privateSyncState = syncStateById.get(elementId);
+ return privateSyncState != null && privateSyncState.isDirty();
+ });
+ }
+
+ private Set<Id> stageElementSubs(SessionContext context, ElementContext elementContext,
+ ElementStore elementStore, ElementEntity parentElement,
+ Function<Id, Date> stagePublishTimeGetter, Action stageAction) {
+ Set<Id> elementTreeIds = new HashSet<>();
+ for (Id elementId : parentElement.getSubElementIds()) {
+ ElementEntity element = elementStore.get(context, elementContext, elementId).get();
+
+ stageElement(context, elementContext, element, stagePublishTimeGetter.apply(elementId),
+ stageAction, false, null);
+
+ elementTreeIds.add(elementId);
+ elementTreeIds.addAll(
+ stageElementSubs(context, elementContext, elementStore, element, stagePublishTimeGetter,
+ stageAction));
+ }
+ return elementTreeIds;
+ }
+
+ private void stageElement(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime, Action action,
+ boolean conflicted, Set<Id> conflictDependents) {
+ StageEntity<ElementEntity> elementStage =
+ new StageEntity<>(element, publishTime, action, conflicted);
+ if (conflictDependents != null) {
+ elementStage.setConflictDependents(
+ conflictDependents.stream().map(ElementEntity::new).collect(Collectors.toSet()));
+ }
+ elementStageStore.create(context, elementContext, elementStage);
+ }
+
+ private void stageVersion(SessionContext context, Id itemId, VersionEntity stageVersion,
+ Action stageAction, Date publishTime) {
+ versionStageStore
+ .create(context, itemId, new StageEntity<>(stageVersion, publishTime, stageAction, false));
+ }
+
+ private Map<Id, SynchronizationStateEntity> toMapById(
+ Collection<SynchronizationStateEntity> syncStates) {
+ return syncStates.stream()
+ .collect(Collectors.toMap(SynchronizationStateEntity::getId, Function.identity()));
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java
deleted file mode 100644
index db3066c313..0000000000
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.openecomp.core.zusammen.plugin.collaboration;
-
-import com.amdocs.zusammen.datatypes.Id;
-import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.Space;
-import com.amdocs.zusammen.datatypes.item.Action;
-import com.amdocs.zusammen.datatypes.itemversion.Tag;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
-import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementChange;
-import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
-import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
-import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
-
-public class VersionCollaborationStore {
-
- public void tagItemVersion(SessionContext context, Id itemId, Id versionId, Id changeId,
- Tag tag) {
- if (changeId != null) {
- throw new UnsupportedOperationException(
- "In this plugin implementation tag is supported only on versionId");
- }
- String space = getSpaceName(context, Space.PRIVATE);
- ElementEntityContext targetContext = new ElementEntityContext(space, itemId, versionId);
- targetContext.setChangeRef(tag.getName());
- copyElements(context, new ElementEntityContext(space, itemId, versionId), targetContext,
- getElementRepository(context));
- }
-
- public CollaborationMergeChange resetItemVersionHistory(SessionContext context, Id itemId,
- Id versionId, String changeRef) {
- ElementRepository elementRepository = getElementRepository(context);
-
- String spaceName = getSpaceName(context, Space.PRIVATE);
- ElementEntityContext versionContext = new ElementEntityContext(spaceName, itemId, versionId);
-
- Collection<ElementEntity> deletedElements =
- deleteElements(context, versionContext, elementRepository);
-
- ElementEntityContext changeRefContext = new ElementEntityContext(spaceName, itemId, versionId);
- changeRefContext.setChangeRef(changeRef);
-
- Collection<ElementEntity> createdElements =
- copyElements(context, changeRefContext, versionContext, elementRepository);
-
- // TODO: 4/19/2017 version change...
- return createCollaborationMergeChange(versionContext, deletedElements, createdElements);
- }
-
- private Collection<ElementEntity> deleteElements(SessionContext context,
- ElementEntityContext elementContext,
- ElementRepository elementRepository) {
- Collection<ElementEntity> elements = elementRepository.list(context, elementContext);
- elements.forEach(element -> elementRepository
- .delete(context, elementContext, new ElementEntity(element.getId())));
- elementRepository.delete(context, elementContext, new ElementEntity(ROOT_ELEMENTS_PARENT_ID));
- return elements;
- }
-
- private Collection<ElementEntity> copyElements(SessionContext context,
- ElementEntityContext sourceElementContext,
- ElementEntityContext targetElementContext,
- ElementRepository elementRepository) {
- Collection<ElementEntity> elements = elementRepository.list(context, sourceElementContext);
- elements.forEach(elementEntity ->
- elementRepository.create(context, targetElementContext, elementEntity));
- return elements;
- }
-
- private CollaborationMergeChange createCollaborationMergeChange(
- ElementEntityContext versionContext,
- Collection<ElementEntity> deletedElements,
- Collection<ElementEntity> createdElements) {
- CollaborationMergeChange mergeChange = new CollaborationMergeChange();
- mergeChange.getChangedElements().addAll(
- convertToCollaborationElementChanges(versionContext, deletedElements, Action.DELETE));
- mergeChange.getChangedElements().addAll(
- convertToCollaborationElementChanges(versionContext, createdElements, Action.CREATE));
- return mergeChange;
- }
-
- private List<CollaborationElementChange> convertToCollaborationElementChanges(
- ElementEntityContext elementContext, Collection<ElementEntity> changedElements,
- Action action) {
- return changedElements.stream()
- .map(element -> convertToCollaborationElementChange(element, elementContext, action))
- .collect(Collectors.toList());
- }
-
- private CollaborationElementChange convertToCollaborationElementChange(
- ElementEntity elementEntity, ElementEntityContext elementContext, Action action) {
- CollaborationElementChange elementChange = new CollaborationElementChange();
- elementChange
- .setElement(ZusammenPluginUtil.getCollaborationElement(elementContext, elementEntity));
- elementChange.setAction(action);
- return elementChange;
- }
-
- protected ElementRepository getElementRepository(SessionContext context) {
- return ElementRepositoryFactory.getInstance().createInterface(context);
- }
-}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java
new file mode 100644
index 0000000000..a024327548
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java
@@ -0,0 +1,38 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Optional;
+
+public interface VersionPrivateStore {
+ Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId);
+
+ Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context, Id itemId,
+ Id versionId);
+
+ void create(SessionContext context, Id itemId, VersionEntity version);
+
+ void update(SessionContext context, Id itemId, VersionEntity version);
+
+ void update(SessionContext context, Id itemId, VersionEntity version, Date publishTime,
+ boolean dirty);
+
+ void delete(SessionContext context, Id itemId, VersionEntity version);
+
+ void markAsPublished(SessionContext context, Id itemId, Id versionId, Date publishTime);
+
+ void commitStagedCreate(SessionContext context, Id itemId, VersionEntity version,
+ Date publishTime);
+
+ void commitStagedUpdate(SessionContext context, Id itemId, VersionEntity version,
+ Date publishTime);
+
+ void commitStagedIgnore(SessionContext context, Id itemId, VersionEntity version,
+ Date publishTime);
+
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java
new file mode 100644
index 0000000000..c86db0ec43
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java
@@ -0,0 +1,29 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+public interface VersionPublicStore {
+
+ Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId);
+
+ Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+ Id itemId, Id versionId);
+
+ void create(SessionContext context, Id itemId, VersionEntity version, Id revisionId,
+ Map<Id, Id> versionElementIds, Date publishTime, String message);
+
+ void update(SessionContext context, Id itemId, VersionEntity version, Id revisionId,
+ Map<Id, Id> versionElementIds, Date publishTime, String message);
+
+ boolean checkHealth(SessionContext context);
+
+ ItemVersionRevisions listItemVersionRevisions(SessionContext context, Id itemId, Id versionId);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java
new file mode 100644
index 0000000000..5058a262cc
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java
@@ -0,0 +1,18 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Optional;
+
+public interface VersionStageStore {
+
+ Optional<StageEntity<VersionEntity>> get(SessionContext context, Id itemId,
+ VersionEntity versionEntity);
+
+ void create(SessionContext context, Id itemId, StageEntity<VersionEntity> versionStage);
+
+ void delete(SessionContext context, Id itemId, VersionEntity version);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java
new file mode 100644
index 0000000000..9f54ee3ae2
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java
@@ -0,0 +1,269 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPrivateStore;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateElementContext;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class ElementPrivateStoreImpl implements ElementPrivateStore {
+ private static final Id REVISION_ID = Id.ZERO; // the private revision id is Id.ZERO 0000000...
+
+ @Override
+ public Map<Id, Id> listIds(SessionContext context, ElementContext elementContext) {
+ return getElementRepository(context)
+ .listIds(context, new ElementEntityContext(getPrivateSpaceName(context), elementContext));
+ }
+
+ @Override
+ public Collection<ElementEntity> listSubs(SessionContext context, ElementContext elementContext,
+ Id elementId) {
+ if (elementId == null) {
+ elementId = ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+ }
+
+ ElementRepository elementRepository = getElementRepository(context);
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+ return elementRepository.get(context, privateContext, new ElementEntity(elementId))
+ .map(ElementEntity::getSubElementIds).orElse(new HashSet<>()).stream()
+ .map(subElementId -> elementRepository
+ .get(context, privateContext, new ElementEntity(subElementId)).get())
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public Optional<ElementEntity> get(SessionContext context, ElementContext elementContext,
+ Id elementId) {
+ ElementEntityContext privateElementContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateElementContext.setRevisionId(REVISION_ID);
+ return getElementRepository(context)
+ .get(context, privateElementContext,
+ new ElementEntity(elementId));
+ }
+
+ @Override
+ public Optional<ElementEntity> getDescriptor(SessionContext context,
+ ElementContext elementContext, Id elementId) {
+ return getElementRepository(context)
+ .getDescriptor(context,
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+ (elementContext)),
+ new ElementEntity(elementId));
+ }
+
+ @Override
+ public Collection<SynchronizationStateEntity> listSynchronizationStates(SessionContext context,
+ ElementContext elementContext) {
+ ElementEntityContext privateElementContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ return getElementSyncStateRepository(context)
+ .list(context, privateElementContext);
+ }
+
+ @Override
+ public Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+ ElementContext elementContext,
+ Id elementId) {
+
+ ElementEntityContext privateElementContext =
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+ (elementContext));
+ return getElementSyncStateRepository(context)
+ .get(context, privateElementContext,
+ new SynchronizationStateEntity(elementId, REVISION_ID));
+ }
+
+ @Override
+ public void create(SessionContext context, ElementContext elementContext, ElementEntity element) {
+ create(context, elementContext, element, true, null);
+ }
+
+ @Override
+ public boolean update(SessionContext context, ElementContext elementContext,
+ ElementEntity element) {
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+
+ if (!isElementChanged(context, privateContext, element)) {
+ return false;
+ }
+
+ getElementRepository(context).update(context, privateContext, element);
+ getElementSyncStateRepository(context).markAsDirty(context, privateContext,
+ new SynchronizationStateEntity(element.getId(), REVISION_ID));
+ return true;
+ }
+
+ @Override
+ public void delete(SessionContext context, ElementContext elementContext, ElementEntity element) {
+
+ ElementEntityContext privateElementContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateElementContext.setRevisionId(REVISION_ID);
+ deleteElementHierarchy(context, getElementRepository(context),
+ getElementSyncStateRepository(context),
+ privateElementContext, element);
+ }
+
+ @Override
+ public void markAsPublished(SessionContext context, ElementContext elementContext, Id elementId,
+ Date publishTime) {
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+ getElementSyncStateRepository(context).update(context,
+ privateContext,
+ new SynchronizationStateEntity(elementId, REVISION_ID, publishTime, false));
+ }
+
+ @Override
+ public void markDeletionAsPublished(SessionContext context, ElementContext elementContext,
+ Id elementId, Date publishTime) {
+
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+ getElementSyncStateRepository(context).delete(context,
+ privateContext,
+ new SynchronizationStateEntity(elementId, REVISION_ID));
+ }
+
+ @Override
+ public void commitStagedCreate(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime) {
+ create(context, elementContext, element, false, publishTime);
+ }
+
+ @Override
+ public void commitStagedUpdate(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime) {
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+
+ getElementRepository(context).update(context, privateContext, element);
+ // Currently Resolution='Other' is not supported so this is invoked after conflict was
+ // resolved with Resolution='Theirs' so dirty flag should be turned off.
+ // (if there was no conflict it's off anyway)
+ getElementSyncStateRepository(context).update(context, privateContext,
+ new SynchronizationStateEntity(element.getId(), REVISION_ID, publishTime, false));
+ }
+
+ @Override
+ public void commitStagedDelete(SessionContext context, ElementContext elementContext,
+ ElementEntity element) {
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+ getElementRepository(context).delete(context, privateContext, element);
+ getElementSyncStateRepository(context)
+ .delete(context, privateContext,
+ new SynchronizationStateEntity(element.getId(), REVISION_ID));
+ }
+
+ @Override
+ public void commitStagedIgnore(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime) {
+ // publish time - updated to mark that this element was already synced with this publish time
+ // (even though the local data was preferred) and to prevent this conflict again.
+ // dirty - turned on because the local data which is different than the public one was
+ // preferred. It will enable future publication of this data.
+ getElementSyncStateRepository(context).update(context,
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext),
+ new SynchronizationStateEntity(element.getId(), REVISION_ID, publishTime, true));
+ }
+
+ private void create(SessionContext context, ElementContext elementContext,
+ ElementEntity element, boolean dirty, Date publishTime) {
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+ privateContext.setRevisionId(REVISION_ID);
+ getElementRepository(context).create(context, privateContext, element);
+ getElementSyncStateRepository(context).create(context, privateContext,
+ new SynchronizationStateEntity(element.getId(), REVISION_ID, publishTime, dirty));
+ }
+
+
+ private void deleteElementHierarchy(
+ SessionContext context, ElementRepository elementRepository,
+ ElementSynchronizationStateRepository elementSyncStateRepository,
+ ElementEntityContext elementContext, ElementEntity element) {
+
+ Optional<ElementEntity> retrieved = elementRepository.get(context, elementContext, element);
+ if (!retrieved.isPresent()) {
+ return;
+ }
+ retrieved.get().getSubElementIds().stream()
+ .map(ElementEntity::new)
+ .forEach(subElementEntity -> deleteElementHierarchy(
+ context, elementRepository, elementSyncStateRepository, elementContext,
+ subElementEntity));
+
+ // only for the first one the parentId will populated (so it'll be removed from its parent)
+ elementRepository.delete(context, elementContext, element);
+ handleDeletedElementSyncState(context, elementSyncStateRepository, elementContext, element);
+ }
+
+ private void handleDeletedElementSyncState(SessionContext context,
+ ElementSynchronizationStateRepository elementSyncStateRepository,
+ ElementEntityContext elementContext,
+ ElementEntity element) {
+ SynchronizationStateEntity elementSyncState = new SynchronizationStateEntity(element.getId(),
+ REVISION_ID);
+ if (elementSyncStateRepository.get(context, elementContext, elementSyncState).
+ orElseThrow(
+ () -> new IllegalStateException("Synchronization state must exist for an element"))
+ .getPublishTime() == null) {
+ elementSyncStateRepository.delete(context, elementContext, elementSyncState);
+ } else {
+ elementSyncStateRepository.markAsDirty(context, elementContext, elementSyncState);
+ }
+ }
+
+ private boolean isElementChanged(SessionContext context,
+ ElementEntityContext elementContext,
+ ElementEntity newElement) {
+ return getElementHash(context, elementContext, new ElementEntity(newElement.getId()))
+ .map(existingHash -> !newElement.getElementHash().equals(existingHash))
+ .orElse(true);
+ }
+
+ private Optional<Id> getElementHash(SessionContext context,
+ ElementEntityContext elementEntityContext,
+ ElementEntity element) {
+ return getElementRepository(context).getHash(context, elementEntityContext, element);
+ }
+
+ protected ElementRepository getElementRepository(SessionContext context) {
+ return ElementRepositoryFactory.getInstance().createInterface(context);
+ }
+
+ protected ElementSynchronizationStateRepository getElementSyncStateRepository(
+ SessionContext context) {
+ return ElementSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+ }
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java
new file mode 100644
index 0000000000..d946a529ce
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java
@@ -0,0 +1,189 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPublicStore;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
+
+public class ElementPublicStoreImpl implements ElementPublicStore {
+
+ @Override
+ public Optional<ElementEntity> get(SessionContext context,
+ ElementContext elementContext, Id elementId) {
+ return getElementRepository(context)
+ .get(context, new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext),
+ new ElementEntity(elementId));
+ }
+
+ @Override
+ public Optional<ElementEntity> getDescriptor(SessionContext context,
+ ElementContext elementContext, Id elementId) {
+ return getElementRepository(context).getDescriptor(context,
+ new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext),
+ new ElementEntity(elementId));
+ }
+
+ @Override
+ public Collection<SynchronizationStateEntity> listSynchronizationStates(
+ SessionContext context, ElementContext elementContext) {
+ ElementEntityContext entityContext = new ElementEntityContext(getSpaceName
+ (context, Space.PUBLIC), elementContext);
+
+ ElementSynchronizationStateRepository elementSyncStateRepository =
+ getElementSyncStateRepository(context);
+ Map<Id, Id> ids = getElementRepository(context).listIds(context, entityContext);
+
+ Collection<SynchronizationStateEntity> synchronizationStateEntities = new HashSet<>();
+ for (Map.Entry<Id, Id> elementEntry : ids.entrySet()) {
+ Optional<SynchronizationStateEntity> synchronizationStateEntity = elementSyncStateRepository.
+ get(context, entityContext, new SynchronizationStateEntity(elementEntry.getKey(),
+ elementEntry.getValue()));
+ if (synchronizationStateEntity.isPresent()) {
+ synchronizationStateEntities.add(synchronizationStateEntity.get());
+ } else {
+ /*throw new IllegalStateException(String.format(
+ "list Synchronization States error: " + "element %s revision %s, which appears as an " +
+ "element of " +
+ "item" +
+ " %s version %s, does not exist",
+ elementEntry.getKey(), elementEntry.getValue(), elementContext.getItemId().getValue(),
+ elementContext.getVersionId().getValue()));*/
+ }
+ }
+
+ return synchronizationStateEntities;
+ }
+
+ @Override
+ public void create(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime) {
+ ElementEntityContext publicContext =
+ new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+
+ if (element.getParentId() != null) {
+ createParentElement(context, elementContext, element.getParentId(), publishTime);
+ }
+ getElementRepository(context).create(context, publicContext, element);
+ getElementSyncStateRepository(context).create(context, publicContext,
+ new SynchronizationStateEntity(element.getId(), elementContext.getRevisionId(),
+ publishTime, false));
+ }
+
+ @Override
+ public void update(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime) {
+ //todo - update in public should be create new entry with new revision_id in public - this is a
+ // new revision
+ ElementEntityContext publicContext =
+ new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+ Optional<ElementEntity> publicElement = getElementRepository(context).get(context,
+ publicContext, new ElementEntity(element.getId()));
+ if (publicElement.isPresent()) {
+ getElementRepository(context).update(context, publicContext, element);
+ } else {
+ publicElement = get(context,new ElementContext(publicContext.getItemId(),publicContext
+ .getVersionId()),element.getId());
+ element.setSubElementIds(publicElement.get().getSubElementIds());
+ getElementRepository(context).create(context, publicContext, element);
+ }
+ getElementSyncStateRepository(context).update(context, publicContext,
+ new SynchronizationStateEntity(element.getId(), elementContext.getRevisionId(), publishTime,
+ false));
+ }
+
+ @Override
+ public void delete(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Date publishTime) {
+ ElementEntityContext publicContext =
+ new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+ if (element.getParentId() != null) {
+ Optional<ElementEntity> parentElement = get(context, elementContext, element.getParentId());
+ if (parentElement.isPresent()) {
+ createParentElement(context, elementContext, element.getParentId(), publishTime);
+ }
+ }
+
+ getElementRepository(context).delete(context, publicContext, element);
+ getElementSyncStateRepository(context)
+ .delete(context, publicContext, new SynchronizationStateEntity(element.getId(),
+ elementContext.getRevisionId()));
+ }
+
+ @Override
+ public Map<Id, Id> listIds(SessionContext context, ElementContext elementContext) {
+
+ return getElementRepository(context)
+ .listIds(context,
+ new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext));
+
+ }
+
+ private void createParentElement(SessionContext context, ElementContext elementContext,
+ Id parentElementId, Date publishTime
+ ) {
+ ElementEntityContext publicContext =
+ new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+ Optional<ElementEntity> parentElement =
+ getElementRepository(context).get(context, new ElementEntityContext
+ (publicContext.getSpace(), publicContext.getItemId(), publicContext.getVersionId(),
+ elementContext.getRevisionId()),
+ new ElementEntity(parentElementId));
+ if(parentElement.isPresent()) {
+ update(context, elementContext, parentElement.get(), publishTime);
+ }
+
+
+ /* Id elementRevisionId = getElementRevision(context, publicContext, elementContext.getRevisionId()
+ , parentElementId);
+
+ if (elementRevisionId != null && !elementRevisionId.equals(elementContext.getRevisionId())) {
+ Optional<ElementEntity> parentElement =
+ getElementRepository(context).get(context, new ElementEntityContext
+ (publicContext.getSpace(), publicContext.getItemId(), publicContext.getVersionId(),
+ elementContext.getRevisionId()),
+ new ElementEntity(parentElementId));
+ elementRevisionId = getElementRevision(context, publicContext, elementContext.getRevisionId()
+ , parentElement.get().getId());
+ if (elementRevisionId != null) {
+ update(context, elementContext, parentElement.get(), publishTime);
+ } else {
+ create(context, elementContext, parentElement.get(), publishTime);
+ }
+
+ }*/
+ }
+
+
+
+
+ protected ElementRepository getElementRepository(SessionContext context) {
+ return ElementRepositoryFactory.getInstance().createInterface(context);
+ }
+
+ protected ElementSynchronizationStateRepository getElementSyncStateRepository(
+ SessionContext context) {
+ return ElementSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+ }
+
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java
new file mode 100644
index 0000000000..f6c29432df
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java
@@ -0,0 +1,133 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementStageStore;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateElementContext;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class ElementStageStoreImpl implements ElementStageStore {
+
+ @Override
+ public Collection<ElementEntity> listIds(SessionContext context, ElementContext elementContext) {
+ return getElementStageRepository(context)
+ .listIds(context, new ElementEntityContext(getPrivateSpaceName(context),
+ getPrivateElementContext(elementContext)));
+ }
+
+ @Override
+ public Optional<StageEntity<ElementEntity>> get(SessionContext context,
+ ElementContext elementContext,
+ ElementEntity element) {
+ return getElementStageRepository(context).get(context,
+ new ElementEntityContext(getPrivateSpaceName(context),
+ getPrivateElementContext(elementContext)),
+ element);
+ }
+
+ @Override
+ public Optional<StageEntity<ElementEntity>> getConflicted(SessionContext context,
+ ElementContext elementContext,
+ ElementEntity element) {
+ return get(context, elementContext, element).filter(StageEntity::isConflicted);
+ }
+
+ @Override
+ public boolean hasConflicts(SessionContext context, ElementContext elementContext) {
+ return !getElementStageRepository(context).listConflictedIds(context,
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext(elementContext))).isEmpty();
+ }
+
+ @Override
+ public Collection<StageEntity<ElementEntity>> listConflictedDescriptors(SessionContext context,
+ ElementContext elementContext) {
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+ (elementContext));
+ ElementStageRepository elementStageRepository = getElementStageRepository(context);
+
+ return elementStageRepository.listConflictedIds(context, privateContext).stream()
+ .map(conflictedElement -> elementStageRepository
+ .getDescriptor(context, privateContext, conflictedElement).get())
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public void create(SessionContext context, ElementContext elementContext,
+ StageEntity<ElementEntity> elementStage) {
+ getElementStageRepository(context)
+ .create(context,
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext(elementContext)),
+ elementStage);
+ }
+
+ @Override
+ public void delete(SessionContext context, ElementContext elementContext, ElementEntity element) {
+ getElementStageRepository(context)
+ .delete(context,
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext(elementContext)),
+ element);
+ }
+
+
+ @Override
+ public void resolveConflict(SessionContext context, ElementContext elementContext,
+ ElementEntity element, Resolution resolution) {
+ Optional<StageEntity<ElementEntity>> stagedElement =
+ getConflicted(context, elementContext, element);
+ if (!stagedElement.isPresent()) {
+ return;
+ }
+
+ ElementEntityContext privateContext =
+ new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+ (elementContext));
+
+ switch (resolution) {
+ case YOURS:
+ resolveConflictByYours(context, privateContext, stagedElement.get());
+ break;
+ case THEIRS:
+ resolveConflictByTheirs(context, privateContext, stagedElement.get());
+ break;
+ case OTHER: // other = data updates only? no data deletions? if so, then:
+ // conflicted = false
+ // element = the input of resolve
+ // action = update
+ throw new UnsupportedOperationException("'Other' conflict resolution is not yet supported");
+ default:
+ break;
+ }
+ }
+
+ private void resolveConflictByYours(SessionContext context, ElementEntityContext privateContext,
+ StageEntity<ElementEntity> stagedElement) {
+ getElementStageRepository(context)
+ .markAsNotConflicted(context, privateContext, stagedElement.getEntity(), Action.IGNORE);
+ stagedElement.getConflictDependents().forEach(conflictDependant ->
+ getElementStageRepository(context)
+ .markAsNotConflicted(context, privateContext, conflictDependant, Action.IGNORE));
+ }
+
+ private void resolveConflictByTheirs(SessionContext context, ElementEntityContext privateContext,
+ StageEntity<ElementEntity> stagedElement) {
+ getElementStageRepository(context)
+ .markAsNotConflicted(context, privateContext, stagedElement.getEntity());
+ }
+
+ protected ElementStageRepository getElementStageRepository(SessionContext context) {
+ return ElementStageRepositoryFactory.getInstance().createInterface(context);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java
new file mode 100644
index 0000000000..11e61ab5a9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java
@@ -0,0 +1,117 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPrivateStore;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class VersionPrivateStoreImpl implements VersionPrivateStore {
+
+ Id revisionId = Id.ZERO;
+
+ @Override
+ public Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId) {
+ return getVersionDao(context).get(context, getPrivateSpaceName(context), itemId, versionId);
+ }
+
+ @Override
+ public Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+ Id itemId, Id versionId) {
+
+ return getVersionSyncStateRepository(context)
+ .get(context, new VersionContext(getPrivateSpaceName(context), itemId),
+ new SynchronizationStateEntity(versionId, revisionId));
+ }
+
+ @Override
+ public void create(SessionContext context, Id itemId, VersionEntity version) {
+ String privateSpace = getPrivateSpaceName(context);
+
+
+ getVersionDao(context).create(context, privateSpace, itemId, version);
+ getVersionSyncStateRepository(context).create(context, new VersionContext(privateSpace,
+ itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId, null, true));
+ }
+
+ @Override
+ public void update(SessionContext context, Id itemId, VersionEntity version) {
+
+ getVersionDao(context)
+ .updateModificationTime(context, getPrivateSpaceName(context), itemId, version.getId(),
+ version.getModificationTime());
+ }
+
+ @Override
+ public void update(SessionContext context, Id itemId, VersionEntity version, Date publishTime,
+ boolean dirty) {
+ getVersionSyncStateRepository(context).updatePublishTime(context,
+ new VersionContext(getPrivateSpaceName(context), itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId, publishTime, dirty));
+ }
+
+ @Override
+ public void delete(SessionContext context, Id itemId, VersionEntity version) {
+ String privateSpace = getPrivateSpaceName(context);
+
+ getVersionDao(context).delete(context, privateSpace, itemId, version.getId());
+ getVersionSyncStateRepository(context).delete(context, new VersionContext(privateSpace,
+ itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId));
+ }
+
+ @Override
+ public void markAsPublished(SessionContext context, Id itemId, Id versionId, Date publishTime) {
+ getVersionSyncStateRepository(context)
+ .updatePublishTime(context, new VersionContext(getPrivateSpaceName(context), itemId),
+ new SynchronizationStateEntity(versionId, revisionId, publishTime, false));
+ }
+
+ @Override
+ public void commitStagedCreate(SessionContext context, Id itemId, VersionEntity version,
+ Date publishTime) {
+ String privateSpace = getPrivateSpaceName(context);
+
+ getVersionDao(context).create(context, privateSpace, itemId, version);
+ getVersionSyncStateRepository(context).create(context, new VersionContext(privateSpace,
+ itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+ }
+
+ @Override
+ public void commitStagedUpdate(SessionContext context, Id itemId, VersionEntity version,
+ Date publishTime) {
+ update(context, itemId, version, publishTime, false);
+ }
+
+ @Override
+ public void commitStagedIgnore(SessionContext context, Id itemId, VersionEntity version,
+ Date publishTime) {
+ getVersionSyncStateRepository(context).updatePublishTime(context,
+ new VersionContext(getPrivateSpaceName(context), itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+ }
+
+
+
+
+ protected VersionDao getVersionDao(SessionContext context) {
+ return VersionDaoFactory.getInstance().createInterface(context);
+ }
+
+ protected VersionSynchronizationStateRepository getVersionSyncStateRepository(
+ SessionContext context) {
+ return VersionSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java
new file mode 100644
index 0000000000..aa628eb706
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java
@@ -0,0 +1,135 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
+import com.amdocs.zusammen.datatypes.itemversion.Revision;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPublicStore;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
+
+public class VersionPublicStoreImpl implements VersionPublicStore {
+ @Override
+ public Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId) {
+ return getVersionDao(context)
+ .get(context, getSpaceName(context, Space.PUBLIC), itemId, versionId);
+ }
+
+ @Override
+ public Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+ Id itemId, Id versionId) {
+ Id revisionId = getLastItemVersionRevision(context, itemId,
+ versionId);
+ if (revisionId == null) {
+ return Optional.empty();
+ }
+
+ return getVersionSyncStateRepository(context)
+ .get(context, new VersionContext(getSpaceName(context, Space.PUBLIC), itemId),
+ new SynchronizationStateEntity(versionId, revisionId));
+ }
+
+
+ @Override
+ public void create(SessionContext context, Id itemId, VersionEntity version, Id revisionId,
+ Map<Id, Id> versionElementIds, Date
+ publishTime, String message) {
+ String publicSpace = getSpaceName(context, Space.PUBLIC);
+
+ getVersionDao(context).create(context, publicSpace, itemId, version);
+
+ getVersionDao(context).createVersionElements(context, publicSpace, itemId, version.getId(),
+ revisionId, versionElementIds, publishTime,message);
+
+ getVersionSyncStateRepository(context).create(context, new VersionContext(publicSpace,
+ itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+ }
+
+ @Override
+ public void update(SessionContext context, Id itemId, VersionEntity version,
+ Id revisionId, Map<Id, Id> versionElementIds, Date publishTime, String message) {
+ String publicSpace = getSpaceName(context, Space.PUBLIC);
+
+ getVersionDao(context).
+ createVersionElements(context, publicSpace, itemId, version.getId(),
+ revisionId, versionElementIds, publishTime,message);
+
+ getVersionSyncStateRepository(context).
+ updatePublishTime(context, new VersionContext(publicSpace, itemId),
+ new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+ }
+
+ @Override
+ public boolean checkHealth(SessionContext context) {
+ return getVersionDao(context).checkHealth(context);
+ }
+
+ @Override
+ public ItemVersionRevisions listItemVersionRevisions(SessionContext context, Id itemId,
+ Id versionId) {
+ VersionContext entityContext = new VersionContext(getSpaceName(context, Space.PUBLIC), itemId);
+ List<SynchronizationStateEntity> versionRevisions = getVersionSyncStateRepository(context)
+ .list(context, entityContext, new VersionEntity(versionId));
+
+ if (versionRevisions == null || versionRevisions.size() == 0) {
+ return null;
+ }
+
+ versionRevisions.sort(new Comparator<SynchronizationStateEntity>() {
+ @Override
+ public int compare(SynchronizationStateEntity o1, SynchronizationStateEntity o2) {
+ if (o1.getPublishTime().after(o2.getPublishTime())) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ });
+ ItemVersionRevisions itemVersionRevisions = new ItemVersionRevisions();
+ versionRevisions.forEach(synchronizationStateEntity -> itemVersionRevisions.addChange
+ (convertSyncState2Revision(synchronizationStateEntity)));
+ return itemVersionRevisions;
+ }
+
+ private Revision convertSyncState2Revision(
+ SynchronizationStateEntity synchronizationStateEntity) {
+ Revision revision = new Revision();
+ revision.setRevisionId(synchronizationStateEntity.getRevisionId());
+ revision.setTime(synchronizationStateEntity.getPublishTime());
+ revision.setMessage(synchronizationStateEntity.getMessage());
+ revision.setUser(synchronizationStateEntity.getUser());
+ return revision;
+ }
+
+
+ private Id getLastItemVersionRevision(SessionContext context, Id itemId, Id versionId) {
+
+ ItemVersionRevisions versionRevisions = listItemVersionRevisions(context, itemId, versionId);
+ if(versionRevisions ==null ) return null;
+ return versionRevisions.getItemVersionRevisions().get(0).getRevisionId();
+ }
+
+ protected VersionDao getVersionDao(SessionContext context) {
+ return VersionDaoFactory.getInstance().createInterface(context);
+ }
+
+ protected VersionSynchronizationStateRepository getVersionSyncStateRepository(
+ SessionContext context) {
+ return VersionSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java
new file mode 100644
index 0000000000..dac9d257ea
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java
@@ -0,0 +1,39 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionStageStore;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class VersionStageStoreImpl implements VersionStageStore {
+ @Override
+ public Optional<StageEntity<VersionEntity>> get(SessionContext context, Id itemId,
+ VersionEntity versionEntity) {
+ return getVersionStageRepository(context)
+ .get(context, new VersionContext(getPrivateSpaceName(context), itemId), versionEntity);
+ }
+
+ @Override
+ public void create(SessionContext context, Id itemId, StageEntity<VersionEntity> versionStage) {
+ getVersionStageRepository(context)
+ .create(context, new VersionContext(getPrivateSpaceName(context), itemId), versionStage);
+ }
+
+ @Override
+ public void delete(SessionContext context, Id itemId, VersionEntity version) {
+ getVersionStageRepository(context)
+ .delete(context, new VersionContext(getPrivateSpaceName(context), itemId), version);
+ }
+
+ protected VersionStageRepository getVersionStageRepository(SessionContext context) {
+ return VersionStageRepositoryFactory.getInstance().createInterface(context);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java
index 967814c4d8..7681327e40 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java
@@ -1,15 +1,18 @@
package org.openecomp.core.zusammen.plugin.dao;
+import com.amdocs.zusammen.datatypes.Id;
import com.amdocs.zusammen.datatypes.SessionContext;
import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-import java.util.Collection;
+import java.util.Map;
import java.util.Optional;
public interface ElementRepository {
- Collection<ElementEntity> list(SessionContext context, ElementEntityContext elementContext);
+ Map<Id,Id> listIds(SessionContext context, ElementEntityContext elementContext);
+
+/* void createVersionData(SessionContext context, ElementEntityContext elementContext, VersionDataElement element);*/
void create(SessionContext context, ElementEntityContext elementContext, ElementEntity element);
@@ -20,8 +23,28 @@ public interface ElementRepository {
Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
ElementEntity element);
+ Optional<ElementEntity> getDescriptor(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element);
+
void createNamespace(SessionContext context, ElementEntityContext elementContext,
ElementEntity element);
- boolean checkHealth(SessionContext context);
+ Optional<Id> getHash(SessionContext context, ElementEntityContext elementEntityContext,
+ ElementEntity element);
+
+
+
+
+/* Collection<SynchronizationStateEntity> listSynchronizationStates(SessionContext context,
+ ElementEntityContext elementContext);
+
+ void updateSynchronizationState(SessionContext context, ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState);
+
+ void markAsDirty(SessionContext context, ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState);
+
+ Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+ ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState);*/
}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java
new file mode 100644
index 0000000000..ac3dc4e4bf
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java
@@ -0,0 +1,34 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface ElementStageRepository
+ extends StageRepository<ElementEntityContext, ElementEntity> {
+
+ Optional<StageEntity<ElementEntity>> getDescriptor(SessionContext context,
+ ElementEntityContext elementContext,
+ ElementEntity element);
+
+ Collection<ElementEntity> listIds(SessionContext context,
+ ElementEntityContext elementContext);
+
+ Collection<ElementEntity> listConflictedIds(SessionContext context,
+ ElementEntityContext elementContext);
+
+ void markAsNotConflicted(SessionContext context, ElementEntityContext entityContext,
+ ElementEntity entity, Action action);
+
+ void markAsNotConflicted(SessionContext context, ElementEntityContext entityContext,
+ ElementEntity entity);
+
+ void update(SessionContext context, ElementEntityContext entityContext, ElementEntity entity,
+ Action action, boolean conflicted);
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java
new file mode 100644
index 0000000000..1e41308ff2
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java
@@ -0,0 +1,14 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class ElementStageRepositoryFactory
+ extends AbstractComponentFactory<ElementStageRepository> {
+ public static ElementStageRepositoryFactory getInstance() {
+ return AbstractFactory.getInstance(ElementStageRepositoryFactory.class);
+ }
+
+ public abstract ElementStageRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java
new file mode 100644
index 0000000000..53c029bb6f
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java
@@ -0,0 +1,21 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+
+public interface ElementSynchronizationStateRepository
+ extends SynchronizationStateRepository<ElementEntityContext> {
+
+ Collection<SynchronizationStateEntity> list(SessionContext context,
+ ElementEntityContext elementContext);
+
+ void update(SessionContext context, ElementEntityContext entityContext,
+ SynchronizationStateEntity syncStateEntity);
+
+ void markAsDirty(SessionContext context, ElementEntityContext entityContext,
+ SynchronizationStateEntity syncStateEntity);
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java
new file mode 100644
index 0000000000..26f3bb4f56
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java
@@ -0,0 +1,14 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class ElementSynchronizationStateRepositoryFactory
+ extends AbstractComponentFactory<ElementSynchronizationStateRepository> {
+ public static ElementSynchronizationStateRepositoryFactory getInstance() {
+ return AbstractFactory.getInstance(ElementSynchronizationStateRepositoryFactory.class);
+ }
+
+ public abstract ElementSynchronizationStateRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java
new file mode 100644
index 0000000000..98b0d8242c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java
@@ -0,0 +1,15 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Optional;
+
+public interface StageRepository<C, E> {
+
+ Optional<StageEntity<E>> get(SessionContext context, C entityContext, E entity);
+
+ void create(SessionContext context, C entityContext, StageEntity<E> stageEntity);
+
+ void delete(SessionContext context, C entityContext, E entity);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java
new file mode 100644
index 0000000000..f227b0c925
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java
@@ -0,0 +1,16 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Optional;
+
+public interface SynchronizationStateRepository<C> {
+
+ void create(SessionContext context, C entityContext, SynchronizationStateEntity syncStateEntity);
+
+ void delete(SessionContext context, C entityContext, SynchronizationStateEntity syncStateEntity);
+
+ Optional<SynchronizationStateEntity> get(SessionContext context, C entityContext,
+ SynchronizationStateEntity syncStateEntity);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java
new file mode 100644
index 0000000000..f8ad0405b2
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java
@@ -0,0 +1,29 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+public interface VersionDao {
+ Collection<VersionEntity> list(SessionContext context, String space, Id itemId);
+
+ Optional<VersionEntity> get(SessionContext context, String space, Id itemId, Id versionId);
+
+ void create(SessionContext context, String space, Id itemId, VersionEntity version);
+
+ void updateModificationTime(SessionContext context, String space, Id itemId, Id versionId, Date modificationTime);
+
+ void delete(SessionContext context, String space, Id itemId, Id versionId);
+
+ boolean checkHealth(SessionContext context);
+
+ void createVersionElements(SessionContext context, String publicSpace, Id itemId, Id versionId,
+ Id revisionId, Map<Id, Id> versionElementIds, Date publishTime,
+ String message);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java
new file mode 100644
index 0000000000..2847959f8f
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java
@@ -0,0 +1,13 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class VersionDaoFactory extends AbstractComponentFactory<VersionDao> {
+ public static VersionDaoFactory getInstance() {
+ return AbstractFactory.getInstance(VersionDaoFactory.class);
+ }
+
+ public abstract VersionDao createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java
new file mode 100644
index 0000000000..568e0c9d2b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java
@@ -0,0 +1,9 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+public interface VersionStageRepository extends StageRepository<VersionContext, VersionEntity> {
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java
new file mode 100644
index 0000000000..fc9e7725eb
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java
@@ -0,0 +1,13 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class VersionStageRepositoryFactory extends AbstractComponentFactory<VersionStageRepository> {
+ public static VersionStageRepositoryFactory getInstance() {
+ return AbstractFactory.getInstance(VersionStageRepositoryFactory.class);
+ }
+
+ public abstract VersionStageRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java
new file mode 100644
index 0000000000..9134392d3b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java
@@ -0,0 +1,18 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.List;
+
+public interface VersionSynchronizationStateRepository
+ extends SynchronizationStateRepository<VersionContext> {
+
+ void updatePublishTime(SessionContext context, VersionContext entityContext,
+ SynchronizationStateEntity syncStateEntity);
+
+ List<SynchronizationStateEntity> list(SessionContext context, VersionContext entityContext,
+ VersionEntity versionEntity);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java
new file mode 100644
index 0000000000..dfedb5897b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java
@@ -0,0 +1,14 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class VersionSynchronizationStateRepositoryFactory
+ extends AbstractComponentFactory<VersionSynchronizationStateRepository> {
+ public static VersionSynchronizationStateRepositoryFactory getInstance() {
+ return AbstractFactory.getInstance(VersionSynchronizationStateRepositoryFactory.class);
+ }
+
+ public abstract VersionSynchronizationStateRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java
deleted file mode 100644
index 6cc1350444..0000000000
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright © 2016-2017 European Support Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.openecomp.core.zusammen.plugin.dao.impl;
-
-import com.amdocs.zusammen.datatypes.Id;
-import com.amdocs.zusammen.datatypes.Namespace;
-import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.item.Info;
-import com.amdocs.zusammen.datatypes.item.Relation;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
-import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.mapping.annotations.Accessor;
-import com.datastax.driver.mapping.annotations.Param;
-import com.datastax.driver.mapping.annotations.Query;
-import com.google.gson.reflect.TypeToken;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-
-import java.lang.reflect.Type;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public class CassandraElementRepository implements ElementRepository {
-
- private static final String VERSION_ELEMENT_NOT_EXIST_ERROR_MSG =
- "List version elements error: " +
- "element %s, which appears as an element of item %s version %s, does not exist";
-
- @Override
- public Collection<ElementEntity> list(SessionContext context,
- ElementEntityContext elementContext) {
- Set<String> elementIds = getVersionElementIds(context, elementContext);
-
- Collection<ElementEntity> elements = new ArrayList<>();
- for (String elementId : elementIds) {
- elements.add(get(context, elementContext, new ElementEntity(new Id(elementId)))
- .orElseThrow(
- () -> new IllegalStateException(String.format(VERSION_ELEMENT_NOT_EXIST_ERROR_MSG,
- elementId, elementContext.getItemId().getValue(),
- getVersionId(elementContext)))));
- }
- return elements;
- }
-
- @Override
- public void create(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- createElement(context, elementContext, element);
- addElementToParent(context, elementContext, element);
- }
-
- @Override
- public void update(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- updateElement(context, elementContext, element);
- }
-
- @Override
- public void delete(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- removeElementFromParent(context, elementContext, element);
- deleteElement(context, elementContext, element);
- }
-
- @Override
- public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- Row row = getElementAccessor(context).get(
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- getVersionId(elementContext),
- element.getId().toString()).one();
-
- return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
- }
-
- @Override
- public void createNamespace(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- getElementNamespaceAccessor(context).create(
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- element.getId().toString(),
- element.getNamespace().toString());
- }
-
- @Override
- public boolean checkHealth(SessionContext context) {
- ResultSet resultSet = getVersionElementsAccessor(context).checkHealth();
- return resultSet.getColumnDefinitions().contains("element_ids");
- }
-
- private String getVersionId(ElementEntityContext elementContext) {
- return elementContext.getChangeRef() == null
- ? elementContext.getVersionId().toString()
- : elementContext.getChangeRef();
- }
-
- private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
- return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
- }
-
- private ElementAccessor getElementAccessor(SessionContext context) {
- return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
- }
-
- private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
- return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
- }
-
- private void createElement(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- Set<String> subElementIds =
- element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
- String versionId = getVersionId(elementContext);
-
- getElementAccessor(context).create(
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- versionId,
- element.getId().toString(),
- element.getParentId().toString(),
- element.getNamespace().toString(),
- JsonUtil.object2Json(element.getInfo()),
- JsonUtil.object2Json(element.getRelations()),
- element.getData(),
- element.getSearchableData(),
- element.getVisualization(),
- subElementIds);
-
- getVersionElementsAccessor(context).addElements(
- Collections.singleton(element.getId().toString()),
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- versionId);
- }
-
- private void updateElement(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- getElementAccessor(context).update(
- JsonUtil.object2Json(element.getInfo()),
- JsonUtil.object2Json(element.getRelations()),
- element.getData(),
- element.getSearchableData(),
- element.getVisualization(),
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- elementContext.getVersionId().toString(),
- element.getId().toString());
- }
-
- private void deleteElement(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- String versionId = getVersionId(elementContext);
-
- getElementAccessor(context).delete(
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- versionId,
- element.getId().toString());
-
- getVersionElementsAccessor(context).removeElements(
- Collections.singleton(element.getId().toString()),
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- versionId);
- }
-
- private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- getElementAccessor(context).addSubElements(
- Collections.singleton(element.getId().toString()),
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- getVersionId(elementContext),
- element.getParentId().toString());
- }
-
- private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
- ElementEntity element) {
- if (element.getParentId() == null) {
- return;
- }
- getElementAccessor(context).removeSubElements(
- Collections.singleton(element.getId().toString()),
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- getVersionId(elementContext),
- element.getParentId().toString());
- }
-
- private ElementEntity getElementEntity(ElementEntity element, Row row) {
- element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
- element.setParentId(new Id(row.getString(ElementField.PARENT_ID)));
- element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
- element.setRelations(
- json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
- }.getType()));
- element.setData(row.getBytes(ElementField.DATA));
- element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
- element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
- element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
- .stream().map(Id::new).collect(Collectors.toSet()));
- return element;
- }
-
- private Namespace getNamespace(String namespaceStr) {
- Namespace namespace = new Namespace();
- if (namespaceStr != null) {
- namespace.setValue(namespaceStr);
- }
- return namespace;
- }
-
- private static <T> T json2Object(String json, Type typeOfT) {
- return json == null ? null : JsonUtil.json2Object(json, typeOfT);
- }
-
- private Set<String> getVersionElementIds(SessionContext context,
- ElementEntityContext elementContext) {
- Row row = getVersionElementsAccessor(context).get(
- elementContext.getSpace(),
- elementContext.getItemId().toString(),
- getVersionId(elementContext)).one();
- return row == null
- ? new HashSet<>()
- : row.getSet(CassandraElementRepository.VersionElementsField.ELEMENT_IDS, String.class);
- }
-
- /*
-CREATE TABLE IF NOT EXISTS element_namespace (
- space text,
- item_id text,
- element_id text,
- namespace text,
- PRIMARY KEY (( space, item_id, element_id ))
-);
- */
- @Accessor
- interface ElementNamespaceAccessor {
- @Query(
- "UPDATE element_namespace SET namespace=:ns " +
- "WHERE space=:space AND item_id=:item AND element_id=:id ")
- void create(@Param("space") String space,
- @Param("item") String itemId,
- @Param("id") String elementId,
- @Param("ns") String namespace);
- }
-
- /*
-CREATE TABLE IF NOT EXISTS element (
- space text,
- item_id text,
- version_id text,
- element_id text,
- parent_id text,
- namespace text,
- info text,
- relations text,
- data blob,
- searchable_data blob,
- visualization blob,
- sub_element_ids set<text>,
- PRIMARY KEY (( space, item_id, version_id, element_id ))
-);
- */
- @Accessor
- interface ElementAccessor {
- @Query(
- "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
- "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
- "sub_element_ids=sub_element_ids+:subs " +
- "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
- void create(@Param("space") String space,
- @Param("item") String itemId,
- @Param("ver") String versionId,
- @Param("id") String elementId,
- @Param("parentId") String parentElementId,
- @Param("ns") String namespace,
- @Param("info") String info,
- @Param("rels") String relations,
- @Param("data") ByteBuffer data,
- @Param("searchableData") ByteBuffer searchableData,
- @Param("visualization") ByteBuffer visualization,
- @Param("subs") Set<String> subElementIds);
-
- @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=?" +
- " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
- void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
- ByteBuffer visualization, String space, String itemId, String versionId,
- String elementId);
-
- @Query("DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
- void delete(String space, String itemId, String versionId, String elementId);
-
- @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
- "sub_element_ids FROM element " +
- "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
- ResultSet get(String space, String itemId, String versionId, String elementId);
-
- @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
- " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
- void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
- String elementId);
-
- @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
- " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
- void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
- String elementId);
- }
-
- private static final class ElementField {
- private static final String NAMESPACE = "namespace";
- private static final String PARENT_ID = "parent_id";
- private static final String INFO = "info";
- private static final String RELATIONS = "relations";
- private static final String DATA = "data";
- private static final String SEARCHABLE_DATA = "searchable_data";
- private static final String VISUALIZATION = "visualization";
- private static final String SUB_ELEMENT_IDS = "sub_element_ids";
- }
-
- /*
- CREATE TABLE IF NOT EXISTS version_elements (
- space text,
- item_id text,
- version_id text,
- element_ids set<text>,
- PRIMARY KEY (( space, item_id, version_id ))
- );
- */
- @Accessor
- interface VersionElementsAccessor {
-
- @Query("UPDATE version_elements SET element_ids=element_ids+? " +
- "WHERE space=? AND item_id=? AND version_id=?")
- void addElements(Set<String> elementIds, String space, String itemId, String versionId);
-
- @Query("UPDATE version_elements SET element_ids=element_ids-? " +
- "WHERE space=? AND item_id=? AND version_id=?")
- void removeElements(Set<String> elementIds, String space, String itemId, String versionId);
-
- @Query("SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=?")
- ResultSet get(String space, String itemId, String versionId);
-
- @Query("SELECT element_ids FROM version_elements LIMIT 1")
- ResultSet checkHealth();
- }
-
- private static final class VersionElementsField {
- private static final String ELEMENT_IDS = "element_ids";
- }
-}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraDaoUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/CassandraDaoUtils.java
index 20a1e1803f..b6cb9e4070 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraDaoUtils.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/CassandraDaoUtils.java
@@ -1,9 +1,9 @@
-package org.openecomp.core.zusammen.plugin.dao.impl;
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
-import com.datastax.driver.core.Session;
import com.amdocs.zusammen.commons.db.api.cassandra.CassandraConnectorFactory;
import com.amdocs.zusammen.commons.db.api.cassandra.types.CassandraContext;
import com.amdocs.zusammen.datatypes.SessionContext;
+import com.datastax.driver.core.Session;
class CassandraDaoUtils {
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryFactoryImpl.java
index f3072a6502..8540816f00 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryFactoryImpl.java
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-package org.openecomp.core.zusammen.plugin.dao.impl;
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
import com.amdocs.zusammen.datatypes.SessionContext;
import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
-public class CassandraElementRepositoryFactory extends ElementRepositoryFactory {
+public class ElementRepositoryFactoryImpl extends ElementRepositoryFactory {
- private static final ElementRepository INSTANCE = new CassandraElementRepository();
+ private static final ElementRepository INSTANCE = new ElementRepositoryImpl();
@Override
public ElementRepository createInterface(SessionContext context) {
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java
new file mode 100644
index 0000000000..bb3b1cfa7c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.Namespace;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.Relation;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Param;
+import com.datastax.driver.mapping.annotations.Query;
+import com.google.gson.reflect.TypeToken;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+
+import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+public class ElementRepositoryImpl implements ElementRepository {
+
+ @Override
+ public Map<Id, Id> listIds(SessionContext context, ElementEntityContext elementContext) {
+
+ if (elementContext.getRevisionId() == null) {
+ String revisionId = calculateLastRevisionId(context, elementContext);
+ if (revisionId == null) {
+ return new HashMap<>();
+ }
+
+ elementContext.setRevisionId(new Id(revisionId));
+ }
+ return getVersionElementIds(context, elementContext).entrySet().stream().collect(Collectors
+ .toMap(entry -> new Id(entry.getKey()), entry -> new Id(entry.getValue())));
+
+ /* return getVersionElementIds(context, elementContext).stream()
+ .map(Id::new)
+ .collect(Collectors.toList());*/
+
+ }
+
+ @Override
+ public void create(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ createElement(context, elementContext, element);
+ addElementToParent(context, elementContext, element);
+ }
+
+ @Override
+ public void update(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+
+ Id elementRevisionId = getElementRevision(context, elementContext, element.getId());
+ if (elementRevisionId.equals(elementContext.getRevisionId())) {
+ updateElement(context, elementContext, element);
+ } else {
+ createElement(context, elementContext, element);
+ }
+ }
+
+ @Override
+ public void delete(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ removeElementFromParent(context, elementContext, element);
+ deleteElement(context, elementContext, element);
+ }
+
+ @Override
+ public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ String revisionId = calculateElementRevisionId(context, elementContext, element);
+ if (revisionId == null) {
+ return Optional.empty();
+ }
+
+ Row row = getElementAccessor(context).get(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString(),
+ revisionId).one();
+
+ return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
+ }
+
+ @Override
+ public Optional<ElementEntity> getDescriptor(SessionContext context,
+ ElementEntityContext elementContext,
+ ElementEntity element) {
+ String revisionId = calculateElementRevisionId(context, elementContext, element);
+ if (revisionId == null) {
+ return Optional.empty();
+ }
+
+ Row row = getElementAccessor(context).getDescriptor(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString(),
+ revisionId).one();
+
+ return row == null ? Optional.empty() : Optional.of(getElementEntityDescriptor(element, row));
+ }
+
+ @Override
+ public void createNamespace(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ getElementNamespaceAccessor(context).create(elementContext.getItemId().toString(),
+ element.getId().toString(),
+ element.getNamespace().toString());
+ }
+
+ @Override
+ public Optional<Id> getHash(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ String revisionId = calculateElementRevisionId(context, elementContext, element);
+ if (revisionId == null) {
+ return Optional.empty();
+ }
+
+ Row row = getElementAccessor(context).getHash(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getId().toString(),
+ revisionId).one();
+
+ return row == null ? Optional.empty() : Optional.of(getElementHash(row));
+ }
+
+ private String calculateElementRevisionId(SessionContext context,
+ ElementEntityContext elementContext,
+ ElementEntity element) {
+
+ if (elementContext.getSpace().equals(ZusammenPluginConstants.PUBLIC_SPACE)) {
+
+ String versionRevision;
+ if (elementContext.getRevisionId() == null) {
+ versionRevision = calculateLastRevisionId(context, elementContext);
+ } else {
+ versionRevision = elementContext.getRevisionId().getValue();
+ }
+
+ elementContext.setRevisionId(new Id(versionRevision));
+ Map<String, String> elementIds = getVersionElementIds(context, elementContext);
+ if (elementIds.containsKey(element.getId().getValue())) {
+ return elementIds.get(element.getId().getValue());
+ } else {
+ return null;
+ }
+
+ } else {
+ return Id.ZERO.getValue();
+ }
+ }
+
+ private String calculateLastRevisionId(SessionContext context, ElementEntityContext
+ elementContext) {
+ List<Row> rows = getVersionElementsAccessor(context).listRevisions(elementContext.getSpace(),
+ elementContext
+ .getItemId().toString(), elementContext.getVersionId().toString()).all();
+ if (rows == null || rows.size() == 0) {
+ return null;
+ }
+ rows.sort((o1, o2) -> o1.getDate(VersionElementsField.PUBLISH_TIME)
+ .after(o2.getDate(VersionElementsField.PUBLISH_TIME)) ? -1 : 1);
+ return rows.get(0).getString(VersionElementsField.REVISION_ID);
+ }
+
+ /*private static String getVersionId(ElementEntityContext elementContext) {
+ return elementContext.getRevisionId() == null
+ ? elementContext.getVersionId().toString()
+ : elementContext.getRevisionId().getValue();
+ }*/
+
+ private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
+ }
+
+ private ElementAccessor getElementAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
+ }
+
+ private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
+ }
+
+ private void createElement(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ createElementRow(context, elementContext, element);
+
+ Map<String, String> elementIds = new TreeMap<>();
+ elementIds.put(element.getId().toString(), elementContext.getRevisionId().getValue());
+ getVersionElementsAccessor(context).addElements(
+ elementIds,
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ private void createElementRow(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ Set<String> subElementIds =
+ element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
+
+ getElementAccessor(context).create(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getId().toString(),
+ elementContext.getRevisionId().getValue(),
+ element.getParentId() == null ? null : element.getParentId().toString(),
+ element.getNamespace() == null ? null : element.getNamespace().toString(),
+ JsonUtil.object2Json(element.getInfo()),
+ JsonUtil.object2Json(element.getRelations()),
+ element.getData(),
+ element.getSearchableData(),
+ element.getVisualization(),
+ subElementIds,
+ element.getElementHash().getValue());
+ }
+
+ private void updateElement(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+
+
+ if (element.getParentId() == null) {
+ getElementAccessor(context).update(
+ JsonUtil.object2Json(element.getInfo()),
+ JsonUtil.object2Json(element.getRelations()),
+ element.getData(),
+ element.getSearchableData(),
+ element.getVisualization(),
+ element.getElementHash().getValue(),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString(),
+ elementContext.getRevisionId().getValue());
+ } else {
+ getElementAccessor(context).update(
+ JsonUtil.object2Json(element.getInfo()),
+ JsonUtil.object2Json(element.getRelations()),
+ element.getData(),
+ element.getSearchableData(),
+ element.getVisualization(),
+ element.getElementHash().getValue(),
+ element.getParentId().getValue(),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ Map<String, String> elementIds = new TreeMap<>();
+ elementIds.put(element.getId().getValue(), elementContext.getRevisionId().getValue());
+ getVersionElementsAccessor(context).addElements(
+ elementIds,
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ private void deleteElement(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+
+
+ getElementAccessor(context).delete(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString(),
+ elementContext.getRevisionId().getValue());
+
+ getVersionElementsAccessor(context).removeElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ if (element.getParentId() == null) {
+ return;
+ }
+
+
+ getElementAccessor(context).addSubElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getParentId().toString(),
+ elementContext.getRevisionId().getValue());
+
+ Map<String, String> elementIds = new TreeMap<>();
+ elementIds.put(element.getParentId().toString(), elementContext.getRevisionId().getValue());
+ getVersionElementsAccessor(context).addElements(elementIds, elementContext.getSpace(),
+ elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+
+ if (element.getParentId() == null) {
+ return;
+ }
+
+ Optional<ElementEntity> parentElement =
+ get(context, elementContext, new ElementEntity(element.getParentId()));
+ if (!parentElement.isPresent()) {
+ return;
+ }
+ getElementAccessor(context).removeSubElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getParentId().toString(),
+ elementContext.getRevisionId().getValue());
+
+ getVersionElementsAccessor(context)
+ .removeElements(Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+
+ Map<String, String> elementIds = new TreeMap<>();
+ elementIds.put(element.getParentId().toString(), elementContext.getRevisionId().getValue());
+ getVersionElementsAccessor(context).addElements(elementIds, elementContext.getSpace(),
+ elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ static ElementEntity getElementEntityDescriptor(ElementEntity element, Row row) {
+ element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
+ element.setParentId(getParentId(row.getString(ElementField.PARENT_ID)));
+ element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
+ element.setRelations(
+ json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
+ }.getType()));
+
+ element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
+ .stream().map(Id::new).collect(Collectors.toSet()));
+ return element;
+ }
+
+ static ElementEntity getElementEntity(ElementEntity element, Row row) {
+ getElementEntityDescriptor(element, row);
+
+ element.setData(row.getBytes(ElementField.DATA));
+ element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
+ element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
+ element.setElementHash(new Id(row.getString(ElementField.ELEMENT_HASH)));
+ return element;
+ }
+
+ private Id getElementHash(Row row) {
+ return new Id(row.getString(ElementField.ELEMENT_HASH));
+ }
+
+ private static Id getParentId(String parentIdStr) {
+ return parentIdStr == null ? null : new Id(parentIdStr);
+ }
+
+ private static Namespace getNamespace(String namespaceStr) {
+ Namespace namespace = new Namespace();
+ if (namespaceStr != null) {
+ namespace.setValue(namespaceStr);
+ }
+ return namespace;
+ }
+
+ private static <T> T json2Object(String json, Type typeOfT) {
+ return json == null ? null : JsonUtil.json2Object(json, typeOfT);
+ }
+
+ private Map<String, String> getVersionElementIds(SessionContext context,
+ ElementEntityContext elementContext) {
+ Row row = getVersionElementsAccessor(context).get(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue()).one();
+ return row == null
+ ? new HashMap<>()
+ : row.getMap(ElementRepositoryImpl.VersionElementsField.ELEMENT_IDS, String.class, String
+ .class);
+ }
+
+ private Id getElementRevision(SessionContext context, ElementEntityContext elementContext
+ , Id elementId) {
+ Map<Id, Id> versionElementIds =
+ listIds(context, new ElementEntityContext
+ (elementContext.getSpace(), elementContext.getItemId(), elementContext.getVersionId(),
+ elementContext.getRevisionId()));
+ return versionElementIds.get(elementId);
+
+ }
+
+
+ /*
+CREATE TABLE IF NOT EXISTS element_namespace (
+ item_id text,
+ element_id text,
+ namespace text,
+ PRIMARY KEY (( item_id, element_id ))
+);
+ */
+ @Accessor
+ interface ElementNamespaceAccessor {
+ @Query("UPDATE element_namespace SET namespace=:ns " +
+ "WHERE item_id=:item AND element_id=:id ")
+ void create(@Param("item") String itemId,
+ @Param("id") String elementId,
+ @Param("ns") String namespace);
+ }
+
+ @Accessor
+ interface ElementAccessor {
+ @Query(
+ "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
+ "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
+ "sub_element_ids=sub_element_ids+:subs , element_hash=:elementHash " +
+ " WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id AND " +
+ "revision_id=:rev ")
+ void create(@Param("space") String space,
+ @Param("item") String itemId,
+ @Param("ver") String versionId,
+ @Param("id") String elementId,
+ @Param("rev") String revisionId,
+ @Param("parentId") String parentElementId,
+ @Param("ns") String namespace,
+ @Param("info") String info,
+ @Param("rels") String relations,
+ @Param("data") ByteBuffer data,
+ @Param("searchableData") ByteBuffer searchableData,
+ @Param("visualization") ByteBuffer visualization,
+ @Param("subs") Set<String> subElementIds,
+ @Param("elementHash") String elementHash);
+
+
+ @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=? ," +
+ "element_hash=? , parent_id=? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
+ ByteBuffer visualization, String elementHash, String parentId, String space, String
+ itemId, String
+ versionId, String elementId, String revisionId);
+
+ @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=? ," +
+ "element_hash=? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
+ ByteBuffer visualization, String elementHash, String space, String
+ itemId, String
+ versionId, String elementId, String revisionId);
+
+ @Query(
+ "DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ void delete(String space, String itemId, String versionId, String elementId, String revisionId);
+
+ @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
+ "sub_element_ids,element_hash FROM element " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ ResultSet get(String space, String itemId, String versionId, String elementId, String
+ revisionId);
+
+ @Query("SELECT parent_id, namespace, info, relations, sub_element_ids FROM element " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ ResultSet getDescriptor(String space, String itemId, String versionId, String elementId,
+ String revisionId);
+
+ @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+ String elementId, String revisionId);
+
+ @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+ String elementId, String revisionId);
+
+ @Query("SELECT element_hash FROM element " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+ ResultSet getHash(String space, String itemId, String versionId, String elementId, String
+ revisionId);
+ }
+
+ private static final class ElementField {
+ private static final String NAMESPACE = "namespace";
+ private static final String PARENT_ID = "parent_id";
+ private static final String INFO = "info";
+ private static final String RELATIONS = "relations";
+ private static final String DATA = "data";
+ private static final String SEARCHABLE_DATA = "searchable_data";
+ private static final String VISUALIZATION = "visualization";
+ private static final String SUB_ELEMENT_IDS = "sub_element_ids";
+ private static final String ELEMENT_HASH = "element_hash";
+ }
+
+ @Accessor
+ interface VersionElementsAccessor {
+
+ @Query("UPDATE version_elements SET element_ids=element_ids+ ? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ void addElements(Map<String, String> elementIds, String space, String itemId, String versionId,
+ String versionRevisionId);
+
+ @Query("UPDATE version_elements SET element_ids=element_ids-? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=?")
+ void removeElements(Set<String> elementIds, String space, String itemId, String versionId,
+ String revisionId);
+
+ @Query(
+ "SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ ResultSet get(String space, String itemId, String versionId, String revisionId);
+
+ @Query(
+ "SELECT revision_id,publish_time FROM version_elements WHERE space=? AND item_id=? AND " +
+ "version_id=? ")
+ ResultSet listRevisions(String space, String itemId, String versionId);
+
+ }
+
+ private static final class VersionElementsField {
+ private static final String ELEMENT_IDS = "element_ids";
+ private static final String REVISION_ID = "revision_id";
+ private static final String PUBLISH_TIME = "publish_time";
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java
new file mode 100644
index 0000000000..02bec12302
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepositoryFactory;
+
+public class ElementStageRepositoryFactoryImpl extends ElementStageRepositoryFactory {
+
+ private static final ElementStageRepository INSTANCE = new ElementStageRepositoryImpl();
+
+ @Override
+ public ElementStageRepository createInterface(SessionContext context) {
+ return INSTANCE;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java
new file mode 100644
index 0000000000..c215f825a6
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Param;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ElementStageRepositoryImpl implements ElementStageRepository {
+
+ @Override
+ public Collection<ElementEntity> listIds(SessionContext context,
+ ElementEntityContext elementContext) {
+ return getElements(getStageElementIds(context, elementContext));
+ }
+
+ @Override
+ public Collection<ElementEntity> listConflictedIds(SessionContext context,
+ ElementEntityContext elementContext) {
+ return getElements(getConflictedElementIds(context, elementContext));
+ }
+
+ @Override
+ public void create(SessionContext context, ElementEntityContext elementContext,
+ StageEntity<ElementEntity> elementStage) {
+ createElement(context, elementContext, elementStage);
+ addElementToParent(context, elementContext, elementStage.getEntity());
+ }
+
+ @Override
+ public void markAsNotConflicted(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element, Action action) {
+ getElementStageAccessor(context).updateState(action, false,
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString());
+
+ getStageElementsAccessor(context).removeConflictElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ @Override
+ public void markAsNotConflicted(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ getElementStageAccessor(context).markAsNotConflicted(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString());
+
+ getStageElementsAccessor(context).removeConflictElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ @Override
+ public void update(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element, Action action, boolean conflicted) {
+ getElementStageAccessor(context).update(
+ JsonUtil.object2Json(element.getInfo()),
+ JsonUtil.object2Json(element.getRelations()),
+ element.getData(),
+ element.getSearchableData(),
+ element.getVisualization(),
+ element.getElementHash().getValue(),
+ action,
+ conflicted,
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ element.getId().toString());
+
+ if (!conflicted) {
+ getStageElementsAccessor(context).removeConflictElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementContext.getRevisionId().getValue());
+ }
+ }
+
+ @Override
+ public void delete(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ removeElementFromParent(context, elementContext, element);
+ deleteElement(context, elementContext, element);
+ }
+
+ @Override
+ public Optional<StageEntity<ElementEntity>> get(SessionContext context,
+ ElementEntityContext elementContext,
+ ElementEntity element) {
+ Row row = getElementStageAccessor(context).get(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getId().toString()).one();
+
+ return row == null ? Optional.empty() : Optional.of(getStageElement(row));
+ }
+
+ @Override
+ public Optional<StageEntity<ElementEntity>> getDescriptor(SessionContext context,
+ ElementEntityContext elementContext,
+ ElementEntity element) {
+ Row row = getElementStageAccessor(context).getDescriptor(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getId().toString()).one();
+
+ return row == null ? Optional.empty() : Optional.of(getStageElementDescriptor(row));
+ }
+
+
+
+ private Collection<ElementEntity> getElements(Set<String> elementIds) {
+ return elementIds.stream()
+ .map(id -> new ElementEntity(new Id(id)))
+ .collect(Collectors.toList());
+ }
+
+ private void createElement(SessionContext context, ElementEntityContext elementContext,
+ StageEntity<ElementEntity> elementStage) {
+
+
+ ElementEntity element = elementStage.getEntity();
+ Set<String> subElementIds =
+ element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
+ Set<String> conflictDependents = elementStage.getConflictDependents().stream()
+ .map(conflictDependent -> conflictDependent.getId().getValue())
+ .collect(Collectors.toSet());
+
+ getElementStageAccessor(context).create(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getId().toString(),
+ element.getParentId() == null ? null : element.getParentId().toString(),
+ element.getNamespace() == null ? null : element.getNamespace().toString(),
+ JsonUtil.object2Json(element.getInfo()),
+ JsonUtil.object2Json(element.getRelations()),
+ element.getData(),
+ element.getSearchableData(),
+ element.getVisualization(),
+ subElementIds,
+ element.getElementHash() == null ? null : element.getElementHash().getValue(),
+ elementStage.getPublishTime(),
+ elementStage.getAction(),
+ elementStage.isConflicted(),
+ conflictDependents);
+
+ getStageElementsAccessor(context).add(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+
+ if (elementStage.isConflicted()) {
+ getStageElementsAccessor(context).addConflictElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+ }
+
+ private void deleteElement(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+
+
+ getElementStageAccessor(context).delete(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getId().toString());
+
+ getStageElementsAccessor(context).remove(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ if (element.getParentId() == null) {
+ return;
+ }
+ getElementStageAccessor(context).addSubElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getParentId().toString());
+ }
+
+ private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
+ ElementEntity element) {
+ if (element.getParentId() == null) {
+ return;
+ }
+ getElementStageAccessor(context).removeSubElements(
+ Collections.singleton(element.getId().toString()),
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ element.getParentId().toString());
+ }
+
+ private StageEntity<ElementEntity> getStageElementDescriptor(Row row) {
+ return buildStageElement(ElementRepositoryImpl.getElementEntityDescriptor(
+ new ElementEntity(new Id(row.getString(ElementStageField.ID))), row), row);
+ }
+
+ private StageEntity<ElementEntity> getStageElement(Row row) {
+ return buildStageElement(ElementRepositoryImpl.getElementEntity(
+ new ElementEntity(new Id(row.getString(ElementStageField.ID))), row), row);
+ }
+
+
+ private StageEntity<ElementEntity> buildStageElement(ElementEntity element, Row row) {
+ StageEntity<ElementEntity> elementStage =
+ new StageEntity<>(element, row.getDate(ElementStageField.PUBLISH_TIME));
+ elementStage.setAction(Action.valueOf(row.getString(ElementStageField.ACTION)));
+ elementStage.setConflicted(row.getBool(ElementStageField.CONFLICTED));
+ elementStage.setConflictDependents(
+ row.getSet(ElementStageField.CONFLICT_DEPENDENTS, String.class).stream()
+ .map(conflictDependentId -> new ElementEntity(new Id(conflictDependentId)))
+ .collect(Collectors.toSet()));
+ return elementStage;
+ }
+
+ private Set<String> getStageElementIds(SessionContext context,
+ ElementEntityContext elementContext) {
+ Row row = getStageElementsAccessor(context).get(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue()).one();
+ return row == null ? new HashSet<>()
+ : row.getSet(StageElementsField.STAGE_ELEMENT_IDS, String.class);
+ }
+
+ private Set<String> getConflictedElementIds(SessionContext context,
+ ElementEntityContext elementContext) {
+ Row row = getStageElementsAccessor(context).getConflicted(
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().getValue(),
+ elementContext.getRevisionId().getValue()).one();
+ return row == null ? new HashSet<>()
+ : row.getSet(StageElementsField.CONFLICT_ELEMENT_IDS, String.class);
+ }
+
+ private ElementStageAccessor getElementStageAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, ElementStageAccessor.class);
+ }
+
+ private StageElementsAccessor getStageElementsAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, StageElementsAccessor.class);
+ }
+
+ @Accessor
+ interface ElementStageAccessor {
+ @Query(
+ "UPDATE element_stage SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
+ "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
+ "publish_time=:publishTime, action=:action, " +
+ "conflicted=:conflicted, conflict_dependent_ids=:conflictDependents, " +
+ "sub_element_ids=sub_element_ids+:subs, element_hash=:elementHash " +
+ "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
+ void create(@Param("space") String space,
+ @Param("item") String itemId,
+ @Param("ver") String versionId,
+ @Param("id") String elementId,
+ @Param("parentId") String parentElementId,
+ @Param("ns") String namespace,
+ @Param("info") String info,
+ @Param("rels") String relations,
+ @Param("data") ByteBuffer data,
+ @Param("searchableData") ByteBuffer searchableData,
+ @Param("visualization") ByteBuffer visualization,
+ @Param("subs") Set<String> subElementIds,
+ @Param("elementHash") String elementHash,
+ @Param("publishTime") Date publishTime,
+ @Param("action") Action action,
+ @Param("conflicted") boolean conflicted,
+ @Param("conflictDependents") Set<String> conflictDependents);
+
+ @Query("UPDATE element_stage SET info=?, relations=?, data=?, searchable_data=?, " +
+ "visualization=?,element_hash=?, action=?, conflicted=? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
+ ByteBuffer visualization, String elementHash, Action action, boolean conflicted,
+ String space,
+ String itemId, String versionId, String elementId);
+
+ @Query("UPDATE element_stage SET action=?, conflicted=? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ void updateState(Action action, boolean conflicted, String space, String itemId,
+ String versionId, String elementId);
+
+ @Query("UPDATE element_stage SET conflicted=false " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ void markAsNotConflicted(String space, String itemId, String versionId, String elementId);
+
+ @Query(
+ "DELETE FROM element_stage WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
+ void delete(String space, String itemId, String versionId, String elementId);
+
+ @Query("SELECT element_id, parent_id, namespace, info, relations, data, searchable_data, " +
+ "visualization, sub_element_ids,element_hash, publish_time, action, " +
+ "conflicted, conflict_dependent_ids FROM element_stage " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ ResultSet get(String space, String itemId, String versionId, String elementId);
+
+ @Query("SELECT element_id, parent_id, namespace, info, relations, " +
+ "sub_element_ids, publish_time, action, conflicted, conflict_dependent_ids " +
+ "FROM element_stage WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ ResultSet getDescriptor(String space, String itemId, String versionId, String elementId);
+
+ @Query("UPDATE element_stage SET sub_element_ids=sub_element_ids+? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+ String elementId);
+
+ @Query("UPDATE element_stage SET sub_element_ids=sub_element_ids-? " +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+ void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+ String elementId);
+ }
+
+ private static final class ElementStageField {
+ private static final String ID = "element_id";
+ private static final String PUBLISH_TIME = "publish_time";
+ private static final String ACTION = "action";
+ private static final String CONFLICTED = "conflicted";
+ private static final String CONFLICT_DEPENDENTS = "conflict_dependent_ids";
+ }
+
+ @Accessor
+ interface StageElementsAccessor {
+
+ @Query("UPDATE version_elements SET stage_element_ids=stage_element_ids+? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ void add(Set<String> elementIds, String space, String itemId, String versionId, String
+ revisionId);
+
+ @Query("UPDATE version_elements SET stage_element_ids=stage_element_ids-? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ void remove(Set<String> elementIds, String space, String itemId, String versionId, String
+ revisionId);
+
+ @Query("SELECT stage_element_ids FROM version_elements " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=?")
+ ResultSet get(String space, String itemId, String versionId, String revisionId);
+
+ @Query("UPDATE version_elements SET conflict_element_ids=conflict_element_ids+? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ void addConflictElements(Set<String> elementIds, String space, String itemId, String
+ versionId, String revisionId);
+
+ @Query("UPDATE version_elements SET conflict_element_ids=conflict_element_ids-? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ void removeConflictElements(Set<String> elementIds, String space, String itemId,
+ String versionId, String revisionId);
+
+ @Query("SELECT conflict_element_ids FROM version_elements " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ ResultSet getConflicted(String space, String itemId, String versionId, String revisionId);
+ }
+
+ private static final class StageElementsField {
+ private static final String STAGE_ELEMENT_IDS = "stage_element_ids";
+ private static final String CONFLICT_ELEMENT_IDS = "conflict_element_ids";
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java
new file mode 100644
index 0000000000..ec7e1c30ae
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory;
+
+public class ElementSynchronizationStateRepositoryFactoryImpl
+ extends ElementSynchronizationStateRepositoryFactory {
+
+ private static final ElementSynchronizationStateRepository INSTANCE =
+ new ElementSynchronizationStateRepositoryImpl();
+
+ @Override
+ public ElementSynchronizationStateRepository createInterface(SessionContext context) {
+ return INSTANCE;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java
new file mode 100644
index 0000000000..d41d3d73b1
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java
@@ -0,0 +1,209 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ElementSynchronizationStateRepositoryImpl
+ implements ElementSynchronizationStateRepository {
+
+ @Override
+ public Collection<SynchronizationStateEntity> list(SessionContext context,
+ ElementEntityContext elementContext) {
+ List<Row> rows = getAccessor(context)
+ .list(elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString()).all();
+ return rows == null ? new HashSet<>()
+ : rows.stream().map(this::getSynchronizationStateEntity).collect(Collectors.toSet());
+
+ }
+
+ @Override
+ public void create(SessionContext context, ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState) {
+ update(context, elementContext.getSpace(),
+ elementContext.getItemId(),
+ elementContext.getVersionId(),
+ elementContext.getRevisionId(),
+ elementSyncState.getRevisionId(),
+ elementSyncState.getId(),
+ elementSyncState.getPublishTime(),
+ elementSyncState.isDirty()
+
+ );
+ }
+
+ @Override
+ public void update(SessionContext context, ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState) {
+ update(context, elementContext.getSpace(),
+ elementContext.getItemId(),
+ elementContext.getVersionId(),
+ elementContext.getRevisionId(),
+ elementSyncState.getRevisionId(),
+ elementSyncState.getId(),
+ elementSyncState.getPublishTime(),
+ elementSyncState.isDirty()
+
+ );
+ }
+
+ @Override
+ public void markAsDirty(SessionContext context, ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState) {
+
+
+ getAccessor(context).updateDirty(true,
+ elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementSyncState.getId().toString(),
+ elementContext.getRevisionId().getValue());
+
+ getVersionElementsAccessor(context).addDirtyElements(
+ Collections.singleton(elementSyncState.getId().toString()), elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ @Override
+ public void delete(SessionContext context, ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState) {
+ getAccessor(context).delete(elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementSyncState.getId().toString(),
+ elementContext.getRevisionId().getValue());
+
+ getVersionElementsAccessor(context).removeDirtyElements(
+ Collections.singleton(elementSyncState.getId().toString()), elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementContext.getRevisionId().getValue());
+ }
+
+ @Override
+ public Optional<SynchronizationStateEntity> get(SessionContext context,
+ ElementEntityContext elementContext,
+ SynchronizationStateEntity elementSyncState) {
+
+ Row row = getAccessor(context)
+ .get(elementContext.getSpace(),
+ elementContext.getItemId().toString(),
+ elementContext.getVersionId().toString(),
+ elementSyncState.getId().toString(),
+ elementSyncState.getRevisionId().getValue()).one();
+
+ return row == null ? Optional.empty() : Optional.of(getSynchronizationStateEntity(row));
+ }
+
+ private void update(SessionContext context, String space, Id itemId, Id versionId, Id
+ versionRevisionId,Id elementRevisionId,Id elementId, Date publishTime, boolean isDirty) {
+ getAccessor(context).update(publishTime,
+ isDirty,
+ space,
+ itemId.toString(),
+ versionId.toString(),
+ elementId.toString(),
+ elementRevisionId.getValue());
+
+ if (isDirty) {
+ getVersionElementsAccessor(context).addDirtyElements(
+ Collections.singleton(elementId.toString()), space,
+ itemId.toString(),
+ versionId.toString(),
+ versionRevisionId.getValue());
+ } else {
+ getVersionElementsAccessor(context).removeDirtyElements(
+ Collections.singleton(elementId.toString()), space,
+ itemId.toString(),
+ versionId.toString(),
+ versionRevisionId.getValue());
+ }
+ }
+
+
+ private SynchronizationStateEntity getSynchronizationStateEntity(Row row) {
+ SynchronizationStateEntity entity =
+ new SynchronizationStateEntity(new Id(row.getString(SynchronizationStateField.ID)),
+ new Id(row.getString(SynchronizationStateField.REVISION_ID)),
+ row.getDate(SynchronizationStateField.PUBLISH_TIME),
+ row.getBool(SynchronizationStateField.DIRTY));
+ entity.setRevisionId(new Id(row.getString(SynchronizationStateField.REVISION_ID)));
+
+ return entity;
+
+ }
+
+ private ElementSynchronizationStateAccessor getAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, ElementSynchronizationStateAccessor.class);
+ }
+
+ private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
+ }
+
+ @Accessor
+ interface ElementSynchronizationStateAccessor {
+ @Query("UPDATE element_synchronization_state SET publish_time=?, dirty=? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+ void update(Date publishTime, boolean dirty, String space, String itemId, String versionId,
+ String elementId, String revisionId);
+
+ @Query("UPDATE element_synchronization_state SET dirty=? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+ void updateDirty(boolean dirty, String space, String itemId, String versionId,
+ String elementId, String revisionId);
+
+ @Query("DELETE FROM element_synchronization_state " +
+ "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+ void delete(String space, String itemId, String versionId, String elementId, String revisionId);
+
+ @Query("SELECT element_id,revision_id, publish_time, dirty FROM element_synchronization_state" +
+ " WHERE space=? AND item_id=? AND version_id=?")
+ ResultSet list(String space, String itemId, String versionId);
+
+ @Query("SELECT element_id,revision_id, publish_time, dirty FROM element_synchronization_state" +
+ " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+ ResultSet get(String space, String itemId, String versionId, String elementId, String
+ revisionId);
+ }
+
+ private static final class SynchronizationStateField {
+ private static final String ID = "element_id";
+ private static final String PUBLISH_TIME = "publish_time";
+ private static final String DIRTY = "dirty";
+ private static final String REVISION_ID = "revision_id";
+ }
+
+ @Accessor
+ interface VersionElementsAccessor {
+
+ @Query("UPDATE version_elements SET dirty_element_ids=dirty_element_ids+? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=?")
+ void addDirtyElements(Set<String> elementIds, String space, String itemId, String versionId,
+ String revisionId);
+
+ @Query("UPDATE version_elements SET dirty_element_ids=dirty_element_ids-? " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ void removeDirtyElements(Set<String> elementIds, String space, String itemId, String
+ versionId, String revisionId);
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java
new file mode 100644
index 0000000000..60dc9d1765
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java
@@ -0,0 +1,15 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
+
+public class VersionDaoFactoryImpl extends VersionDaoFactory {
+
+ private static final VersionDao INSTANCE = new VersionDaoImpl();
+
+ @Override
+ public VersionDao createInterface(SessionContext context) {
+ return INSTANCE;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java
new file mode 100644
index 0000000000..bba2ddf267
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java
@@ -0,0 +1,185 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toMap;
+
+public class VersionDaoImpl implements VersionDao {
+
+ @Override
+ public void create(SessionContext context, String space, Id itemId, VersionEntity version) {
+ String baseVersion = version.getBaseId() != null ? version.getBaseId().toString() : null;
+
+ getAccessor(context)
+ .create(space, itemId.toString(), version.getId().toString(),
+ baseVersion,
+ version.getCreationTime(), version.getModificationTime());
+
+ }
+
+ @Override
+ public void delete(SessionContext context, String space, Id itemId, Id versionId) {
+
+ getAccessor(context).delete(space, itemId.toString(), versionId.toString());
+ }
+
+ @Override
+ public void updateModificationTime(SessionContext context, String space, Id itemId,
+ Id versionId, Date modificationTime) {
+ getAccessor(context)
+ .updateModificationTime(modificationTime, space, itemId.toString(), versionId.toString());
+ }
+
+
+ @Override
+ public Collection<VersionEntity> list(SessionContext context, String space, Id itemId) {
+ List<Row> rows = getAccessor(context).list(space, itemId.toString()).all();
+ return rows == null ? new ArrayList<>() :
+ rows.stream().map(VersionDaoImpl::convertToVersionEntity).collect(Collectors.toList());
+ }
+
+
+ @Override
+ public Optional<VersionEntity> get(SessionContext context, String space, Id itemId,
+ Id versionId) {
+ Row row;
+
+ row = getAccessor(context).get(space, itemId.toString(), versionId.toString()).one();
+
+
+ return row == null ? Optional.empty() : Optional.of(convertToVersionEntity(row));
+ }
+
+ @Override
+ public boolean checkHealth(SessionContext context) {
+ return getAccessor(context).checkHealth().getColumnDefinitions()
+ .contains(VersionField.VERSION_ID);
+ }
+
+ @Override
+ public void createVersionElements(SessionContext context, String space, Id itemId,
+ Id versionId, Id revisionId, Map<Id, Id> versionElementIds,
+ Date publishTime, String message) {
+ Map<String, String> elementIds = versionElementIds==null?null:versionElementIds.
+ entrySet().
+ stream().
+ collect(toMap((Map.Entry<Id, Id>entry)->entry.getKey().getValue(),
+ (Map.Entry<Id, Id>entry)->entry.getValue().getValue()));
+
+ getVersionElementsAccessor(context).create(space,itemId.toString(),versionId.toString(),
+ revisionId.getValue(),elementIds,publishTime,message,context.getUser().getUserName());
+ }
+
+
+ private static VersionEntity convertToVersionEntity(Row row) {
+
+ /*Id revisionId = row.getColumnDefinitions().contains("revision_id")?new Id(row.getString
+ (VersionField.REVISION_ID)):null;*/
+
+ VersionEntity version = new VersionEntity(new Id(row.getString(VersionField.VERSION_ID)));
+ return enrichVersionEntity(version, row);
+ }
+
+ static VersionEntity enrichVersionEntity(VersionEntity version, Row row) {
+ version.setBaseId(new Id(row.getString(VersionField.BASE_VERSION_ID)));
+ version.setCreationTime(row.getDate(VersionField.CREATION_TIME));
+ version.setModificationTime(row.getDate(VersionField.MODIFICATION_TIME));
+ return version;
+ }
+
+ private VersionAccessor getAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, VersionAccessor.class);
+ }
+
+ private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
+ }
+
+ @Accessor
+ interface VersionAccessor {
+
+ @Query(
+ "INSERT INTO version (space, item_id, version_id, base_version_id, " +
+ "creation_time, " +
+ "modification_time) " +
+ "VALUES (?, ?, ?, ?, ?, ?)")
+ void create(String space, String itemId, String versionId, String baseVersionId,
+ Date creationTime, Date modificationTime);
+
+ @Query("UPDATE version SET modification_time=? WHERE space=? AND item_id=? AND version_id=? ")
+ void updateModificationTime(Date modificationTime, String space, String itemId,
+ String versionId);
+
+ @Query("DELETE FROM version WHERE space=? AND item_id=? AND version_id=? ")
+ void delete(String space, String itemId, String versionId);
+
+ @Query("SELECT version_id, base_version_id, creation_time, modification_time " +
+ "FROM version WHERE space=? AND item_id=? AND version_id=? ")
+ ResultSet get(String space, String itemId, String versionId);
+
+ /*@Query("SELECT version_id, base_version_id, creation_time, modification_time " +
+ "FROM version WHERE space=? AND item_id=? AND version_id=? ")
+ ResultSet get(String space, String itemId, String versionId);*/
+
+
+ @Query("SELECT version_id, base_version_id, creation_time, modification_time " +
+ "FROM version WHERE space=? AND item_id=?")
+ ResultSet list(String space, String itemId);
+
+ @Query("SELECT version_id FROM version LIMIT 1")
+ ResultSet checkHealth();
+ }
+
+ private static final class VersionField {
+ private static final String VERSION_ID = "version_id";
+ private static final String BASE_VERSION_ID = "base_version_id";
+ private static final String CREATION_TIME = "creation_time";
+ private static final String MODIFICATION_TIME = "modification_time";
+ //private static final String REVISION_ID = "revision_id";
+ }
+
+ @Accessor
+ interface VersionElementsAccessor {
+
+ @Query("INSERT INTO version_elements (space,item_id,version_id,revision_id,element_ids," +
+ "publish_time,message,user) " +
+ "VALUES (?,?,?,?,?,?,?,?)")
+ void create(String space,
+ String itemId,
+ String versionId,
+ String versionRevisionId,
+ Map<String,String> elementIds,
+ Date publishTime,
+ String message,
+ String user);
+
+
+
+ }
+
+ /* public static final class VersionElementsField {
+ private static final String SPACE = "space";
+ private static final String ITEM_ID = "item_id";
+ private static final String VERSION_ID = "version_id";
+ private static final String ELEMENT_IDS = "element_ids";
+ private static final String REVISION_ID = "revision_id";
+
+ }*/
+
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java
new file mode 100644
index 0000000000..547bf6a06c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java
@@ -0,0 +1,15 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepositoryFactory;
+
+public class VersionStageRepositoryFactoryImpl extends VersionStageRepositoryFactory {
+
+ private static final VersionStageRepository INSTANCE = new VersionStageRepositoryImpl();
+
+ @Override
+ public VersionStageRepository createInterface(SessionContext context) {
+ return INSTANCE;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java
new file mode 100644
index 0000000000..353f37b91b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java
@@ -0,0 +1,82 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Optional;
+
+public class VersionStageRepositoryImpl implements VersionStageRepository {
+
+ @Override
+ public Optional<StageEntity<VersionEntity>> get(SessionContext context,
+ VersionContext entityContext,
+ VersionEntity entity) {
+ Row row = getAccessor(context)
+ .get(entityContext.getSpace(), entityContext.getItemId().toString(),
+ entity.getId().toString()).one();
+ return row == null ? Optional.empty() : Optional.of(convertToVersionStage(entity, row));
+ }
+
+ @Override
+ public void create(SessionContext context, VersionContext entityContext,
+ StageEntity<VersionEntity> stageEntity) {
+ VersionEntity entity = stageEntity.getEntity();
+ getAccessor(context).create(entityContext.getSpace(),
+ entityContext.getItemId().toString(),
+ entity.getId().toString(),
+ entity.getBaseId() == null ? null : entity.getBaseId().toString(),
+ entity.getCreationTime() == null ? null : entity.getCreationTime(),
+ entity.getModificationTime() == null ? null : entity.getModificationTime(),
+ stageEntity.getPublishTime(),
+ stageEntity.getAction());
+ }
+
+ @Override
+ public void delete(SessionContext context, VersionContext entityContext, VersionEntity entity) {
+ getAccessor(context).delete(entityContext.getSpace(), entityContext.getItemId().toString(),
+ entity.getId().toString());
+ }
+
+ private StageEntity<VersionEntity> convertToVersionStage(VersionEntity version, Row row) {
+ StageEntity<VersionEntity> versionStage =
+ new StageEntity<>(VersionDaoImpl.enrichVersionEntity(version, row),
+ row.getDate(VersionStageField.PUBLISH_TIME));
+ versionStage.setAction(Action.valueOf(row.getString(VersionStageField.ACTION)));
+ return versionStage;
+ }
+
+ private VersionStageAccessor getAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, VersionStageAccessor.class);
+ }
+
+ @Accessor
+ interface VersionStageAccessor {
+
+ @Query("INSERT INTO version_stage (space, item_id, version_id, base_version_id, " +
+ "creation_time, modification_time, publish_time, action) " +
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
+ void create(String space, String itemId, String versionId, String baseVersionId,
+ Date creationTime, Date modificationTime, Date publishTime, Action action);
+
+ @Query("DELETE FROM version_stage WHERE space=? AND item_id=? AND version_id=?")
+ void delete(String space, String itemId, String versionId);
+
+ @Query("SELECT base_version_id, creation_time, modification_time, publish_time, action " +
+ "FROM version_stage WHERE space=? AND item_id=? AND version_id=?")
+ ResultSet get(String space, String itemId, String versionId);
+ }
+
+ private static final class VersionStageField {
+ private static final String PUBLISH_TIME = "publish_time";
+ private static final String ACTION = "action";
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java
new file mode 100644
index 0000000000..95c3ec2730
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory;
+
+public class VersionSynchronizationStateRepositoryFactoryImpl
+ extends VersionSynchronizationStateRepositoryFactory {
+
+ private static final VersionSynchronizationStateRepository INSTANCE =
+ new VersionSynchronizationStateRepositoryImpl();
+
+ @Override
+ public VersionSynchronizationStateRepository createInterface(SessionContext context) {
+ return INSTANCE;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java
new file mode 100644
index 0000000000..5fb9779bc2
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java
@@ -0,0 +1,137 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class VersionSynchronizationStateRepositoryImpl
+ implements VersionSynchronizationStateRepository {
+
+ @Override
+ public void create(SessionContext context, VersionContext entityContext,
+ SynchronizationStateEntity syncStateEntity) {
+ updatePublishTime(context, entityContext, syncStateEntity);
+ }
+
+ @Override
+ public void updatePublishTime(SessionContext context, VersionContext entityContext,
+ SynchronizationStateEntity syncStateEntity) {
+ getAccessor(context)
+ .updatePublishTime(syncStateEntity.getPublishTime(), entityContext.getSpace(),
+ entityContext.getItemId().toString(), syncStateEntity.getId().toString(),
+ syncStateEntity.getRevisionId().getValue());
+ }
+
+ @Override
+ public List<SynchronizationStateEntity> list(SessionContext context, VersionContext
+ entityContext, VersionEntity versionEntity) {
+
+ List<Row> rows = getAccessor(context).list(entityContext.getSpace(), entityContext.getItemId().toString
+ (),versionEntity.getId().toString()).all();
+ return rows == null ? new ArrayList<>():
+ rows.stream().map(VersionSynchronizationStateRepositoryImpl::getSynchronizationStateEntity).collect(Collectors.toList());
+ }
+
+
+
+ /*@Override
+ public List<SynchronizationStateEntity> listRevisions(SessionContext context,
+ VersionContext entityContext,
+ SynchronizationStateEntity syncStateEntity) {
+ List<Row> rows = getAccessor(context).list(entityContext.getSpace(), entityContext.getItemId()
+ .toString(), syncStateEntity.getId().toString()).all();
+ return rows == null ? new ArrayList<>() :rows.stream()
+ .map(VersionSynchronizationStateRepositoryImpl::getSynchronizationStateEntity)
+ .collect(Collectors.toList());
+
+
+
+
+ //forEach(row -> getSynchronizationStateEntity(syncStateEntity.getId(), row));
+
+
+ }*/
+
+
+ @Override
+ public void delete(SessionContext context, VersionContext entityContext,
+ SynchronizationStateEntity syncStateEntity) {
+ // done by version dao
+ }
+
+ @Override
+ public Optional<SynchronizationStateEntity> get(SessionContext context,
+ VersionContext entityContext,
+ SynchronizationStateEntity syncStateEntity) {
+ Row row =
+ getAccessor(context).get(entityContext.getSpace(), entityContext.getItemId().toString(),
+ syncStateEntity.getId().toString(), syncStateEntity.getRevisionId().getValue()).one();
+
+ return row == null ? Optional.empty()
+ : Optional.of(getSynchronizationStateEntity(syncStateEntity.getId(), row));
+ }
+
+ private SynchronizationStateEntity getSynchronizationStateEntity(Id entityId, Row row) {
+ SynchronizationStateEntity syncStateEntity = new SynchronizationStateEntity(entityId,
+ new Id(row.getString(REVISION_ID_FIELD)));
+ syncStateEntity.setPublishTime(row.getDate(PUBLISH_TIME_FIELD));
+ syncStateEntity.setDirty(!row.getSet(DIRTY_ELEMENT_FIELD, String.class).isEmpty());
+ return syncStateEntity;
+ }
+
+ private static SynchronizationStateEntity getSynchronizationStateEntity(Row row) {
+ Id entityId = new Id(row.getColumnDefinitions().contains("version_id") ? row.getString
+ ("version_id") : row.getString("element_id"));
+ SynchronizationStateEntity syncStateEntity = new SynchronizationStateEntity(entityId,
+ new Id(row.getString(REVISION_ID_FIELD)));
+ syncStateEntity.setPublishTime(row.getDate(PUBLISH_TIME_FIELD));
+ syncStateEntity.setDirty(!row.getSet(DIRTY_ELEMENT_FIELD, String.class).isEmpty());
+ syncStateEntity.setRevisionId(new Id(row.getString(REVISION_ID_FIELD)));
+ syncStateEntity.setUser(row.getString(USER));
+ syncStateEntity.setMessage(row.getString(MESSAGE));
+ return syncStateEntity;
+ }
+
+ private VersionSyncStateAccessor getAccessor(SessionContext context) {
+ return CassandraDaoUtils.getAccessor(context, VersionSyncStateAccessor.class);
+ }
+
+ @Accessor
+ interface VersionSyncStateAccessor {
+ @Query(
+ "UPDATE version_elements SET publish_time=? WHERE space=? AND item_id=? AND version_id=? " +
+ "AND revision_id=? ")
+ void updatePublishTime(Date publishTime, String space, String itemId, String versionId, String
+ revisionId);
+
+ @Query("SELECT version_id,revision_id,publish_time, dirty_element_ids FROM version_elements " +
+ "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+ ResultSet get(String space, String itemId, String versionId, String revisionId);
+
+ @Query("SELECT version_id,revision_id,publish_time,user,message, dirty_element_ids FROM " +
+ "version_elements " +
+ "WHERE space=? AND item_id=? AND version_id=? ")
+ ResultSet list(String space, String itemId, String versionId);
+
+ }
+
+
+ private static final String PUBLISH_TIME_FIELD = "publish_time";
+ private static final String DIRTY_ELEMENT_FIELD = "dirty_element_ids";
+ private static final String REVISION_ID_FIELD = "revision_id";
+ private static final String USER = "user";
+ private static final String MESSAGE = "message";
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java
index 1663d83427..1cd15102f2 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java
@@ -30,6 +30,7 @@ public class ElementEntity {
private Id id;
private Id parentId;
private Namespace namespace;
+ private Id elementHash;
private Info info;
private Collection<Relation> relations = Collections.emptyList();
private ByteBuffer data;
@@ -41,6 +42,10 @@ public class ElementEntity {
this.id = id;
}
+ public Id getId() {
+ return id;
+ }
+
public Id getParentId() {
return parentId;
}
@@ -49,14 +54,6 @@ public class ElementEntity {
this.parentId = parentId;
}
- public Id getId() {
- return id;
- }
-
- public void setId(Id id) {
- this.id = id;
- }
-
public Namespace getNamespace() {
return namespace;
}
@@ -127,8 +124,17 @@ public class ElementEntity {
return id.equals(that.id);
}
+ public Id getElementHash() {
+ return elementHash;
+ }
+
+ public void setElementHash(Id elementHash) {
+ this.elementHash = elementHash;
+ }
+
@Override
public int hashCode() {
return id.hashCode();
}
+
}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java
new file mode 100644
index 0000000000..58ac0a918a
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java
@@ -0,0 +1,60 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.item.Action;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.Set;
+
+public class StageEntity<E> {
+ private E entity;
+ private Date publishTime;
+ private Action action = Action.IGNORE;
+ private boolean conflicted;
+ private Set<E> conflictDependents = Collections.emptySet();
+
+ // used by sync on stage creation
+ public StageEntity(E entity, Date publishTime) {
+ this.entity = entity;
+ this.publishTime = publishTime;
+ }
+
+ public StageEntity(E entity, Date publishTime, Action action, boolean conflicted) {
+ this.entity = entity;
+ this.publishTime = publishTime;
+ this.action = action;
+ this.conflicted = conflicted;
+ }
+
+ public E getEntity() {
+ return entity;
+ }
+
+ public Date getPublishTime() {
+ return publishTime;
+ }
+
+ public Action getAction() {
+ return action;
+ }
+
+ public void setAction(Action action) {
+ this.action = action;
+ }
+
+ public boolean isConflicted() {
+ return conflicted;
+ }
+
+ public void setConflicted(boolean conflicted) {
+ this.conflicted = conflicted;
+ }
+
+ public Set<E> getConflictDependents() {
+ return conflictDependents;
+ }
+
+ public void setConflictDependents(Set<E> conflictDependents) {
+ this.conflictDependents = conflictDependents;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java
new file mode 100644
index 0000000000..510cef820b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+
+import java.util.Date;
+
+/**
+ * Synchronization state of an entity:
+ * <ul>
+ * <li>On private entity edit (create/update/delete): marked as dirty</li>
+ * <li>On entity publication:
+ * <ul>
+ * <li>if the private entity exists - updated with the publish time, marked as not dirty</li>
+ * <li>Otherwise - deleted</li>
+ * </ul>
+ * </li>
+ * </ul>
+ */
+public class SynchronizationStateEntity {
+ private Id id;
+ private Id revisionId;
+ private Date publishTime;
+ private boolean dirty;
+ private String user;
+ private String message;
+
+ public SynchronizationStateEntity(Id id,Id revisionId) {
+ this.id = id;
+ this.revisionId = revisionId;
+ }
+
+ public SynchronizationStateEntity(Id id,Id revisionId, Date publishTime, boolean dirty) {
+ this(id,revisionId);
+ this.publishTime = publishTime;
+ this.dirty = dirty;
+ }
+
+ public Id getId() {
+ return id;
+ }
+
+ public Date getPublishTime() {
+ return publishTime;
+ }
+
+ public void setPublishTime(Date publishTime) {
+ this.publishTime = publishTime;
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ public Id getRevisionId() {
+ return revisionId;
+ }
+
+ public void setRevisionId(Id revisionId) {
+ this.revisionId = revisionId;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ SynchronizationStateEntity that = (SynchronizationStateEntity) o;
+
+ return id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java
new file mode 100644
index 0000000000..41a3e66e0e
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java
@@ -0,0 +1,23 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+
+public class VersionContext {
+ private String space;
+ private Id itemId;
+
+
+ public VersionContext(String space, Id itemId) {
+ this.space = space;
+ this.itemId = itemId;
+ }
+
+ public String getSpace() {
+ return space;
+ }
+
+ public Id getItemId() {
+ return itemId;
+ }
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java
new file mode 100644
index 0000000000..48a52c0d85
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java
@@ -0,0 +1,21 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.calculateElementHash;
+
+public class VersionDataElement extends ElementEntity {
+
+ public VersionDataElement() {
+ super(ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID);
+ }
+
+ public VersionDataElement(ItemVersionData itemVersionData) {
+ this();
+ setInfo(itemVersionData.getInfo());
+ setRelations(itemVersionData.getRelations());
+ setElementHash(new Id(calculateElementHash(this)));
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java
new file mode 100644
index 0000000000..aeed998d96
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java
@@ -0,0 +1,45 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+
+import java.util.Date;
+
+public class VersionEntity {
+ private Id id;
+ private Id baseId;
+ private Date creationTime;
+ private Date modificationTime;
+
+ public VersionEntity(Id id) {
+ this.id = id;
+ }
+
+ public Id getId() {
+ return id;
+ }
+
+ public Id getBaseId() {
+ return baseId;
+ }
+
+ public void setBaseId(Id baseId) {
+ this.baseId = baseId;
+ }
+
+ public Date getCreationTime() {
+ return creationTime;
+ }
+
+ public void setCreationTime(Date creationTime) {
+ this.creationTime = creationTime;
+ }
+
+ public Date getModificationTime() {
+ return modificationTime;
+ }
+
+ public void setModificationTime(Date modificationTime) {
+ this.modificationTime = modificationTime;
+ }
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java
index 90fd3366fe..f9b65224e0 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java
@@ -21,97 +21,302 @@ import com.amdocs.zusammen.commons.health.data.HealthStatus;
import com.amdocs.zusammen.datatypes.Id;
import com.amdocs.zusammen.datatypes.Namespace;
import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.item.Action;
import com.amdocs.zusammen.datatypes.item.ElementContext;
import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
import com.amdocs.zusammen.datatypes.item.ItemVersionData;
-import com.amdocs.zusammen.datatypes.itemversion.ItemVersionHistory;
+import com.amdocs.zusammen.datatypes.item.ItemVersionDataConflict;
+import com.amdocs.zusammen.datatypes.item.ItemVersionStatus;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
+import com.amdocs.zusammen.datatypes.itemversion.Revision;
import com.amdocs.zusammen.datatypes.itemversion.Tag;
+import com.amdocs.zusammen.datatypes.response.ErrorCode;
+import com.amdocs.zusammen.datatypes.response.Module;
import com.amdocs.zusammen.datatypes.response.Response;
+import com.amdocs.zusammen.datatypes.response.ReturnCode;
import com.amdocs.zusammen.datatypes.response.ZusammenException;
import com.amdocs.zusammen.sdk.collaboration.CollaborationStore;
import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElement;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementConflict;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationItemVersionConflict;
import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeResult;
import com.amdocs.zusammen.sdk.collaboration.types.CollaborationPublishResult;
-import org.openecomp.core.zusammen.plugin.collaboration.ElementCollaborationStore;
-import org.openecomp.core.zusammen.plugin.collaboration.VersionCollaborationStore;
+import com.amdocs.zusammen.sdk.types.ElementConflictDescriptor;
+import com.amdocs.zusammen.sdk.types.ElementDescriptor;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
+import org.openecomp.core.zusammen.plugin.collaboration.CommitStagingService;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPrivateStore;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPublicStore;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementStageStore;
+import org.openecomp.core.zusammen.plugin.collaboration.PublishService;
+import org.openecomp.core.zusammen.plugin.collaboration.RevertService;
+import org.openecomp.core.zusammen.plugin.collaboration.SyncService;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPrivateStore;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPublicStore;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionStageStore;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementPrivateStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementPublicStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementStageStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.VersionPrivateStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.VersionPublicStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.VersionStageStoreImpl;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionDataElement;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static com.amdocs.zusammen.datatypes.item.SynchronizationStatus.MERGING;
+import static com.amdocs.zusammen.datatypes.item.SynchronizationStatus.OUT_OF_SYNC;
+import static com.amdocs.zusammen.datatypes.item.SynchronizationStatus.UP_TO_DATE;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToCollaborationElement;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementChange;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementDescriptor;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementEntity;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToItemVersion;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionData;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionEntity;
public class CassandraCollaborationStorePluginImpl implements CollaborationStore {
+ // TODO: 8/15/2017 inject
+
+ private VersionPrivateStore versionPrivateStore = new VersionPrivateStoreImpl();
+ private VersionPublicStore versionPublicStore = new VersionPublicStoreImpl();
+ private VersionStageStore versionStageStore = new VersionStageStoreImpl();
+
+ private ElementPrivateStore elementPrivateStore = new ElementPrivateStoreImpl();
+ private ElementPublicStore elementPublicStore = new ElementPublicStoreImpl();
+ private ElementStageStore elementStageStore = new ElementStageStoreImpl();
- private VersionCollaborationStore versionCollaborationStore = new VersionCollaborationStore();
- private ElementCollaborationStore elementCollaborationStore = new ElementCollaborationStore();
+ // TODO: 9/4/2017
+ private CommitStagingService commitStagingService =
+ new CommitStagingService(versionPrivateStore, versionStageStore, elementPrivateStore,
+ elementStageStore);
+ private PublishService publishService =
+ new PublishService(versionPublicStore, versionPrivateStore, elementPublicStore,
+ elementPrivateStore);
+ private SyncService syncService =
+ new SyncService(versionPublicStore, versionPrivateStore, versionStageStore,
+ elementPublicStore, elementPrivateStore, elementStageStore);
+
+ private RevertService revertService =
+ new RevertService(elementPublicStore, elementPrivateStore);
@Override
- public Response<Void> createItem(SessionContext context, Id id, Info info) {
+ public Response<Void> createItem(SessionContext context, Id itemId, Info info) {
// done by state store
return new Response(Void.TYPE);
}
@Override
- public Response<Void> deleteItem(SessionContext context, Id id) {
+ public Response<Void> deleteItem(SessionContext context, Id itemId) {
// done by state store
return new Response(Void.TYPE);
}
@Override
- public Response<Void> createItemVersion(SessionContext context, Id itemId, Id versionId, Id id2,
- ItemVersionData itemVersionData) {
- // done by state store
+ public Response<Void> createItemVersion(SessionContext context, Id itemId, Id baseVersionId,
+ Id versionId, ItemVersionData itemVersionData) {
+ Date creationTime = new Date();
+ versionPrivateStore.create(context, itemId,
+ convertToVersionEntity(versionId, baseVersionId, creationTime, creationTime));
+
+ ElementContext elementContext = new ElementContext(itemId, versionId);
+ VersionDataElement versionData = new VersionDataElement(itemVersionData);
+
+ if (baseVersionId == null) {
+ elementPrivateStore.create(context, elementContext, versionData);
+ } else {
+ copyElements(context, new ElementContext(itemId, baseVersionId), elementContext);
+ elementPrivateStore.update(context, elementContext, versionData);
+ }
+
return new Response(Void.TYPE);
}
@Override
public Response<Void> updateItemVersion(SessionContext context, Id itemId, Id versionId,
ItemVersionData itemVersionData) {
- // done by state store
+
+ if (elementPrivateStore.update(context, new ElementContext(itemId, versionId),
+ new VersionDataElement(itemVersionData))) {
+
+ VersionEntity version = new VersionEntity(versionId);
+ version.setModificationTime(new Date());
+ versionPrivateStore.update(context, itemId, version);
+ }
+
return new Response(Void.TYPE);
}
@Override
public Response<Void> deleteItemVersion(SessionContext context, Id itemId, Id versionId) {
- // done by state store
+ elementPrivateStore
+ .delete(context, new ElementContext(itemId, versionId), new VersionDataElement());
+
+ versionPrivateStore.delete(context, itemId, new VersionEntity(versionId));
return new Response(Void.TYPE);
}
@Override
- public Response<Void> tagItemVersion(SessionContext context, Id itemId, Id versionId, Id changeId,
+ public Response<ItemVersionStatus> getItemVersionStatus(SessionContext context, Id itemId,
+ Id versionId) {
+ if (versionStageStore.get(context, itemId, new VersionEntity(versionId)).isPresent()) {
+ return new Response<>(new ItemVersionStatus(MERGING, true));
+ }
+
+ Optional<SynchronizationStateEntity> publicSyncState =
+ versionPublicStore.getSynchronizationState(context, itemId, versionId);
+
+ if (!publicSyncState.isPresent()) {
+ return new Response<>(new ItemVersionStatus(UP_TO_DATE, true));
+ }
+
+ SynchronizationStateEntity privateSyncState =
+ versionPrivateStore.getSynchronizationState(context, itemId, versionId)
+ // TODO: 7/18/2017 ?
+ .orElseThrow(() -> new IllegalStateException("private version must exist"));
+
+ return new Response<>(new ItemVersionStatus(
+ privateSyncState.getPublishTime().equals(publicSyncState.get().getPublishTime())
+ ? UP_TO_DATE
+ : OUT_OF_SYNC,
+ privateSyncState.isDirty()));
+ }
+
+ @Override
+ public Response<Void> tagItemVersion(SessionContext context, Id itemId, Id versionId,
+ Id revisionId,
Tag tag) {
- versionCollaborationStore.tagItemVersion(context, itemId, versionId, changeId, tag);
+ /* if (revisionId != null) {
+ throw new UnsupportedOperationException(
+ "In this plugin implementation tag is supported only on versionId");
+ }
+
+ copyElements(context,
+ new ElementContext(itemId, versionId),
+ new ElementContext(itemId, versionId, tag.getName()));*/
+
return new Response(Void.TYPE);
}
@Override
public Response<CollaborationPublishResult> publishItemVersion(SessionContext context,
Id itemId, Id versionId,
- String s) {
- throw new UnsupportedOperationException("publishItemVersion");
+ String message) {
+ try {
+ return new Response<>(publishService.publish(context, itemId, versionId, message));
+ } catch (ZusammenException ze) {
+ return new Response<>(
+ new ReturnCode(ErrorCode.CL_ITEM_VERSION_PUBLISH, Module.ZCSP, null, ze.getReturnCode()));
+ }
+ }
+
+ @Override
+ public Response<CollaborationMergeResult> syncItemVersion(SessionContext context, Id itemId,
+ Id versionId) {
+ CollaborationMergeResult result = syncService.sync(context, itemId, versionId, false);
+ commitStagingService.commitStaging(context, itemId, versionId);
+
+ return new Response<>(result);
}
@Override
- public Response<CollaborationMergeResult> syncItemVersion(SessionContext context, Id id,
- Id id1) {
- throw new UnsupportedOperationException("syncItemVersion");
+ public Response<CollaborationMergeResult> forceSyncItemVersion(SessionContext context, Id itemId,
+ Id versionId) {
+ CollaborationMergeResult result = syncService.sync(context, itemId, versionId, true);
+ commitStagingService.commitStaging(context, itemId, versionId);
+
+ return new Response<>(result);
}
@Override
- public Response<CollaborationMergeResult> mergeItemVersion(SessionContext context, Id id,
- Id id1, Id id2) {
+ public Response<CollaborationMergeResult> mergeItemVersion(SessionContext context, Id itemId,
+ Id versionId, Id sourceVersionId) {
throw new UnsupportedOperationException("mergeItemVersion");
}
@Override
- public Response<ItemVersionHistory> listItemVersionHistory(SessionContext context, Id id,
- Id id1) {
- throw new UnsupportedOperationException("listItemVersionHistory");
+ public Response<CollaborationItemVersionConflict> getItemVersionConflict(SessionContext context,
+ Id itemId,
+ Id versionId) {
+ ElementContext elementContext = new ElementContext(itemId, versionId, Id.ZERO);
+
+ Collection<StageEntity<ElementEntity>> conflictedStagedElementDescriptors =
+ elementStageStore.listConflictedDescriptors(context, elementContext);
+
+ CollaborationItemVersionConflict result = new CollaborationItemVersionConflict();
+ for (StageEntity<ElementEntity> stagedElementDescriptor : conflictedStagedElementDescriptors) {
+ if (ROOT_ELEMENTS_PARENT_ID.equals(stagedElementDescriptor.getEntity().getId())) {
+ result.setVersionDataConflict(
+ getVersionDataConflict(context, elementContext, stagedElementDescriptor));
+ } else {
+ result.getElementConflictDescriptors()
+ .add(getElementConflictDescriptor(context, elementContext, stagedElementDescriptor));
+ }
+ }
+ return new Response<>(result);
+ }
+
+ @Override
+ public Response<ItemVersionRevisions> listItemVersionRevisions(SessionContext context, Id itemId,
+ Id versionId) {
+ return new Response<>(versionPublicStore.listItemVersionRevisions(context, itemId, versionId));
}
@Override
- public Response<CollaborationMergeChange> resetItemVersionHistory(SessionContext context,
- Id itemId, Id versionId,
- String changeRef) {
- return new Response<>(versionCollaborationStore.resetItemVersionHistory(context, itemId, versionId, changeRef));
+ public Response<Revision> getItemVersionRevision(SessionContext context, Id itemId, Id versionId,
+ Id revisionId) {
+ throw new UnsupportedOperationException(
+ "get revision is not supported in the current cassandra plugin");
+ }
+
+ @Override
+ public Response<CollaborationMergeChange> resetItemVersionRevision(SessionContext context,
+ Id itemId, Id versionId,
+ Id revisionId) {
+ throw new UnsupportedOperationException("resetItemVersionRevision function not supported");
+
+ }
+
+ @Override
+ public Response<CollaborationMergeChange> revertItemVersionRevision(SessionContext context,
+ Id itemId, Id versionId,
+ Id revisionId) {
+ Optional<ItemVersion> itemVersion = getItemVersion(context, itemId, versionId, revisionId);
+ if (!itemVersion.isPresent()) {
+ throw new RuntimeException(String
+ .format("Item %s, version %s: Cannot revert to revision %s since it is not found",
+ itemId, versionId, revisionId));
+ }
+
+ // TODO: 12/4/2017 force sync is done in order to clear dirty element on private
+ // this is temp solution that should be fixed.
+ forceSyncItemVersion(context, itemId, versionId);
+
+ //updateItemVersion(context, itemId, versionId, itemVersion.get().getData());
+ revertService.revert(context, itemId, versionId, revisionId);
+
+ return new Response<>(new CollaborationMergeChange());
+ }
+
+
+ @Override
+ public Response<Void> commitElements(SessionContext context, Id itemId, Id versionId, String s) {
+ // not needed
+ return new Response(Void.TYPE);
}
@Override
@@ -119,52 +324,198 @@ public class CassandraCollaborationStorePluginImpl implements CollaborationStore
ElementContext elementContext,
Namespace namespace,
Id elementId) {
- return new Response<>(
- elementCollaborationStore.listElements(context, elementContext, elementId));
+ return new Response<>(elementPrivateStore.listSubs(context, elementContext, elementId).stream()
+ .map(elementEntity -> convertToCollaborationElement(elementContext, elementEntity))
+ .collect(Collectors.toList()));
}
@Override
public Response<CollaborationElement> getElement(SessionContext context,
ElementContext elementContext,
Namespace namespace, Id elementId) {
- return new Response<>(elementCollaborationStore.getElement(context, elementContext, elementId));
+ return new Response<>(elementPrivateStore.get(context, elementContext, elementId)
+ .map(elementEntity -> convertToCollaborationElement(elementContext, elementEntity))
+ .orElse(null));
+ }
+
+ @Override
+ public Response<CollaborationElementConflict> getElementConflict(SessionContext context,
+ ElementContext elementContext,
+ Namespace namespace,
+ Id elementId) {
+ Optional<StageEntity<ElementEntity>> conflictedStagedElement =
+ elementStageStore
+ .getConflicted(context, elementContext, new ElementEntity(elementId));
+
+ return new Response<>(conflictedStagedElement
+ .map(stagedElement -> getElementConflict(context, elementContext, stagedElement))
+ .orElse(null));
}
@Override
public Response<Void> createElement(SessionContext context, CollaborationElement element) {
- elementCollaborationStore.createElement(context, element);
+ elementPrivateStore.create(context,
+ new ElementContext(element.getItemId(), element.getVersionId()),
+ convertToElementEntity(element));
return new Response(Void.TYPE);
}
@Override
public Response<Void> updateElement(SessionContext context, CollaborationElement element) {
- elementCollaborationStore.updateElement(context, element);
+ elementPrivateStore.update(context,
+ new ElementContext(element.getItemId(), element.getVersionId()),
+ convertToElementEntity(element));
return new Response(Void.TYPE);
}
@Override
public Response<Void> deleteElement(SessionContext context, CollaborationElement element) {
- elementCollaborationStore.deleteElement(context, element);
+ elementPrivateStore
+ .delete(context, new ElementContext(element.getItemId(), element.getVersionId()),
+ convertToElementEntity(element));
+
return new Response(Void.TYPE);
}
@Override
- public Response<Void> commitElements(SessionContext context, Id itemId, Id versionId, String s) {
- // not needed
- return new Response(Void.TYPE);
+ public Response<CollaborationMergeResult> resolveElementConflict(SessionContext context,
+ CollaborationElement element,
+ Resolution resolution) {
+ ElementContext elementContext = new ElementContext(element.getItemId(), element.getVersionId());
+ elementStageStore
+ .resolveConflict(context, elementContext, convertToElementEntity(element), resolution);
+ commitStagingService.commitStaging(context, element.getItemId(), element.getVersionId());
+
+ return new Response<>(new CollaborationMergeResult());
}
@Override
- public Response<HealthInfo> checkHealth(SessionContext sessionContext) throws ZusammenException {
+ public Response<ItemVersion> getItemVersion(SessionContext context, Space space, Id itemId,
+ Id versionId, Id revisionId) {
+ return new Response<>(getItemVersion(context, itemId, versionId, revisionId).orElse(null));
+ }
- boolean health = elementCollaborationStore.checkHealth(sessionContext);
- HealthInfo healthInfo ;
- if (health){
- healthInfo = new HealthInfo("Collaboration", HealthStatus.UP,"");
- } else {
- healthInfo = new HealthInfo("Collaboration", HealthStatus.DOWN,"No Schema Available");
+ @Override
+ public Response<HealthInfo> checkHealth(SessionContext context) throws ZusammenException {
+ HealthInfo healthInfo = versionPublicStore.checkHealth(context)
+ ? new HealthInfo(Module.ZCSP.getDescription(), HealthStatus.UP, "")
+ : new HealthInfo(Module.ZCSP.getDescription(), HealthStatus.DOWN, "No Schema Available");
+
+ return new Response<>(healthInfo);
+ }
+
+ private Optional<ItemVersion> getItemVersion(SessionContext context, Id itemId, Id versionId,
+ Id revisionId) {
+ // since revisions are kept only on public - get from there
+ Optional<VersionEntity> versionEntity = versionPublicStore.get(context, itemId, versionId);
+ if (!versionEntity.isPresent()) {
+ return Optional.empty();
+ }
+
+ return elementPublicStore
+ .getDescriptor(context, new ElementContext(itemId, versionId, revisionId),
+ ROOT_ELEMENTS_PARENT_ID)
+ .map(ZusammenPluginUtil::convertToVersionData)
+ .map(itemVersionData -> convertToItemVersion(versionEntity.get(), itemVersionData));
+ }
+
+ private List<ElementEntity> listVersionElements(SessionContext context,
+ ElementContext elementContext) {
+ return elementPrivateStore.listIds(context, elementContext).entrySet().stream() // TODO:
+ // 9/5/2017 parallel
+ .map(entry -> elementPrivateStore.get(context, elementContext, entry.getKey()).get())
+ .collect(Collectors.toList());
+ }
+
+ private void copyElements(SessionContext context,
+ ElementContext sourceContext, ElementContext targetContext) {
+ listVersionElements(context, sourceContext).forEach(element -> {
+ // publishTime copied as is and dirty is off
+ Date publishTime =
+ elementPrivateStore.getSynchronizationState(context, sourceContext, element.getId())
+ .get().getPublishTime();
+ elementPrivateStore.commitStagedCreate(context, targetContext, element, publishTime);
+ });
+ }
+
+ private ItemVersionDataConflict getVersionDataConflict(SessionContext context,
+ ElementContext elementContext,
+ StageEntity<ElementEntity> stagedElementDescriptor) {
+ ItemVersionDataConflict versionConflict = new ItemVersionDataConflict();
+ versionConflict.setRemoteData(convertToVersionData(stagedElementDescriptor.getEntity()));
+ if (stagedElementDescriptor.getAction() == Action.UPDATE) {
+ versionConflict.setLocalData(getPrivateVersionData(context, elementContext));
}
- return new Response<HealthInfo>(healthInfo);
+ return versionConflict;
+ }
+ private ItemVersionData getPrivateVersionData(SessionContext context,
+ ElementContext elementContext) {
+ return elementPrivateStore.getDescriptor(context, elementContext, ROOT_ELEMENTS_PARENT_ID)
+ .map(ZusammenPluginUtil::convertToVersionData)
+ .orElseThrow(() -> new IllegalStateException("Version must have data"));
+ }
+
+ private ElementConflictDescriptor getElementConflictDescriptor(SessionContext context,
+ ElementContext elementContext,
+ StageEntity<ElementEntity> stagedElementDescriptor) {
+ ElementDescriptor elementDescriptorFromStage =
+ convertToElementDescriptor(elementContext, (stagedElementDescriptor.getEntity()));
+
+ ElementConflictDescriptor conflictDescriptor = new ElementConflictDescriptor();
+ switch (stagedElementDescriptor.getAction()) {
+ case CREATE:
+ conflictDescriptor.setRemoteElementDescriptor(elementDescriptorFromStage);
+ break;
+ case UPDATE:
+ conflictDescriptor.setRemoteElementDescriptor(elementDescriptorFromStage);
+ conflictDescriptor.setLocalElementDescriptor(convertToElementDescriptor(elementContext,
+ elementPrivateStore
+ .getDescriptor(context, elementContext, stagedElementDescriptor.getEntity().getId())
+ .orElse(null)));// updated on public while deleted from private
+ break;
+ case DELETE:
+ conflictDescriptor.setLocalElementDescriptor(elementDescriptorFromStage);
+ break;
+ default:
+ break;
+ }
+ return conflictDescriptor;
+ }
+
+ private void addElementsToChangedElements(ElementContext elementContext,
+ Collection<ElementEntity> elements,
+ Collection<CollaborationElementChange> changedElements,
+ Action action) {
+ elements.stream()
+ .map(elementEntity -> convertToElementChange(elementContext, elementEntity, action))
+ .forEach(changedElements::add);
+ }
+
+ private CollaborationElementConflict getElementConflict(SessionContext context,
+ ElementContext entityContext,
+ StageEntity<ElementEntity> stagedElement) {
+ CollaborationElement elementFromStage =
+ convertToCollaborationElement(entityContext, (stagedElement.getEntity()));
+
+ CollaborationElementConflict conflict = new CollaborationElementConflict();
+ switch (stagedElement.getAction()) {
+ case CREATE:
+ conflict.setRemoteElement(elementFromStage);
+ break;
+ case UPDATE:
+ conflict.setRemoteElement(elementFromStage);
+ conflict.setLocalElement(
+ elementPrivateStore.get(context, entityContext, stagedElement.getEntity().getId())
+ .map(element -> convertToCollaborationElement(entityContext, element))
+ .orElse(null));// updated on public while deleted from private
+ break;
+ case DELETE:
+ conflict.setLocalElement(elementFromStage);
+ break;
+ default:
+ break;
+ }
+ return conflict;
}
} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java
index b4767b2872..3ed668e331 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java
@@ -17,18 +17,87 @@
package org.openecomp.core.zusammen.plugin.main;
+import com.amdocs.zusammen.datatypes.Id;
import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
import com.amdocs.zusammen.datatypes.response.Response;
import com.amdocs.zusammen.plugin.statestore.cassandra.StateStoreImpl;
import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
import com.amdocs.zusammen.sdk.state.types.StateElement;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPrivateStore;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementPrivateStoreImpl;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionDataElement;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+import java.util.Collection;
+import java.util.Date;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToItemVersion;
import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
public class CassandraStateStorePluginImpl extends StateStoreImpl {
+ private ElementPrivateStore elementPrivateStore = new ElementPrivateStoreImpl();
+
+ @Override
+ public Response<Collection<ItemVersion>> listItemVersions(SessionContext context, Space space,
+ Id itemId) {
+ String spaceName = getSpaceName(context, space);
+ return new Response<>(getVersionDao(context).list(context, spaceName, itemId).stream()
+ .map(versionEntity -> getItemVersion(context, spaceName, itemId, versionEntity))
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public Response<Boolean> isItemVersionExist(SessionContext context, Space space, Id itemId,
+ Id versionId) {
+ return new Response<>(
+ getVersionDao(context).get(context, getSpaceName(context, space), itemId, versionId)
+ .isPresent());
+ }
+
+ @Override
+ public Response<ItemVersion> getItemVersion(SessionContext context, Space space, Id itemId,
+ Id versionId) {
+ String spaceName = getSpaceName(context, space);
+ return new Response<>(getVersionDao(context).get(context, spaceName, itemId, versionId)
+ .map(versionEntity -> getItemVersion(context, spaceName, itemId, versionEntity))
+ .orElse(null));
+ }
+
+ @Override
+ public Response<Void> createItemVersion(SessionContext context, Space space, Id itemId,
+ Id baseVersionId, Id versionId, ItemVersionData data,
+ Date creationTime) {
+ // done by collaboration store
+ return new Response(Void.TYPE);
+ }
+
+ @Override
+ public Response<Void> updateItemVersion(SessionContext context, Space space, Id itemId,
+ Id versionId, ItemVersionData data,
+ Date modificationTime) {
+ // done by collaboration store
+ return new Response(Void.TYPE);
+ }
+
+ @Override
+ public Response<Void> deleteItemVersion(SessionContext context, Space space, Id itemId,
+ Id versionId) {
+ // done by collaboration store
+ return new Response(Void.TYPE);
+ }
+
@Override
public Response<Void> createElement(SessionContext context, StateElement element) {
ElementEntity elementEntity = new ElementEntity(element.getId());
@@ -37,8 +106,7 @@ public class CassandraStateStorePluginImpl extends StateStoreImpl {
ElementRepositoryFactory.getInstance().createInterface(context)
.createNamespace(context,
new ElementEntityContext(getSpaceName(context, element.getSpace()),
- element.getItemId(), element.getVersionId()),
- elementEntity);
+ element.getItemId(), element.getVersionId()), elementEntity);
// create element is done by collaboration store
return new Response(Void.TYPE);
}
@@ -55,4 +123,46 @@ public class CassandraStateStorePluginImpl extends StateStoreImpl {
return new Response(Void.TYPE);
}
+ @Override
+ public Response<Collection<StateElement>> listElements(SessionContext context,
+ ElementContext elementContext,
+ Id elementId) {
+ return new Response(elementPrivateStore.listSubs(context, elementContext, elementId).stream()
+ .map(elementEntity -> ZusammenPluginUtil.getStateElement(elementContext, elementEntity))
+ .collect(Collectors.toList()));
+
+ }
+
+ @Override
+ public Response<StateElement> getElement(SessionContext context, ElementContext elementContext,
+ Id elementId) {
+
+ return new Response(elementPrivateStore.get(context, elementContext, elementId)
+ .map(elementEntity -> ZusammenPluginUtil
+ .getStateElement(elementContext, elementEntity))
+ .orElse
+ (null));
+
+
+ }
+
+ private ItemVersion getItemVersion(SessionContext context, String spaceName, Id itemId,
+ VersionEntity versionEntity) {
+
+ ItemVersionData itemVersionData = getElementRepository(context)
+ .get(context, new ElementEntityContext(spaceName, itemId, versionEntity.getId(), null),
+ new VersionDataElement())
+ .map(ZusammenPluginUtil::convertToVersionData)
+ .orElseThrow(() -> new IllegalStateException("Version must have data"));
+
+ return convertToItemVersion(versionEntity, itemVersionData);
+ }
+
+ protected VersionDao getVersionDao(SessionContext context) {
+ return VersionDaoFactory.getInstance().createInterface(context);
+ }
+
+ protected ElementRepository getElementRepository(SessionContext context) {
+ return ElementRepositoryFactory.getInstance().createInterface(context);
+ }
}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json
index cd1e293b4b..841e005709 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json
@@ -1,3 +1,8 @@
{
- "org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.CassandraElementRepositoryFactory"
+ "org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.VersionDaoFactoryImpl",
+ "org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.ElementRepositoryFactoryImpl",
+ "org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.VersionSynchronizationStateRepositoryFactoryImpl",
+ "org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.ElementSynchronizationStateRepositoryFactoryImpl",
+ "org.openecomp.core.zusammen.plugin.dao.VersionStageRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.VersionStageRepositoryFactoryImpl",
+ "org.openecomp.core.zusammen.plugin.dao.ElementStageRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.ElementStageRepositoryFactoryImpl"
} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java
new file mode 100644
index 0000000000..79e918c808
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.UserInfo;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.Relation;
+
+import java.util.Arrays;
+
+public class TestUtils {
+
+ public static SessionContext createSessionContext(UserInfo user, String tenant) {
+ SessionContext context = new SessionContext();
+ context.setUser(user);
+ context.setTenant(tenant);
+ return context;
+ }
+
+ public static ElementContext createElementContext(Id itemId, Id versionId) {
+ ElementContext elementContext = new ElementContext();
+ elementContext.setItemId(itemId);
+ elementContext.setVersionId(versionId);
+ return elementContext;
+ }
+
+ public static Info createInfo(String value) {
+ Info info = new Info();
+ info.setName(value);
+ info.addProperty("Name", "name_" + value);
+ info.addProperty("Desc", "desc_" + value);
+ return info;
+ }
+
+ public static ItemVersion createItemVersion(Id id, Id baseId, String name, boolean dirty) {
+ ItemVersion version = new ItemVersion();
+ version.setId(id);
+ version.setBaseId(baseId);
+ ItemVersionData data = new ItemVersionData();
+ data.setInfo(TestUtils.createInfo(name));
+ data.setRelations(Arrays.asList(new Relation(), new Relation()));
+ version.setData(data);
+ return version;
+ }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java
new file mode 100644
index 0000000000..4c4621e98b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java
@@ -0,0 +1,237 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+public class VersionCollaborationStoreTest {/*
+ private static final String TENANT = "test";
+ private static final String USER = "ItemStateStoreTest_user";
+ private static final SessionContext context =
+ TestUtils.createSessionContext(new UserInfo(USER), TENANT);
+
+ @Mock
+ private VersionDao versionDaoMock;
+ @Mock
+ private ElementStore elementCollaborationStore;
+ @Spy
+ @InjectMocks
+ private VersionStore versionCollaborationStore;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(versionCollaborationStore.getVersionDao(anyObject())).thenReturn(versionDaoMock);
+ }
+*//*
+ @Test
+ public void testListPrivateItemVersions() throws Exception {
+ testListItemVersions(Space.PRIVATE, USER);
+ }
+
+ @Test
+ public void testListPublicItemVersions() throws Exception {
+ testListItemVersions(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+ }
+
+ @Test
+ public void testIsPrivateItemVersionExist() throws Exception {
+ testIsItemVersionExist(Space.PRIVATE, USER);
+ }
+
+ @Test
+ public void testIsPublicItemVersionExist() throws Exception {
+ testIsItemVersionExist(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+ }
+
+ @Test
+ public void testIsItemVersionExistWhenNot() throws Exception {
+ Id itemId = new Id();
+ Id versionId = new Id();
+ doReturn(Optional.empty()).when(versionDaoMock).get(context, USER, itemId, versionId);
+
+ boolean itemExist =
+ versionCollaborationStore.isItemVersionExist(context, Space.PRIVATE, itemId, versionId);
+ Assert.assertFalse(itemExist);
+ }
+
+ @Test
+ public void testGetPrivateItemVersion() throws Exception {
+ testGetItemVersion(Space.PRIVATE, USER);
+ }
+
+ @Test
+ public void testGetPublicItemVersion() throws Exception {
+ testGetItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+ }
+
+
+ @Test
+ public void testGetNonExistingItemVersion() throws Exception {
+ Id itemId = new Id();
+ Id versionId = new Id();
+ doReturn(Optional.empty()).when(versionDaoMock).get(context, USER, itemId, versionId);
+
+ ItemVersion itemVersion =
+ versionCollaborationStore.getItemVersion(context, Space.PRIVATE, itemId, versionId);
+ Assert.assertNull(itemVersion);
+ }*//*
+
+ @Test
+ public void testCreatePrivateItemVersion() throws Exception {
+ testCreateItemVersion(Space.PRIVATE, USER, null);
+ }
+
+ @Test
+ public void testCreatePrivateItemVersionBasedOn() throws Exception {
+ testCreateItemVersion(Space.PRIVATE, USER, new Id());
+ }
+
+ @Test
+ public void testCreatePublicItemVersion() throws Exception {
+ testCreateItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE, null);
+ }
+
+ @Test
+ public void testCreatePublicItemVersionBasedOn() throws Exception {
+ testCreateItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE, new Id());
+ }
+
+ @Test
+ public void testUpdatePrivateItemVersion() throws Exception {
+ testUpdateItemVersion(Space.PRIVATE, USER);
+ }
+
+ @Test
+ public void testUpdatePublicItemVersion() throws Exception {
+ testUpdateItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+ }
+
+ @Test
+ public void testDeletePrivateItemVersion() throws Exception {
+ testDeleteItemVersion(Space.PRIVATE, USER);
+ }
+
+ @Test
+ public void testDeletePublicItemVersion() throws Exception {
+ testDeleteItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+ }
+
+ @Test
+ public void testPublishItemVersionWhenNotDirty() throws Exception {
+ Id itemId = new Id();
+ ItemVersion version = TestUtils.createItemVersion(new Id(), null, "v1", false);
+ doReturn(Optional.of(version)).when(versionDaoMock).get(context, USER, itemId, version.getId());
+
+ versionCollaborationStore.publishItemVersion(context, itemId, version.getId(), "message");
+
+ }
+*//*
+ private void testIsItemVersionExist(Space space, String spaceName) {
+ Id itemId = new Id();
+ ItemVersion retrievedVersion = TestUtils.createItemVersion(new Id(), null, "v1");
+ doReturn(Optional.of(retrievedVersion)).when(versionDaoMock)
+ .get(context, spaceName, itemId, retrievedVersion.getId());
+
+ boolean itemExist =
+ versionCollaborationStore
+ .isItemVersionExist(context, space, itemId, retrievedVersion.getId());
+ Assert.assertTrue(itemExist);
+ }
+
+ private void testGetItemVersion(Space space, String spaceName) throws Exception {
+ Id itemId = new Id();
+ ItemVersion retrievedVersion = TestUtils.createItemVersion(new Id(), null, "v1");
+ doReturn(Optional.of(retrievedVersion)).when(versionDaoMock)
+ .get(context, spaceName, itemId, retrievedVersion.getId());
+
+ ItemVersion itemVersion =
+ versionCollaborationStore.getItemVersion(context, space, itemId, retrievedVersion.getId());
+ Assert.assertEquals(itemVersion, retrievedVersion);
+ }
+
+ private void testListItemVersions(Space space, String spaceName) {
+ Id itemId = new Id();
+ ItemVersion v1 = TestUtils.createItemVersion(new Id(), null, "v1");
+ ItemVersion v2 = TestUtils.createItemVersion(new Id(), v1.getId(), "v2");
+ ItemVersion v3 = TestUtils.createItemVersion(new Id(), v2.getId(), "v3");
+ List<ItemVersion> retrievedVersions = Arrays.asList(v1, v2, v3);
+ doReturn(retrievedVersions).when(versionDaoMock).list(context, spaceName, itemId);
+
+ Collection<ItemVersion> itemVersions =
+ versionCollaborationStore.listItemVersions(context, space, itemId);
+ Assert.assertEquals(itemVersions, retrievedVersions);
+ }*//*
+
+ private void testCreateItemVersion(Space space, String spaceName, Id baseId) {
+ Id itemId = new Id();
+ ItemVersion v1 = TestUtils.createItemVersion(new Id(), baseId, "v1", false);
+ List<ElementEntity> baseVersionElements = mockVersionElements(spaceName, itemId, baseId);
+
+ ArgumentCaptor<ItemVersion> versionCaptor = ArgumentCaptor.forClass(ItemVersion.class);
+
+ Date creationTime = new Date();
+ versionCollaborationStore
+ .createItemVersion(context, space, itemId, baseId, v1.getId(), v1.getData(), creationTime);
+
+ verify(versionDaoMock).create(eq(context), eq(spaceName), eq(itemId), versionCaptor.capture());
+ //baseId, v1.getId(),v1.getData(), creationTime);
+
+ ItemVersion capturedVersion = versionCaptor.getValue();
+ Assert.assertEquals(baseId, capturedVersion.getBaseId());
+ Assert.assertEquals(v1.getId(), capturedVersion.getId());
+ Assert.assertEquals(v1.getData(), capturedVersion.getData());
+ Assert.assertEquals(creationTime, capturedVersion.getCreationTime());
+*//* verify(versionDaoMock)
+ .create(anyObject(), anyObject(), anyObject(), anyObject(), anyObject(), anyObject(),
+ anyObject());*//*
+
+*//* if (baseId != null) {
+ baseVersionElements.forEach(element ->
+ verify(elementCollaborationStore).create(eq(context),
+ eq(new ElementEntityContext(spaceName, itemId, v1.getId())),
+ eq(element)));
+ } else {
+ verifyZeroInteractions(elementCollaborationStore);
+ }*//*
+ }
+
+ private void testUpdateItemVersion(Space space, String spaceName) {
+ Id itemId = new Id();
+ ItemVersion retrievedVersion = TestUtils.createItemVersion(new Id(), null, "v1", false);
+ doReturn(Optional.of(retrievedVersion)).when(versionDaoMock)
+ .get(context, spaceName, itemId, retrievedVersion.getId());
+
+ ItemVersionData updatedData = new ItemVersionData();
+ updatedData.setInfo(TestUtils.createInfo("v1 updated"));
+ updatedData.setRelations(
+ Arrays.asList(new Relation(), new Relation(), new Relation(), new Relation()));
+ versionCollaborationStore.updateItemVersion(
+ context, space, itemId, retrievedVersion.getId(), updatedData, new Date());
+
+ *//*verify(versionDaoMock)
+ .update(context, spaceName, itemId, retrievedVersion.getId(), updatedData, modificationTime);*//*
+ verify(versionDaoMock)
+ .update(anyObject(), anyObject(), anyObject(), anyObject());
+
+ }
+
+ private void testDeleteItemVersion(Space space, String spaceName) {
+ Id itemId = new Id();
+ Id versionId = new Id();
+
+ List<ElementEntity> versionElements = mockVersionElements(spaceName, itemId, versionId);
+ versionCollaborationStore.deleteItemVersion(context, space, itemId, versionId);
+
+*//* versionElements.forEach(element ->
+ verify(elementCollaborationStore).delete(eq(context),
+ eq(new ElementEntityContext(spaceName, itemId, versionId)),
+ eq(element)));*//*
+ verify(versionDaoMock).delete(context, spaceName, itemId, versionId);
+ }
+
+ private List<ElementEntity> mockVersionElements(String spaceName, Id itemId, Id versionId) {
+ ElementEntity elm1 = new ElementEntity(new Id());
+ ElementEntity elm2 = new ElementEntity(new Id());
+ List<ElementEntity> baseVersionElements = Arrays.asList(elm1, elm2);
+*//* doReturn(baseVersionElements).when(elementCollaborationStore)
+ .list(eq(context), eq(new ElementEntityContext(spaceName, itemId, versionId)));*//*
+ return baseVersionElements;
+ }*/
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java
new file mode 100644
index 0000000000..7f137b01b0
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java
@@ -0,0 +1,167 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.UserInfo;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.openecomp.core.zusammen.plugin.collaboration.TestUtils;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ElementStageStoreImplTest {
+ private static final UserInfo USER = new UserInfo("user");
+ private static final SessionContext context = TestUtils.createSessionContext(USER, "test");
+ private static final ElementContext elementContext =
+ TestUtils.createElementContext(new Id(), new Id());
+
+ @Mock
+ private ElementStageRepository elementStageRepositoryMock;
+ @Spy
+ private ElementStageStoreImpl elementStageStore;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(elementStageStore.getElementStageRepository(anyObject()))
+ .thenReturn(elementStageRepositoryMock);
+ }
+
+ @Test
+ public void testListIds() throws Exception {
+
+ }
+
+ @Test
+ public void testGet() throws Exception {
+
+ }
+
+ @Test
+ public void testGetConflicted() throws Exception {
+
+ }
+
+ @Test
+ public void testHasConflicts() throws Exception {
+
+ }
+
+ @Test
+ public void testListConflictedDescriptors() throws Exception {
+
+ }
+
+ @Test
+ public void testCreate() throws Exception {
+
+ }
+
+ @Test
+ public void testDelete() throws Exception {
+
+ }
+
+ @Test
+ public void testResolveConflictWhenNotStaged() throws Exception {
+ doReturn(Optional.empty())
+ .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+ elementStageStore
+ .resolveConflict(context, elementContext, new ElementEntity(new Id()), Resolution.YOURS);
+ }
+
+ @Test
+ public void testResolveConflictWhenNotConflicted() throws Exception {
+ Id elementId = new Id();
+ StageEntity<ElementEntity> stagedElement =
+ new StageEntity<>(new ElementEntity(elementId), new Date());
+ doReturn(Optional.of(stagedElement))
+ .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+ elementStageStore
+ .resolveConflict(context, elementContext, new ElementEntity(elementId), Resolution.YOURS);
+ }
+
+ @Test
+ public void testResolveConflictByYours() throws Exception {
+ Id elementId = new Id();
+ StageEntity<ElementEntity> stagedElement =
+ new StageEntity<>(new ElementEntity(elementId), new Date());
+ stagedElement.setAction(Action.UPDATE);
+ stagedElement.setConflicted(true);
+
+ doReturn(Optional.of(stagedElement))
+ .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+
+ elementStageStore
+ .resolveConflict(context, elementContext, new ElementEntity(elementId), Resolution.YOURS);
+
+ verify(elementStageRepositoryMock).markAsNotConflicted(same(context),
+ eq(new ElementEntityContext(USER.getUserName(), elementContext)),
+ same(stagedElement.getEntity()), same(Action.IGNORE));
+ }
+
+ @Test
+ public void testResolveConflictByYoursWithRelated() throws Exception {
+ Id elementId = new Id();
+ StageEntity<ElementEntity> stagedElement =
+ new StageEntity<>(new ElementEntity(elementId), new Date());
+ stagedElement.setAction(Action.UPDATE);
+ stagedElement.setConflicted(true);
+ ElementEntity relatedElement1 = new ElementEntity(new Id());
+ ElementEntity relatedElement2 = new ElementEntity(new Id());
+ ElementEntity relatedElement3 = new ElementEntity(new Id());
+ Set<ElementEntity> relatedElements = new HashSet<>();
+ relatedElements.add(relatedElement1);
+ relatedElements.add(relatedElement2);
+ relatedElements.add(relatedElement3);
+ stagedElement.setConflictDependents(relatedElements);
+
+ doReturn(Optional.of(stagedElement))
+ .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+
+ elementStageStore
+ .resolveConflict(context, elementContext, new ElementEntity(elementId), Resolution.YOURS);
+
+ ElementEntityContext elementEntityContext =
+ new ElementEntityContext(USER.getUserName(), elementContext);
+ verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+ same(stagedElement.getEntity()), same(Action.IGNORE));
+ verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+ same(relatedElement1), same(Action.IGNORE));
+ verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+ same(relatedElement2), same(Action.IGNORE));
+ verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+ same(relatedElement3), same(Action.IGNORE));
+ }
+
+ @Test
+ public void testResolveConflictByTheirs() throws Exception {
+
+ }
+
+ @Test
+ public void testResolveConflictByTheirsWithRelated() throws Exception {
+
+ }
+
+} \ No newline at end of file