2 * ============LICENSE_START==========================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * ============LICENSE_END=============================================
20 * ====================================================================
22 package org.onap.music.rest;
24 import java.util.ArrayList;
25 import java.util.List;
27 import java.util.UUID;
28 import javax.ws.rs.Consumes;
29 import javax.ws.rs.DELETE;
30 import javax.ws.rs.GET;
31 import javax.ws.rs.HeaderParam;
32 import javax.ws.rs.POST;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.Context;
38 import javax.ws.rs.core.HttpHeaders;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.MultivaluedMap;
41 import javax.ws.rs.core.Response;
42 import javax.ws.rs.core.Response.ResponseBuilder;
43 import javax.ws.rs.core.Response.Status;
44 import javax.ws.rs.core.UriInfo;
46 import org.mindrot.jbcrypt.BCrypt;
47 import org.onap.music.datastore.PreparedQueryObject;
48 import org.onap.music.datastore.jsonobjects.JsonDelete;
49 import org.onap.music.datastore.jsonobjects.JsonInsert;
50 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
51 import org.onap.music.datastore.jsonobjects.JsonTable;
52 import org.onap.music.datastore.jsonobjects.JsonUpdate;
53 import org.onap.music.eelf.logging.EELFLoggerDelegate;
54 import org.onap.music.exceptions.MusicLockingException;
55 import org.onap.music.eelf.logging.format.AppMessages;
56 import org.onap.music.eelf.logging.format.ErrorSeverity;
57 import org.onap.music.eelf.logging.format.ErrorTypes;
58 import org.onap.music.exceptions.MusicServiceException;
59 import org.onap.music.main.CachingUtil;
60 import org.onap.music.main.MusicCore;
61 import org.onap.music.main.MusicCore.Condition;
62 import org.onap.music.main.MusicUtil;
63 import org.onap.music.main.ResultType;
64 import org.onap.music.main.ReturnType;
65 import org.onap.music.response.jsonobjects.JsonResponse;
67 import com.datastax.driver.core.DataType;
68 import com.datastax.driver.core.ResultSet;
69 import com.datastax.driver.core.Row;
70 import com.datastax.driver.core.TableMetadata;
71 import io.swagger.annotations.Api;
72 import io.swagger.annotations.ApiOperation;
73 import io.swagger.annotations.ApiParam;
76 //@Path("/v{version: [0-9]+}/keyspaces")
77 @Path("/v2/keyspaces")
78 @Api(value = "Data Api")
79 public class RestMusicDataAPI {
81 * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
82 * version back from the client to the server, and from the server back to the client - This
83 * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
84 * version (if not specified by the client on the request) - Contains a single position value
85 * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
86 * request; however, this header should be provided if the client needs to take advantage of
87 * MINOR incremented version functionality - Is mandatory for the server on response
89 *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
90 * troubleshooting purposes only, and will not be provided by the client on request - This will
91 * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
92 * of the MAJOR (if not specified by the client on the request) - Contains a single position
93 * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
94 * server on response (CURRENTLY NOT USED)
96 *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
97 * server on response, and shall include the entire version of the API (e.g. if the full version
98 * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
99 * not using the latest version of the API (CURRENTLY NOT USED)
103 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
104 private static final String XMINORVERSION = "X-minorVersion";
105 private static final String XPATCHVERSION = "X-patchVersion";
106 private static final String NS = "ns";
107 private static final String USERID = "userId";
108 private static final String PASSWORD = "password";
109 private static final String VERSION = "v2";
111 private class RowIdentifier {
112 public String primarKeyValue;
113 public StringBuilder rowIdString;
114 @SuppressWarnings("unused")
115 public PreparedQueryObject queryObject;// the string with all the row
116 // identifiers separated by AND
118 public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
119 PreparedQueryObject queryObject) {
120 this.primarKeyValue = primaryKeyValue;
121 this.rowIdString = rowIdString;
122 this.queryObject = queryObject;
128 * Create Keyspace REST
131 * @param keyspaceName
137 @ApiOperation(value = "Create Keyspace", response = String.class)
138 @Consumes(MediaType.APPLICATION_JSON)
139 @Produces(MediaType.APPLICATION_JSON)
140 //public Map<String, Object> createKeySpace(
141 public Response createKeySpace(
142 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
143 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
144 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
145 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
146 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
147 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
148 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
149 JsonKeySpace kspObject,
150 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) {
151 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
153 Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
154 if (!authMap.isEmpty()) {
155 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
156 response.status(Status.UNAUTHORIZED);
157 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
159 if(kspObject == null || kspObject.getReplicationInfo() == null) {
160 authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult());
161 response.status(Status.BAD_REQUEST);
162 return response.entity(authMap).build();
166 authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
168 } catch (Exception e) {
169 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
170 response.status(Status.BAD_REQUEST);
171 return response.entity(new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap()).build();
173 String newAid = null;
174 if (!authMap.isEmpty()) {
175 if (authMap.containsKey("aid")) {
176 newAid = (String) authMap.get("aid");
178 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
179 response.status(Status.UNAUTHORIZED);
180 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
184 String consistency = MusicUtil.EVENTUAL;// for now this needs only
185 // eventual consistency
187 PreparedQueryObject queryObject = new PreparedQueryObject();
188 long start = System.currentTimeMillis();
189 Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
190 String repString = null;
192 repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
193 } catch (Exception e) {
194 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
197 queryObject.appendQueryString(
198 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
199 if (kspObject.getDurabilityOfWrites() != null) {
200 queryObject.appendQueryString(
201 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
204 queryObject.appendQueryString(";");
205 long end = System.currentTimeMillis();
206 logger.info(EELFLoggerDelegate.applicationLogger,
207 "Time taken for setting up query in create keyspace:" + (end - start));
209 ResultType result = ResultType.FAILURE;
211 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
212 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
213 } catch ( MusicServiceException ex) {
214 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
215 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
219 queryObject = new PreparedQueryObject();
220 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
221 + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
222 MusicCore.nonKeyRelatedPut(queryObject, consistency);
223 queryObject = new PreparedQueryObject();
224 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
225 + " to '" + userId + "'");
226 queryObject.appendQueryString(";");
227 MusicCore.nonKeyRelatedPut(queryObject, consistency);
228 } catch (Exception e) {
229 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
233 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
234 String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt());
235 queryObject = new PreparedQueryObject();
236 queryObject.appendQueryString(
237 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
238 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
239 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
240 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
241 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
242 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
243 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd));
244 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
245 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
246 CachingUtil.updateMusicCache(keyspaceName, ns);
247 CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
248 MusicCore.eventualPut(queryObject);
249 } catch (Exception e) {
250 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
251 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
254 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
260 * @param keyspaceName
266 @ApiOperation(value = "Delete Keyspace", response = String.class)
267 @Produces(MediaType.APPLICATION_JSON)
268 //public Map<String, Object> dropKeySpace(
269 public Response dropKeySpace(
270 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
271 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
272 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
273 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
274 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
275 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
276 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
277 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
278 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
280 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace");
281 if (authMap.containsKey("aid"))
282 authMap.remove("aid");
283 if (!authMap.isEmpty()) {
284 return response.status(Status.UNAUTHORIZED).entity(authMap).build();
287 String consistency = MusicUtil.EVENTUAL;// for now this needs only
290 String appName = CachingUtil.getAppName(keyspaceName);
291 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
292 PreparedQueryObject pQuery = new PreparedQueryObject();
293 pQuery.appendQueryString(
294 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
295 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
296 Row row = MusicCore.get(pQuery).one();
297 long count = row.getLong(0);
300 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
301 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
303 } else if (count == 1) {
304 pQuery = new PreparedQueryObject();
305 pQuery.appendQueryString(
306 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
307 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
308 MusicUtil.DEFAULTKEYSPACENAME));
309 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
310 MusicCore.nonKeyRelatedPut(pQuery, consistency);
312 pQuery = new PreparedQueryObject();
313 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
314 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
315 MusicCore.nonKeyRelatedPut(pQuery, consistency);
318 PreparedQueryObject queryObject = new PreparedQueryObject();
319 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
320 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
321 if ( result.equals(ResultType.FAILURE) ) {
322 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
324 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
338 @Path("/{keyspace}/tables/{tablename}")
339 @ApiOperation(value = "Create Table", response = String.class)
340 @Consumes(MediaType.APPLICATION_JSON)
341 @Produces(MediaType.APPLICATION_JSON)
342 //public Map<String, Object> createTable(
343 public Response createTable(
344 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
345 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
346 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
347 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
348 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
349 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
350 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
352 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
353 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
354 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
355 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
357 if (authMap.containsKey("aid"))
358 authMap.remove("aid");
359 if (!authMap.isEmpty()) {
360 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
361 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
363 String consistency = MusicUtil.EVENTUAL;
364 // for now this needs only eventual consistency
365 PreparedQueryObject queryObject = new PreparedQueryObject();
366 // first read the information about the table fields
367 Map<String, String> fields = tableObj.getFields();
368 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
371 for (Map.Entry<String, String> entry : fields.entrySet()) {
373 if (entry.getKey().equals("PRIMARY KEY")) {
374 if(! entry.getValue().contains("("))
375 primaryKey = entry.getValue();
377 primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
378 primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
380 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
382 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
383 if (counter == fields.size() - 1)
384 fieldsString.append(")");
386 fieldsString.append(",");
387 counter = counter + 1;
389 // information about the name-value style properties
390 Map<String, Object> propertiesMap = tableObj.getProperties();
391 StringBuilder propertiesString = new StringBuilder();
392 if (propertiesMap != null) {
394 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
395 Object ot = entry.getValue();
396 String value = ot + "";
397 if (ot instanceof String) {
398 value = "'" + value + "'";
399 } else if (ot instanceof Map) {
400 @SuppressWarnings("unchecked")
401 Map<String, Object> otMap = (Map<String, Object>) ot;
402 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
405 propertiesString.append(entry.getKey() + "=" + value + "");
406 if (counter != propertiesMap.size() - 1)
407 propertiesString.append(" AND ");
409 counter = counter + 1;
413 queryObject.appendQueryString(
414 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
416 if (propertiesMap != null)
417 queryObject.appendQueryString(" WITH " + propertiesString);
419 queryObject.appendQueryString(";");
420 ResultType result = ResultType.FAILURE;
423 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
424 } catch (MusicServiceException ex) {
425 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
426 response.status(Status.BAD_REQUEST);
427 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
429 if ( result.equals(ResultType.FAILURE) ) {
430 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
432 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename + " Created under keyspace " + keyspace).toMap()).build();
444 @Path("/{keyspace}/tables/{tablename}/index/{field}")
445 @ApiOperation(value = "Create Index", response = String.class)
446 @Produces(MediaType.APPLICATION_JSON)
447 public Response createIndex(
448 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
449 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
450 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
451 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
452 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
453 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
454 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
455 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
456 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename,
457 @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName,
458 @Context UriInfo info) throws Exception {
459 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
461 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex");
462 if (authMap.containsKey("aid"))
463 authMap.remove("aid");
464 if (!authMap.isEmpty()) {
465 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
466 response.status(Status.UNAUTHORIZED);
467 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
469 MultivaluedMap<String, String> rowParams = info.getQueryParameters();
470 String indexName = "";
471 if (rowParams.getFirst("index_name") != null)
472 indexName = rowParams.getFirst("index_name");
473 PreparedQueryObject query = new PreparedQueryObject();
474 query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
475 + tablename + " (" + fieldName + ");");
477 ResultType result = ResultType.FAILURE;
479 result = MusicCore.nonKeyRelatedPut(query, "eventual");
480 } catch (MusicServiceException ex) {
481 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
482 response.status(Status.BAD_REQUEST);
483 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
485 if ( result.equals(ResultType.SUCCESS) ) {
486 return response.entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build();
488 return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
501 @Path("/{keyspace}/tables/{tablename}/rows")
502 @ApiOperation(value = "Insert Into Table", response = String.class)
503 @Consumes(MediaType.APPLICATION_JSON)
504 @Produces(MediaType.APPLICATION_JSON)
505 public Response insertIntoTable(
506 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
507 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
508 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
509 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
510 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
511 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
512 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
514 @ApiParam(value = "Keyspace Name",
515 required = true) @PathParam("keyspace") String keyspace,
516 @ApiParam(value = "Table Name",
517 required = true) @PathParam("tablename") String tablename) {
518 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
520 Map<String, Object> authMap = null;
523 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
524 aid, "insertIntoTable");
525 } catch (Exception e) {
526 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
527 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
529 if (authMap.containsKey("aid"))
530 authMap.remove("aid");
531 if (!authMap.isEmpty()) {
532 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
533 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
536 Map<String, Object> valuesMap = insObj.getValues();
537 PreparedQueryObject queryObject = new PreparedQueryObject();
538 TableMetadata tableInfo = null;
540 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
541 if(tableInfo == null) {
542 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
544 } catch (MusicServiceException e) {
545 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
546 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
548 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
549 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
551 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
552 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
553 queryObject.addValue(vectorTs);
555 String primaryKey = "";
557 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
558 fieldsString.append("" + entry.getKey());
559 Object valueObj = entry.getValue();
560 if (primaryKeyName.equals(entry.getKey())) {
561 primaryKey = entry.getValue() + "";
562 primaryKey = primaryKey.replace("'", "''");
564 DataType colType = null;
566 colType = tableInfo.getColumn(entry.getKey()).getType();
567 } catch(NullPointerException ex) {
568 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
569 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
572 Object formattedValue = null;
574 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
575 } catch (Exception e) {
576 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
578 valueString.append("?");
579 queryObject.addValue(formattedValue);
581 if (counter == valuesMap.size() - 1) {
582 fieldsString.append(")");
583 valueString.append(")");
585 fieldsString.append(",");
586 valueString.append(",");
588 counter = counter + 1;
591 if(primaryKey == null || primaryKey.length() <= 0) {
592 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
593 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
596 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
597 + fieldsString + " VALUES " + valueString);
599 String ttl = insObj.getTtl();
600 String timestamp = insObj.getTimestamp();
602 if ((ttl != null) && (timestamp != null)) {
603 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
604 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
605 queryObject.addValue(Integer.parseInt(ttl));
606 queryObject.addValue(Long.parseLong(timestamp));
609 if ((ttl != null) && (timestamp == null)) {
610 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
611 queryObject.appendQueryString(" USING TTL ?");
612 queryObject.addValue(Integer.parseInt(ttl));
615 if ((ttl == null) && (timestamp != null)) {
616 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
617 queryObject.appendQueryString(" USING TIMESTAMP ?");
618 queryObject.addValue(Long.parseLong(timestamp));
621 queryObject.appendQueryString(";");
623 ReturnType result = null;
624 String consistency = insObj.getConsistencyInfo().get("type");
626 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
627 result = MusicCore.eventualPut(queryObject);
628 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
629 String lockId = insObj.getConsistencyInfo().get("lockId");
631 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
632 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
633 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
634 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
636 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
637 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
638 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
641 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
642 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
645 } catch (Exception ex) {
646 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
647 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
651 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
652 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
654 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
667 @Path("/{keyspace}/tables/{tablename}/rows")
668 @ApiOperation(value = "Update Table", response = String.class)
669 @Consumes(MediaType.APPLICATION_JSON)
670 @Produces(MediaType.APPLICATION_JSON)
671 public Response updateTable(
672 @ApiParam(value = "Major Version",
673 required = true) @PathParam("version") String version,
674 @ApiParam(value = "Minor Version",
675 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
676 @ApiParam(value = "Patch Version",
677 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
678 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
679 @ApiParam(value = "Application namespace",
680 required = true) @HeaderParam(NS) String ns,
681 @ApiParam(value = "userId",
682 required = true) @HeaderParam(USERID) String userId,
683 @ApiParam(value = "Password",
684 required = true) @HeaderParam(PASSWORD) String password,
685 JsonUpdate updateObj,
686 @ApiParam(value = "Keyspace Name",
687 required = true) @PathParam("keyspace") String keyspace,
688 @ApiParam(value = "Table Name",
689 required = true) @PathParam("tablename") String tablename,
690 @Context UriInfo info) {
691 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
693 Map<String, Object> authMap;
695 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
697 } catch (Exception e) {
698 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
699 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
701 if (authMap.containsKey("aid"))
702 authMap.remove("aid");
703 if (!authMap.isEmpty()) {
704 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
705 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
707 long startTime = System.currentTimeMillis();
708 String operationId = UUID.randomUUID().toString();// just for infoging
710 String consistency = updateObj.getConsistencyInfo().get("type");
711 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
712 + " update-" + operationId + "-------------------------");
713 // obtain the field value pairs of the update
715 PreparedQueryObject queryObject = new PreparedQueryObject();
716 Map<String, Object> valuesMap = updateObj.getValues();
718 TableMetadata tableInfo;
720 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
721 } catch (MusicServiceException e) {
722 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
723 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
725 if (tableInfo == null) {
726 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
727 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
728 .setError("Table information not found. Please check input for table name= "
729 + keyspace + "." + tablename).toMap()).build();
732 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
733 StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
734 queryObject.addValue(vectorTs);
736 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
737 Object valueObj = entry.getValue();
738 DataType colType = null;
740 colType = tableInfo.getColumn(entry.getKey()).getType();
741 } catch(NullPointerException ex) {
742 logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
743 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
745 Object valueString = null;
747 valueString = MusicUtil.convertToActualDataType(colType, valueObj);
748 } catch (Exception e) {
749 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
751 fieldValueString.append(entry.getKey() + "= ?");
752 queryObject.addValue(valueString);
753 if (counter != valuesMap.size() - 1)
754 fieldValueString.append(",");
755 counter = counter + 1;
757 String ttl = updateObj.getTtl();
758 String timestamp = updateObj.getTimestamp();
760 queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
761 if ((ttl != null) && (timestamp != null)) {
763 logger.info("both there");
764 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
765 queryObject.addValue(Integer.parseInt(ttl));
766 queryObject.addValue(Long.parseLong(timestamp));
769 if ((ttl != null) && (timestamp == null)) {
770 logger.info("ONLY TTL there");
771 queryObject.appendQueryString(" USING TTL ?");
772 queryObject.addValue(Integer.parseInt(ttl));
775 if ((ttl == null) && (timestamp != null)) {
776 logger.info("ONLY timestamp there");
777 queryObject.appendQueryString(" USING TIMESTAMP ?");
778 queryObject.addValue(Long.parseLong(timestamp));
780 // get the row specifier
781 RowIdentifier rowId = null;
783 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
784 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
785 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
786 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
788 } catch (MusicServiceException ex) {
789 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
790 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
793 queryObject.appendQueryString(
794 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
796 // get the conditional, if any
797 Condition conditionInfo;
798 if (updateObj.getConditions() == null)
799 conditionInfo = null;
800 else {// to avoid parsing repeatedly, just send the select query to
802 PreparedQueryObject selectQuery = new PreparedQueryObject();
803 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
804 + rowId.rowIdString + ";");
805 selectQuery.addValue(rowId.primarKeyValue);
806 conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
809 ReturnType operationResult = null;
810 long jsonParseCompletionTime = System.currentTimeMillis();
812 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
813 operationResult = MusicCore.eventualPut(queryObject);
814 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
815 String lockId = updateObj.getConsistencyInfo().get("lockId");
817 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
818 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
819 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
820 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
822 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
823 queryObject, lockId, conditionInfo);
824 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
825 // this function is mainly for the benchmarks
827 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
828 rowId.primarKeyValue, queryObject, conditionInfo);
829 } catch (MusicLockingException e) {
830 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
831 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
833 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
835 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
836 queryObject, conditionInfo);
837 } catch (MusicLockingException e) {
838 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
839 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
842 long actualUpdateCompletionTime = System.currentTimeMillis();
844 long endTime = System.currentTimeMillis();
845 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
846 + ":" + "|total operation time:" + (endTime - startTime)
847 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
848 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
851 if (operationResult != null && operationResult.getTimingInfo() != null) {
852 String lockManagementTime = operationResult.getTimingInfo();
853 timingString = timingString + lockManagementTime;
855 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
857 if (operationResult==null) {
858 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
859 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
861 if ( operationResult.getResult() == ResultType.SUCCESS ) {
862 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
864 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
865 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
880 @Path("/{keyspace}/tables/{tablename}/rows")
881 @ApiOperation(value = "Delete From table", response = String.class)
882 @Consumes(MediaType.APPLICATION_JSON)
883 @Produces(MediaType.APPLICATION_JSON)
884 public Response deleteFromTable(
885 @ApiParam(value = "Major Version",
886 required = true) @PathParam("version") String version,
887 @ApiParam(value = "Minor Version",
888 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
889 @ApiParam(value = "Patch Version",
890 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
891 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
892 @ApiParam(value = "Application namespace",
893 required = true) @HeaderParam(NS) String ns,
894 @ApiParam(value = "userId",
895 required = true) @HeaderParam(USERID) String userId,
896 @ApiParam(value = "Password",
897 required = true) @HeaderParam(PASSWORD) String password,
899 @ApiParam(value = "Keyspace Name",
900 required = true) @PathParam("keyspace") String keyspace,
901 @ApiParam(value = "Table Name",
902 required = true) @PathParam("tablename") String tablename,
903 @Context UriInfo info) {
904 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
906 Map<String, Object> authMap = null;
908 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
909 aid, "deleteFromTable");
910 } catch (Exception e) {
911 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
912 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
914 if (authMap.containsKey("aid"))
915 authMap.remove("aid");
916 if (!authMap.isEmpty()) {
917 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
918 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
921 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
922 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
924 PreparedQueryObject queryObject = new PreparedQueryObject();
925 StringBuilder columnString = new StringBuilder();
928 ArrayList<String> columnList = delObj.getColumns();
929 if (columnList != null) {
930 for (String column : columnList) {
931 columnString.append(column);
932 if (counter != columnList.size() - 1)
933 columnString.append(",");
934 counter = counter + 1;
938 // get the row specifier
939 RowIdentifier rowId = null;
941 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
942 } catch (MusicServiceException ex) {
943 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
944 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
946 String rowSpec = rowId.rowIdString.toString();
948 if ((columnList != null) && (!rowSpec.isEmpty())) {
949 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
950 + tablename + " WHERE " + rowSpec + ";");
953 if ((columnList == null) && (!rowSpec.isEmpty())) {
954 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
958 if ((columnList != null) && (rowSpec.isEmpty())) {
959 queryObject.appendQueryString(
960 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
962 // get the conditional, if any
963 Condition conditionInfo;
964 if (delObj.getConditions() == null)
965 conditionInfo = null;
966 else {// to avoid parsing repeatedly, just send the select query to
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(delObj.getConditions(), selectQuery);
975 String consistency = delObj.getConsistencyInfo().get("type");
977 ReturnType operationResult = null;
979 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
980 operationResult = MusicCore.eventualPut(queryObject);
981 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
982 String lockId = delObj.getConsistencyInfo().get("lockId");
984 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
985 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
986 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
987 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
989 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
990 queryObject, lockId, conditionInfo);
991 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
992 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
993 queryObject, conditionInfo);
995 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
996 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
997 queryObject, conditionInfo);
999 } catch (MusicLockingException e) {
1000 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1001 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1002 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1004 if (operationResult==null) {
1005 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1006 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1008 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1009 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1011 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1012 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1024 @Path("/{keyspace}/tables/{tablename}")
1025 @ApiOperation(value = "Drop Table", response = String.class)
1026 @Produces(MediaType.APPLICATION_JSON)
1027 public Response dropTable(
1028 @ApiParam(value = "Major Version",
1029 required = true) @PathParam("version") String version,
1030 @ApiParam(value = "Minor Version",
1031 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1032 @ApiParam(value = "Patch Version",
1033 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1034 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1035 @ApiParam(value = "Application namespace",
1036 required = true) @HeaderParam(NS) String ns,
1037 @ApiParam(value = "userId",
1038 required = true) @HeaderParam(USERID) String userId,
1039 @ApiParam(value = "Password",
1040 required = true) @HeaderParam(PASSWORD) String password,
1041 @ApiParam(value = "Keyspace Name",
1042 required = true) @PathParam("keyspace") String keyspace,
1043 @ApiParam(value = "Table Name",
1044 required = true) @PathParam("tablename") String tablename) throws Exception {
1045 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1047 Map<String, Object> authMap =
1048 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1049 if (authMap.containsKey("aid"))
1050 authMap.remove("aid");
1051 if (!authMap.isEmpty()) {
1052 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1053 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1055 String consistency = "eventual";// for now this needs only eventual
1057 PreparedQueryObject query = new PreparedQueryObject();
1058 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1060 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1061 } catch (MusicServiceException ex) {
1062 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1063 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1077 @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
1078 @ApiOperation(value = "Select Critical", response = Map.class)
1079 @Consumes(MediaType.APPLICATION_JSON)
1080 @Produces(MediaType.APPLICATION_JSON)
1081 public Response selectCritical(
1082 @ApiParam(value = "Major Version",
1083 required = true) @PathParam("version") String version,
1084 @ApiParam(value = "Minor Version",
1085 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1086 @ApiParam(value = "Patch Version",
1087 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1088 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1089 @ApiParam(value = "Application namespace",
1090 required = true) @HeaderParam(NS) String ns,
1091 @ApiParam(value = "userId",
1092 required = true) @HeaderParam(USERID) String userId,
1093 @ApiParam(value = "Password",
1094 required = true) @HeaderParam(PASSWORD) String password,
1096 @ApiParam(value = "Keyspace Name",
1097 required = true) @PathParam("keyspace") String keyspace,
1098 @ApiParam(value = "Table Name",
1099 required = true) @PathParam("tablename") String tablename,
1100 @Context UriInfo info) throws Exception {
1101 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1103 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical");
1104 if (authMap.containsKey("aid"))
1105 authMap.remove("aid");
1106 if (!authMap.isEmpty()) {
1107 logger.error(EELFLoggerDelegate.errorLogger,"Error while authentication... ", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1108 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1110 String lockId = selObj.getConsistencyInfo().get("lockId");
1112 PreparedQueryObject queryObject = new PreparedQueryObject();
1114 RowIdentifier rowId = null;
1116 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1117 } catch (MusicServiceException ex) {
1118 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1119 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1121 queryObject.appendQueryString(
1122 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1124 ResultSet results = null;
1126 String consistency = selObj.getConsistencyInfo().get("type");
1128 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1129 if(lockId == null) {
1130 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1131 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1132 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1133 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1135 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1137 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1138 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1141 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1142 results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1145 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1157 @Path("/{keyspace}/tables/{tablename}/rows")
1158 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1159 @Produces(MediaType.APPLICATION_JSON)
1160 public Response select(
1161 @ApiParam(value = "Major Version",
1162 required = true) @PathParam("version") String version,
1163 @ApiParam(value = "Minor Version",
1164 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1165 @ApiParam(value = "Patch Version",
1166 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1167 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1168 @ApiParam(value = "Application namespace",
1169 required = true) @HeaderParam(NS) String ns,
1170 @ApiParam(value = "userId",
1171 required = true) @HeaderParam(USERID) String userId,
1172 @ApiParam(value = "Password",
1173 required = true) @HeaderParam(PASSWORD) String password,
1174 @ApiParam(value = "Keyspace Name",
1175 required = true) @PathParam("keyspace") String keyspace,
1176 @ApiParam(value = "Table Name",
1177 required = true) @PathParam("tablename") String tablename,
1178 @Context UriInfo info) throws Exception {
1179 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1181 Map<String, Object> authMap =
1182 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1183 if (authMap.containsKey("aid"))
1184 authMap.remove("aid");
1185 if (!authMap.isEmpty()) {
1186 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1187 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1189 PreparedQueryObject queryObject = new PreparedQueryObject();
1191 if (info.getQueryParameters().isEmpty())// select all
1192 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1194 int limit = -1; // do not limit the number of results
1196 queryObject = selectSpecificQuery(VERSION, minorVersion, patchVersion, aid, ns,
1197 userId, password, keyspace, tablename, info, limit);
1198 } catch (MusicServiceException ex) {
1199 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1200 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1205 ResultSet results = MusicCore.get(queryObject);
1206 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1207 } catch (MusicServiceException ex) {
1208 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1209 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1221 * @throws MusicServiceException
1223 public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1224 String patchVersion, String aid, String ns, String userId, String password,
1225 String keyspace, String tablename, UriInfo info, int limit)
1226 throws MusicServiceException {
1228 PreparedQueryObject queryObject = new PreparedQueryObject();
1229 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1230 queryObject).rowIdString;
1232 queryObject.appendQueryString(
1233 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1236 queryObject.appendQueryString(" LIMIT " + limit);
1239 queryObject.appendQueryString(";");
1249 * @param queryObject
1251 * @throws MusicServiceException
1253 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1254 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1255 throws MusicServiceException {
1256 StringBuilder rowSpec = new StringBuilder();
1258 TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1259 if (tableInfo == null) {
1260 logger.error(EELFLoggerDelegate.errorLogger,
1261 "Table information not found. Please check input for table name= "
1262 + keyspace + "." + tablename);
1263 throw new MusicServiceException(
1264 "Table information not found. Please check input for table name= "
1265 + keyspace + "." + tablename);
1267 StringBuilder primaryKey = new StringBuilder();
1268 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1269 String keyName = entry.getKey();
1270 List<String> valueList = entry.getValue();
1271 String indValue = valueList.get(0);
1272 DataType colType = null;
1273 Object formattedValue = null;
1275 colType = tableInfo.getColumn(entry.getKey()).getType();
1276 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1277 } catch (Exception e) {
1278 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1280 primaryKey.append(indValue);
1281 rowSpec.append(keyName + "= ?");
1282 queryObject.addValue(formattedValue);
1283 if (counter != rowParams.size() - 1)
1284 rowSpec.append(" AND ");
1285 counter = counter + 1;
1287 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);