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 * ====================================================================
23 package org.onap.music.rest;
25 import java.util.ArrayList;
26 import java.util.List;
28 import java.util.UUID;
29 import javax.ws.rs.Consumes;
30 import javax.ws.rs.DELETE;
31 import javax.ws.rs.GET;
32 import javax.ws.rs.HeaderParam;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.PUT;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.PathParam;
37 import javax.ws.rs.Produces;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.HttpHeaders;
40 import javax.ws.rs.core.MediaType;
41 import javax.ws.rs.core.MultivaluedMap;
42 import javax.ws.rs.core.Response;
43 import javax.ws.rs.core.Response.ResponseBuilder;
44 import javax.ws.rs.core.Response.Status;
45 import javax.ws.rs.core.UriInfo;
47 import org.mindrot.jbcrypt.BCrypt;
48 import org.onap.music.datastore.PreparedQueryObject;
49 import org.onap.music.datastore.jsonobjects.JsonDelete;
50 import org.onap.music.datastore.jsonobjects.JsonInsert;
51 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
52 import org.onap.music.datastore.jsonobjects.JsonTable;
53 import org.onap.music.datastore.jsonobjects.JsonUpdate;
54 import org.onap.music.eelf.logging.EELFLoggerDelegate;
55 import org.onap.music.exceptions.MusicLockingException;
56 import org.onap.music.eelf.logging.format.AppMessages;
57 import org.onap.music.eelf.logging.format.ErrorSeverity;
58 import org.onap.music.eelf.logging.format.ErrorTypes;
59 import org.onap.music.exceptions.MusicServiceException;
60 import org.onap.music.main.CachingUtil;
61 import org.onap.music.main.MusicCore;
62 import org.onap.music.main.MusicCore.Condition;
63 import org.onap.music.main.MusicUtil;
64 import org.onap.music.main.ResultType;
65 import org.onap.music.main.ReturnType;
66 import org.onap.music.response.jsonobjects.JsonResponse;
68 import com.datastax.driver.core.DataType;
69 import com.datastax.driver.core.ResultSet;
70 import com.datastax.driver.core.Row;
71 import com.datastax.driver.core.TableMetadata;
72 import io.swagger.annotations.Api;
73 import io.swagger.annotations.ApiOperation;
74 import io.swagger.annotations.ApiParam;
77 //@Path("/v{version: [0-9]+}/keyspaces")
78 @Path("/v2/keyspaces")
79 @Api(value = "Data Api")
80 public class RestMusicDataAPI {
82 * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
83 * version back from the client to the server, and from the server back to the client - This
84 * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
85 * version (if not specified by the client on the request) - Contains a single position value
86 * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
87 * request; however, this header should be provided if the client needs to take advantage of
88 * MINOR incremented version functionality - Is mandatory for the server on response
90 *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
91 * troubleshooting purposes only, and will not be provided by the client on request - This will
92 * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
93 * of the MAJOR (if not specified by the client on the request) - Contains a single position
94 * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
95 * server on response (CURRENTLY NOT USED)
97 *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
98 * server on response, and shall include the entire version of the API (e.g. if the full version
99 * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
100 * not using the latest version of the API (CURRENTLY NOT USED)
104 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
105 private static final String XMINORVERSION = "X-minorVersion";
106 private static final String XPATCHVERSION = "X-patchVersion";
107 private static final String NS = "ns";
108 private static final String USERID = "userId";
109 private static final String PASSWORD = "password";
110 private static final String VERSION = "v2";
112 private class RowIdentifier {
113 public String primarKeyValue;
114 public StringBuilder rowIdString;
115 @SuppressWarnings("unused")
116 public PreparedQueryObject queryObject;// the string with all the row
117 // identifiers separated by AND
119 public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
120 PreparedQueryObject queryObject) {
121 this.primarKeyValue = primaryKeyValue;
122 this.rowIdString = rowIdString;
123 this.queryObject = queryObject;
129 * Create Keyspace REST
132 * @param keyspaceName
138 @ApiOperation(value = "Create Keyspace", response = String.class)
139 @Consumes(MediaType.APPLICATION_JSON)
140 @Produces(MediaType.APPLICATION_JSON)
141 //public Map<String, Object> createKeySpace(
142 public Response createKeySpace(
143 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
144 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
145 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
146 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
147 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
148 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
149 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
150 JsonKeySpace kspObject,
151 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) {
152 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
154 Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
155 if (!authMap.isEmpty()) {
156 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
157 response.status(Status.UNAUTHORIZED);
158 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
160 if(kspObject == null || kspObject.getReplicationInfo() == null) {
161 authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult());
162 response.status(Status.BAD_REQUEST);
163 return response.entity(authMap).build();
167 authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
169 } catch (Exception e) {
170 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
171 response.status(Status.BAD_REQUEST);
172 return response.entity(new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap()).build();
174 String newAid = null;
175 if (!authMap.isEmpty()) {
176 if (authMap.containsKey("aid")) {
177 newAid = (String) authMap.get("aid");
179 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
180 response.status(Status.UNAUTHORIZED);
181 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
185 String consistency = MusicUtil.EVENTUAL;// for now this needs only
186 // eventual consistency
188 PreparedQueryObject queryObject = new PreparedQueryObject();
189 long start = System.currentTimeMillis();
190 Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
191 String repString = null;
193 repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
194 } catch (Exception e) {
195 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
198 queryObject.appendQueryString(
199 "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
200 if (kspObject.getDurabilityOfWrites() != null) {
201 queryObject.appendQueryString(
202 " AND durable_writes = " + kspObject.getDurabilityOfWrites());
205 queryObject.appendQueryString(";");
206 long end = System.currentTimeMillis();
207 logger.info(EELFLoggerDelegate.applicationLogger,
208 "Time taken for setting up query in create keyspace:" + (end - start));
210 ResultType result = ResultType.FAILURE;
212 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
213 logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
214 } catch ( MusicServiceException ex) {
215 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
216 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
220 queryObject = new PreparedQueryObject();
221 queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
222 + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
223 MusicCore.nonKeyRelatedPut(queryObject, consistency);
224 queryObject = new PreparedQueryObject();
225 queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
226 + " to '" + userId + "'");
227 queryObject.appendQueryString(";");
228 MusicCore.nonKeyRelatedPut(queryObject, consistency);
229 } catch (Exception e) {
230 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
234 boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns));
235 String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt());
236 queryObject = new PreparedQueryObject();
237 queryObject.appendQueryString(
238 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
239 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
240 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
241 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName));
242 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
243 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
244 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd));
245 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
246 queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
247 CachingUtil.updateMusicCache(keyspaceName, ns);
248 CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
249 MusicCore.eventualPut(queryObject);
250 } catch (Exception e) {
251 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
252 return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
255 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
261 * @param keyspaceName
267 @ApiOperation(value = "Delete Keyspace", response = String.class)
268 @Produces(MediaType.APPLICATION_JSON)
269 //public Map<String, Object> dropKeySpace(
270 public Response dropKeySpace(
271 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
272 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
273 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
274 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
275 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
276 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
277 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
278 @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception {
279 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
281 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace");
282 if (authMap.containsKey("aid"))
283 authMap.remove("aid");
284 if (!authMap.isEmpty()) {
285 return response.status(Status.UNAUTHORIZED).entity(authMap).build();
288 String consistency = MusicUtil.EVENTUAL;// for now this needs only
291 String appName = CachingUtil.getAppName(keyspaceName);
292 String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
293 PreparedQueryObject pQuery = new PreparedQueryObject();
294 pQuery.appendQueryString(
295 "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
296 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
297 Row row = MusicCore.get(pQuery).one();
298 long count = row.getLong(0);
301 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
302 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
304 } else if (count == 1) {
305 pQuery = new PreparedQueryObject();
306 pQuery.appendQueryString(
307 "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
308 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
309 MusicUtil.DEFAULTKEYSPACENAME));
310 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
311 MusicCore.nonKeyRelatedPut(pQuery, consistency);
313 pQuery = new PreparedQueryObject();
314 pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
315 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
316 MusicCore.nonKeyRelatedPut(pQuery, consistency);
319 PreparedQueryObject queryObject = new PreparedQueryObject();
320 queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
321 ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
322 if ( result.equals(ResultType.FAILURE) ) {
323 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
325 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
339 @Path("/{keyspace}/tables/{tablename}")
340 @ApiOperation(value = "Create Table", response = String.class)
341 @Consumes(MediaType.APPLICATION_JSON)
342 @Produces(MediaType.APPLICATION_JSON)
343 //public Map<String, Object> createTable(
344 public Response createTable(
345 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
346 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
347 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
348 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
349 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
350 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
351 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
353 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
354 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception {
355 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
356 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
358 if (authMap.containsKey("aid"))
359 authMap.remove("aid");
360 if (!authMap.isEmpty()) {
361 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
362 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
364 String consistency = MusicUtil.EVENTUAL;
365 // for now this needs only eventual consistency
366 PreparedQueryObject queryObject = new PreparedQueryObject();
367 // first read the information about the table fields
368 Map<String, String> fields = tableObj.getFields();
369 StringBuilder fieldsString = new StringBuilder("(vector_ts text,");
372 for (Map.Entry<String, String> entry : fields.entrySet()) {
374 if (entry.getKey().equals("PRIMARY KEY")) {
375 if(! entry.getValue().contains("("))
376 primaryKey = entry.getValue();
378 primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1);
379 primaryKey = primaryKey.substring(0, primaryKey.indexOf(')'));
381 fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")");
383 fieldsString.append("" + entry.getKey() + " " + entry.getValue() + "");
384 if (counter == fields.size() - 1)
385 fieldsString.append(")");
387 fieldsString.append(",");
388 counter = counter + 1;
390 // information about the name-value style properties
391 Map<String, Object> propertiesMap = tableObj.getProperties();
392 StringBuilder propertiesString = new StringBuilder();
393 if (propertiesMap != null) {
395 for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
396 Object ot = entry.getValue();
397 String value = ot + "";
398 if (ot instanceof String) {
399 value = "'" + value + "'";
400 } else if (ot instanceof Map) {
401 @SuppressWarnings("unchecked")
402 Map<String, Object> otMap = (Map<String, Object>) ot;
403 value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
406 propertiesString.append(entry.getKey() + "=" + value + "");
407 if (counter != propertiesMap.size() - 1)
408 propertiesString.append(" AND ");
410 counter = counter + 1;
414 queryObject.appendQueryString(
415 "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
417 if (propertiesMap != null)
418 queryObject.appendQueryString(" WITH " + propertiesString);
420 queryObject.appendQueryString(";");
421 ResultType result = ResultType.FAILURE;
424 result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
425 } catch (MusicServiceException ex) {
426 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
427 response.status(Status.BAD_REQUEST);
428 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
430 if ( result.equals(ResultType.FAILURE) ) {
431 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
433 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename + " Created under keyspace " + keyspace).toMap()).build();
445 @Path("/{keyspace}/tables/{tablename}/index/{field}")
446 @ApiOperation(value = "Create Index", response = String.class)
447 @Produces(MediaType.APPLICATION_JSON)
448 public Response createIndex(
449 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
450 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
451 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
452 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
453 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
454 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
455 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
456 @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace,
457 @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename,
458 @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName,
459 @Context UriInfo info) throws Exception {
460 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
462 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex");
463 if (authMap.containsKey("aid"))
464 authMap.remove("aid");
465 if (!authMap.isEmpty()) {
466 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
467 response.status(Status.UNAUTHORIZED);
468 return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
470 MultivaluedMap<String, String> rowParams = info.getQueryParameters();
471 String indexName = "";
472 if (rowParams.getFirst("index_name") != null)
473 indexName = rowParams.getFirst("index_name");
474 PreparedQueryObject query = new PreparedQueryObject();
475 query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "."
476 + tablename + " (" + fieldName + ");");
478 ResultType result = ResultType.FAILURE;
480 result = MusicCore.nonKeyRelatedPut(query, "eventual");
481 } catch (MusicServiceException ex) {
482 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
483 response.status(Status.BAD_REQUEST);
484 return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
486 if ( result.equals(ResultType.SUCCESS) ) {
487 return response.entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build();
489 return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
502 @Path("/{keyspace}/tables/{tablename}/rows")
503 @ApiOperation(value = "Insert Into Table", response = String.class)
504 @Consumes(MediaType.APPLICATION_JSON)
505 @Produces(MediaType.APPLICATION_JSON)
506 public Response insertIntoTable(
507 @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
508 @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion,
509 @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
510 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
511 @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns,
512 @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId,
513 @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password,
515 @ApiParam(value = "Keyspace Name",
516 required = true) @PathParam("keyspace") String keyspace,
517 @ApiParam(value = "Table Name",
518 required = true) @PathParam("tablename") String tablename) {
519 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
521 Map<String, Object> authMap = null;
524 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
525 aid, "insertIntoTable");
526 } catch (Exception e) {
527 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
528 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
530 if (authMap.containsKey("aid"))
531 authMap.remove("aid");
532 if (!authMap.isEmpty()) {
533 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
534 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
537 Map<String, Object> valuesMap = insObj.getValues();
538 PreparedQueryObject queryObject = new PreparedQueryObject();
539 TableMetadata tableInfo = null;
541 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
542 if(tableInfo == null) {
543 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
545 } catch (MusicServiceException e) {
546 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
547 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
549 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
550 StringBuilder fieldsString = new StringBuilder("(vector_ts,");
552 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
553 StringBuilder valueString = new StringBuilder("(" + "?" + ",");
554 queryObject.addValue(vectorTs);
556 String primaryKey = "";
558 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
559 fieldsString.append("" + entry.getKey());
560 Object valueObj = entry.getValue();
561 if (primaryKeyName.equals(entry.getKey())) {
562 primaryKey = entry.getValue() + "";
563 primaryKey = primaryKey.replace("'", "''");
565 DataType colType = null;
567 colType = tableInfo.getColumn(entry.getKey()).getType();
568 } catch(NullPointerException ex) {
569 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
570 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
573 Object formattedValue = null;
575 formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
576 } catch (Exception e) {
577 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
579 valueString.append("?");
580 queryObject.addValue(formattedValue);
582 if (counter == valuesMap.size() - 1) {
583 fieldsString.append(")");
584 valueString.append(")");
586 fieldsString.append(",");
587 valueString.append(",");
589 counter = counter + 1;
592 if(primaryKey == null || primaryKey.length() <= 0) {
593 logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName );
594 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build();
597 queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
598 + fieldsString + " VALUES " + valueString);
600 String ttl = insObj.getTtl();
601 String timestamp = insObj.getTimestamp();
603 if ((ttl != null) && (timestamp != null)) {
604 logger.info(EELFLoggerDelegate.applicationLogger, "both there");
605 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
606 queryObject.addValue(Integer.parseInt(ttl));
607 queryObject.addValue(Long.parseLong(timestamp));
610 if ((ttl != null) && (timestamp == null)) {
611 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
612 queryObject.appendQueryString(" USING TTL ?");
613 queryObject.addValue(Integer.parseInt(ttl));
616 if ((ttl == null) && (timestamp != null)) {
617 logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
618 queryObject.appendQueryString(" USING TIMESTAMP ?");
619 queryObject.addValue(Long.parseLong(timestamp));
622 queryObject.appendQueryString(";");
624 ReturnType result = null;
625 String consistency = insObj.getConsistencyInfo().get("type");
627 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
628 result = MusicCore.eventualPut(queryObject);
629 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
630 String lockId = insObj.getConsistencyInfo().get("lockId");
632 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
633 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
634 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
635 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
637 result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
638 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
639 result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
642 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
643 result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
646 } catch (Exception ex) {
647 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
648 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
652 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
653 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
655 return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
668 @Path("/{keyspace}/tables/{tablename}/rows")
669 @ApiOperation(value = "Update Table", response = String.class)
670 @Consumes(MediaType.APPLICATION_JSON)
671 @Produces(MediaType.APPLICATION_JSON)
672 public Response updateTable(
673 @ApiParam(value = "Major Version",
674 required = true) @PathParam("version") String version,
675 @ApiParam(value = "Minor Version",
676 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
677 @ApiParam(value = "Patch Version",
678 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
679 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
680 @ApiParam(value = "Application namespace",
681 required = true) @HeaderParam(NS) String ns,
682 @ApiParam(value = "userId",
683 required = true) @HeaderParam(USERID) String userId,
684 @ApiParam(value = "Password",
685 required = true) @HeaderParam(PASSWORD) String password,
686 JsonUpdate updateObj,
687 @ApiParam(value = "Keyspace Name",
688 required = true) @PathParam("keyspace") String keyspace,
689 @ApiParam(value = "Table Name",
690 required = true) @PathParam("tablename") String tablename,
691 @Context UriInfo info) {
692 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
694 Map<String, Object> authMap;
696 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
698 } catch (Exception e) {
699 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
700 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
702 if (authMap.containsKey("aid"))
703 authMap.remove("aid");
704 if (!authMap.isEmpty()) {
705 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
706 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
708 long startTime = System.currentTimeMillis();
709 String operationId = UUID.randomUUID().toString();// just for infoging
711 String consistency = updateObj.getConsistencyInfo().get("type");
712 logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
713 + " update-" + operationId + "-------------------------");
714 // obtain the field value pairs of the update
716 PreparedQueryObject queryObject = new PreparedQueryObject();
717 Map<String, Object> valuesMap = updateObj.getValues();
719 TableMetadata tableInfo;
721 tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
722 } catch (MusicServiceException e) {
723 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
724 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
726 if (tableInfo == null) {
727 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
728 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
729 .setError("Table information not found. Please check input for table name= "
730 + keyspace + "." + tablename).toMap()).build();
733 String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
734 StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
735 queryObject.addValue(vectorTs);
737 for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
738 Object valueObj = entry.getValue();
739 DataType colType = null;
741 colType = tableInfo.getColumn(entry.getKey()).getType();
742 } catch(NullPointerException ex) {
743 logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
744 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
746 Object valueString = null;
748 valueString = MusicUtil.convertToActualDataType(colType, valueObj);
749 } catch (Exception e) {
750 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
752 fieldValueString.append(entry.getKey() + "= ?");
753 queryObject.addValue(valueString);
754 if (counter != valuesMap.size() - 1)
755 fieldValueString.append(",");
756 counter = counter + 1;
758 String ttl = updateObj.getTtl();
759 String timestamp = updateObj.getTimestamp();
761 queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
762 if ((ttl != null) && (timestamp != null)) {
764 logger.info("both there");
765 queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
766 queryObject.addValue(Integer.parseInt(ttl));
767 queryObject.addValue(Long.parseLong(timestamp));
770 if ((ttl != null) && (timestamp == null)) {
771 logger.info("ONLY TTL there");
772 queryObject.appendQueryString(" USING TTL ?");
773 queryObject.addValue(Integer.parseInt(ttl));
776 if ((ttl == null) && (timestamp != null)) {
777 logger.info("ONLY timestamp there");
778 queryObject.appendQueryString(" USING TIMESTAMP ?");
779 queryObject.addValue(Long.parseLong(timestamp));
781 // get the row specifier
782 RowIdentifier rowId = null;
784 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
785 if(rowId == null || rowId.primarKeyValue.isEmpty()) {
786 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
787 .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
789 } catch (MusicServiceException ex) {
790 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
791 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
794 queryObject.appendQueryString(
795 " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
797 // get the conditional, if any
798 Condition conditionInfo;
799 if (updateObj.getConditions() == null)
800 conditionInfo = null;
801 else {// to avoid parsing repeatedly, just send the select query to
803 PreparedQueryObject selectQuery = new PreparedQueryObject();
804 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
805 + rowId.rowIdString + ";");
806 selectQuery.addValue(rowId.primarKeyValue);
807 conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
810 ReturnType operationResult = null;
811 long jsonParseCompletionTime = System.currentTimeMillis();
813 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
814 operationResult = MusicCore.eventualPut(queryObject);
815 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
816 String lockId = updateObj.getConsistencyInfo().get("lockId");
818 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
819 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
820 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
821 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
823 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
824 queryObject, lockId, conditionInfo);
825 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
826 // this function is mainly for the benchmarks
828 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
829 rowId.primarKeyValue, queryObject, conditionInfo);
830 } catch (MusicLockingException e) {
831 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
832 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
834 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
836 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
837 queryObject, conditionInfo);
838 } catch (MusicLockingException e) {
839 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
840 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
843 long actualUpdateCompletionTime = System.currentTimeMillis();
845 long endTime = System.currentTimeMillis();
846 String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
847 + ":" + "|total operation time:" + (endTime - startTime)
848 + "|json parsing time:" + (jsonParseCompletionTime - startTime)
849 + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
852 if (operationResult != null && operationResult.getTimingInfo() != null) {
853 String lockManagementTime = operationResult.getTimingInfo();
854 timingString = timingString + lockManagementTime;
856 logger.info(EELFLoggerDelegate.applicationLogger, timingString);
858 if (operationResult==null) {
859 logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
860 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
862 if ( operationResult.getResult() == ResultType.SUCCESS ) {
863 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
865 logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
866 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
881 @Path("/{keyspace}/tables/{tablename}/rows")
882 @ApiOperation(value = "Delete From table", response = String.class)
883 @Consumes(MediaType.APPLICATION_JSON)
884 @Produces(MediaType.APPLICATION_JSON)
885 public Response deleteFromTable(
886 @ApiParam(value = "Major Version",
887 required = true) @PathParam("version") String version,
888 @ApiParam(value = "Minor Version",
889 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
890 @ApiParam(value = "Patch Version",
891 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
892 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
893 @ApiParam(value = "Application namespace",
894 required = true) @HeaderParam(NS) String ns,
895 @ApiParam(value = "userId",
896 required = true) @HeaderParam(USERID) String userId,
897 @ApiParam(value = "Password",
898 required = true) @HeaderParam(PASSWORD) String password,
900 @ApiParam(value = "Keyspace Name",
901 required = true) @PathParam("keyspace") String keyspace,
902 @ApiParam(value = "Table Name",
903 required = true) @PathParam("tablename") String tablename,
904 @Context UriInfo info) {
905 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
907 Map<String, Object> authMap = null;
909 authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
910 aid, "deleteFromTable");
911 } catch (Exception e) {
912 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
913 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
915 if (authMap.containsKey("aid"))
916 authMap.remove("aid");
917 if (!authMap.isEmpty()) {
918 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
919 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
922 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
923 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
925 PreparedQueryObject queryObject = new PreparedQueryObject();
926 StringBuilder columnString = new StringBuilder();
929 ArrayList<String> columnList = delObj.getColumns();
930 if (columnList != null) {
931 for (String column : columnList) {
932 columnString.append(column);
933 if (counter != columnList.size() - 1)
934 columnString.append(",");
935 counter = counter + 1;
939 // get the row specifier
940 RowIdentifier rowId = null;
942 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
943 } catch (MusicServiceException ex) {
944 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
945 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
947 String rowSpec = rowId.rowIdString.toString();
949 if ((columnList != null) && (!rowSpec.isEmpty())) {
950 queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
951 + tablename + " WHERE " + rowSpec + ";");
954 if ((columnList == null) && (!rowSpec.isEmpty())) {
955 queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
959 if ((columnList != null) && (rowSpec.isEmpty())) {
960 queryObject.appendQueryString(
961 "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
963 // get the conditional, if any
964 Condition conditionInfo;
965 if (delObj.getConditions() == null)
966 conditionInfo = null;
967 else {// to avoid parsing repeatedly, just send the select query to
969 PreparedQueryObject selectQuery = new PreparedQueryObject();
970 selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
971 + rowId.rowIdString + ";");
972 selectQuery.addValue(rowId.primarKeyValue);
973 conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
976 String consistency = delObj.getConsistencyInfo().get("type");
978 ReturnType operationResult = null;
980 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
981 operationResult = MusicCore.eventualPut(queryObject);
982 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
983 String lockId = delObj.getConsistencyInfo().get("lockId");
985 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
986 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
987 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
988 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
990 operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
991 queryObject, lockId, conditionInfo);
992 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
993 operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
994 queryObject, conditionInfo);
996 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
997 operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
998 queryObject, conditionInfo);
1000 } catch (MusicLockingException e) {
1001 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1002 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
1003 .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
1005 if (operationResult==null) {
1006 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1007 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
1009 if (operationResult.getResult().equals(ResultType.SUCCESS)) {
1010 return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
1012 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1013 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
1025 @Path("/{keyspace}/tables/{tablename}")
1026 @ApiOperation(value = "Drop Table", response = String.class)
1027 @Produces(MediaType.APPLICATION_JSON)
1028 public Response dropTable(
1029 @ApiParam(value = "Major Version",
1030 required = true) @PathParam("version") String version,
1031 @ApiParam(value = "Minor Version",
1032 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1033 @ApiParam(value = "Patch Version",
1034 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1035 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1036 @ApiParam(value = "Application namespace",
1037 required = true) @HeaderParam(NS) String ns,
1038 @ApiParam(value = "userId",
1039 required = true) @HeaderParam(USERID) String userId,
1040 @ApiParam(value = "Password",
1041 required = true) @HeaderParam(PASSWORD) String password,
1042 @ApiParam(value = "Keyspace Name",
1043 required = true) @PathParam("keyspace") String keyspace,
1044 @ApiParam(value = "Table Name",
1045 required = true) @PathParam("tablename") String tablename) throws Exception {
1046 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1048 Map<String, Object> authMap =
1049 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
1050 if (authMap.containsKey("aid"))
1051 authMap.remove("aid");
1052 if (!authMap.isEmpty()) {
1053 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1054 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1056 String consistency = "eventual";// for now this needs only eventual
1058 PreparedQueryObject query = new PreparedQueryObject();
1059 query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
1061 return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
1062 } catch (MusicServiceException ex) {
1063 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1064 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1078 @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
1079 @ApiOperation(value = "Select Critical", response = Map.class)
1080 @Consumes(MediaType.APPLICATION_JSON)
1081 @Produces(MediaType.APPLICATION_JSON)
1082 public Response selectCritical(
1083 @ApiParam(value = "Major Version",
1084 required = true) @PathParam("version") String version,
1085 @ApiParam(value = "Minor Version",
1086 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1087 @ApiParam(value = "Patch Version",
1088 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1089 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1090 @ApiParam(value = "Application namespace",
1091 required = true) @HeaderParam(NS) String ns,
1092 @ApiParam(value = "userId",
1093 required = true) @HeaderParam(USERID) String userId,
1094 @ApiParam(value = "Password",
1095 required = true) @HeaderParam(PASSWORD) String password,
1097 @ApiParam(value = "Keyspace Name",
1098 required = true) @PathParam("keyspace") String keyspace,
1099 @ApiParam(value = "Table Name",
1100 required = true) @PathParam("tablename") String tablename,
1101 @Context UriInfo info) throws Exception {
1102 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1104 Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical");
1105 if (authMap.containsKey("aid"))
1106 authMap.remove("aid");
1107 if (!authMap.isEmpty()) {
1108 logger.error(EELFLoggerDelegate.errorLogger,"Error while authentication... ", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1109 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1111 String lockId = selObj.getConsistencyInfo().get("lockId");
1113 PreparedQueryObject queryObject = new PreparedQueryObject();
1115 RowIdentifier rowId = null;
1117 rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
1118 } catch (MusicServiceException ex) {
1119 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1120 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1122 queryObject.appendQueryString(
1123 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
1125 ResultSet results = null;
1127 String consistency = selObj.getConsistencyInfo().get("type");
1129 if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1130 if(lockId == null) {
1131 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1132 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1133 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
1134 + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
1136 results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
1138 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1139 results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
1142 else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
1143 results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
1146 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1158 @Path("/{keyspace}/tables/{tablename}/rows")
1159 @ApiOperation(value = "Select All or Select Specific", response = Map.class)
1160 @Produces(MediaType.APPLICATION_JSON)
1161 public Response select(
1162 @ApiParam(value = "Major Version",
1163 required = true) @PathParam("version") String version,
1164 @ApiParam(value = "Minor Version",
1165 required = false) @HeaderParam(XMINORVERSION) String minorVersion,
1166 @ApiParam(value = "Patch Version",
1167 required = false) @HeaderParam(XPATCHVERSION) String patchVersion,
1168 @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid,
1169 @ApiParam(value = "Application namespace",
1170 required = true) @HeaderParam(NS) String ns,
1171 @ApiParam(value = "userId",
1172 required = true) @HeaderParam(USERID) String userId,
1173 @ApiParam(value = "Password",
1174 required = true) @HeaderParam(PASSWORD) String password,
1175 @ApiParam(value = "Keyspace Name",
1176 required = true) @PathParam("keyspace") String keyspace,
1177 @ApiParam(value = "Table Name",
1178 required = true) @PathParam("tablename") String tablename,
1179 @Context UriInfo info) throws Exception {
1180 ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
1182 Map<String, Object> authMap =
1183 MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
1184 if (authMap.containsKey("aid"))
1185 authMap.remove("aid");
1186 if (!authMap.isEmpty()) {
1187 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
1188 return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
1190 PreparedQueryObject queryObject = new PreparedQueryObject();
1192 if (info.getQueryParameters().isEmpty())// select all
1193 queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
1195 int limit = -1; // do not limit the number of results
1197 queryObject = selectSpecificQuery(VERSION, minorVersion, patchVersion, aid, ns,
1198 userId, password, keyspace, tablename, info, limit);
1199 } catch (MusicServiceException ex) {
1200 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
1201 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1206 ResultSet results = MusicCore.get(queryObject);
1207 return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
1208 } catch (MusicServiceException ex) {
1209 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR);
1210 return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
1222 * @throws MusicServiceException
1224 public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
1225 String patchVersion, String aid, String ns, String userId, String password,
1226 String keyspace, String tablename, UriInfo info, int limit)
1227 throws MusicServiceException {
1229 PreparedQueryObject queryObject = new PreparedQueryObject();
1230 StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
1231 queryObject).rowIdString;
1233 queryObject.appendQueryString(
1234 "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
1237 queryObject.appendQueryString(" LIMIT " + limit);
1240 queryObject.appendQueryString(";");
1250 * @param queryObject
1252 * @throws MusicServiceException
1254 private RowIdentifier getRowIdentifier(String keyspace, String tablename,
1255 MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
1256 throws MusicServiceException {
1257 StringBuilder rowSpec = new StringBuilder();
1259 TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
1260 if (tableInfo == null) {
1261 logger.error(EELFLoggerDelegate.errorLogger,
1262 "Table information not found. Please check input for table name= "
1263 + keyspace + "." + tablename);
1264 throw new MusicServiceException(
1265 "Table information not found. Please check input for table name= "
1266 + keyspace + "." + tablename);
1268 StringBuilder primaryKey = new StringBuilder();
1269 for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
1270 String keyName = entry.getKey();
1271 List<String> valueList = entry.getValue();
1272 String indValue = valueList.get(0);
1273 DataType colType = null;
1274 Object formattedValue = null;
1276 colType = tableInfo.getColumn(entry.getKey()).getType();
1277 formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
1278 } catch (Exception e) {
1279 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1281 primaryKey.append(indValue);
1282 rowSpec.append(keyName + "= ?");
1283 queryObject.addValue(formattedValue);
1284 if (counter != rowParams.size() - 1)
1285 rowSpec.append(" AND ");
1286 counter = counter + 1;
1288 return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);