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