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());
102 public boolean checkHealth(SessionContext context) {
103 ResultSet resultSet = getVersionElementsAccessor(context).checkHealth();
104 return resultSet.getColumnDefinitions().contains("element_ids");
107 private String getVersionId(ElementEntityContext elementContext) {
108 return elementContext.getChangeRef() == null
109 ? elementContext.getVersionId().toString()
110 : elementContext.getChangeRef();
113 private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
114 return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
117 private ElementAccessor getElementAccessor(SessionContext context) {
118 return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
121 private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
122 return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
125 private void createElement(SessionContext context, ElementEntityContext elementContext,
126 ElementEntity element) {
127 Set<String> subElementIds =
128 element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
129 String versionId = getVersionId(elementContext);
131 getElementAccessor(context).create(
132 elementContext.getSpace(),
133 elementContext.getItemId().toString(),
135 element.getId().toString(),
136 element.getParentId().toString(),
137 element.getNamespace().toString(),
138 JsonUtil.object2Json(element.getInfo()),
139 JsonUtil.object2Json(element.getRelations()),
141 element.getSearchableData(),
142 element.getVisualization(),
145 getVersionElementsAccessor(context).addElements(
146 Collections.singleton(element.getId().toString()),
147 elementContext.getSpace(),
148 elementContext.getItemId().toString(),
152 private void updateElement(SessionContext context, ElementEntityContext elementContext,
153 ElementEntity element) {
154 getElementAccessor(context).update(
155 JsonUtil.object2Json(element.getInfo()),
156 JsonUtil.object2Json(element.getRelations()),
158 element.getSearchableData(),
159 element.getVisualization(),
160 elementContext.getSpace(),
161 elementContext.getItemId().toString(),
162 elementContext.getVersionId().toString(),
163 element.getId().toString());
166 private void deleteElement(SessionContext context, ElementEntityContext elementContext,
167 ElementEntity element) {
168 String versionId = getVersionId(elementContext);
170 getElementAccessor(context).delete(
171 elementContext.getSpace(),
172 elementContext.getItemId().toString(),
174 element.getId().toString());
176 getVersionElementsAccessor(context).removeElements(
177 Collections.singleton(element.getId().toString()),
178 elementContext.getSpace(),
179 elementContext.getItemId().toString(),
183 private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
184 ElementEntity element) {
185 getElementAccessor(context).addSubElements(
186 Collections.singleton(element.getId().toString()),
187 elementContext.getSpace(),
188 elementContext.getItemId().toString(),
189 getVersionId(elementContext),
190 element.getParentId().toString());
193 private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
194 ElementEntity element) {
195 if (element.getParentId() == null) {
198 getElementAccessor(context).removeSubElements(
199 Collections.singleton(element.getId().toString()),
200 elementContext.getSpace(),
201 elementContext.getItemId().toString(),
202 getVersionId(elementContext),
203 element.getParentId().toString());
206 private ElementEntity getElementEntity(ElementEntity element, Row row) {
207 element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
208 element.setParentId(new Id(row.getString(ElementField.PARENT_ID)));
209 element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
210 element.setRelations(
211 json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
213 element.setData(row.getBytes(ElementField.DATA));
214 element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
215 element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
216 element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
217 .stream().map(Id::new).collect(Collectors.toSet()));
221 private Namespace getNamespace(String namespaceStr) {
222 Namespace namespace = new Namespace();
223 if (namespaceStr != null) {
224 namespace.setValue(namespaceStr);
229 private static <T> T json2Object(String json, Type typeOfT) {
230 return json == null ? null : JsonUtil.json2Object(json, typeOfT);
233 private Set<String> getVersionElementIds(SessionContext context,
234 ElementEntityContext elementContext) {
235 Row row = getVersionElementsAccessor(context).get(
236 elementContext.getSpace(),
237 elementContext.getItemId().toString(),
238 getVersionId(elementContext)).one();
241 : row.getSet(CassandraElementRepository.VersionElementsField.ELEMENT_IDS, String.class);
245 CREATE TABLE IF NOT EXISTS element_namespace (
250 PRIMARY KEY (( space, item_id, element_id ))
254 interface ElementNamespaceAccessor {
256 "UPDATE element_namespace SET namespace=:ns " +
257 "WHERE space=:space AND item_id=:item AND element_id=:id ")
258 void create(@Param("space") String space,
259 @Param("item") String itemId,
260 @Param("id") String elementId,
261 @Param("ns") String namespace);
265 CREATE TABLE IF NOT EXISTS element (
275 searchable_data blob,
277 sub_element_ids set<text>,
278 PRIMARY KEY (( space, item_id, version_id, element_id ))
282 interface ElementAccessor {
284 "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
285 "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
286 "sub_element_ids=sub_element_ids+:subs " +
287 "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
288 void create(@Param("space") String space,
289 @Param("item") String itemId,
290 @Param("ver") String versionId,
291 @Param("id") String elementId,
292 @Param("parentId") String parentElementId,
293 @Param("ns") String namespace,
294 @Param("info") String info,
295 @Param("rels") String relations,
296 @Param("data") ByteBuffer data,
297 @Param("searchableData") ByteBuffer searchableData,
298 @Param("visualization") ByteBuffer visualization,
299 @Param("subs") Set<String> subElementIds);
301 @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=?" +
302 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
303 void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
304 ByteBuffer visualization, String space, String itemId, String versionId,
307 @Query("DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
308 void delete(String space, String itemId, String versionId, String elementId);
310 @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
311 "sub_element_ids FROM element " +
312 "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
313 ResultSet get(String space, String itemId, String versionId, String elementId);
315 @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
316 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
317 void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
320 @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
321 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
322 void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
326 private static final class ElementField {
327 private static final String NAMESPACE = "namespace";
328 private static final String PARENT_ID = "parent_id";
329 private static final String INFO = "info";
330 private static final String RELATIONS = "relations";
331 private static final String DATA = "data";
332 private static final String SEARCHABLE_DATA = "searchable_data";
333 private static final String VISUALIZATION = "visualization";
334 private static final String SUB_ELEMENT_IDS = "sub_element_ids";
338 CREATE TABLE IF NOT EXISTS version_elements (
342 element_ids set<text>,
343 PRIMARY KEY (( space, item_id, version_id ))
347 interface VersionElementsAccessor {
349 @Query("UPDATE version_elements SET element_ids=element_ids+? " +
350 "WHERE space=? AND item_id=? AND version_id=?")
351 void addElements(Set<String> elementIds, String space, String itemId, String versionId);
353 @Query("UPDATE version_elements SET element_ids=element_ids-? " +
354 "WHERE space=? AND item_id=? AND version_id=?")
355 void removeElements(Set<String> elementIds, String space, String itemId, String versionId);
357 @Query("SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=?")
358 ResultSet get(String space, String itemId, String versionId);
360 @Query("SELECT element_ids FROM version_elements LIMIT 1")
361 ResultSet checkHealth();
364 private static final class VersionElementsField {
365 private static final String ELEMENT_IDS = "element_ids";