bcdb8dd263f4a28f6c4f3f16477a71ed9a0b0682
[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, "resulta = " + result);
209         } catch (Exception e) {
210             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
211             return new JsonResponse(ResultType.FAILURE)
212                         .setError("Couldn't create keyspace. Please make sure all the information is correct.").toMap();
213         }
214
215         if (result==ResultType.FAILURE) {
216                 logger.info(EELFLoggerDelegate.applicationLogger, "Cannot create keyspace, cleaning up");
217                 JsonResponse resultJson = new JsonResponse(ResultType.FAILURE);
218             resultJson.setError("Keyspace already exists. Please contact admin.");
219             if (authMap.get("uuid").equals("new")) {
220                 queryObject = new PreparedQueryObject();
221                 queryObject.appendQueryString(
222                                 "DELETE FROM admin.keyspace_master where uuid = " + newAid);
223                 queryObject.appendQueryString(";");
224                 try {
225                                         MusicCore.nonKeyRelatedPut(queryObject, consistency);
226                                 } catch (MusicServiceException e) {
227                                         logger.error(EELFLoggerDelegate.errorLogger,
228                                                         "Error cleaning up createKeyspace. Cannot DELETE uuid. " + e.getMessage());
229                                 }
230                 return resultJson.toMap();
231             } else {
232                 queryObject = new PreparedQueryObject();
233                 queryObject.appendQueryString(
234                                 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
235                 try {
236                         queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(),
237                                 MusicUtil.DEFAULTKEYSPACENAME));
238                                         queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
239                                 } catch (Exception e) {
240                                         logger.error(EELFLoggerDelegate.errorLogger,
241                                                         "Error cleaning up createKeyspace. Cannot get correct data types" + e.getMessage());
242                                 }
243                 try {
244                                          MusicCore.nonKeyRelatedPut(queryObject, consistency);
245                                 } catch (MusicServiceException e) {
246                                         logger.error(EELFLoggerDelegate.errorLogger, "Unable to process operation. Error: "+e.getMessage());
247                                 }
248                 return resultJson.toMap();
249             }
250         }
251         
252         try {
253             queryObject = new PreparedQueryObject();
254             queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
255                             + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
256             MusicCore.nonKeyRelatedPut(queryObject, consistency);
257             queryObject = new PreparedQueryObject();
258             queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
259                                 + " to '" + userId + "'");
260             queryObject.appendQueryString(";");
261             MusicCore.nonKeyRelatedPut(queryObject, consistency);
262         } catch (Exception e) {
263                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
264         }
265         
266         return new JsonResponse(ResultType.SUCCESS).toMap();
267     }
268
269     /**
270      * 
271      * @param kspObject
272      * @param keyspaceName
273      * @return
274      * @throws Exception
275      */
276     @DELETE
277     @Path("/{name}")
278     @ApiOperation(value = "Delete Keyspace", response = String.class)
279     @Consumes(MediaType.APPLICATION_JSON)
280     @Produces(MediaType.APPLICATION_JSON)
281     public Map<String, Object> dropKeySpace(
282                     @ApiParam(value = "Major Version",
283                                     required = true) @PathParam("version") String version,
284                     @ApiParam(value = "Minor Version",
285                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
286                     @ApiParam(value = "Patch Version",
287                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
288                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
289                     @ApiParam(value = "Application namespace",
290                                     required = true) @HeaderParam("ns") String ns,
291                     @ApiParam(value = "userId",
292                                     required = true) @HeaderParam("userId") String userId,
293                     @ApiParam(value = "Password",
294                                     required = true) @HeaderParam("password") String password,
295                     JsonKeySpace kspObject,
296                     @ApiParam(value = "Keyspace Name",
297                                     required = true) @PathParam("name") String keyspaceName,
298                     @Context HttpServletResponse response) throws Exception {
299         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,
300                         keyspaceName, aid, "dropKeySpace");
301         response.addHeader(xLatestVersion, MusicUtil.getVersion());
302         if (authMap.containsKey("aid"))
303                 authMap.remove("aid");
304         if (!authMap.isEmpty()) {
305             return authMap;
306         }
307
308         String consistency = MusicUtil.EVENTUAL;// for now this needs only
309                                                 // eventual
310         // consistency
311         String appName = CachingUtil.getAppName(keyspaceName);
312         String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
313         PreparedQueryObject pQuery = new PreparedQueryObject();
314         pQuery.appendQueryString(
315                         "select  count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
316         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
317         Row row = MusicCore.get(pQuery).one();
318         long count = row.getLong(0);
319
320         if (count == 0) {
321             return new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap();
322         } else if (count == 1) {
323             pQuery = new PreparedQueryObject();
324             pQuery.appendQueryString(
325                     "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
326             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
327                     MusicUtil.DEFAULTKEYSPACENAME));
328             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
329             MusicCore.nonKeyRelatedPut(pQuery, consistency);
330         } else {
331             pQuery = new PreparedQueryObject();
332             pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
333             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
334             MusicCore.nonKeyRelatedPut(pQuery, consistency);
335         }
336
337         PreparedQueryObject queryObject = new PreparedQueryObject();
338         queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
339         return new JsonResponse(MusicCore.nonKeyRelatedPut(queryObject, consistency)).toMap();
340     }
341
342     /**
343      * 
344      * @param tableObj
345      * @param keyspace
346      * @param tablename
347      * @return
348      * @throws Exception
349      */
350     @POST
351     @Path("/{keyspace}/tables/{tablename}")
352     @ApiOperation(value = "Create Table", response = String.class)
353     @Consumes(MediaType.APPLICATION_JSON)
354     @Produces(MediaType.APPLICATION_JSON)
355     public Map<String, Object> createTable(
356                     @ApiParam(value = "Major Version",
357                                     required = true) @PathParam("version") String version,
358                     @ApiParam(value = "Minor Version",
359                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
360                     @ApiParam(value = "Patch Version",
361                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
362                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
363                     @ApiParam(value = "Application namespace",
364                                     required = true) @HeaderParam("ns") String ns,
365                     @ApiParam(value = "userId",
366                                     required = true) @HeaderParam("userId") String userId,
367                     @ApiParam(value = "Password",
368                                     required = true) @HeaderParam("password") String password,
369                     JsonTable tableObj,
370                     @ApiParam(value = "Keyspace Name",
371                                     required = true) @PathParam("keyspace") String keyspace,
372                     @ApiParam(value = "Table Name",
373                                     required = true) @PathParam("tablename") String tablename,
374                     @Context HttpServletResponse response) throws Exception {
375         
376         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
377                         aid, "createTable");
378         response.addHeader(xLatestVersion, MusicUtil.getVersion());
379         if (authMap.containsKey("aid"))
380                 authMap.remove("aid");
381         if (!authMap.isEmpty()) {
382             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
383         }
384         String consistency = MusicUtil.EVENTUAL;
385         // for now this needs only eventual consistency
386         PreparedQueryObject queryObject = new PreparedQueryObject();
387         // first read the information about the table fields
388         Map<String, String> fields = tableObj.getFields();
389         StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
390         int counter = 0;
391         String primaryKey;
392         for (Map.Entry<String, String> entry : fields.entrySet()) {
393             
394             if (entry.getKey().equals("PRIMARY KEY")) {
395                 if(! entry.getValue().contains("("))
396                         primaryKey = entry.getValue();
397                 else {
398                         primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
399                         primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
400                 }
401                 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
402             } else
403                 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
404             if (counter == fields.size() - 1)
405                 fieldsString.append(")");
406             else
407                 fieldsString.append(",");
408             counter = counter + 1;
409         }
410         // information about the name-value style properties
411         Map<String, Object> propertiesMap = tableObj.getProperties();
412         StringBuilder propertiesString = new StringBuilder();
413         if (propertiesMap != null) {
414             counter = 0;
415             for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
416                 Object ot = entry.getValue();
417                 String value = ot + "";
418                 if (ot instanceof String) {
419                     value = "'" + value + "'";
420                 } else if (ot instanceof Map) {
421                     @SuppressWarnings("unchecked")
422                     Map<String, Object> otMap = (Map<String, Object>) ot;
423                     value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
424                 }
425
426                 propertiesString.append(entry.getKey() + "=" + value + "");
427                 if (counter != propertiesMap.size() - 1)
428                     propertiesString.append(" AND ");
429
430                 counter = counter + 1;
431             }
432         }
433
434         queryObject.appendQueryString(
435                         "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
436
437         if (propertiesMap != null)
438             queryObject.appendQueryString(" WITH " + propertiesString);
439
440         queryObject.appendQueryString(";");
441         ResultType result = ResultType.FAILURE;
442
443         try {
444             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
445         } catch (MusicServiceException ex) {
446                 response.setStatus(400);
447             return new JsonResponse(result).toMap();
448         }
449
450         return new JsonResponse(result).toMap();
451     }
452
453     /**
454      * 
455      * @param keyspace
456      * @param tablename
457      * @param fieldName
458      * @param info
459      * @throws Exception
460      */
461     @POST
462     @Path("/{keyspace}/tables/{tablename}/index/{field}")
463     @ApiOperation(value = "Create Index", response = String.class)
464     @Produces(MediaType.APPLICATION_JSON)
465     public Map<String, Object> createIndex(
466                     @ApiParam(value = "Major Version",
467                                     required = true) @PathParam("version") String version,
468                     @ApiParam(value = "Minor Version",
469                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
470                     @ApiParam(value = "Patch Version",
471                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
472                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
473                     @ApiParam(value = "Application namespace",
474                                     required = true) @HeaderParam("ns") String ns,
475                     @ApiParam(value = "userId",
476                                     required = true) @HeaderParam("userId") String userId,
477                     @ApiParam(value = "Password",
478                                     required = true) @HeaderParam("password") String password,
479                     @ApiParam(value = "Keyspace Name",
480                                     required = true) @PathParam("keyspace") String keyspace,
481                     @ApiParam(value = "Table Name",
482                                     required = true) @PathParam("tablename") String tablename,
483                     @ApiParam(value = "Field Name",
484                                     required = true) @PathParam("field") String fieldName,
485                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
486         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
487                         aid, "createIndex");
488         response.addHeader(xLatestVersion, MusicUtil.getVersion());
489         if (authMap.containsKey("aid"))
490                 authMap.remove("aid");
491         if (!authMap.isEmpty())
492             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
493         MultivaluedMap<String, String> rowParams = info.getQueryParameters();
494         String indexName = "";
495         if (rowParams.getFirst("index_name") != null)
496             indexName = rowParams.getFirst("index_name");
497         PreparedQueryObject query = new PreparedQueryObject();
498         query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
499                         + tablename + " (" + fieldName + ");");
500         
501         ResultType result = ResultType.FAILURE;
502         try {
503             result = MusicCore.nonKeyRelatedPut(query, "eventual");
504         } catch (MusicServiceException ex) {
505             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
506         }
507
508         return new JsonResponse(result).toMap();
509     }
510
511     /**
512      * 
513      * @param insObj
514      * @param keyspace
515      * @param tablename
516      * @return
517      * @throws Exception
518      */
519     @POST
520     @Path("/{keyspace}/tables/{tablename}/rows")
521     @ApiOperation(value = "Insert Into Table", response = String.class)
522     @Consumes(MediaType.APPLICATION_JSON)
523     @Produces(MediaType.APPLICATION_JSON)
524     public Map<String, Object> insertIntoTable(
525                     @ApiParam(value = "Major Version",
526                                     required = true) @PathParam("version") String version,
527                     @ApiParam(value = "Minor Version",
528                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
529                     @ApiParam(value = "Patch Version",
530                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
531                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
532                     @ApiParam(value = "Application namespace",
533                                     required = true) @HeaderParam("ns") String ns,
534                     @ApiParam(value = "userId",
535                                     required = true) @HeaderParam("userId") String userId,
536                     @ApiParam(value = "Password",
537                                     required = true) @HeaderParam("password") String password,
538                     JsonInsert insObj,
539                     @ApiParam(value = "Keyspace Name",
540                                     required = true) @PathParam("keyspace") String keyspace,
541                     @ApiParam(value = "Table Name",
542                                     required = true) @PathParam("tablename") String tablename,
543                     @Context HttpServletResponse response) {
544         Map<String, Object> authMap = null;
545         try {
546                 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
547                           aid, "insertIntoTable");
548         } catch (Exception e) {
549           logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
550           return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
551         }
552         response.addHeader(xLatestVersion, MusicUtil.getVersion());
553         if (authMap.containsKey("aid"))
554                 authMap.remove("aid");
555         if (!authMap.isEmpty()) {
556             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
557         }
558
559         Map<String, Object> valuesMap = insObj.getValues();
560         PreparedQueryObject queryObject = new PreparedQueryObject();
561         TableMetadata tableInfo = null;
562                 try {
563                         tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
564                         if(tableInfo == null) {
565                                 return new JsonResponse(ResultType.FAILURE)
566                                                 .setError("Table name doesn't exists. Please check the table name.").toMap();
567                         }
568                 } catch (MusicServiceException e) {
569                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
570                         return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
571                 }
572         String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
573         StringBuilder fieldsString = new StringBuilder("(vector_ts,");
574         String vectorTs =
575                         String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
576         StringBuilder valueString = new StringBuilder("(" + "?" + ",");
577         queryObject.addValue(vectorTs);
578         int counter = 0;
579         String primaryKey = "";
580
581         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
582             fieldsString.append("" + entry.getKey());
583             Object valueObj = entry.getValue();
584             if (primaryKeyName.equals(entry.getKey())) {
585                 primaryKey = entry.getValue() + "";
586                 primaryKey = primaryKey.replace("'", "''");
587             }
588
589             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
590
591             Object formattedValue = null;
592             try {
593               formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
594             } catch (Exception e) {
595               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
596           }
597             valueString.append("?");
598             queryObject.addValue(formattedValue);
599
600             if (counter == valuesMap.size() - 1) {
601                 fieldsString.append(")");
602                 valueString.append(")");
603             } else {
604                 fieldsString.append(",");
605                 valueString.append(",");
606             }
607             counter = counter + 1;
608         }
609         
610         if(primaryKey == null || primaryKey.length() <= 0) {
611                 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
612                         return new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap();
613         }
614
615         queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
616                         + fieldsString + " VALUES " + valueString);
617
618         String ttl = insObj.getTtl();
619         String timestamp = insObj.getTimestamp();
620
621         if ((ttl != null) && (timestamp != null)) {
622             logger.info(EELFLoggerDelegate.applicationLogger, "both there");
623             queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
624             queryObject.addValue(Integer.parseInt(ttl));
625             queryObject.addValue(Long.parseLong(timestamp));
626         }
627
628         if ((ttl != null) && (timestamp == null)) {
629             logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
630             queryObject.appendQueryString(" USING TTL ?");
631             queryObject.addValue(Integer.parseInt(ttl));
632         }
633
634         if ((ttl == null) && (timestamp != null)) {
635             logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
636             queryObject.appendQueryString(" USING TIMESTAMP ?");
637             queryObject.addValue(Long.parseLong(timestamp));
638         }
639
640         queryObject.appendQueryString(";");
641
642         ReturnType result = null;
643         String consistency = insObj.getConsistencyInfo().get("type");
644         try {
645             if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
646                 result = MusicCore.eventualPut(queryObject);
647             } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
648                 String lockId = insObj.getConsistencyInfo().get("lockId");
649                 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,
650                                 null);
651             } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
652                 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
653
654             }
655             else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
656                 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
657
658             }
659         } catch (Exception ex) {
660                 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
661             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
662         }
663         
664         if (result==null) {
665                 return new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap();
666         }
667         return new JsonResponse(result.getResult()).toMap();
668     }
669
670     /**
671      * 
672      * @param insObj
673      * @param keyspace
674      * @param tablename
675      * @param info
676      * @return
677      * @throws Exception
678      */
679     @PUT
680     @Path("/{keyspace}/tables/{tablename}/rows")
681     @ApiOperation(value = "Update Table", response = String.class)
682     @Consumes(MediaType.APPLICATION_JSON)
683     @Produces(MediaType.APPLICATION_JSON)
684     public Map<String, Object> updateTable(
685                     @ApiParam(value = "Major Version",
686                                     required = true) @PathParam("version") String version,
687                     @ApiParam(value = "Minor Version",
688                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
689                     @ApiParam(value = "Patch Version",
690                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
691                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
692                     @ApiParam(value = "Application namespace",
693                                     required = true) @HeaderParam("ns") String ns,
694                     @ApiParam(value = "userId",
695                                     required = true) @HeaderParam("userId") String userId,
696                     @ApiParam(value = "Password",
697                                     required = true) @HeaderParam("password") String password,
698                     JsonUpdate updateObj,
699                     @ApiParam(value = "Keyspace Name",
700                                     required = true) @PathParam("keyspace") String keyspace,
701                     @ApiParam(value = "Table Name",
702                                     required = true) @PathParam("tablename") String tablename,
703                     @Context UriInfo info, @Context HttpServletResponse response) {
704         Map<String, Object> authMap;
705         try {
706                 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
707                           aid, "updateTable");
708         } catch (Exception e) {
709           logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
710           return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
711         }
712         response.addHeader(xLatestVersion, MusicUtil.getVersion());
713         if (authMap.containsKey("aid"))
714                 authMap.remove("aid");
715         if (!authMap.isEmpty()) {
716             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
717         }
718         long startTime = System.currentTimeMillis();
719         String operationId = UUID.randomUUID().toString();// just for infoging
720                                                           // purposes.
721         String consistency = updateObj.getConsistencyInfo().get("type");
722         logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
723                         + " update-" + operationId + "-------------------------");
724         // obtain the field value pairs of the update
725
726         PreparedQueryObject queryObject = new PreparedQueryObject();
727         Map<String, Object> valuesMap = updateObj.getValues();
728
729         TableMetadata tableInfo;
730                 try {
731                         tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
732                 } catch (MusicServiceException e) {
733                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
734                         return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
735                 }
736         if (tableInfo == null) {
737             return new JsonResponse(ResultType.FAILURE)
738                             .setError("Table information not found. Please check input for table name= "
739                                             + keyspace + "." + tablename).toMap();
740         }
741         String vectorTs =
742                         String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
743         StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
744         queryObject.addValue(vectorTs);
745         int counter = 0;
746         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
747             Object valueObj = entry.getValue();
748             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
749             Object valueString = null;
750             try {
751               valueString = MusicUtil.convertToActualDataType(colType, valueObj);
752             } catch (Exception e) {
753               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
754             }
755             fieldValueString.append(entry.getKey() + "= ?");
756             queryObject.addValue(valueString);
757             if (counter != valuesMap.size() - 1)
758                 fieldValueString.append(",");
759             counter = counter + 1;
760         }
761         String ttl = updateObj.getTtl();
762         String timestamp = updateObj.getTimestamp();
763
764         queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
765         if ((ttl != null) && (timestamp != null)) {
766
767             logger.info("both there");
768             queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
769             queryObject.addValue(Integer.parseInt(ttl));
770             queryObject.addValue(Long.parseLong(timestamp));
771         }
772
773         if ((ttl != null) && (timestamp == null)) {
774             logger.info("ONLY TTL there");
775             queryObject.appendQueryString(" USING TTL ?");
776             queryObject.addValue(Integer.parseInt(ttl));
777         }
778
779         if ((ttl == null) && (timestamp != null)) {
780             logger.info("ONLY timestamp there");
781             queryObject.appendQueryString(" USING TIMESTAMP ?");
782             queryObject.addValue(Long.parseLong(timestamp));
783         }
784         // get the row specifier
785         RowIdentifier rowId = null;
786         try {
787             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
788             if(rowId == null || rowId.primarKeyValue.isEmpty()) {
789                 
790                 return new JsonResponse(ResultType.FAILURE)
791                                 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap();
792             }
793         } catch (MusicServiceException ex) {
794             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage());
795             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
796         }
797
798         queryObject.appendQueryString(
799                         " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
800
801         // get the conditional, if any
802         Condition conditionInfo;
803         if (updateObj.getConditions() == null)
804             conditionInfo = null;
805         else {// to avoid parsing repeatedly, just send the select query to
806               // obtain row
807             PreparedQueryObject selectQuery = new PreparedQueryObject();
808             selectQuery.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + " WHERE "
809                             + rowId.rowIdString + ";");
810             selectQuery.addValue(rowId.primarKeyValue);
811             conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
812         }
813
814         ReturnType operationResult = null;
815         long jsonParseCompletionTime = System.currentTimeMillis();
816
817         if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
818             operationResult = MusicCore.eventualPut(queryObject);
819         else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
820             String lockId = updateObj.getConsistencyInfo().get("lockId");
821             operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
822                             queryObject, lockId, conditionInfo);
823         } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
824             // this function is mainly for the benchmarks
825             try {
826               operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
827                               rowId.primarKeyValue, queryObject, conditionInfo);
828             } catch (MusicLockingException e) {
829                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
830                 return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
831             }
832         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
833             try {
834               operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
835                               queryObject, conditionInfo);
836             } catch (MusicLockingException e) {
837               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
838               return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
839             }
840         }
841         long actualUpdateCompletionTime = System.currentTimeMillis();
842
843         long endTime = System.currentTimeMillis();
844         String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
845                         + ":" + "|total operation time:" + (endTime - startTime)
846                         + "|json parsing time:" + (jsonParseCompletionTime - startTime)
847                         + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
848                         + "|";
849
850         if (operationResult != null && operationResult.getTimingInfo() != null) {
851             String lockManagementTime = operationResult.getTimingInfo();
852             timingString = timingString + lockManagementTime;
853         }
854         logger.info(EELFLoggerDelegate.applicationLogger, timingString);
855         
856         if (operationResult==null) {
857                 return new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap();
858         }
859         return new JsonResponse(operationResult.getResult()).toMap();
860     }
861
862     /**
863      * 
864      * @param delObj
865      * @param keyspace
866      * @param tablename
867      * @param info
868      * @return
869      * @throws Exception
870      */
871     @DELETE
872     @Path("/{keyspace}/tables/{tablename}/rows")
873     @ApiOperation(value = "Delete From table", response = String.class)
874     @Consumes(MediaType.APPLICATION_JSON)
875     @Produces(MediaType.APPLICATION_JSON)
876     public Map<String, Object> deleteFromTable(
877                     @ApiParam(value = "Major Version",
878                                     required = true) @PathParam("version") String version,
879                     @ApiParam(value = "Minor Version",
880                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
881                     @ApiParam(value = "Patch Version",
882                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
883                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
884                     @ApiParam(value = "Application namespace",
885                                     required = true) @HeaderParam("ns") String ns,
886                     @ApiParam(value = "userId",
887                                     required = true) @HeaderParam("userId") String userId,
888                     @ApiParam(value = "Password",
889                                     required = true) @HeaderParam("password") String password,
890                     JsonDelete delObj,
891                     @ApiParam(value = "Keyspace Name",
892                                     required = true) @PathParam("keyspace") String keyspace,
893                     @ApiParam(value = "Table Name",
894                                     required = true) @PathParam("tablename") String tablename,
895                     @Context UriInfo info, @Context HttpServletResponse response) {
896         Map<String, Object> authMap = null;
897                 try {
898                         authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
899                                         aid, "deleteFromTable");
900                 } catch (Exception e) {
901                         return new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap();
902                 }
903         response.addHeader(xLatestVersion, MusicUtil.getVersion());
904         if (authMap.containsKey("aid"))
905                 authMap.remove("aid");
906         if (!authMap.isEmpty()) {
907             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
908         }
909         if(delObj == null) {
910                         return new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap();
911                 }
912         PreparedQueryObject queryObject = new PreparedQueryObject();
913         StringBuilder columnString = new StringBuilder();
914
915         int counter = 0;
916         ArrayList<String> columnList = delObj.getColumns();
917         if (columnList != null) {
918             for (String column : columnList) {
919                 columnString.append(column);
920                 if (counter != columnList.size() - 1)
921                     columnString.append(",");
922                 counter = counter + 1;
923             }
924         }
925
926         // get the row specifier
927         RowIdentifier rowId = null;
928         try {
929             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
930         } catch (MusicServiceException ex) {
931             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
932         }
933         String rowSpec = rowId.rowIdString.toString();
934
935         if ((columnList != null) && (!rowSpec.isEmpty())) {
936             queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
937                             + tablename + " WHERE " + rowSpec + ";");
938         }
939
940         if ((columnList == null) && (!rowSpec.isEmpty())) {
941             queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
942                             + rowSpec + ";");
943         }
944
945         if ((columnList != null) && (rowSpec.isEmpty())) {
946             queryObject.appendQueryString(
947                             "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
948         }
949
950         // get the conditional, if any
951         Condition conditionInfo;
952         if (delObj.getConditions() == null)
953             conditionInfo = null;
954         else {// to avoid parsing repeatedly, just send the select query to
955               // obtain row
956             PreparedQueryObject selectQuery = new PreparedQueryObject();
957             selectQuery.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + " WHERE "
958                             + rowId.rowIdString + ";");
959             selectQuery.addValue(rowId.primarKeyValue);
960             conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
961         }
962
963         String consistency = delObj.getConsistencyInfo().get("type");
964
965         ReturnType operationResult = null;
966         try {
967                 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
968                     operationResult = MusicCore.eventualPut(queryObject);
969                 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
970                     String lockId = delObj.getConsistencyInfo().get("lockId");
971                     operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
972                                     queryObject, lockId, conditionInfo);
973                 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
974                                         operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
975                                                         queryObject, conditionInfo);
976                 }
977                 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
978                                         operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
979                                                         queryObject, conditionInfo);
980                 }
981         } catch (MusicLockingException e) {
982                         return new JsonResponse(ResultType.FAILURE)
983                                         .setError("Unable to perform Delete operation. Exception from music").toMap();
984                 }
985         if (operationResult==null) {
986                 return new JsonResponse(ResultType.FAILURE).toMap();
987         }
988         return new JsonResponse(operationResult.getResult()).toMap();
989     }
990
991     /**
992      * 
993      * @param tabObj
994      * @param keyspace
995      * @param tablename
996      * @throws Exception
997      */
998     @DELETE
999     @Path("/{keyspace}/tables/{tablename}")
1000     @ApiOperation(value = "Drop Table", response = String.class)
1001     @Consumes(MediaType.APPLICATION_JSON)
1002     @Produces(MediaType.APPLICATION_JSON)
1003     public Map<String, Object> dropTable(
1004                     @ApiParam(value = "Major Version",
1005                                     required = true) @PathParam("version") String version,
1006                     @ApiParam(value = "Minor Version",
1007                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1008                     @ApiParam(value = "Patch Version",
1009                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1010                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1011                     @ApiParam(value = "Application namespace",
1012                                     required = true) @HeaderParam("ns") String ns,
1013                     @ApiParam(value = "userId",
1014                                     required = true) @HeaderParam("userId") String userId,
1015                     @ApiParam(value = "Password",
1016                                     required = true) @HeaderParam("password") String password,
1017                     JsonTable tabObj,
1018                     @ApiParam(value = "Keyspace Name",
1019                                     required = true) @PathParam("keyspace") String keyspace,
1020                     @ApiParam(value = "Table Name",
1021                                     required = true) @PathParam("tablename") String tablename,
1022                     @Context HttpServletResponse response) throws Exception {
1023         Map<String, Object> authMap =
1024                         MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1025         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1026         if (authMap.containsKey("aid"))
1027                 authMap.remove("aid");
1028         if (!authMap.isEmpty()) {
1029                 return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
1030         }
1031         String consistency = "eventual";// for now this needs only eventual
1032                                         // consistency
1033         PreparedQueryObject query = new PreparedQueryObject();
1034         query.appendQueryString("DROP TABLE  " + keyspace + "." + tablename + ";");
1035         try {
1036             return new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap();
1037         } catch (MusicServiceException ex) {
1038             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1039         }
1040
1041     }
1042
1043     /**
1044      * 
1045      * @param selObj
1046      * @param keyspace
1047      * @param tablename
1048      * @param info
1049      * @return
1050      */
1051     @PUT
1052     @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
1053     @ApiOperation(value = "Select Critical", response = Map.class)
1054     @Consumes(MediaType.APPLICATION_JSON)
1055     @Produces(MediaType.APPLICATION_JSON)
1056     public Map<String, Object> selectCritical(
1057                     @ApiParam(value = "Major Version",
1058                                     required = true) @PathParam("version") String version,
1059                     @ApiParam(value = "Minor Version",
1060                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1061                     @ApiParam(value = "Patch Version",
1062                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1063                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1064                     @ApiParam(value = "Application namespace",
1065                                     required = true) @HeaderParam("ns") String ns,
1066                     @ApiParam(value = "userId",
1067                                     required = true) @HeaderParam("userId") String userId,
1068                     @ApiParam(value = "Password",
1069                                     required = true) @HeaderParam("password") String password,
1070                     JsonInsert selObj,
1071                     @ApiParam(value = "Keyspace Name",
1072                                     required = true) @PathParam("keyspace") String keyspace,
1073                     @ApiParam(value = "Table Name",
1074                                     required = true) @PathParam("tablename") String tablename,
1075                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
1076         Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
1077                         aid, "selectCritical");
1078         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1079         if (authMap.containsKey("aid"))
1080                 authMap.remove("aid");
1081         if (!authMap.isEmpty()) {
1082             logger.error("Error while authentication... ");
1083             return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
1084         }
1085         String lockId = selObj.getConsistencyInfo().get("lockId");
1086
1087         PreparedQueryObject queryObject = new PreparedQueryObject();
1088
1089         RowIdentifier rowId = null;
1090         try {
1091             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1092         } catch (MusicServiceException ex) {
1093             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1094         }
1095         queryObject.appendQueryString(
1096                         "SELECT *  FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1097
1098         ResultSet results = null;
1099
1100         String consistency = selObj.getConsistencyInfo().get("type");
1101
1102         if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1103             results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1104                             lockId);
1105         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1106             results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1107         }
1108         
1109         else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1110             results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1111         }
1112
1113         return new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap();
1114     }
1115
1116     /**
1117      * 
1118      * @param keyspace
1119      * @param tablename
1120      * @param info
1121      * @return
1122      * @throws Exception
1123      */
1124     @GET
1125     @Path("/{keyspace}/tables/{tablename}/rows")
1126     @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1127     @Produces(MediaType.APPLICATION_JSON)
1128     public Map<String, Object> select(
1129                     @ApiParam(value = "Major Version",
1130                                     required = true) @PathParam("version") String version,
1131                     @ApiParam(value = "Minor Version",
1132                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1133                     @ApiParam(value = "Patch Version",
1134                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1135                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1136                     @ApiParam(value = "Application namespace",
1137                                     required = true) @HeaderParam("ns") String ns,
1138                     @ApiParam(value = "userId",
1139                                     required = true) @HeaderParam("userId") String userId,
1140                     @ApiParam(value = "Password",
1141                                     required = true) @HeaderParam("password") String password,
1142                     @ApiParam(value = "Keyspace Name",
1143                                     required = true) @PathParam("keyspace") String keyspace,
1144                     @ApiParam(value = "Table Name",
1145                                     required = true) @PathParam("tablename") String tablename,
1146                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
1147         Map<String, Object> authMap =
1148                         MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1149         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1150         if (authMap.containsKey("aid"))
1151                 authMap.remove("aid");
1152         if (!authMap.isEmpty()) {
1153                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1154                 return new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap();
1155         }
1156         PreparedQueryObject queryObject = new PreparedQueryObject();
1157
1158         if (info.getQueryParameters().isEmpty())// select all
1159             queryObject.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + ";");
1160         else {
1161             int limit = -1; // do not limit the number of results
1162             try {
1163                 queryObject = selectSpecificQuery(version, minorVersion, patchVersion, aid, ns,
1164                                 userId, password, keyspace, tablename, info, limit);
1165             } catch (MusicServiceException ex) {
1166                 return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1167             }
1168         }
1169
1170         try {
1171             ResultSet results = MusicCore.get(queryObject);
1172             return new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap();
1173         } catch (MusicServiceException ex) {
1174                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR  ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1175             return new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap();
1176         }
1177
1178     }
1179
1180     /**
1181      * 
1182      * @param keyspace
1183      * @param tablename
1184      * @param info
1185      * @param limit
1186      * @return
1187      * @throws MusicServiceException
1188      */
1189     public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1190                     String patchVersion, String aid, String ns, String userId, String password,
1191                     String keyspace, String tablename, UriInfo info, int limit)
1192                     throws MusicServiceException {
1193
1194         PreparedQueryObject queryObject = new PreparedQueryObject();
1195         StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1196                         queryObject).rowIdString;
1197
1198         queryObject.appendQueryString(
1199                         "SELECT *  FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1200
1201         if (limit != -1) {
1202             queryObject.appendQueryString(" LIMIT " + limit);
1203         }
1204
1205         queryObject.appendQueryString(";");
1206         return queryObject;
1207
1208     }
1209
1210     /**
1211      * 
1212      * @param keyspace
1213      * @param tablename
1214      * @param rowParams
1215      * @param queryObject
1216      * @return
1217      * @throws MusicServiceException
1218      */
1219     private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1220                     MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1221                     throws MusicServiceException {
1222         StringBuilder rowSpec = new StringBuilder();
1223         int counter = 0;
1224         TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1225         if (tableInfo == null) {
1226             logger.error(EELFLoggerDelegate.errorLogger,
1227                             "Table information not found. Please check input for table name= "
1228                                             + keyspace + "." + tablename);
1229             throw new MusicServiceException(
1230                             "Table information not found. Please check input for table name= "
1231                                             + keyspace + "." + tablename);
1232         }
1233         StringBuilder primaryKey = new StringBuilder();
1234         for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1235             String keyName = entry.getKey();
1236             List<String> valueList = entry.getValue();
1237             String indValue = valueList.get(0);
1238             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
1239             Object formattedValue = null;
1240             try {
1241               formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1242             } catch (Exception e) {
1243               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1244             }
1245             primaryKey.append(indValue);
1246             rowSpec.append(keyName + "= ?");
1247             queryObject.addValue(formattedValue);
1248             if (counter != rowParams.size() - 1)
1249                 rowSpec.append(" AND ");
1250             counter = counter + 1;
1251         }
1252         return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
1253     }
1254 }