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