X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Fmusic%2Fdatastore%2Fjsonobjects%2FJsonInsert.java;h=57ff245a4da8d99cbd62925cb1703481cac8b04b;hb=6aad1c6198726b0e7963db363ea0cfc28e93fcd5;hp=4533f947c234bdd30be5597d43d5dabc637a6e43;hpb=a27be9fdbbf2d271c9c5780ba70fe15a24dbdb63;p=music.git diff --git a/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java b/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java index 4533f947..57ff245a 100644 --- a/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java +++ b/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java @@ -3,7 +3,7 @@ * org.onap.music * =================================================================== * Copyright (c) 2017 AT&T Intellectual Property - * Modifications Copyright (C) 2018 IBM. + * Modifications Copyright (C) 2019 IBM * =================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,21 +28,34 @@ import java.io.IOException; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.nio.ByteBuffer; +import java.util.List; import java.util.Map; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response.Status; +import org.onap.music.datastore.MusicDataStoreHandle; +import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; import org.onap.music.eelf.logging.format.AppMessages; import org.onap.music.eelf.logging.format.ErrorSeverity; import org.onap.music.eelf.logging.format.ErrorTypes; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicUtil; + +import com.datastax.driver.core.DataType; +import com.datastax.driver.core.TableMetadata; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; -@ApiModel(value = "JsonTable", description = "Json model for table vlaues insert") +@ApiModel(value = "InsertTable", description = "Json model for table vlaues insert") @JsonIgnoreProperties(ignoreUnknown = true) public class JsonInsert implements Serializable { + private static final long serialVersionUID = 1L; private String keyspaceName; private String tableName; private transient Map values; @@ -51,9 +64,10 @@ public class JsonInsert implements Serializable { private transient Map rowSpecification; private Map consistencyInfo; private Map objectMap; + private String primaryKeyVal; private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(JsonInsert.class); - @ApiModelProperty(value = "objectMap") + @ApiModelProperty(value = "objectMap",hidden = true) public Map getObjectMap() { return objectMap; } @@ -89,7 +103,10 @@ public class JsonInsert implements Serializable { this.consistencyInfo = consistencyInfo; } - @ApiModelProperty(value = "Time to live information") + @ApiModelProperty(value = "Columns and tables support an optional " + + "expiration period called TTL (time-to-live) in seconds.", + notes="TTL precision is one second, which is calculated by the coordinator " + + "node. When using TTL, ensure that all nodes in the cluster have synchronized clocks.",allowEmptyValue = true) public String getTtl() { return ttl; } @@ -98,7 +115,10 @@ public class JsonInsert implements Serializable { this.ttl = ttl; } - @ApiModelProperty(value = "Time stamp") + @ApiModelProperty(value = "Time stamp (epoch_in_microseconds)", + notes = "Marks inserted data (write time) with TIMESTAMP. " + + "Enter the time since epoch (January 1, 1970) in microseconds." + + "By default, the actual time of write is used.", allowEmptyValue = true) public String getTimestamp() { return timestamp; } @@ -107,7 +127,9 @@ public class JsonInsert implements Serializable { this.timestamp = timestamp; } - @ApiModelProperty(value = "values returned") + @ApiModelProperty(value = "Json Object of key/values", notes="Where key is the column name and value is the data value for that column.", + example = "{'emp_id': 'df98a3d40cd6','emp_name': 'john'," + + "'emp_salary': 50,'address':{'street' : '1 Some way','city' : 'New York'}}") public Map getValues() { return values; } @@ -116,14 +138,22 @@ public class JsonInsert implements Serializable { this.values = values; } - @ApiModelProperty(value = "Information for selecting specific rows for insert") - public Map getRow_specification() { + @ApiModelProperty(value = "Information for selecting specific rows for insert",hidden = true) + public Map getRowSpecification() { return rowSpecification; } - public void setRow_specification(Map rowSpecification) { + public void setRowSpecification(Map rowSpecification) { this.rowSpecification = rowSpecification; } + + public String getPrimaryKeyVal() { + return primaryKeyVal; + } + + public void setPrimaryKeyVal(String primaryKeyVal) { + this.primaryKeyVal = primaryKeyVal; + } public byte[] serialize() { ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -136,5 +166,255 @@ public class JsonInsert implements Serializable { } return bos.toByteArray(); } + + /** + * Generate TableInsertQuery + * @return + * @throws MusicQueryException + */ + public PreparedQueryObject genInsertPreparedQueryObj() throws MusicQueryException { + if (logger.isDebugEnabled()) { + logger.debug("Coming inside genTableInsertQuery method " + this.getKeyspaceName()); + logger.debug("Coming inside genTableInsertQuery method " + this.getTableName()); + } + + PreparedQueryObject queryObject = new PreparedQueryObject(); + TableMetadata tableInfo = null; + try { + tableInfo = MusicDataStoreHandle.returnColumnMetadata(this.getKeyspaceName(), this.getTableName()); + if(tableInfo == null) { + throw new MusicQueryException("Table name doesn't exists. Please check the table name.", + Status.BAD_REQUEST.getStatusCode()); + } + } catch (MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger, e, AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); + throw new MusicQueryException(e.getMessage(),Status.BAD_REQUEST.getStatusCode()); + + } + String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName(); + StringBuilder fieldsString = new StringBuilder("(vector_ts,"); + String vectorTs = + String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis()); + StringBuilder valueString = new StringBuilder("(" + "?" + ","); + queryObject.addValue(vectorTs); + + Map valuesMap = this.getValues(); + if (valuesMap==null) { + throw new MusicQueryException("Nothing to insert. No values provided in request.", + Status.BAD_REQUEST.getStatusCode()); + } + int counter = 0; + String primaryKey = ""; + for (Map.Entry entry : valuesMap.entrySet()) { + fieldsString.append("" + entry.getKey()); + Object valueObj = entry.getValue(); + if (primaryKeyName.equals(entry.getKey())) { + primaryKey = entry.getValue() + ""; + primaryKey = primaryKey.replace("'", "''"); + } + DataType colType = null; + try { + colType = tableInfo.getColumn(entry.getKey()).getType(); + } catch(NullPointerException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey + (), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR, ex); + throw new MusicQueryException("Invalid column name : " + entry.getKey(), + Status.BAD_REQUEST.getStatusCode()); + } + + Object formattedValue = null; + try { + formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e); + } + valueString.append("?"); + + queryObject.addValue(formattedValue); + + if (counter == valuesMap.size() - 1) { + fieldsString.append(")"); + valueString.append(")"); + } else { + fieldsString.append(","); + valueString.append(","); + } + counter = counter + 1; + } + + //blobs.. + Map objectMap = this.getObjectMap(); + if(objectMap != null) { + for (Map.Entry entry : objectMap.entrySet()) { + if(counter > 0) { + fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ","); + valueString.replace(valueString.length()-1, valueString.length(), ","); + } + fieldsString.append("" + entry.getKey()); + byte[] valueObj = entry.getValue(); + if (primaryKeyName.equals(entry.getKey())) { + primaryKey = entry.getValue() + ""; + primaryKey = primaryKey.replace("'", "''"); + } + DataType colType = tableInfo.getColumn(entry.getKey()).getType(); + ByteBuffer formattedValue = null; + if(colType.toString().toLowerCase().contains("blob")) { + formattedValue = MusicUtil.convertToActualDataType(colType, valueObj); + } + valueString.append("?"); + queryObject.addValue(formattedValue); + counter = counter + 1; + fieldsString.append(","); + valueString.append(","); + } + } + this.setPrimaryKeyVal(primaryKey); + if(primaryKey == null || primaryKey.length() <= 0) { + logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName ); + throw new MusicQueryException("Some required partition key parts are missing: " + primaryKeyName, + Status.BAD_REQUEST.getStatusCode()); + } + + fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ")"); + valueString.replace(valueString.length()-1, valueString.length(), ")"); + + queryObject.appendQueryString("INSERT INTO " + this.getKeyspaceName() + "." + this.getTableName() + " " + + fieldsString + " VALUES " + valueString); + + String ttl = this.getTtl(); + String timestamp = this.getTimestamp(); + + if ((ttl != null) && (timestamp != null)) { + logger.info(EELFLoggerDelegate.applicationLogger, "both there"); + queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?"); + queryObject.addValue(Integer.parseInt(ttl)); + queryObject.addValue(Long.parseLong(timestamp)); + } + + if ((ttl != null) && (timestamp == null)) { + logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there"); + queryObject.appendQueryString(" USING TTL ?"); + queryObject.addValue(Integer.parseInt(ttl)); + } + + if ((ttl == null) && (timestamp != null)) { + logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there"); + queryObject.appendQueryString(" USING TIMESTAMP ?"); + queryObject.addValue(Long.parseLong(timestamp)); + } + + queryObject.appendQueryString(";"); + + String consistency = this.getConsistencyInfo().get("type"); + if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL) && this.getConsistencyInfo().get("consistency") != null) { + if(MusicUtil.isValidConsistency(this.getConsistencyInfo().get("consistency"))) { + queryObject.setConsistency(this.getConsistencyInfo().get("consistency")); + } else { + throw new MusicQueryException("Invalid Consistency type", Status.BAD_REQUEST.getStatusCode()); + } + } + queryObject.setOperation("insert"); + + logger.info("Data insert Query ::::: " + queryObject.getQuery()); + + return queryObject; + } + + /** + * + * @param rowParams + * @return + * @throws MusicQueryException + */ + public PreparedQueryObject genSelectCriticalPreparedQueryObj(MultivaluedMap rowParams) throws MusicQueryException { + + PreparedQueryObject queryObject = new PreparedQueryObject(); + + if((this.getKeyspaceName() == null || this.getKeyspaceName().isEmpty()) + || (this.getTableName() == null || this.getTableName().isEmpty())){ + throw new MusicQueryException("one or more path parameters are not set, please check and try again", + Status.BAD_REQUEST.getStatusCode()); + } + EELFLoggerDelegate.mdcPut("keyspace", "( "+this.getKeyspaceName()+" ) "); + RowIdentifier rowId = null; + try { + rowId = getRowIdentifier(this.getKeyspaceName(), this.getTableName(), rowParams, queryObject); + this.setPrimaryKeyVal(rowId.primarKeyValue); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger,ex, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes + .GENERALSERVICEERROR, ex); + throw new MusicQueryException(ex.getMessage(), Status.BAD_REQUEST.getStatusCode()); + } + + queryObject.appendQueryString( + "SELECT * FROM " + this.getKeyspaceName() + "." + this.getTableName() + " WHERE " + rowId.rowIdString + ";"); + + return queryObject; + } + + private class RowIdentifier { + public String primarKeyValue; + public StringBuilder rowIdString; + @SuppressWarnings("unused") + public PreparedQueryObject queryObject; // the string with all the row + // identifiers separated by AND + + public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString, + PreparedQueryObject queryObject) { + this.primarKeyValue = primaryKeyValue; + this.rowIdString = rowIdString; + this.queryObject = queryObject; + } + } + + /** + * + * @param keyspace + * @param tablename + * @param rowParams + * @param queryObject + * @return + * @throws MusicServiceException + */ + private RowIdentifier getRowIdentifier(String keyspace, String tablename, + MultivaluedMap rowParams, PreparedQueryObject queryObject) + throws MusicServiceException { + StringBuilder rowSpec = new StringBuilder(); + int counter = 0; + TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, tablename); + if (tableInfo == null) { + logger.error(EELFLoggerDelegate.errorLogger, + "Table information not found. Please check input for table name= " + + keyspace + "." + tablename); + throw new MusicServiceException( + "Table information not found. Please check input for table name= " + + keyspace + "." + tablename); + } + StringBuilder primaryKey = new StringBuilder(); + for (MultivaluedMap.Entry> entry : rowParams.entrySet()) { + String keyName = entry.getKey(); + List valueList = entry.getValue(); + String indValue = valueList.get(0); + DataType colType = null; + Object formattedValue = null; + try { + colType = tableInfo.getColumn(entry.getKey()).getType(); + formattedValue = MusicUtil.convertToActualDataType(colType, indValue); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,e); + } + if(tableInfo.getPrimaryKey().get(0).getName().equals(entry.getKey())) { + primaryKey.append(indValue); + } + rowSpec.append(keyName + "= ?"); + queryObject.addValue(formattedValue); + if (counter != rowParams.size() - 1) { + rowSpec.append(" AND "); + } + counter = counter + 1; + } + return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject); + } + }