Merge "CLM Changes"
[music.git] / src / main / java / org / onap / music / rest / RestMusicDataAPI.java
1 /*
2  * ============LICENSE_START========================================== org.onap.music
3  * =================================================================== Copyright (c) 2017 AT&T
4  * Intellectual Property ===================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6  * in compliance with the License. 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 distributed under the License
11  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12  * or implied. See the License for the specific language governing permissions and limitations under
13  * the License.
14  * 
15  * ============LICENSE_END=============================================
16  * ====================================================================
17  */
18 package org.onap.music.rest;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.UUID;
25 import javax.servlet.http.HttpServletResponse;
26 import javax.ws.rs.Consumes;
27 import javax.ws.rs.DELETE;
28 import javax.ws.rs.GET;
29 import javax.ws.rs.HeaderParam;
30 import javax.ws.rs.POST;
31 import javax.ws.rs.PUT;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.core.Context;
36 import javax.ws.rs.core.MediaType;
37 import javax.ws.rs.core.MultivaluedMap;
38 import javax.ws.rs.core.UriInfo;
39 import org.onap.music.datastore.PreparedQueryObject;
40 import org.onap.music.datastore.jsonobjects.JsonDelete;
41 import org.onap.music.datastore.jsonobjects.JsonInsert;
42 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
43 import org.onap.music.datastore.jsonobjects.JsonTable;
44 import org.onap.music.datastore.jsonobjects.JsonUpdate;
45 import org.onap.music.eelf.logging.EELFLoggerDelegate;
46 import org.onap.music.exceptions.MusicLockingException;
47 import org.onap.music.eelf.logging.format.AppMessages;
48 import org.onap.music.eelf.logging.format.ErrorSeverity;
49 import org.onap.music.eelf.logging.format.ErrorTypes;
50 import org.onap.music.exceptions.MusicServiceException;
51 import org.onap.music.main.CachingUtil;
52 import org.onap.music.main.MusicCore;
53 import org.onap.music.main.MusicCore.Condition;
54 import org.onap.music.main.MusicUtil;
55 import org.onap.music.main.ResultType;
56 import org.onap.music.main.ReturnType;
57 import org.onap.music.response.jsonobjects.JsonResponse;
58
59 import com.att.eelf.configuration.EELFLogger;
60 import com.datastax.driver.core.DataType;
61 import com.datastax.driver.core.ResultSet;
62 import com.datastax.driver.core.Row;
63 import com.datastax.driver.core.TableMetadata;
64 import io.swagger.annotations.Api;
65 import io.swagger.annotations.ApiOperation;
66 import io.swagger.annotations.ApiParam;
67
68 @Path("/v{version: [0-9]+}/keyspaces")
69 @Api(value = "Data Api")
70 public class RestMusicDataAPI {
71     /*
72      * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
73      * version back from the client to the server, and from the server back to the client - This
74      * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
75      * version (if not specified by the client on the request) - Contains a single position value
76      * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
77      * request; however, this header should be provided if the client needs to take advantage of
78      * MINOR incremented version functionality - Is mandatory for the server on response
79      * 
80      *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
81      * troubleshooting purposes only, and will not be provided by the client on request - This will
82      * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
83      * of the MAJOR (if not specified by the client on the request) - Contains a single position
84      * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
85      * server on response
86      *
87      *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
88      * server on response, and shall include the entire version of the API (e.g. if the full version
89      * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
90      * not using the latest version of the API
91      *
92      */
93
94     private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
95     private static String xLatestVersion = "X-latestVersion";
96
97     private class RowIdentifier {
98         public String primarKeyValue;
99         public StringBuilder rowIdString;
100         @SuppressWarnings("unused")
101         public PreparedQueryObject queryObject;// the string with all the row
102                                                // identifiers separated by AND
103
104         public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
105                         PreparedQueryObject queryObject) {
106             this.primarKeyValue = primaryKeyValue;
107             this.rowIdString = rowIdString;
108             this.queryObject = queryObject;
109         }
110     }
111
112     @SuppressWarnings("unused")
113     private String buildVersion(String major, String minor, String patch) {
114         if (minor != null) {
115             major += "." + minor;
116             if (patch != null) {
117                 major += "." + patch;
118             }
119         }
120         return major;
121     }
122
123     /**
124      * Create Keyspace REST
125      * 
126      * @param kspObject
127      * @param keyspaceName
128      * @return
129      * @throws Exception
130      */
131     @POST
132     @Path("/{name}")
133     @ApiOperation(value = "Create Keyspace", response = String.class)
134     @Consumes(MediaType.APPLICATION_JSON)
135     @Produces(MediaType.APPLICATION_JSON)
136     public Map<String, Object> createKeySpace(
137                     @ApiParam(value = "Major Version",
138                                     required = true) @PathParam("version") String version,
139                     @ApiParam(value = "Minor Version",
140                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
141                     @ApiParam(value = "Patch Version",
142                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
143                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
144                     @ApiParam(value = "Application namespace",
145                                     required = true) @HeaderParam("ns") String ns,
146                     @ApiParam(value = "userId",
147                                     required = true) @HeaderParam("userId") String userId,
148                     @ApiParam(value = "Password",
149                                     required = true) @HeaderParam("password") String password,
150                     JsonKeySpace kspObject,
151                     @ApiParam(value = "Keyspace Name",
152                                     required = true) @PathParam("name") String keyspaceName,
153                     @Context HttpServletResponse response) {
154         Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
155         response.addHeader(xLatestVersion, MusicUtil.getVersion());
156         if (!authMap.isEmpty()) {
157             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
158         }
159         if(kspObject == null || kspObject.getReplicationInfo() == null) {
160                 authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult());
161                 return authMap;
162         }
163
164         try {
165                 authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
166                                         "createKeySpace");
167                 } catch (Exception e) {
168                         logger.error(EELFLoggerDelegate.applicationLogger,
169                         "Exception while authenting the user.");
170                         return new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap();
171                 }
172         String newAid = null;
173         if (!authMap.isEmpty()) {
174             if (authMap.containsKey("aid")) {
175                 newAid = (String) authMap.get("aid");
176             } else {
177                 return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
178             }
179         }
180
181         String consistency = MusicUtil.EVENTUAL;// for now this needs only
182                                                 // eventual consistency
183
184         PreparedQueryObject queryObject = new PreparedQueryObject();
185         long start = System.currentTimeMillis();
186         Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
187         String repString = null;
188         try {
189             repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
190         } catch (Exception e) {
191             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
192         }
193         queryObject.appendQueryString(
194                         "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
195         if (kspObject.getDurabilityOfWrites() != null) {
196             queryObject.appendQueryString(
197                             " AND durable_writes = " + kspObject.getDurabilityOfWrites());
198         }
199
200         queryObject.appendQueryString(";");
201         long end = System.currentTimeMillis();
202         logger.info(EELFLoggerDelegate.applicationLogger,
203                         "Time taken for setting up query in create keyspace:" + (end - start));
204
205         ResultType result = ResultType.FAILURE;
206         try {
207             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
208             logger.error(EELFLoggerDelegate.errorLogger, "result = " + result);
209         } catch ( MusicServiceException ex) {
210             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
211             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
212         }
213         
214         try {
215             queryObject = new PreparedQueryObject();
216             queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
217                             + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
218             MusicCore.nonKeyRelatedPut(queryObject, consistency);
219             queryObject = new PreparedQueryObject();
220             queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
221                                 + " to '" + userId + "'");
222             queryObject.appendQueryString(";");
223             MusicCore.nonKeyRelatedPut(queryObject, consistency);
224         } catch (Exception e) {
225                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
226         }
227         
228         try {
229             boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
230             queryObject = new PreparedQueryObject();
231             queryObject.appendQueryString(
232                         "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
233                                         + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
234             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
235             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
236             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
237             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
238             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), password));
239             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
240             queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
241             CachingUtil.updateMusicCache(newAid, keyspaceName);
242             MusicCore.eventualPut(queryObject);
243         } catch (Exception e) {
244             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
245             return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
246         }
247         
248         return new JsonResponse(ResultType.SUCCESS).toMap();
249     }
250
251     /**
252      * 
253      * @param kspObject
254      * @param keyspaceName
255      * @return
256      * @throws Exception
257      */
258     @DELETE
259     @Path("/{name}")
260     @ApiOperation(value = "Delete Keyspace", response = String.class)
261     @Consumes(MediaType.APPLICATION_JSON)
262     @Produces(MediaType.APPLICATION_JSON)
263     public Map<String, Object> dropKeySpace(
264                     @ApiParam(value = "Major Version",
265                                     required = true) @PathParam("version") String version,
266                     @ApiParam(value = "Minor Version",
267                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
268                     @ApiParam(value = "Patch Version",
269                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
270                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
271                     @ApiParam(value = "Application namespace",
272                                     required = true) @HeaderParam("ns") String ns,
273                     @ApiParam(value = "userId",
274                                     required = true) @HeaderParam("userId") String userId,
275                     @ApiParam(value = "Password",
276                                     required = true) @HeaderParam("password") String password,
277                     JsonKeySpace kspObject,
278                     @ApiParam(value = "Keyspace Name",
279                                     required = true) @PathParam("name") String keyspaceName,
280                     @Context HttpServletResponse response) throws Exception {
281         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,
282                         keyspaceName, aid, "dropKeySpace");
283         response.addHeader(xLatestVersion, MusicUtil.getVersion());
284         if (authMap.containsKey("aid"))
285                 authMap.remove("aid");
286         if (!authMap.isEmpty()) {
287             return authMap;
288         }
289
290         String consistency = MusicUtil.EVENTUAL;// for now this needs only
291                                                 // eventual
292         // consistency
293         String appName = CachingUtil.getAppName(keyspaceName);
294         String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
295         PreparedQueryObject pQuery = new PreparedQueryObject();
296         pQuery.appendQueryString(
297                         "select  count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
298         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
299         Row row = MusicCore.get(pQuery).one();
300         long count = row.getLong(0);
301
302         if (count == 0) {
303             return new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap();
304         } else if (count == 1) {
305             pQuery = new PreparedQueryObject();
306             pQuery.appendQueryString(
307                     "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
308             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
309                     MusicUtil.DEFAULTKEYSPACENAME));
310             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
311             MusicCore.nonKeyRelatedPut(pQuery, consistency);
312         } else {
313             pQuery = new PreparedQueryObject();
314             pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
315             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
316             MusicCore.nonKeyRelatedPut(pQuery, consistency);
317         }
318
319         PreparedQueryObject queryObject = new PreparedQueryObject();
320         queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
321         return new JsonResponse(MusicCore.nonKeyRelatedPut(queryObject, consistency)).toMap();
322     }
323
324     /**
325      * 
326      * @param tableObj
327      * @param keyspace
328      * @param tablename
329      * @return
330      * @throws Exception
331      */
332     @POST
333     @Path("/{keyspace}/tables/{tablename}")
334     @ApiOperation(value = "Create Table", response = String.class)
335     @Consumes(MediaType.APPLICATION_JSON)
336     @Produces(MediaType.APPLICATION_JSON)
337     public Map<String, Object> createTable(
338                     @ApiParam(value = "Major Version",
339                                     required = true) @PathParam("version") String version,
340                     @ApiParam(value = "Minor Version",
341                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
342                     @ApiParam(value = "Patch Version",
343                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
344                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
345                     @ApiParam(value = "Application namespace",
346                                     required = true) @HeaderParam("ns") String ns,
347                     @ApiParam(value = "userId",
348                                     required = true) @HeaderParam("userId") String userId,
349                     @ApiParam(value = "Password",
350                                     required = true) @HeaderParam("password") String password,
351                     JsonTable tableObj,
352                     @ApiParam(value = "Keyspace Name",
353                                     required = true) @PathParam("keyspace") String keyspace,
354                     @ApiParam(value = "Table Name",
355                                     required = true) @PathParam("tablename") String tablename,
356                     @Context HttpServletResponse response) throws Exception {
357         
358         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
359                         aid, "createTable");
360         response.addHeader(xLatestVersion, MusicUtil.getVersion());
361         if (authMap.containsKey("aid"))
362                 authMap.remove("aid");
363         if (!authMap.isEmpty()) {
364             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
365         }
366         String consistency = MusicUtil.EVENTUAL;
367         // for now this needs only eventual consistency
368         PreparedQueryObject queryObject = new PreparedQueryObject();
369         // first read the information about the table fields
370         Map<String, String> fields = tableObj.getFields();
371         StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
372         int counter = 0;
373         String primaryKey;
374         for (Map.Entry<String, String> entry : fields.entrySet()) {
375             
376             if (entry.getKey().equals("PRIMARY KEY")) {
377                 if(! entry.getValue().contains("("))
378                         primaryKey = entry.getValue();
379                 else {
380                         primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
381                         primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
382                 }
383                 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
384             } else
385                 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
386             if (counter == fields.size() - 1)
387                 fieldsString.append(")");
388             else
389                 fieldsString.append(",");
390             counter = counter + 1;
391         }
392         // information about the name-value style properties
393         Map<String, Object> propertiesMap = tableObj.getProperties();
394         StringBuilder propertiesString = new StringBuilder();
395         if (propertiesMap != null) {
396             counter = 0;
397             for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
398                 Object ot = entry.getValue();
399                 String value = ot + "";
400                 if (ot instanceof String) {
401                     value = "'" + value + "'";
402                 } else if (ot instanceof Map) {
403                     @SuppressWarnings("unchecked")
404                     Map<String, Object> otMap = (Map<String, Object>) ot;
405                     value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
406                 }
407
408                 propertiesString.append(entry.getKey() + "=" + value + "");
409                 if (counter != propertiesMap.size() - 1)
410                     propertiesString.append(" AND ");
411
412                 counter = counter + 1;
413             }
414         }
415
416         queryObject.appendQueryString(
417                         "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
418
419         if (propertiesMap != null)
420             queryObject.appendQueryString(" WITH " + propertiesString);
421
422         queryObject.appendQueryString(";");
423         ResultType result = ResultType.FAILURE;
424
425         try {
426             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
427         } catch (MusicServiceException ex) {
428                 response.setStatus(400);
429             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
430         }
431
432         return new JsonResponse(result).toMap();
433     }
434
435     /**
436      * 
437      * @param keyspace
438      * @param tablename
439      * @param fieldName
440      * @param info
441      * @throws Exception
442      */
443     @POST
444     @Path("/{keyspace}/tables/{tablename}/index/{field}")
445     @ApiOperation(value = "Create Index", response = String.class)
446     @Produces(MediaType.APPLICATION_JSON)
447     public Map<String, Object> createIndex(
448                     @ApiParam(value = "Major Version",
449                                     required = true) @PathParam("version") String version,
450                     @ApiParam(value = "Minor Version",
451                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
452                     @ApiParam(value = "Patch Version",
453                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
454                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
455                     @ApiParam(value = "Application namespace",
456                                     required = true) @HeaderParam("ns") String ns,
457                     @ApiParam(value = "userId",
458                                     required = true) @HeaderParam("userId") String userId,
459                     @ApiParam(value = "Password",
460                                     required = true) @HeaderParam("password") String password,
461                     @ApiParam(value = "Keyspace Name",
462                                     required = true) @PathParam("keyspace") String keyspace,
463                     @ApiParam(value = "Table Name",
464                                     required = true) @PathParam("tablename") String tablename,
465                     @ApiParam(value = "Field Name",
466                                     required = true) @PathParam("field") String fieldName,
467                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
468         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
469                         aid, "createIndex");
470         response.addHeader(xLatestVersion, MusicUtil.getVersion());
471         if (authMap.containsKey("aid"))
472                 authMap.remove("aid");
473         if (!authMap.isEmpty())
474             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
475         MultivaluedMap<String, String> rowParams = info.getQueryParameters();
476         String indexName = "";
477         if (rowParams.getFirst("index_name") != null)
478             indexName = rowParams.getFirst("index_name");
479         PreparedQueryObject query = new PreparedQueryObject();
480         query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
481                         + tablename + " (" + fieldName + ");");
482         
483         ResultType result = ResultType.FAILURE;
484         try {
485             result = MusicCore.nonKeyRelatedPut(query, "eventual");
486         } catch (MusicServiceException ex) {
487             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
488         }
489
490         return new JsonResponse(result).toMap();
491     }
492
493     /**
494      * 
495      * @param insObj
496      * @param keyspace
497      * @param tablename
498      * @return
499      * @throws Exception
500      */
501     @POST
502     @Path("/{keyspace}/tables/{tablename}/rows")
503     @ApiOperation(value = "Insert Into Table", response = String.class)
504     @Consumes(MediaType.APPLICATION_JSON)
505     @Produces(MediaType.APPLICATION_JSON)
506     public Map<String, Object> insertIntoTable(
507                     @ApiParam(value = "Major Version",
508                                     required = true) @PathParam("version") String version,
509                     @ApiParam(value = "Minor Version",
510                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
511                     @ApiParam(value = "Patch Version",
512                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
513                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
514                     @ApiParam(value = "Application namespace",
515                                     required = true) @HeaderParam("ns") String ns,
516                     @ApiParam(value = "userId",
517                                     required = true) @HeaderParam("userId") String userId,
518                     @ApiParam(value = "Password",
519                                     required = true) @HeaderParam("password") String password,
520                     JsonInsert insObj,
521                     @ApiParam(value = "Keyspace Name",
522                                     required = true) @PathParam("keyspace") String keyspace,
523                     @ApiParam(value = "Table Name",
524                                     required = true) @PathParam("tablename") String tablename,
525                     @Context HttpServletResponse response) {
526         Map<String, Object> authMap = null;
527         try {
528                 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
529                           aid, "insertIntoTable");
530         } catch (Exception e) {
531           logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
532           return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
533         }
534         response.addHeader(xLatestVersion, MusicUtil.getVersion());
535         if (authMap.containsKey("aid"))
536                 authMap.remove("aid");
537         if (!authMap.isEmpty()) {
538             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
539         }
540
541         Map<String, Object> valuesMap = insObj.getValues();
542         PreparedQueryObject queryObject = new PreparedQueryObject();
543         TableMetadata tableInfo = null;
544                 try {
545                         tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
546                         if(tableInfo == null) {
547                                 return new JsonResponse(ResultType.FAILURE)
548                                                 .setError("Table name doesn't exists. Please check the table name.").toMap();
549                         }
550                 } catch (MusicServiceException e) {
551                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
552                         return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
553                 }
554         String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
555         StringBuilder fieldsString = new StringBuilder("(vector_ts,");
556         String vectorTs =
557                         String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
558         StringBuilder valueString = new StringBuilder("(" + "?" + ",");
559         queryObject.addValue(vectorTs);
560         int counter = 0;
561         String primaryKey = "";
562
563         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
564             fieldsString.append("" + entry.getKey());
565             Object valueObj = entry.getValue();
566             if (primaryKeyName.equals(entry.getKey())) {
567                 primaryKey = entry.getValue() + "";
568                 primaryKey = primaryKey.replace("'", "''");
569             }
570             DataType colType = null;
571             try {
572                 colType = tableInfo.getColumn(entry.getKey()).getType();
573             } catch(NullPointerException ex) {
574                 logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
575                 return new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap();
576             }
577
578             Object formattedValue = null;
579             try {
580               formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
581             } catch (Exception e) {
582               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
583           }
584             valueString.append("?");
585             queryObject.addValue(formattedValue);
586
587             if (counter == valuesMap.size() - 1) {
588                 fieldsString.append(")");
589                 valueString.append(")");
590             } else {
591                 fieldsString.append(",");
592                 valueString.append(",");
593             }
594             counter = counter + 1;
595         }
596         
597         if(primaryKey == null || primaryKey.length() <= 0) {
598                 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
599                         return new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap();
600         }
601
602         queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
603                         + fieldsString + " VALUES " + valueString);
604
605         String ttl = insObj.getTtl();
606         String timestamp = insObj.getTimestamp();
607
608         if ((ttl != null) && (timestamp != null)) {
609             logger.info(EELFLoggerDelegate.applicationLogger, "both there");
610             queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
611             queryObject.addValue(Integer.parseInt(ttl));
612             queryObject.addValue(Long.parseLong(timestamp));
613         }
614
615         if ((ttl != null) && (timestamp == null)) {
616             logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
617             queryObject.appendQueryString(" USING TTL ?");
618             queryObject.addValue(Integer.parseInt(ttl));
619         }
620
621         if ((ttl == null) && (timestamp != null)) {
622             logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
623             queryObject.appendQueryString(" USING TIMESTAMP ?");
624             queryObject.addValue(Long.parseLong(timestamp));
625         }
626
627         queryObject.appendQueryString(";");
628
629         ReturnType result = null;
630         String consistency = insObj.getConsistencyInfo().get("type");
631         try {
632             if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
633                 result = MusicCore.eventualPut(queryObject);
634             } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
635                 String lockId = insObj.getConsistencyInfo().get("lockId");
636                 if(lockId == null) {
637                     logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
638                             + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
639                     return new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
640                             + "and acquire lock or use ATOMIC instead of CRITICAL").toMap();
641                 }
642                 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,
643                                 null);
644             } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
645                 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
646
647             }
648             else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
649                 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
650
651             }
652         } catch (Exception ex) {
653                 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
654             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
655         }
656         
657         if (result==null) {
658                 return new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap();
659         }
660         return new JsonResponse(result.getResult()).toMap();
661     }
662
663     /**
664      * 
665      * @param insObj
666      * @param keyspace
667      * @param tablename
668      * @param info
669      * @return
670      * @throws Exception
671      */
672     @PUT
673     @Path("/{keyspace}/tables/{tablename}/rows")
674     @ApiOperation(value = "Update Table", response = String.class)
675     @Consumes(MediaType.APPLICATION_JSON)
676     @Produces(MediaType.APPLICATION_JSON)
677     public Map<String, Object> updateTable(
678                     @ApiParam(value = "Major Version",
679                                     required = true) @PathParam("version") String version,
680                     @ApiParam(value = "Minor Version",
681                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
682                     @ApiParam(value = "Patch Version",
683                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
684                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
685                     @ApiParam(value = "Application namespace",
686                                     required = true) @HeaderParam("ns") String ns,
687                     @ApiParam(value = "userId",
688                                     required = true) @HeaderParam("userId") String userId,
689                     @ApiParam(value = "Password",
690                                     required = true) @HeaderParam("password") String password,
691                     JsonUpdate updateObj,
692                     @ApiParam(value = "Keyspace Name",
693                                     required = true) @PathParam("keyspace") String keyspace,
694                     @ApiParam(value = "Table Name",
695                                     required = true) @PathParam("tablename") String tablename,
696                     @Context UriInfo info, @Context HttpServletResponse response) {
697         Map<String, Object> authMap;
698         try {
699                 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
700                           aid, "updateTable");
701         } catch (Exception e) {
702           logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
703           return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
704         }
705         response.addHeader(xLatestVersion, MusicUtil.getVersion());
706         if (authMap.containsKey("aid"))
707                 authMap.remove("aid");
708         if (!authMap.isEmpty()) {
709             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
710         }
711         long startTime = System.currentTimeMillis();
712         String operationId = UUID.randomUUID().toString();// just for infoging
713                                                           // purposes.
714         String consistency = updateObj.getConsistencyInfo().get("type");
715         logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
716                         + " update-" + operationId + "-------------------------");
717         // obtain the field value pairs of the update
718
719         PreparedQueryObject queryObject = new PreparedQueryObject();
720         Map<String, Object> valuesMap = updateObj.getValues();
721
722         TableMetadata tableInfo;
723                 try {
724                         tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
725                 } catch (MusicServiceException e) {
726                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
727                         return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
728                 }
729         if (tableInfo == null) {
730             return new JsonResponse(ResultType.FAILURE)
731                             .setError("Table information not found. Please check input for table name= "
732                                             + keyspace + "." + tablename).toMap();
733         }
734         String vectorTs =
735                         String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
736         StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
737         queryObject.addValue(vectorTs);
738         int counter = 0;
739         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
740             Object valueObj = entry.getValue();
741             DataType colType = null;
742             try {
743                 colType = tableInfo.getColumn(entry.getKey()).getType();
744             } catch(NullPointerException ex) {
745                 logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
746                 return new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap();
747             }
748             Object valueString = null;
749             try {
750               valueString = MusicUtil.convertToActualDataType(colType, valueObj);
751             } catch (Exception e) {
752               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
753             }
754             fieldValueString.append(entry.getKey() + "= ?");
755             queryObject.addValue(valueString);
756             if (counter != valuesMap.size() - 1)
757                 fieldValueString.append(",");
758             counter = counter + 1;
759         }
760         String ttl = updateObj.getTtl();
761         String timestamp = updateObj.getTimestamp();
762
763         queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
764         if ((ttl != null) && (timestamp != null)) {
765
766             logger.info("both there");
767             queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
768             queryObject.addValue(Integer.parseInt(ttl));
769             queryObject.addValue(Long.parseLong(timestamp));
770         }
771
772         if ((ttl != null) && (timestamp == null)) {
773             logger.info("ONLY TTL there");
774             queryObject.appendQueryString(" USING TTL ?");
775             queryObject.addValue(Integer.parseInt(ttl));
776         }
777
778         if ((ttl == null) && (timestamp != null)) {
779             logger.info("ONLY timestamp there");
780             queryObject.appendQueryString(" USING TIMESTAMP ?");
781             queryObject.addValue(Long.parseLong(timestamp));
782         }
783         // get the row specifier
784         RowIdentifier rowId = null;
785         try {
786             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
787             if(rowId == null || rowId.primarKeyValue.isEmpty()) {
788                 
789                 return new JsonResponse(ResultType.FAILURE)
790                                 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap();
791             }
792         } catch (MusicServiceException ex) {
793             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage());
794             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
795         }
796
797         queryObject.appendQueryString(
798                         " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
799
800         // get the conditional, if any
801         Condition conditionInfo;
802         if (updateObj.getConditions() == null)
803             conditionInfo = null;
804         else {// to avoid parsing repeatedly, just send the select query to
805               // obtain row
806             PreparedQueryObject selectQuery = new PreparedQueryObject();
807             selectQuery.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + " WHERE "
808                             + rowId.rowIdString + ";");
809             selectQuery.addValue(rowId.primarKeyValue);
810             conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
811         }
812
813         ReturnType operationResult = null;
814         long jsonParseCompletionTime = System.currentTimeMillis();
815
816         if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
817             operationResult = MusicCore.eventualPut(queryObject);
818         else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
819             String lockId = updateObj.getConsistencyInfo().get("lockId");
820             if(lockId == null) {
821                 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
822                         + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
823                 return new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
824                         + "and acquire lock or use ATOMIC instead of CRITICAL").toMap();
825             }
826             operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
827                             queryObject, lockId, conditionInfo);
828         } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
829             // this function is mainly for the benchmarks
830             try {
831               operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
832                               rowId.primarKeyValue, queryObject, conditionInfo);
833             } catch (MusicLockingException e) {
834                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
835                 return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
836             }
837         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
838             try {
839               operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
840                               queryObject, conditionInfo);
841             } catch (MusicLockingException e) {
842               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
843               return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
844             }
845         }
846         long actualUpdateCompletionTime = System.currentTimeMillis();
847
848         long endTime = System.currentTimeMillis();
849         String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
850                         + ":" + "|total operation time:" + (endTime - startTime)
851                         + "|json parsing time:" + (jsonParseCompletionTime - startTime)
852                         + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
853                         + "|";
854
855         if (operationResult != null && operationResult.getTimingInfo() != null) {
856             String lockManagementTime = operationResult.getTimingInfo();
857             timingString = timingString + lockManagementTime;
858         }
859         logger.info(EELFLoggerDelegate.applicationLogger, timingString);
860         
861         if (operationResult==null) {
862                 return new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap();
863         }
864         return new JsonResponse(operationResult.getResult()).toMap();
865     }
866
867     /**
868      * 
869      * @param delObj
870      * @param keyspace
871      * @param tablename
872      * @param info
873      * @return
874      * @throws Exception
875      */
876     @DELETE
877     @Path("/{keyspace}/tables/{tablename}/rows")
878     @ApiOperation(value = "Delete From table", response = String.class)
879     @Consumes(MediaType.APPLICATION_JSON)
880     @Produces(MediaType.APPLICATION_JSON)
881     public Map<String, Object> deleteFromTable(
882                     @ApiParam(value = "Major Version",
883                                     required = true) @PathParam("version") String version,
884                     @ApiParam(value = "Minor Version",
885                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
886                     @ApiParam(value = "Patch Version",
887                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
888                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
889                     @ApiParam(value = "Application namespace",
890                                     required = true) @HeaderParam("ns") String ns,
891                     @ApiParam(value = "userId",
892                                     required = true) @HeaderParam("userId") String userId,
893                     @ApiParam(value = "Password",
894                                     required = true) @HeaderParam("password") String password,
895                     JsonDelete delObj,
896                     @ApiParam(value = "Keyspace Name",
897                                     required = true) @PathParam("keyspace") String keyspace,
898                     @ApiParam(value = "Table Name",
899                                     required = true) @PathParam("tablename") String tablename,
900                     @Context UriInfo info, @Context HttpServletResponse response) {
901         Map<String, Object> authMap = null;
902                 try {
903                         authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
904                                         aid, "deleteFromTable");
905                 } catch (Exception e) {
906                         return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
907                 }
908         response.addHeader(xLatestVersion, MusicUtil.getVersion());
909         if (authMap.containsKey("aid"))
910                 authMap.remove("aid");
911         if (!authMap.isEmpty()) {
912             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
913         }
914         if(delObj == null) {
915                         return new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap();
916                 }
917         PreparedQueryObject queryObject = new PreparedQueryObject();
918         StringBuilder columnString = new StringBuilder();
919
920         int counter = 0;
921         ArrayList<String> columnList = delObj.getColumns();
922         if (columnList != null) {
923             for (String column : columnList) {
924                 columnString.append(column);
925                 if (counter != columnList.size() - 1)
926                     columnString.append(",");
927                 counter = counter + 1;
928             }
929         }
930
931         // get the row specifier
932         RowIdentifier rowId = null;
933         try {
934             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
935         } catch (MusicServiceException ex) {
936             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
937         }
938         String rowSpec = rowId.rowIdString.toString();
939
940         if ((columnList != null) && (!rowSpec.isEmpty())) {
941             queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
942                             + tablename + " WHERE " + rowSpec + ";");
943         }
944
945         if ((columnList == null) && (!rowSpec.isEmpty())) {
946             queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
947                             + rowSpec + ";");
948         }
949
950         if ((columnList != null) && (rowSpec.isEmpty())) {
951             queryObject.appendQueryString(
952                             "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
953         }
954         // get the conditional, if any
955         Condition conditionInfo;
956         if (delObj.getConditions() == null)
957             conditionInfo = null;
958         else {// to avoid parsing repeatedly, just send the select query to
959               // obtain row
960             PreparedQueryObject selectQuery = new PreparedQueryObject();
961             selectQuery.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + " WHERE "
962                             + rowId.rowIdString + ";");
963             selectQuery.addValue(rowId.primarKeyValue);
964             conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
965         }
966
967         String consistency = delObj.getConsistencyInfo().get("type");
968
969         ReturnType operationResult = null;
970         try {
971                 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
972                     operationResult = MusicCore.eventualPut(queryObject);
973                 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
974                     String lockId = delObj.getConsistencyInfo().get("lockId");
975                     if(lockId == null) {
976                     logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
977                             + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
978                     return new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
979                             + "and acquire lock or use ATOMIC instead of CRITICAL").toMap();
980                 }
981                     operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
982                                     queryObject, lockId, conditionInfo);
983                 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
984                                         operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
985                                                         queryObject, conditionInfo);
986                 }
987                 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
988                                         operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
989                                                         queryObject, conditionInfo);
990                 }
991         } catch (MusicLockingException e) {
992                         return new JsonResponse(ResultType.FAILURE)
993                                         .setError("Unable to perform Delete operation. Exception from music").toMap();
994                 }
995         if (operationResult.getResult().equals(ResultType.FAILURE)) {
996                 return new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap();
997         }
998         return new JsonResponse(operationResult.getResult()).toMap();
999     }
1000
1001     /**
1002      * 
1003      * @param tabObj
1004      * @param keyspace
1005      * @param tablename
1006      * @throws Exception
1007      */
1008     @DELETE
1009     @Path("/{keyspace}/tables/{tablename}")
1010     @ApiOperation(value = "Drop Table", response = String.class)
1011     @Consumes(MediaType.APPLICATION_JSON)
1012     @Produces(MediaType.APPLICATION_JSON)
1013     public Map<String, Object> dropTable(
1014                     @ApiParam(value = "Major Version",
1015                                     required = true) @PathParam("version") String version,
1016                     @ApiParam(value = "Minor Version",
1017                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1018                     @ApiParam(value = "Patch Version",
1019                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1020                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1021                     @ApiParam(value = "Application namespace",
1022                                     required = true) @HeaderParam("ns") String ns,
1023                     @ApiParam(value = "userId",
1024                                     required = true) @HeaderParam("userId") String userId,
1025                     @ApiParam(value = "Password",
1026                                     required = true) @HeaderParam("password") String password,
1027                     JsonTable tabObj,
1028                     @ApiParam(value = "Keyspace Name",
1029                                     required = true) @PathParam("keyspace") String keyspace,
1030                     @ApiParam(value = "Table Name",
1031                                     required = true) @PathParam("tablename") String tablename,
1032                     @Context HttpServletResponse response) throws Exception {
1033         Map<String, Object> authMap =
1034                         MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1035         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1036         if (authMap.containsKey("aid"))
1037                 authMap.remove("aid");
1038         if (!authMap.isEmpty()) {
1039                 return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
1040         }
1041         String consistency = "eventual";// for now this needs only eventual
1042                                         // consistency
1043         PreparedQueryObject query = new PreparedQueryObject();
1044         query.appendQueryString("DROP TABLE  " + keyspace + "." + tablename + ";");
1045         try {
1046             return new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap();
1047         } catch (MusicServiceException ex) {
1048             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1049         }
1050
1051     }
1052
1053     /**
1054      * 
1055      * @param selObj
1056      * @param keyspace
1057      * @param tablename
1058      * @param info
1059      * @return
1060      */
1061     @PUT
1062     @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
1063     @ApiOperation(value = "Select Critical", response = Map.class)
1064     @Consumes(MediaType.APPLICATION_JSON)
1065     @Produces(MediaType.APPLICATION_JSON)
1066     public Map<String, Object> selectCritical(
1067                     @ApiParam(value = "Major Version",
1068                                     required = true) @PathParam("version") String version,
1069                     @ApiParam(value = "Minor Version",
1070                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1071                     @ApiParam(value = "Patch Version",
1072                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1073                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1074                     @ApiParam(value = "Application namespace",
1075                                     required = true) @HeaderParam("ns") String ns,
1076                     @ApiParam(value = "userId",
1077                                     required = true) @HeaderParam("userId") String userId,
1078                     @ApiParam(value = "Password",
1079                                     required = true) @HeaderParam("password") String password,
1080                     JsonInsert selObj,
1081                     @ApiParam(value = "Keyspace Name",
1082                                     required = true) @PathParam("keyspace") String keyspace,
1083                     @ApiParam(value = "Table Name",
1084                                     required = true) @PathParam("tablename") String tablename,
1085                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
1086         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
1087                         aid, "selectCritical");
1088         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1089         if (authMap.containsKey("aid"))
1090                 authMap.remove("aid");
1091         if (!authMap.isEmpty()) {
1092             logger.error("Error while authentication... ");
1093             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
1094         }
1095         String lockId = selObj.getConsistencyInfo().get("lockId");
1096
1097         PreparedQueryObject queryObject = new PreparedQueryObject();
1098
1099         RowIdentifier rowId = null;
1100         try {
1101             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1102         } catch (MusicServiceException ex) {
1103             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1104         }
1105         queryObject.appendQueryString(
1106                         "SELECT *  FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1107
1108         ResultSet results = null;
1109
1110         String consistency = selObj.getConsistencyInfo().get("type");
1111
1112         if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1113                 if(lockId == null) {
1114                 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1115                         + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1116                 return new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1117                         + "and acquire lock or use ATOMIC instead of CRITICAL").toMap();
1118             }
1119             results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1120                             lockId);
1121         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1122             results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1123         }
1124         
1125         else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1126             results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1127         }
1128
1129         return new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap();
1130     }
1131
1132     /**
1133      * 
1134      * @param keyspace
1135      * @param tablename
1136      * @param info
1137      * @return
1138      * @throws Exception
1139      */
1140     @GET
1141     @Path("/{keyspace}/tables/{tablename}/rows")
1142     @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1143     @Produces(MediaType.APPLICATION_JSON)
1144     public Map<String, Object> select(
1145                     @ApiParam(value = "Major Version",
1146                                     required = true) @PathParam("version") String version,
1147                     @ApiParam(value = "Minor Version",
1148                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1149                     @ApiParam(value = "Patch Version",
1150                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1151                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1152                     @ApiParam(value = "Application namespace",
1153                                     required = true) @HeaderParam("ns") String ns,
1154                     @ApiParam(value = "userId",
1155                                     required = true) @HeaderParam("userId") String userId,
1156                     @ApiParam(value = "Password",
1157                                     required = true) @HeaderParam("password") String password,
1158                     @ApiParam(value = "Keyspace Name",
1159                                     required = true) @PathParam("keyspace") String keyspace,
1160                     @ApiParam(value = "Table Name",
1161                                     required = true) @PathParam("tablename") String tablename,
1162                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
1163         Map<String, Object> authMap =
1164                         MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1165         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1166         if (authMap.containsKey("aid"))
1167                 authMap.remove("aid");
1168         if (!authMap.isEmpty()) {
1169                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1170                 return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
1171         }
1172         PreparedQueryObject queryObject = new PreparedQueryObject();
1173
1174         if (info.getQueryParameters().isEmpty())// select all
1175             queryObject.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + ";");
1176         else {
1177             int limit = -1; // do not limit the number of results
1178             try {
1179                 queryObject = selectSpecificQuery(version, minorVersion, patchVersion, aid, ns,
1180                                 userId, password, keyspace, tablename, info, limit);
1181             } catch (MusicServiceException ex) {
1182                 return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1183             }
1184         }
1185
1186         try {
1187             ResultSet results = MusicCore.get(queryObject);
1188             return new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap();
1189         } catch (MusicServiceException ex) {
1190                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR  ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1191             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1192         }
1193
1194     }
1195
1196     /**
1197      * 
1198      * @param keyspace
1199      * @param tablename
1200      * @param info
1201      * @param limit
1202      * @return
1203      * @throws MusicServiceException
1204      */
1205     public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1206                     String patchVersion, String aid, String ns, String userId, String password,
1207                     String keyspace, String tablename, UriInfo info, int limit)
1208                     throws MusicServiceException {
1209
1210         PreparedQueryObject queryObject = new PreparedQueryObject();
1211         StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1212                         queryObject).rowIdString;
1213
1214         queryObject.appendQueryString(
1215                         "SELECT *  FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1216
1217         if (limit != -1) {
1218             queryObject.appendQueryString(" LIMIT " + limit);
1219         }
1220
1221         queryObject.appendQueryString(";");
1222         return queryObject;
1223
1224     }
1225
1226     /**
1227      * 
1228      * @param keyspace
1229      * @param tablename
1230      * @param rowParams
1231      * @param queryObject
1232      * @return
1233      * @throws MusicServiceException
1234      */
1235     private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1236                     MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1237                     throws MusicServiceException {
1238         StringBuilder rowSpec = new StringBuilder();
1239         int counter = 0;
1240         TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1241         if (tableInfo == null) {
1242             logger.error(EELFLoggerDelegate.errorLogger,
1243                             "Table information not found. Please check input for table name= "
1244                                             + keyspace + "." + tablename);
1245             throw new MusicServiceException(
1246                             "Table information not found. Please check input for table name= "
1247                                             + keyspace + "." + tablename);
1248         }
1249         StringBuilder primaryKey = new StringBuilder();
1250         for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1251             String keyName = entry.getKey();
1252             List<String> valueList = entry.getValue();
1253             String indValue = valueList.get(0);
1254             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
1255             Object formattedValue = null;
1256             try {
1257               formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1258             } catch (Exception e) {
1259               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1260             }
1261             primaryKey.append(indValue);
1262             rowSpec.append(keyName + "= ?");
1263             queryObject.addValue(formattedValue);
1264             if (counter != rowParams.size() - 1)
1265                 rowSpec.append(" AND ");
1266             counter = counter + 1;
1267         }
1268         return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
1269     }
1270 }