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.amdocs.zusammen.datatypes.Id;
20 import com.amdocs.zusammen.datatypes.Namespace;
21 import com.amdocs.zusammen.datatypes.SessionContext;
22 import com.amdocs.zusammen.datatypes.item.Info;
23 import com.amdocs.zusammen.datatypes.item.Relation;
24 import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
25 import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
26 import com.datastax.driver.core.ResultSet;
27 import com.datastax.driver.core.Row;
28 import com.datastax.driver.mapping.annotations.Accessor;
29 import com.datastax.driver.mapping.annotations.Param;
30 import com.datastax.driver.mapping.annotations.Query;
31 import com.google.gson.reflect.TypeToken;
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.Optional;
43 import java.util.stream.Collectors;
45 public class CassandraElementRepository implements ElementRepository {
47 private static final String VERSION_ELEMENT_NOT_EXIST_ERROR_MSG =
48 "List version elements error: " +
49 "element %s, which appears as an element of item %s version %s, does not exist";
52 public Collection<ElementEntity> list(SessionContext context,
53 ElementEntityContext elementContext) {
54 Set<String> elementIds = getVersionElementIds(context, elementContext);
56 Collection<ElementEntity> elements = new ArrayList<>();
57 for (String elementId : elementIds) {
58 elements.add(get(context, elementContext, new ElementEntity(new Id(elementId)))
60 () -> new IllegalStateException(String.format(VERSION_ELEMENT_NOT_EXIST_ERROR_MSG,
61 elementId, elementContext.getItemId().getValue(),
62 getVersionId(elementContext)))));
68 public void create(SessionContext context, ElementEntityContext elementContext,
69 ElementEntity element) {
70 createElement(context, elementContext, element);
71 addElementToParent(context, elementContext, element);
75 public void update(SessionContext context, ElementEntityContext elementContext,
76 ElementEntity element) {
77 updateElement(context, elementContext, element);
81 public void delete(SessionContext context, ElementEntityContext elementContext,
82 ElementEntity element) {
83 removeElementFromParent(context, elementContext, element);
84 deleteElement(context, elementContext, element);
88 public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
89 ElementEntity element) {
90 Row row = getElementAccessor(context).get(
91 elementContext.getSpace(),
92 elementContext.getItemId().toString(),
93 getVersionId(elementContext),
94 element.getId().toString()).one();
96 return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
100 public void createNamespace(SessionContext context, ElementEntityContext elementContext,
101 ElementEntity element) {
102 getElementNamespaceAccessor(context).create(
103 elementContext.getSpace(),
104 elementContext.getItemId().toString(),
105 element.getId().toString(),
106 element.getNamespace().toString());
110 public boolean checkHealth(SessionContext context) {
111 ResultSet resultSet = getVersionElementsAccessor(context).checkHealth();
112 return resultSet.getColumnDefinitions().contains("element_ids");
115 private String getVersionId(ElementEntityContext elementContext) {
116 return elementContext.getChangeRef() == null
117 ? elementContext.getVersionId().toString()
118 : elementContext.getChangeRef();
121 private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
122 return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
125 private ElementAccessor getElementAccessor(SessionContext context) {
126 return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
129 private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
130 return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
133 private void createElement(SessionContext context, ElementEntityContext elementContext,
134 ElementEntity element) {
135 Set<String> subElementIds =
136 element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
137 String versionId = getVersionId(elementContext);
139 getElementAccessor(context).create(
140 elementContext.getSpace(),
141 elementContext.getItemId().toString(),
143 element.getId().toString(),
144 element.getParentId().toString(),
145 element.getNamespace().toString(),
146 JsonUtil.object2Json(element.getInfo()),
147 JsonUtil.object2Json(element.getRelations()),
149 element.getSearchableData(),
150 element.getVisualization(),
153 getVersionElementsAccessor(context).addElements(
154 Collections.singleton(element.getId().toString()),
155 elementContext.getSpace(),
156 elementContext.getItemId().toString(),
160 private void updateElement(SessionContext context, ElementEntityContext elementContext,
161 ElementEntity element) {
162 getElementAccessor(context).update(
163 JsonUtil.object2Json(element.getInfo()),
164 JsonUtil.object2Json(element.getRelations()),
166 element.getSearchableData(),
167 element.getVisualization(),
168 elementContext.getSpace(),
169 elementContext.getItemId().toString(),
170 elementContext.getVersionId().toString(),
171 element.getId().toString());
174 private void deleteElement(SessionContext context, ElementEntityContext elementContext,
175 ElementEntity element) {
176 String versionId = getVersionId(elementContext);
178 getElementAccessor(context).delete(
179 elementContext.getSpace(),
180 elementContext.getItemId().toString(),
182 element.getId().toString());
184 getVersionElementsAccessor(context).removeElements(
185 Collections.singleton(element.getId().toString()),
186 elementContext.getSpace(),
187 elementContext.getItemId().toString(),
191 private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
192 ElementEntity element) {
193 getElementAccessor(context).addSubElements(
194 Collections.singleton(element.getId().toString()),
195 elementContext.getSpace(),
196 elementContext.getItemId().toString(),
197 getVersionId(elementContext),
198 element.getParentId().toString());
201 private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
202 ElementEntity element) {
203 if (element.getParentId() == null) {
206 getElementAccessor(context).removeSubElements(
207 Collections.singleton(element.getId().toString()),
208 elementContext.getSpace(),
209 elementContext.getItemId().toString(),
210 getVersionId(elementContext),
211 element.getParentId().toString());
214 private ElementEntity getElementEntity(ElementEntity element, Row row) {
215 element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
216 element.setParentId(new Id(row.getString(ElementField.PARENT_ID)));
217 element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
218 element.setRelations(
219 json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
221 element.setData(row.getBytes(ElementField.DATA));
222 element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
223 element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
224 element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
225 .stream().map(Id::new).collect(Collectors.toSet()));
229 private Namespace getNamespace(String namespaceStr) {
230 Namespace namespace = new Namespace();
231 if (namespaceStr != null) {
232 namespace.setValue(namespaceStr);
237 private static <T> T json2Object(String json, Type typeOfT) {
238 return json == null ? null : JsonUtil.json2Object(json, typeOfT);
241 private Set<String> getVersionElementIds(SessionContext context,
242 ElementEntityContext elementContext) {
243 Row row = getVersionElementsAccessor(context).get(
244 elementContext.getSpace(),
245 elementContext.getItemId().toString(),
246 getVersionId(elementContext)).one();
249 : row.getSet(CassandraElementRepository.VersionElementsField.ELEMENT_IDS, String.class);
253 CREATE TABLE IF NOT EXISTS element_namespace (
258 PRIMARY KEY (( space, item_id, element_id ))
262 interface ElementNamespaceAccessor {
264 "UPDATE element_namespace SET namespace=:ns " +
265 "WHERE space=:space AND item_id=:item AND element_id=:id ")
266 void create(@Param("space") String space,
267 @Param("item") String itemId,
268 @Param("id") String elementId,
269 @Param("ns") String namespace);
273 CREATE TABLE IF NOT EXISTS element (
283 searchable_data blob,
285 sub_element_ids set<text>,
286 PRIMARY KEY (( space, item_id, version_id, element_id ))
290 interface ElementAccessor {
292 "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
293 "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
294 "sub_element_ids=sub_element_ids+:subs " +
295 "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
296 void create(@Param("space") String space,
297 @Param("item") String itemId,
298 @Param("ver") String versionId,
299 @Param("id") String elementId,
300 @Param("parentId") String parentElementId,
301 @Param("ns") String namespace,
302 @Param("info") String info,
303 @Param("rels") String relations,
304 @Param("data") ByteBuffer data,
305 @Param("searchableData") ByteBuffer searchableData,
306 @Param("visualization") ByteBuffer visualization,
307 @Param("subs") Set<String> subElementIds);
309 @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=?" +
310 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
311 void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
312 ByteBuffer visualization, String space, String itemId, String versionId,
315 @Query("DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
316 void delete(String space, String itemId, String versionId, String elementId);
318 @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
319 "sub_element_ids FROM element " +
320 "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
321 ResultSet get(String space, String itemId, String versionId, String elementId);
323 @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
324 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
325 void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
328 @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
329 " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
330 void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
334 private static final class ElementField {
335 private static final String NAMESPACE = "namespace";
336 private static final String PARENT_ID = "parent_id";
337 private static final String INFO = "info";
338 private static final String RELATIONS = "relations";
339 private static final String DATA = "data";
340 private static final String SEARCHABLE_DATA = "searchable_data";
341 private static final String VISUALIZATION = "visualization";
342 private static final String SUB_ELEMENT_IDS = "sub_element_ids";
346 CREATE TABLE IF NOT EXISTS version_elements (
350 element_ids set<text>,
351 PRIMARY KEY (( space, item_id, version_id ))
355 interface VersionElementsAccessor {
357 @Query("UPDATE version_elements SET element_ids=element_ids+? " +
358 "WHERE space=? AND item_id=? AND version_id=?")
359 void addElements(Set<String> elementIds, String space, String itemId, String versionId);
361 @Query("UPDATE version_elements SET element_ids=element_ids-? " +
362 "WHERE space=? AND item_id=? AND version_id=?")
363 void removeElements(Set<String> elementIds, String space, String itemId, String versionId);
365 @Query("SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=?")
366 ResultSet get(String space, String itemId, String versionId);
368 @Query("SELECT element_ids FROM version_elements LIMIT 1")
369 ResultSet checkHealth();
372 private static final class VersionElementsField {
373 private static final String ELEMENT_IDS = "element_ids";