Add collaboration feature
[sdc.git] / openecomp-be / tools / zusammen-tools / src / main / java / org / openecomp / core / tools / store / CassandraElementRepository.java
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.openecomp.core.tools.store;
18
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.nosqldb.factory.NoSqlDbFactory;
33 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
34
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.HashSet;
40 import java.util.Objects;
41 import java.util.Optional;
42 import java.util.Set;
43 import java.util.stream.Collectors;
44
45 public class CassandraElementRepository {
46
47
48   public Collection<ElementEntity> list(SessionContext context,
49                                         ElementEntityContext elementContext) {
50     Set<String> elementIds = getVersionElementIds(context, elementContext);
51
52     return elementIds.stream()
53         .map(elementId -> get(context, elementContext, new ElementEntity(new Id(elementId))).get())
54         .filter(Objects::nonNull)
55         .collect(Collectors.toList());
56   }
57
58
59   public void update(SessionContext context, ElementEntityContext elementContext,
60                      ElementEntity element) {
61     updateElement(context, elementContext, element);
62   }
63
64
65   public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
66                                      ElementEntity element) {
67     Row row = getElementAccessor(context).get(
68         elementContext.getSpace(),
69         elementContext.getItemId().getValue(),
70         getVersionId(elementContext),
71         element.getId().getValue()).one();
72
73     return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
74   }
75
76
77   private String getVersionId(ElementEntityContext elementContext) {
78     return elementContext.getRevisionId() == null
79         ? elementContext.getVersionId().getValue()
80         : elementContext.getRevisionId().getValue();
81   }
82
83
84   private ElementAccessor getElementAccessor(SessionContext context) {
85     return NoSqlDbFactory.getInstance().createInterface().getMappingManager().createAccessor
86         (ElementAccessor.class);
87
88   }
89
90   private VersionElementsAccessor getVersionElementsAccessor() {
91     return NoSqlDbFactory.getInstance().createInterface().getMappingManager().createAccessor
92         (VersionElementsAccessor.class);
93
94   }
95
96
97   private void updateElement(SessionContext context, ElementEntityContext elementContext,
98                              ElementEntity element) {
99
100     if (elementContext.getRevisionId() == null) {
101
102       getElementAccessor(context).update(
103           JsonUtil.object2Json(element.getInfo()),
104           JsonUtil.object2Json(element.getRelations()),
105           element.getData(),
106           element.getSearchableData(),
107           element.getVisualization(),
108           elementContext.getSpace(),
109           elementContext.getItemId().toString(),
110           elementContext.getVersionId().toString(),
111           element.getId().toString());
112     } else {
113       getElementAccessor(context).update(
114           JsonUtil.object2Json(element.getInfo()),
115           JsonUtil.object2Json(element.getRelations()),
116           element.getData(),
117           element.getSearchableData(),
118           element.getVisualization(),
119           elementContext.getSpace(),
120           elementContext.getItemId().toString(),
121           elementContext.getRevisionId().getValue(),
122           element.getId().toString());
123     }
124   }
125
126
127   private ElementEntity getElementEntity(ElementEntity element, Row row) {
128     element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
129     element.setParentId(new Id(row.getString(ElementField.PARENT_ID)));
130     element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
131     element.setRelations(
132         json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
133         }.getType()));
134     element.setData(row.getBytes(ElementField.DATA));
135     element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
136     element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
137     element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
138         .stream().map(Id::new).collect(Collectors.toSet()));
139     return element;
140   }
141
142   private Namespace getNamespace(String namespaceStr) {
143     Namespace namespace = new Namespace();
144     if (namespaceStr != null) {
145       namespace.setValue(namespaceStr);
146     }
147     return namespace;
148   }
149
150   private static <T> T json2Object(String json, Type typeOfT) {
151     return json == null ? null : JsonUtil.json2Object(json, typeOfT);
152   }
153
154   private Set<String> getVersionElementIds(SessionContext context,
155                                            ElementEntityContext elementContext) {
156     Row row = getVersionElementsAccessor().get(
157         elementContext.getSpace(),
158         elementContext.getItemId().toString(),
159         getVersionId(elementContext)).one();
160     return row == null
161         ? new HashSet<>()
162         : row.getSet(VersionElementsField.ELEMENT_IDS, String.class);
163   }
164
165   /*
166 CREATE TABLE IF NOT EXISTS element_namespace (
167         space text,
168         item_id text,
169         element_id text,
170         namespace text,
171         PRIMARY KEY (( space, item_id, element_id ))
172 );
173    */
174   @Accessor
175   interface ElementNamespaceAccessor {
176     @Query(
177         "UPDATE element_namespace SET namespace=:ns " +
178             "WHERE space=:space AND item_id=:item AND element_id=:id ")
179     void create(@Param("space") String space,
180                 @Param("item") String itemId,
181                 @Param("id") String elementId,
182                 @Param("ns") String namespace);
183   }
184
185   /*
186 CREATE TABLE IF NOT EXISTS element (
187         space text,
188         item_id text,
189         version_id text,
190         element_id text,
191         parent_id text,
192         namespace text,
193         info text,
194         relations text,
195         data blob,
196         searchable_data blob,
197         visualization blob,
198         sub_element_ids set<text>,
199         PRIMARY KEY (( space, item_id, version_id, element_id ))
200 );
201    */
202   @Accessor
203   interface ElementAccessor {
204     @Query(
205         "UPDATE zusammen_dox.element SET parent_id=:parentId, namespace=:ns, info=:info, " +
206             "relations=:rels, " +
207             "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
208             "sub_element_ids=sub_element_ids+:subs " +
209             "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
210     void create(@Param("space") String space,
211                 @Param("item") String itemId,
212                 @Param("ver") String versionId,
213                 @Param("id") String elementId,
214                 @Param("parentId") String parentElementId,
215                 @Param("ns") String namespace,
216                 @Param("info") String info,
217                 @Param("rels") String relations,
218                 @Param("data") ByteBuffer data,
219                 @Param("searchableData") ByteBuffer searchableData,
220                 @Param("visualization") ByteBuffer visualization,
221                 @Param("subs") Set<String> subElementIds);
222
223     @Query("UPDATE zusammen_dox.element SET info=?, relations=?, data=?, searchable_data=?, " +
224         "visualization=?" +
225         " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
226     void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
227                 ByteBuffer visualization, String space, String itemId, String versionId,
228                 String elementId);
229
230
231     @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
232         "sub_element_ids FROM zusammen_dox.element " +
233         "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
234     ResultSet get(String space, String itemId, String versionId, String elementId);
235
236
237   }
238
239   private static final class ElementField {
240     private static final String NAMESPACE = "namespace";
241     private static final String PARENT_ID = "parent_id";
242     private static final String INFO = "info";
243     private static final String RELATIONS = "relations";
244     private static final String DATA = "data";
245     private static final String SEARCHABLE_DATA = "searchable_data";
246     private static final String VISUALIZATION = "visualization";
247     private static final String SUB_ELEMENT_IDS = "sub_element_ids";
248   }
249
250   /*
251   CREATE TABLE IF NOT EXISTS version_elements (
252     space text,
253     item_id text,
254     version_id text,
255     element_ids set<text>,
256     PRIMARY KEY (( space, item_id, version_id ))
257   );
258    */
259   @Accessor
260   interface VersionElementsAccessor {
261
262
263     @Query("SELECT element_ids FROM zusammen_dox.version_elements WHERE space=? AND item_id=? AND version_id=?")
264     ResultSet get(String space, String itemId, String versionId);
265
266
267   }
268
269   private static final class VersionElementsField {
270     private static final String ELEMENT_IDS = "element_ids";
271   }
272 }