More Unit tests for Sonar coverage
[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> resultMap = CachingUtil.verifyOnboarding(ns, userId, password);
155         response.addHeader(xLatestVersion, MusicUtil.getVersion());
156         if (!resultMap.isEmpty()) {
157             return resultMap;
158         }
159
160         try {
161                         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
162                                         "createKeySpace");
163                 } catch (Exception e) {
164                         logger.error(EELFLoggerDelegate.applicationLogger,
165                         "Exception while authenting the user.");
166                         return resultMap;
167                 }
168         String newAid = null;
169         if (!resultMap.isEmpty()) {
170             if (resultMap.containsKey("aid")) {
171                 newAid = (String) resultMap.get("aid");
172             } else
173                 return resultMap;
174         }
175
176         String consistency = MusicUtil.EVENTUAL;// for now this needs only
177                                                 // eventual
178         // consistency
179
180         PreparedQueryObject queryObject = new PreparedQueryObject();
181         boolean result = false;
182         long start = System.currentTimeMillis();
183         Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
184         String repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
185         queryObject.appendQueryString(
186                         "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
187         if (kspObject.getDurabilityOfWrites() != null) {
188             queryObject.appendQueryString(
189                             " AND durable_writes = " + kspObject.getDurabilityOfWrites());
190         }
191
192         queryObject.appendQueryString(";");
193         long end = System.currentTimeMillis();
194         logger.info(EELFLoggerDelegate.applicationLogger,
195                         "Time taken for setting up query in create keyspace:" + (end - start));
196
197         try {
198             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
199             logger.error(EELFLoggerDelegate.errorLogger, "resulta = " + result);
200         } catch (Exception e) {
201             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
202             resultMap.put("Exception", "Couldn't create keyspace. Please make sure all the information is correct.");
203
204         }
205         logger.debug("result = " + result);
206         if (!result) {
207             resultMap.put("Status", String.valueOf(result));
208             if(!resultMap.containsKey("Exception"))
209                 resultMap.put("Exception", "Keyspace already exists. Please contact admin.");
210             if (resultMap.get("uuid").equals("new")) {
211                 queryObject = new PreparedQueryObject();
212                 queryObject.appendQueryString(
213                                 "DELETE FROM admin.keyspace_master where uuid = " + newAid);
214                 queryObject.appendQueryString(";");
215                 try {
216                                         result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
217                                 } catch (MusicServiceException e) {
218                                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
219                                         resultMap.put("Exception", e.getMessage());
220                                 }
221                 resultMap.remove("aid");
222                 resultMap.remove("uuid");
223                 return resultMap;
224
225             } else {
226                 queryObject = new PreparedQueryObject();
227                 queryObject.appendQueryString(
228                                 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
229                 try {
230                         queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(),
231                                 MusicUtil.DEFAULTKEYSPACENAME));
232                                         queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
233                                 } catch (Exception e) {
234                                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
235                                         resultMap.put("Exception", "Unable to process input data. Invalid input data type. "
236                                                         + "Please check keyspace_name and aid.. ");
237                                 }
238                 try {
239                                         result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
240                                 } catch (MusicServiceException e) {
241                                         e.printStackTrace();
242                                         logger.error(EELFLoggerDelegate.errorLogger, "Unable to process operation. Error: "+e.getMessage());
243                                         resultMap.put("Exception", "Unable to process operation. Error: "+e.getMessage());
244                                         return resultMap;
245                                 }
246                 resultMap.remove("aid");
247                 resultMap.remove("uuid");
248                 return resultMap;
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             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
257             queryObject = new PreparedQueryObject();
258             queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
259                                 + " to '" + userId + "'");
260             queryObject.appendQueryString(";");
261             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
262         } catch (Exception e) {
263                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
264         }
265         resultMap.remove("uuid");
266         try {
267                         if (CachingUtil.isAAFApplication(ns))
268                             resultMap.remove("aid");
269                 } catch (MusicServiceException e) {
270                         e.printStackTrace();
271                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
272                         resultMap.put("Exception", e.getMessage());
273                         return resultMap;
274                 }
275         resultMap.put("Status", String.valueOf(result));
276         return resultMap;
277
278     }
279
280     /**
281      * 
282      * @param kspObject
283      * @param keyspaceName
284      * @return
285      * @throws Exception
286      */
287     @DELETE
288     @Path("/{name}")
289     @ApiOperation(value = "Delete Keyspace", response = String.class)
290     @Consumes(MediaType.APPLICATION_JSON)
291     @Produces(MediaType.APPLICATION_JSON)
292     public Map<String, Object> dropKeySpace(
293                     @ApiParam(value = "Major Version",
294                                     required = true) @PathParam("version") String version,
295                     @ApiParam(value = "Minor Version",
296                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
297                     @ApiParam(value = "Patch Version",
298                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
299                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
300                     @ApiParam(value = "Application namespace",
301                                     required = true) @HeaderParam("ns") String ns,
302                     @ApiParam(value = "userId",
303                                     required = true) @HeaderParam("userId") String userId,
304                     @ApiParam(value = "Password",
305                                     required = true) @HeaderParam("password") String password,
306                     JsonKeySpace kspObject,
307                     @ApiParam(value = "Keyspace Name",
308                                     required = true) @PathParam("name") String keyspaceName,
309                     @Context HttpServletResponse response) throws Exception {
310         Map<String, Object> resultMap = MusicCore.autheticateUser(ns, userId, password,
311                         keyspaceName, aid, "dropKeySpace");
312         response.addHeader(xLatestVersion, MusicUtil.getVersion());
313         if (resultMap.containsKey("aid"))
314             resultMap.remove("aid");
315         if (!resultMap.isEmpty()) {
316             return resultMap;
317         }
318
319         String consistency = MusicUtil.EVENTUAL;// for now this needs only
320                                                 // eventual
321         // consistency
322         String appName = CachingUtil.getAppName(keyspaceName);
323         String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
324         PreparedQueryObject pQuery = new PreparedQueryObject();
325         pQuery.appendQueryString(
326                         "select  count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
327         pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
328         Row row = MusicCore.get(pQuery).one();
329         long count = row.getLong(0);
330
331         if (count == 0) {
332             resultMap.put("Exception", "Keyspace not found. Please make sure keyspace exists.");
333             return resultMap;
334         } else if (count == 1) {
335             pQuery = new PreparedQueryObject();
336             pQuery.appendQueryString(
337                     "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
338             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
339                     MusicUtil.DEFAULTKEYSPACENAME));
340             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
341             MusicCore.nonKeyRelatedPut(pQuery, consistency);
342         } else {
343             pQuery = new PreparedQueryObject();
344             pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
345             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
346             MusicCore.nonKeyRelatedPut(pQuery, consistency);
347         }
348
349         PreparedQueryObject queryObject = new PreparedQueryObject();
350         queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
351         return new JsonResponse(MusicCore.nonKeyRelatedPut(queryObject, consistency), "", "")
352                         .toMap();
353     }
354
355     /**
356      * 
357      * @param tableObj
358      * @param keyspace
359      * @param tablename
360      * @return
361      * @throws Exception
362      */
363     @POST
364     @Path("/{keyspace}/tables/{tablename}")
365     @ApiOperation(value = "Create Table", response = String.class)
366     @Consumes(MediaType.APPLICATION_JSON)
367     @Produces(MediaType.APPLICATION_JSON)
368     public Map<String, Object> createTable(
369                     @ApiParam(value = "Major Version",
370                                     required = true) @PathParam("version") String version,
371                     @ApiParam(value = "Minor Version",
372                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
373                     @ApiParam(value = "Patch Version",
374                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
375                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
376                     @ApiParam(value = "Application namespace",
377                                     required = true) @HeaderParam("ns") String ns,
378                     @ApiParam(value = "userId",
379                                     required = true) @HeaderParam("userId") String userId,
380                     @ApiParam(value = "Password",
381                                     required = true) @HeaderParam("password") String password,
382                     JsonTable tableObj,
383                     @ApiParam(value = "Keyspace Name",
384                                     required = true) @PathParam("keyspace") String keyspace,
385                     @ApiParam(value = "Table Name",
386                                     required = true) @PathParam("tablename") String tablename,
387                     @Context HttpServletResponse response) throws Exception {
388         
389         Map<String, Object> resultMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
390                         aid, "createTable");
391         response.addHeader(xLatestVersion, MusicUtil.getVersion());
392         if (resultMap.containsKey("aid"))
393             resultMap.remove("aid");
394         if (!resultMap.isEmpty()) {
395             return resultMap;
396         }
397         String consistency = MusicUtil.EVENTUAL;
398         // for now this needs only eventual consistency
399         PreparedQueryObject queryObject = new PreparedQueryObject();
400         boolean result = false;
401         // first read the information about the table fields
402         Map<String, String> fields = tableObj.getFields();
403         StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
404         int counter = 0;
405         String primaryKey;
406         for (Map.Entry<String, String> entry : fields.entrySet()) {
407             
408             if (entry.getKey().equals("PRIMARY KEY")) {
409                 if(! entry.getValue().contains("("))
410                         primaryKey = entry.getValue();
411                 else {
412                         primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
413                         primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
414                 }
415                 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
416             } else
417                 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
418             if (counter == fields.size() - 1)
419                 fieldsString.append(")");
420             else
421                 fieldsString.append(",");
422             counter = counter + 1;
423         }
424         // information about the name-value style properties
425         Map<String, Object> propertiesMap = tableObj.getProperties();
426         StringBuilder propertiesString = new StringBuilder();
427         if (propertiesMap != null) {
428             counter = 0;
429             for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
430                 Object ot = entry.getValue();
431                 String value = ot + "";
432                 if (ot instanceof String) {
433                     value = "'" + value + "'";
434                 } else if (ot instanceof Map) {
435                     @SuppressWarnings("unchecked")
436                     Map<String, Object> otMap = (Map<String, Object>) ot;
437                     value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
438                 }
439
440                 propertiesString.append(entry.getKey() + "=" + value + "");
441                 if (counter != propertiesMap.size() - 1)
442                     propertiesString.append(" AND ");
443
444                 counter = counter + 1;
445             }
446         }
447
448         queryObject.appendQueryString(
449                         "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
450
451         if (propertiesMap != null)
452             queryObject.appendQueryString(" WITH " + propertiesString);
453
454         queryObject.appendQueryString(";");
455         try {
456             result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
457         } catch (MusicServiceException ex) {
458             return new JsonResponse(false, ex.getMessage(), "").toMap();
459         }
460
461         return new JsonResponse(result, "", "").toMap();
462     }
463
464     /**
465      * 
466      * @param keyspace
467      * @param tablename
468      * @param fieldName
469      * @param info
470      * @throws Exception
471      */
472     @POST
473     @Path("/{keyspace}/tables/{tablename}/index/{field}")
474     @ApiOperation(value = "Create Index", response = String.class)
475     @Produces(MediaType.APPLICATION_JSON)
476     public Map<String, Object> createIndex(
477                     @ApiParam(value = "Major Version",
478                                     required = true) @PathParam("version") String version,
479                     @ApiParam(value = "Minor Version",
480                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
481                     @ApiParam(value = "Patch Version",
482                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
483                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
484                     @ApiParam(value = "Application namespace",
485                                     required = true) @HeaderParam("ns") String ns,
486                     @ApiParam(value = "userId",
487                                     required = true) @HeaderParam("userId") String userId,
488                     @ApiParam(value = "Password",
489                                     required = true) @HeaderParam("password") String password,
490                     @ApiParam(value = "Keyspace Name",
491                                     required = true) @PathParam("keyspace") String keyspace,
492                     @ApiParam(value = "Table Name",
493                                     required = true) @PathParam("tablename") String tablename,
494                     @ApiParam(value = "Field Name",
495                                     required = true) @PathParam("field") String fieldName,
496                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
497         Map<String, Object> resultMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
498                         aid, "createIndex");
499         response.addHeader(xLatestVersion, MusicUtil.getVersion());
500         if (resultMap.containsKey("aid"))
501             resultMap.remove("aid");
502         if (!resultMap.isEmpty())
503             return resultMap;
504         MultivaluedMap<String, String> rowParams = info.getQueryParameters();
505         String indexName = "";
506         if (rowParams.getFirst("index_name") != null)
507             indexName = rowParams.getFirst("index_name");
508         PreparedQueryObject query = new PreparedQueryObject();
509         query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
510                         + tablename + " (" + fieldName + ");");
511         return new JsonResponse(MusicCore.nonKeyRelatedPut(query, "eventual"), "", "").toMap();
512
513     }
514
515     /**
516      * 
517      * @param insObj
518      * @param keyspace
519      * @param tablename
520      * @return
521      * @throws Exception
522      */
523     @POST
524     @Path("/{keyspace}/tables/{tablename}/rows")
525     @ApiOperation(value = "Insert Into Table", response = String.class)
526     @Consumes(MediaType.APPLICATION_JSON)
527     @Produces(MediaType.APPLICATION_JSON)
528     public Map<String, Object> insertIntoTable(
529                     @ApiParam(value = "Major Version",
530                                     required = true) @PathParam("version") String version,
531                     @ApiParam(value = "Minor Version",
532                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
533                     @ApiParam(value = "Patch Version",
534                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
535                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
536                     @ApiParam(value = "Application namespace",
537                                     required = true) @HeaderParam("ns") String ns,
538                     @ApiParam(value = "userId",
539                                     required = true) @HeaderParam("userId") String userId,
540                     @ApiParam(value = "Password",
541                                     required = true) @HeaderParam("password") String password,
542                     JsonInsert insObj,
543                     @ApiParam(value = "Keyspace Name",
544                                     required = true) @PathParam("keyspace") String keyspace,
545                     @ApiParam(value = "Table Name",
546                                     required = true) @PathParam("tablename") String tablename,
547                     @Context HttpServletResponse response) {
548         Map<String, Object> resultMap = null;
549         try {
550           resultMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
551                           aid, "insertIntoTable");
552         } catch (Exception e) {
553           logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
554           return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
555         }
556         response.addHeader(xLatestVersion, MusicUtil.getVersion());
557         if (resultMap.containsKey("aid"))
558             resultMap.remove("aid");
559         if (!resultMap.isEmpty()) {
560             return resultMap;
561         }
562         ReturnType result = null;
563         Map<String, Object> valuesMap = insObj.getValues();
564         PreparedQueryObject queryObject = new PreparedQueryObject();
565         TableMetadata tableInfo = null;
566                 try {
567                         tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
568                         if(tableInfo == null) 
569                                 throw new MusicServiceException("Table name doesn't exists. Please check the table name.");
570                 } catch (MusicServiceException e) {
571                         e.printStackTrace();
572                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
573                         resultMap.put(ResultType.SYNTAXERROR.getResult(), e.getMessage());
574                         return resultMap;
575                 }
576         String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
577         StringBuilder fieldsString = new StringBuilder("(vector_ts,");
578         String vectorTs =
579                         String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
580         StringBuilder valueString = new StringBuilder("(" + "?" + ",");
581         queryObject.addValue(vectorTs);
582         int counter = 0;
583         String primaryKey = "";
584
585         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
586             fieldsString.append("" + entry.getKey());
587             Object valueObj = entry.getValue();
588             if (primaryKeyName.equals(entry.getKey())) {
589                 primaryKey = entry.getValue() + "";
590                 primaryKey = primaryKey.replace("'", "''");
591             }
592
593             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
594
595             Object formattedValue = null;
596             try {
597               formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
598             } catch (Exception e) {
599               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
600               //return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
601           }
602             valueString.append("?");
603             queryObject.addValue(formattedValue);
604
605             if (counter == valuesMap.size() - 1) {
606                 fieldsString.append(")");
607                 valueString.append(")");
608             } else {
609                 fieldsString.append(",");
610                 valueString.append(",");
611             }
612             counter = counter + 1;
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         String consistency = insObj.getConsistencyInfo().get("type");
643         try {
644             if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
645                 result = MusicCore.eventualPut(queryObject);
646             } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
647                 String lockId = insObj.getConsistencyInfo().get("lockId");
648                 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,
649                                 null);
650             } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
651                 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
652
653             }
654             else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
655                 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
656
657             }
658             return (result != null) ? result.toMap()
659                             : new ReturnType(ResultType.FAILURE,
660                                             "Null result - Please Contact admin").toMap();
661         } catch (Exception ex) {
662                 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
663             return new ReturnType(ResultType.FAILURE, ex.getMessage()).toMap();
664         }
665     }
666
667     /**
668      * 
669      * @param insObj
670      * @param keyspace
671      * @param tablename
672      * @param info
673      * @return
674      * @throws Exception
675      */
676     @PUT
677     @Path("/{keyspace}/tables/{tablename}/rows")
678     @ApiOperation(value = "Update Table", response = String.class)
679     @Consumes(MediaType.APPLICATION_JSON)
680     @Produces(MediaType.APPLICATION_JSON)
681     public Map<String, Object> updateTable(
682                     @ApiParam(value = "Major Version",
683                                     required = true) @PathParam("version") String version,
684                     @ApiParam(value = "Minor Version",
685                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
686                     @ApiParam(value = "Patch Version",
687                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
688                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
689                     @ApiParam(value = "Application namespace",
690                                     required = true) @HeaderParam("ns") String ns,
691                     @ApiParam(value = "userId",
692                                     required = true) @HeaderParam("userId") String userId,
693                     @ApiParam(value = "Password",
694                                     required = true) @HeaderParam("password") String password,
695                     JsonUpdate updateObj,
696                     @ApiParam(value = "Keyspace Name",
697                                     required = true) @PathParam("keyspace") String keyspace,
698                     @ApiParam(value = "Table Name",
699                                     required = true) @PathParam("tablename") String tablename,
700                     @Context UriInfo info, @Context HttpServletResponse response) {
701         Map<String, Object> resultMap;
702         try {
703           resultMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
704                           aid, "updateTable");
705         } catch (Exception e) {
706           logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
707           return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
708         }
709         response.addHeader(xLatestVersion, MusicUtil.getVersion());
710         if (resultMap.containsKey("aid"))
711             resultMap.remove("aid");
712         if (!resultMap.isEmpty()) {
713             return resultMap;
714         }
715         long startTime = System.currentTimeMillis();
716         String operationId = UUID.randomUUID().toString();// just for infoging
717                                                           // purposes.
718         String consistency = updateObj.getConsistencyInfo().get("type");
719         logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
720                         + " update-" + operationId + "-------------------------");
721         // obtain the field value pairs of the update
722
723         PreparedQueryObject queryObject = new PreparedQueryObject();
724         Map<String, Object> valuesMap = updateObj.getValues();
725
726         TableMetadata tableInfo;
727                 try {
728                         tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
729                 } catch (MusicServiceException e) {
730                         e.printStackTrace();
731                         logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
732                         resultMap.put("Exception", e.getMessage());
733                         return resultMap;
734                 }
735         if (tableInfo == null) {
736             return new ReturnType(ResultType.FAILURE,
737                             "Table information not found. Please check input for table name= "
738                                             + keyspace + "." + tablename).toMap();
739         }
740         String vectorTs =
741                         String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
742         StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
743         queryObject.addValue(vectorTs);
744         int counter = 0;
745         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
746             Object valueObj = entry.getValue();
747             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
748             Object valueString = null;
749             try {
750               valueString = MusicUtil.convertToActualDataType(colType, valueObj);
751             } catch (Exception e) {
752               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
753               //return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
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                 resultMap.put(ResultType.SYNTAXERROR.getResult(), "Mandatory WHERE clause is missing. Please check the input request.");
790                 return resultMap;
791             }
792         } catch (MusicServiceException ex) {
793             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage());
794             return new ReturnType(ResultType.FAILURE, 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             operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
821                             queryObject, lockId, conditionInfo);
822         } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
823             // this function is mainly for the benchmarks
824             try {
825               operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
826                               rowId.primarKeyValue, queryObject, conditionInfo);
827             } catch (MusicLockingException e) {
828                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
829                 return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
830             }
831         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
832             try {
833               operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
834                               queryObject, conditionInfo);
835             } catch (MusicLockingException e) {
836               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
837               return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
838             }
839         }
840         long actualUpdateCompletionTime = System.currentTimeMillis();
841
842         long endTime = System.currentTimeMillis();
843         String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
844                         + ":" + "|total operation time:" + (endTime - startTime)
845                         + "|json parsing time:" + (jsonParseCompletionTime - startTime)
846                         + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
847                         + "|";
848
849         if (operationResult != null && operationResult.getTimingInfo() != null) {
850             String lockManagementTime = operationResult.getTimingInfo();
851             timingString = timingString + lockManagementTime;
852         }
853         logger.info(EELFLoggerDelegate.applicationLogger, timingString);
854         return (operationResult != null) ? operationResult.toMap()
855                         : new ReturnType(ResultType.FAILURE, "Null result - Please Contact admin")
856                                         .toMap();
857     }
858
859     /**
860      * 
861      * @param delObj
862      * @param keyspace
863      * @param tablename
864      * @param info
865      * @return
866      * @throws Exception
867      */
868     @DELETE
869     @Path("/{keyspace}/tables/{tablename}/rows")
870     @ApiOperation(value = "Delete From table", response = String.class)
871     @Consumes(MediaType.APPLICATION_JSON)
872     @Produces(MediaType.APPLICATION_JSON)
873     public Map<String, Object> deleteFromTable(
874                     @ApiParam(value = "Major Version",
875                                     required = true) @PathParam("version") String version,
876                     @ApiParam(value = "Minor Version",
877                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
878                     @ApiParam(value = "Patch Version",
879                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
880                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
881                     @ApiParam(value = "Application namespace",
882                                     required = true) @HeaderParam("ns") String ns,
883                     @ApiParam(value = "userId",
884                                     required = true) @HeaderParam("userId") String userId,
885                     @ApiParam(value = "Password",
886                                     required = true) @HeaderParam("password") String password,
887                     JsonDelete delObj,
888                     @ApiParam(value = "Keyspace Name",
889                                     required = true) @PathParam("keyspace") String keyspace,
890                     @ApiParam(value = "Table Name",
891                                     required = true) @PathParam("tablename") String tablename,
892                     @Context UriInfo info, @Context HttpServletResponse response) {
893         Map<String, Object> resultMap = null;
894                 try {
895                         resultMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
896                                         aid, "deleteFromTable");
897                 } catch (Exception e) {
898                         resultMap.put("Exception", e.getMessage());
899                         return resultMap;
900                 }
901         response.addHeader(xLatestVersion, MusicUtil.getVersion());
902         if (resultMap.containsKey("aid"))
903             resultMap.remove("aid");
904         if (!resultMap.isEmpty()) {
905             return resultMap;
906         }
907         if(delObj == null) {
908                         resultMap.put("Exception", "Request body is missing. Please check your input data and retry.");
909                         return resultMap;
910                 }
911         PreparedQueryObject queryObject = new PreparedQueryObject();
912         StringBuilder columnString = new StringBuilder();
913
914         int counter = 0;
915         ArrayList<String> columnList = delObj.getColumns();
916         if (columnList != null) {
917             for (String column : columnList) {
918                 columnString.append(column);
919                 if (counter != columnList.size() - 1)
920                     columnString.append(",");
921                 counter = counter + 1;
922             }
923         }
924
925         // get the row specifier
926         RowIdentifier rowId = null;
927         try {
928             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
929         } catch (MusicServiceException ex) {
930             return new ReturnType(ResultType.FAILURE, ex.getMessage()).toMap();
931         }
932         String rowSpec = rowId.rowIdString.toString();
933
934         if ((columnList != null) && (!rowSpec.isEmpty())) {
935             queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
936                             + tablename + " WHERE " + rowSpec + ";");
937         }
938
939         if ((columnList == null) && (!rowSpec.isEmpty())) {
940             queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
941                             + rowSpec + ";");
942         }
943
944         if ((columnList != null) && (rowSpec.isEmpty())) {
945             queryObject.appendQueryString(
946                             "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
947         }
948
949         // get the conditional, if any
950         Condition conditionInfo;
951         if (delObj.getConditions() == null)
952             conditionInfo = null;
953         else {// to avoid parsing repeatedly, just send the select query to
954               // obtain row
955             PreparedQueryObject selectQuery = new PreparedQueryObject();
956             selectQuery.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + " WHERE "
957                             + rowId.rowIdString + ";");
958             selectQuery.addValue(rowId.primarKeyValue);
959             conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
960         }
961
962         String consistency = delObj.getConsistencyInfo().get("type");
963
964         ReturnType operationResult = null;
965         try {
966                 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
967                     operationResult = MusicCore.eventualPut(queryObject);
968                 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
969                     String lockId = delObj.getConsistencyInfo().get("lockId");
970                     operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
971                                     queryObject, lockId, conditionInfo);
972                 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
973                                         operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
974                                                         queryObject, conditionInfo);
975                 }
976                 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
977                                         operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
978                                                         queryObject, conditionInfo);
979                 }
980         } catch (MusicLockingException e) {
981                         resultMap.put("Exception", "Unable to perform Delete operation. Exception from music: "+e.getMessage());
982                         return resultMap;
983                 }
984         try {
985             return operationResult.toMap();
986         } catch (NullPointerException e) {
987             return new ReturnType(ResultType.FAILURE, e.getMessage()).toMap();
988         }
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> resultMap =
1024                         MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1025         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1026         if (resultMap.containsKey("aid"))
1027             resultMap.remove("aid");
1028         if (!resultMap.isEmpty()) {
1029             return resultMap;
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(false, 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, HashMap<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> resultMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
1077                         aid, "selectCritical");
1078         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1079         if (resultMap.containsKey("aid"))
1080             resultMap.remove("aid");
1081         if (!resultMap.isEmpty()) {
1082             logger.error("Error while authentication... ");
1083             HashMap<String, Object> tempMap = new HashMap<>();
1084             tempMap.putAll(resultMap);
1085             Map<String, HashMap<String, Object>> results = new HashMap<>();
1086             results.put("Result", tempMap);
1087             return results;
1088         }
1089         String lockId = selObj.getConsistencyInfo().get("lockId");
1090
1091         PreparedQueryObject queryObject = new PreparedQueryObject();
1092
1093         RowIdentifier rowId = null;
1094         try {
1095             rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1096         } catch (MusicServiceException ex) {
1097             return MusicUtil.setErrorResponse(ex);
1098         }
1099         queryObject.appendQueryString(
1100                         "SELECT *  FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1101
1102         ResultSet results = null;
1103
1104         String consistency = selObj.getConsistencyInfo().get("type");
1105
1106         if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1107             results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1108                             lockId);
1109         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1110             results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1111         }
1112         
1113         else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1114             results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1115         }
1116
1117         return MusicCore.marshallResults(results);
1118     }
1119
1120     /**
1121      * 
1122      * @param keyspace
1123      * @param tablename
1124      * @param info
1125      * @return
1126      * @throws Exception
1127      */
1128     @GET
1129     @Path("/{keyspace}/tables/{tablename}/rows")
1130     @ApiOperation(value = "Select All or Select Specivic", response = Map.class)
1131     @Produces(MediaType.APPLICATION_JSON)
1132     public Map<String, HashMap<String, Object>> select(
1133                     @ApiParam(value = "Major Version",
1134                                     required = true) @PathParam("version") String version,
1135                     @ApiParam(value = "Minor Version",
1136                                     required = false) @HeaderParam("X-minorVersion") String minorVersion,
1137                     @ApiParam(value = "Patch Version",
1138                                     required = false) @HeaderParam("X-patchVersion") String patchVersion,
1139                     @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1140                     @ApiParam(value = "Application namespace",
1141                                     required = true) @HeaderParam("ns") String ns,
1142                     @ApiParam(value = "userId",
1143                                     required = true) @HeaderParam("userId") String userId,
1144                     @ApiParam(value = "Password",
1145                                     required = true) @HeaderParam("password") String password,
1146                     @ApiParam(value = "Keyspace Name",
1147                                     required = true) @PathParam("keyspace") String keyspace,
1148                     @ApiParam(value = "Table Name",
1149                                     required = true) @PathParam("tablename") String tablename,
1150                     @Context UriInfo info, @Context HttpServletResponse response) throws Exception {
1151         Map<String, Object> resultMap =
1152                         MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1153         response.addHeader(xLatestVersion, MusicUtil.getVersion());
1154         if (resultMap.containsKey("aid"))
1155             resultMap.remove("aid");
1156         if (!resultMap.isEmpty()) {
1157                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR  ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1158             HashMap<String, Object> tempMap = new HashMap<>();
1159             tempMap.putAll(resultMap);
1160             Map<String, HashMap<String, Object>> results = new HashMap<>();
1161             results.put("Result", tempMap);
1162             return results;
1163         }
1164         PreparedQueryObject queryObject = new PreparedQueryObject();
1165
1166         if (info.getQueryParameters().isEmpty())// select all
1167             queryObject.appendQueryString("SELECT *  FROM " + keyspace + "." + tablename + ";");
1168         else {
1169             int limit = -1; // do not limit the number of results
1170             try {
1171                 queryObject = selectSpecificQuery(version, minorVersion, patchVersion, aid, ns,
1172                                 userId, password, keyspace, tablename, info, limit);
1173             } catch (MusicServiceException ex) {
1174                 return MusicUtil.setErrorResponse(ex);
1175             }
1176         }
1177
1178         try {
1179             ResultSet results = MusicCore.get(queryObject);
1180             return MusicCore.marshallResults(results);
1181         } catch (MusicServiceException ex) {
1182                 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR  ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1183             return MusicUtil.setErrorResponse(ex);
1184         }
1185
1186     }
1187
1188     /**
1189      * 
1190      * @param keyspace
1191      * @param tablename
1192      * @param info
1193      * @param limit
1194      * @return
1195      * @throws MusicServiceException
1196      */
1197     public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1198                     String patchVersion, String aid, String ns, String userId, String password,
1199                     String keyspace, String tablename, UriInfo info, int limit)
1200                     throws MusicServiceException {
1201
1202         PreparedQueryObject queryObject = new PreparedQueryObject();
1203         StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1204                         queryObject).rowIdString;
1205
1206         queryObject.appendQueryString(
1207                         "SELECT *  FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1208
1209         if (limit != -1) {
1210             queryObject.appendQueryString(" LIMIT " + limit);
1211         }
1212
1213         queryObject.appendQueryString(";");
1214         return queryObject;
1215
1216     }
1217
1218     /**
1219      * 
1220      * @param keyspace
1221      * @param tablename
1222      * @param rowParams
1223      * @param queryObject
1224      * @return
1225      * @throws MusicServiceException
1226      */
1227     private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1228                     MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1229                     throws MusicServiceException {
1230         StringBuilder rowSpec = new StringBuilder();
1231         int counter = 0;
1232         TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1233         if (tableInfo == null) {
1234             logger.error(EELFLoggerDelegate.errorLogger,
1235                             "Table information not found. Please check input for table name= "
1236                                             + keyspace + "." + tablename);
1237             throw new MusicServiceException(
1238                             "Table information not found. Please check input for table name= "
1239                                             + keyspace + "." + tablename);
1240         }
1241         StringBuilder primaryKey = new StringBuilder();
1242         for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1243             String keyName = entry.getKey();
1244             List<String> valueList = entry.getValue();
1245             String indValue = valueList.get(0);
1246             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
1247             Object formattedValue = null;
1248             try {
1249               formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1250             } catch (Exception e) {
1251               logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1252             }
1253             primaryKey.append(indValue);
1254             rowSpec.append(keyName + "= ?");
1255             queryObject.addValue(formattedValue);
1256             if (counter != rowParams.size() - 1)
1257                 rowSpec.append(" AND ");
1258             counter = counter + 1;
1259         }
1260         return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
1261     }
1262 }