MUSIC-ORM-Implemetation
[music.git] / src / main / java / org / onap / music / datastore / jsonobjects / JsonDelete.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2017 AT&T Intellectual Property
6  * ===================================================================
7  *  Modifications Copyright (c) 2019 Samsung
8  * ===================================================================
9  *  Modifications Copyright (C) 2019 IBM 
10  * ===================================================================
11  *  Licensed under the Apache License, Version 2.0 (the "License");
12  *  you may not use this file except in compliance with the License.
13  *  You may obtain a copy of the License at
14  * 
15  *     http://www.apache.org/licenses/LICENSE-2.0
16  * 
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS,
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  * 
23  * ============LICENSE_END=============================================
24  * ====================================================================
25  */
26
27 package org.onap.music.datastore.jsonobjects;
28
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.ws.rs.core.MultivaluedMap;
33 import javax.ws.rs.core.Response.Status;
34
35 import org.onap.music.datastore.Condition;
36 import org.onap.music.datastore.MusicDataStoreHandle;
37 import org.onap.music.datastore.PreparedQueryObject;
38 import org.onap.music.eelf.logging.EELFLoggerDelegate;
39 import org.onap.music.eelf.logging.format.AppMessages;
40 import org.onap.music.eelf.logging.format.ErrorSeverity;
41 import org.onap.music.eelf.logging.format.ErrorTypes;
42 import org.onap.music.exceptions.MusicQueryException;
43 import org.onap.music.exceptions.MusicServiceException;
44 import org.onap.music.main.MusicUtil;
45
46 import com.datastax.driver.core.DataType;
47 import com.datastax.driver.core.TableMetadata;
48 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
49
50 import io.swagger.annotations.ApiModel;
51 import io.swagger.annotations.ApiModelProperty;
52
53 @ApiModel(value = "JsonTable", description = "Json model for delete")
54 @JsonIgnoreProperties(ignoreUnknown = true)
55 public class JsonDelete {
56
57     private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonDelete.class);
58     
59     private List<String> columns = null;
60     private Map<String, String> consistencyInfo;
61     private Map<String, Object> conditions;
62     private String ttl;
63     private String timestamp;
64     private String keyspaceName;
65     private String tableName;
66     private StringBuilder rowIdString;
67     private String primarKeyValue;
68
69
70     @ApiModelProperty(value = "Conditions")
71     public Map<String, Object> getConditions() {
72         return conditions;
73     }
74
75     public void setConditions(Map<String, Object> conditions) {
76         this.conditions = conditions;
77     }
78
79     @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
80     public Map<String, String> getConsistencyInfo() {
81         return consistencyInfo;
82     }
83
84     public void setConsistencyInfo(Map<String, String> consistencyInfo) {
85         this.consistencyInfo = consistencyInfo;
86     }
87
88     @ApiModelProperty(value = "Column values")
89     public List<String> getColumns() {
90         return columns;
91     }
92
93     public void setColumns(List<String> columns) {
94         this.columns = columns;
95     }
96
97
98     @ApiModelProperty(value = "Time to live information")
99     public String getTtl() {
100         return ttl;
101     }
102
103     public void setTtl(String ttl) {
104         this.ttl = ttl;
105     }
106
107     @ApiModelProperty(value = "Time stamp")
108     public String getTimestamp() {
109         return timestamp;
110     }
111
112     public void setTimestamp(String timestamp) {
113         this.timestamp = timestamp;
114     }
115     
116     public String getKeyspaceName() {
117         return keyspaceName;
118     }
119
120     public void setKeyspaceName(String keyspaceName) {
121         this.keyspaceName = keyspaceName;
122     }
123
124     public String getTableName() {
125         return tableName;
126     }
127
128     public void setTableName(String tableName) {
129         this.tableName = tableName;
130     }
131
132     public StringBuilder getRowIdString() {
133         return rowIdString;
134     }
135
136     public void setRowIdString(StringBuilder rowIdString) {
137         this.rowIdString = rowIdString;
138     }
139
140     public String getPrimarKeyValue() {
141         return primarKeyValue;
142     }
143
144     public void setPrimarKeyValue(String primarKeyValue) {
145         this.primarKeyValue = primarKeyValue;
146     }
147
148     
149     public PreparedQueryObject genDeletePreparedQueryObj(MultivaluedMap<String, String> rowParams) throws MusicQueryException {
150         if (logger.isDebugEnabled()) {
151             logger.debug("Coming inside genUpdatePreparedQueryObj method " + this.getKeyspaceName());
152             logger.debug("Coming inside genUpdatePreparedQueryObj method " + this.getTableName());
153         }
154         
155         PreparedQueryObject queryObject = new PreparedQueryObject();
156         
157         if((this.getKeyspaceName() == null || this.getKeyspaceName().isEmpty()) 
158                 || (this.getTableName() == null || this.getTableName().isEmpty())){
159             /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
160                 .setError("one or more path parameters are not set, please check and try again")
161                 .toMap()).build();*/
162             
163             throw new MusicQueryException("one or more path parameters are not set, please check and try again",
164                      Status.BAD_REQUEST.getStatusCode());
165         }
166         
167         EELFLoggerDelegate.mdcPut("keyspace", "( "+this.getKeyspaceName()+" ) ");
168         
169         if(this == null) {
170             logger.error(EELFLoggerDelegate.errorLogger,"Required HTTP Request body is missing.", AppMessages.MISSINGDATA  ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
171             /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();*/
172             
173             throw new MusicQueryException("Required HTTP Request body is missing.",
174                      Status.BAD_REQUEST.getStatusCode());
175         }
176         StringBuilder columnString = new StringBuilder();
177
178         int counter = 0;
179         List<String> columnList = this.getColumns();
180         if (columnList != null) {
181             for (String column : columnList) {
182                 columnString.append(column);
183                 if (counter != columnList.size() - 1)
184                     columnString.append(",");
185                 counter = counter + 1;
186             }
187         }
188
189         // get the row specifier
190         RowIdentifier rowId = null;
191         try {
192             rowId = getRowIdentifier(this.getKeyspaceName(), this.getTableName(), rowParams, queryObject);
193             this.setRowIdString(rowId.rowIdString);
194             this.setPrimarKeyValue(rowId.primarKeyValue);
195             if(rowId == null || rowId.primarKeyValue.isEmpty()) {
196                 /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
197                         .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();*/
198                 
199                 throw new MusicQueryException("Mandatory WHERE clause is missing. Please check the input request.", 
200                         Status.BAD_REQUEST.getStatusCode());
201             }
202         } catch (MusicServiceException ex) {
203             logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes
204                 .GENERALSERVICEERROR, ex);
205             /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();*/
206             throw new MusicQueryException(AppMessages.UNKNOWNERROR.toString(), Status.BAD_REQUEST.getStatusCode());
207         }
208         String rowSpec = rowId.rowIdString.toString();
209
210         if ((columnList != null) && (!rowSpec.isEmpty())) {
211             queryObject.appendQueryString("DELETE " + columnString + " FROM " + this.getKeyspaceName() + "."
212                             + this.getTableName() + " WHERE " + rowSpec + ";");
213         }
214
215         if ((columnList == null) && (!rowSpec.isEmpty())) {
216             queryObject.appendQueryString("DELETE FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE "
217                             + rowSpec + ";");
218         }
219
220         if ((columnList != null) && (rowSpec.isEmpty())) {
221             queryObject.appendQueryString(
222                             "DELETE " + columnString + " FROM " + this.getKeyspaceName() + "." + rowSpec + ";");
223         }
224         // get the conditional, if any
225         Condition conditionInfo;
226         if (this.getConditions() == null) {
227             conditionInfo = null;
228         } else {
229             // to avoid parsing repeatedly, just send the select query to
230             // obtain row
231             PreparedQueryObject selectQuery = new PreparedQueryObject();
232             selectQuery.appendQueryString("SELECT *  FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE "
233                 + rowId.rowIdString + ";");
234             selectQuery.addValue(rowId.primarKeyValue);
235             conditionInfo = new Condition(this.getConditions(), selectQuery);
236         }
237
238         String consistency = this.getConsistencyInfo().get("type");
239
240
241         if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && this.getConsistencyInfo().get("consistency")!=null) {
242             if(MusicUtil.isValidConsistency(this.getConsistencyInfo().get("consistency"))) {
243                 queryObject.setConsistency(this.getConsistencyInfo().get("consistency"));
244             } else {
245                 /*return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR)
246                     .setError("Invalid Consistency type").toMap()).build();*/
247                 throw new MusicQueryException("Invalid Consistency type", Status.BAD_REQUEST.getStatusCode());
248             }
249         }
250         
251         queryObject.setOperation("delete");
252         
253         return queryObject;
254     }    
255     
256     
257     /**
258     *
259     * @param keyspace
260     * @param tablename
261     * @param rowParams
262     * @param queryObject
263     * @return
264     * @throws MusicServiceException
265     */
266    private RowIdentifier getRowIdentifier(String keyspace, String tablename,
267        MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
268        throws MusicServiceException {
269        StringBuilder rowSpec = new StringBuilder();
270        int counter = 0;
271        TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename);
272        if (tableInfo == null) {
273            logger.error(EELFLoggerDelegate.errorLogger,
274                "Table information not found. Please check input for table name= "
275                + keyspace + "." + tablename);
276            throw new MusicServiceException(
277                "Table information not found. Please check input for table name= "
278                + keyspace + "." + tablename);
279        }
280        StringBuilder primaryKey = new StringBuilder();
281        for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
282            String keyName = entry.getKey();
283            List<String> valueList = entry.getValue();
284            String indValue = valueList.get(0);
285            DataType colType = null;
286            Object formattedValue = null;
287            try {
288                colType = tableInfo.getColumn(entry.getKey()).getType();
289                formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
290            } catch (Exception e) {
291                logger.error(EELFLoggerDelegate.errorLogger,e);
292            }
293            if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) {
294                primaryKey.append(indValue);
295            }
296            rowSpec.append(keyName + "= ?");
297            queryObject.addValue(formattedValue);
298            if (counter != rowParams.size() - 1) {
299                rowSpec.append(" AND ");
300            }
301            counter = counter + 1;
302        }
303        return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
304     }
305    
306     private class RowIdentifier {
307        public String primarKeyValue;
308        public StringBuilder rowIdString;
309        @SuppressWarnings("unused")
310        public PreparedQueryObject queryObject; // the string with all the row
311                                                // identifiers separated by AND
312
313        public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
314                        PreparedQueryObject queryObject) {
315            this.primarKeyValue = primaryKeyValue;
316            this.rowIdString = rowIdString;
317            this.queryObject = queryObject;
318        }
319    }
320 }