2 * Copyright © 2016-2017 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.core.zusammen.plugin.dao.impl;
19 import com.datastax.driver.core.ResultSet;
20 import com.datastax.driver.core.Row;
21 import com.datastax.driver.mapping.annotations.Accessor;
22 import com.datastax.driver.mapping.annotations.Param;
23 import com.datastax.driver.mapping.annotations.Query;
24 import com.google.gson.reflect.TypeToken;
25 import com.amdocs.zusammen.datatypes.Id;
26 import com.amdocs.zusammen.datatypes.Namespace;
27 import com.amdocs.zusammen.datatypes.SessionContext;
28 import com.amdocs.zusammen.datatypes.item.Info;
29 import com.amdocs.zusammen.datatypes.item.Relation;
30 import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
31 import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
32 import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
33 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
35 import java.lang.reflect.Type;
36 import java.nio.ByteBuffer;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.Collections;
40 import java.util.HashSet;
41 import java.util.Objects;
42 import java.util.Optional;
44 import java.util.stream.Collectors;
46 public class CassandraElementRepository implements ElementRepository {
49 public Collection<ElementEntity> list(SessionContext context,
50 ElementEntityContext elementContext) {
51 Set<String> elementIds = getVersionElementIds(context, elementContext);
53 return elementIds.stream()
54 .map(elementId -> get(context, elementContext, new ElementEntity(new Id(elementId))).get())
55 .filter(Objects::nonNull)
56 .collect(Collectors.toList());
60 public void create(SessionContext context, ElementEntityContext elementContext,
61 ElementEntity element) {
62 createElement(context, elementContext, element);
63 addElementToParent(context, elementContext, element);
67 public void update(SessionContext context, ElementEntityContext elementContext,
68 ElementEntity element) {
69 updateElement(context, elementContext, element);
73 public void delete(SessionContext context, ElementEntityContext elementContext,
74 ElementEntity element) {
75 removeElementFromParent(context, elementContext, element);
76 deleteElement(context, elementContext, element);
80 public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
81 ElementEntity element) {
82 Row row = getElementAccessor(context).get(
83 elementContext.getSpace(),
84 elementContext.getItemId().toString(),
85 getVersionId(elementContext),
86 element.getId().toString()).one();
88 return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
92 public void createNamespace(SessionContext context, ElementEntityContext elementContext,
93 ElementEntity element) {
94 getElementNamespaceAccessor(context).create(
95 elementContext.getSpace(),
96 elementContext.getItemId().toString(),
97 element.getId().toString(),
98 element.getNamespace().toString());
101 private String getVersionId(ElementEntityContext elementContext) {
102 return elementContext.getChangeRef() == null
103 ? elementContext.getVersionId().toString()
104 : elementContext.getChangeRef();
107 private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
108 return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
111 private ElementAccessor getElementAccessor(SessionContext context) {
112 return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
115 private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
116 return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
119 private void createElement(SessionContext context, ElementEntityContext elementContext,
120 ElementEntity element) {
121 Set<String> subElementIds =
122 element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
123 String versionId = getVersionId(elementContext);
125 getElementAccessor(context).create(
126 elementContext.getSpace(),
127 elementContext.getItemId().toString(),
129 element.getId().toString(),
130 element.getParentId().toString(),
131 element.getNamespace().toString(),
132 JsonUtil.object2Json(element.getInfo()),
133 JsonUtil.object2Json(element.getRelations()),
135 element.getSearchableData(),
136 element.getVisualization(),
139 getVersionElementsAccessor(context).addElements(
140 Collections.singleton(element.getId().toString()),
141 elementContext.getSpace(),
142 elementContext.getItemId().toString(),
146 private void updateElement(SessionContext context, ElementEntityContext elementContext,
147 ElementEntity element) {
148 getElementAccessor(context).update(
149 JsonUtil.object2Json(element.getInfo()),
150 JsonUtil.object2Json(element.getRelations()),
152 element.getSearchableData(),
153 element.getVisualization(),
154 elementContext.getSpace(),
155 elementContext.getItemId().toString(),
156 elementContext.getVersionId().toString(),
157 element.getId().toString());
160 private void deleteElement(SessionContext context, ElementEntityContext elementContext,
161 ElementEntity element) {
162 String versionId = getVersionId(elementContext);
164 getElementAccessor(context).delete(
165 elementContext.getSpace(),
166 elementContext.getItemId().toString(),
168 element.getId().toString());
170 getVersionElementsAccessor(context).removeElements(
171 Collections.singleton(element.getId().toString()),
172 elementContext.getSpace(),
173 elementContext.getItemId().toString(),
177 private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
178 ElementEntity element) {
179 getElementAccessor(context).addSubElements(
180 Collections.singleton(element.getId().toString()),
181 elementContext.getSpace(),
182 elementContext.getItemId().toString(),
183 getVersionId(elementContext),
184 element.getParentId().toString());
187 private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
188 ElementEntity element) {
189 if (element.getParentId() == null) {
192 getElementAccessor(context).removeSubElements(
193 Collections.singleton(element.getId().toString()),
194 elementContext.getSpace(),
195 elementContext.getItemId().toString(),
196 getVersionId(elementContext),
197 element.getParentId().toString());
200 private ElementEntity getElementEntity(ElementEntity element, Row row) {
201 element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
202 element.setParentId(new Id(row.getString(ElementField.PARENT_ID)));
203 element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
204 element.setRelations(
205 json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
207 element.setData(row.getBytes(ElementField.DATA));
208 element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
209 element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
210 element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
211 .stream().map(Id::new).collect(Collectors.toSet()));
215 private Namespace getNamespace(String namespaceStr) {
216 Namespace namespace = new Namespace();
217 if (namespaceStr != null) {
218 namespace.setValue(namespaceStr);
223 private static <T> T json2Object(String json, Type typeOfT) {
224 return json == null ? null : JsonUtil.json2Object(json, typeOfT);
227 private Set<String> getVersionElementIds(SessionContext context,
228 ElementEntityContext elementContext) {
229 Row row = getVersionElementsAccessor(context).get(
230 elementContext.getSpace(),
231 elementContext.getItemId().toString(),
232 getVersionId(elementContext)).one();
235 : row.getSet(CassandraElementRepository.VersionElementsField.ELEMENT_IDS, String.class);
239 CREATE TABLE IF NOT EXISTS element_namespace (
244 PRIMARY KEY (( space, item_id, element_id ))
248 interface ElementNamespaceAccessor {
250 "UPDATE element_namespace SET namespace=:ns " +
251 "WHERE space=:space AND item_id=:item AND element_id=:id ")
252 void create(@Param("space") String space,
253 @Param("item") String itemId,
254 @Param("id") String elementId,
255 @Param("ns") String namespace);
259 CREATE TABLE IF NOT EXISTS element (
269 searchable_data blob,
271 sub_element_ids set<text>,
272 PRIMARY KEY (( space, item_id, version_id, element_id ))
276 interface ElementAccessor {
278 "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
279 "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
280 "sub_element_ids=sub_element_ids+:subs " +
281 "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
282 void create(@Param("space") String space,
283 @Param("item") String itemId,
284 @Param("ver") String versionId,
285 @Param("id") String elementId,
286 @Param("parentId") String parentElementId,
287 @Param("ns") String namespace,
288 @Param("info") String info,
289 @Param("rels") String relations,
290 @Param("data") ByteBuffer data,
291 @Param("searchableData") ByteBuffer searchableData,
292 @Param("visualization") ByteBuffer visualization,
293 @Param("subs") Set<String> subElementIds);
295 @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=?" +
296 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
297 void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
298 ByteBuffer visualization, String space, String itemId, String versionId,
301 @Query("DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
302 void delete(String space, String itemId, String versionId, String elementId);
304 @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
305 "sub_element_ids FROM element " +
306 "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
307 ResultSet get(String space, String itemId, String versionId, String elementId);
309 @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
310 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
311 void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
314 @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
315 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
316 void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
320 private static final class ElementField {
321 private static final String NAMESPACE = "namespace";
322 private static final String PARENT_ID = "parent_id";
323 private static final String INFO = "info";
324 private static final String RELATIONS = "relations";
325 private static final String DATA = "data";
326 private static final String SEARCHABLE_DATA = "searchable_data";
327 private static final String VISUALIZATION = "visualization";
328 private static final String SUB_ELEMENT_IDS = "sub_element_ids";
332 CREATE TABLE IF NOT EXISTS version_elements (
336 element_ids set<text>,
337 PRIMARY KEY (( space, item_id, version_id ))
341 interface VersionElementsAccessor {
343 @Query("UPDATE version_elements SET element_ids=element_ids+? " +
344 "WHERE space=? AND item_id=? AND version_id=?")
345 void addElements(Set<String> elementIds, String space, String itemId, String versionId);
347 @Query("UPDATE version_elements SET element_ids=element_ids-? " +
348 "WHERE space=? AND item_id=? AND version_id=?")
349 void removeElements(Set<String> elementIds, String space, String itemId, String versionId);
351 @Query("SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=?")
352 ResultSet get(String space, String itemId, String versionId);
355 private static final class VersionElementsField {
356 private static final String ELEMENT_IDS = "element_ids";