diff options
author | Thomas Nelson Jr (arthurdent3) tn1381@att.com <tn1381@att.com> | 2018-07-16 16:41:20 -0400 |
---|---|---|
committer | Thomas Nelson Jr (arthurdent3) tn1381@att.com <tn1381@att.com> | 2018-07-16 16:41:20 -0400 |
commit | 9b6efbd93a12c858a0d2643013217ec3d6c3a46d (patch) | |
tree | baf6c8de19daba3f4dc2b7761bda4cb858ba90e4 /src/main | |
parent | 5a28a331688c5578fef9c64d462d07cbae6797da (diff) |
various Updates
Q-api,
triggers,
conductor conditional updates.
Bug fixes
Change-Id: Iec392309787cd90f0a2827a2955399723640e800
Issue-ID: MUSIC-93
Signed-off-by: Thomas Nelson Jr (arthurdent3) tn1381@att.com <tn1381@att.com>
Diffstat (limited to 'src/main')
21 files changed, 1330 insertions, 422 deletions
diff --git a/src/main/java/org/onap/music/conductor/conditionals/JsonConditional.java b/src/main/java/org/onap/music/conductor/conditionals/JsonConditional.java index 0e971eb6..33a14bef 100644 --- a/src/main/java/org/onap/music/conductor/conditionals/JsonConditional.java +++ b/src/main/java/org/onap/music/conductor/conditionals/JsonConditional.java @@ -86,4 +86,4 @@ public class JsonConditional implements Serializable { -} +}
\ No newline at end of file diff --git a/src/main/java/org/onap/music/conductor/conditionals/MusicContional.java b/src/main/java/org/onap/music/conductor/conditionals/MusicConditional.java index 492f7c62..0fc9ffe3 100644 --- a/src/main/java/org/onap/music/conductor/conditionals/MusicContional.java +++ b/src/main/java/org/onap/music/conductor/conditionals/MusicConditional.java @@ -26,8 +26,6 @@ import java.io.StringWriter; import java.util.HashMap; import java.util.Map; -import javax.ws.rs.core.Response.Status; - import org.codehaus.jettison.json.JSONObject; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; @@ -39,7 +37,6 @@ import org.onap.music.main.MusicCore; import org.onap.music.main.MusicUtil; import org.onap.music.main.ResultType; import org.onap.music.main.ReturnType; -import org.onap.music.response.jsonobjects.JsonResponse; import org.onap.music.rest.RestMusicDataAPI; import com.datastax.driver.core.ColumnDefinitions; @@ -48,7 +45,7 @@ import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.TableMetadata; -public class MusicContional { +public class MusicConditional { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class); public static ReturnType conditionalInsert(String keyspace, String tablename, String casscadeColumnName, @@ -79,7 +76,8 @@ public class MusicContional { update.addValue(MusicUtil.convertToActualDataType(primaryIdType, primaryKey)); queryBank.put(MusicUtil.UPDATE, update); - Map<String, String> insertColumnvalues = new HashMap<>(); + + Map<String, String> insertColumnvalues = new HashMap<>();//casscade column values insertColumnvalues = getValues(false, casscadeColumnData, status); formatedValues = MusicUtil.convertToActualDataType(casscadeColumnType, insertColumnvalues); PreparedQueryObject insert = extractQuery(valuesMap, tableInfo, tablename, keyspace, primaryId, primaryKey,casscadeColumnName,formatedValues); @@ -95,7 +93,7 @@ public class MusicContional { if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { ReturnType criticalPutResult = conditionalInsertAtomic(lockId, keyspace, tablename, primaryKey, queryBank); - MusicCore.releaseLock(lockId, true); + MusicCore.destroyLockRef(lockId); if (criticalPutResult.getMessage().contains("insert")) criticalPutResult .setMessage("Insert values: "); @@ -105,11 +103,11 @@ public class MusicContional { return criticalPutResult; } else { - MusicCore.releaseLock(lockId, true); + MusicCore.destroyLockRef(lockId); return lockAcqResult; } } catch (Exception e) { - MusicCore.releaseLock(lockId, true); + MusicCore.destroyLockRef(lockId); return new ReturnType(ResultType.FAILURE, e.getMessage()); } @@ -163,17 +161,15 @@ public class MusicContional { try { if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { - ReturnType updateResult= updateAtomic(lockId, keyspace, tableName, primaryKey,primaryKeyValue, queryBank,planId,cascadeColumnValues,cascadeColumnName); - MusicCore.releaseLock(lockId, true); - return updateResult; + return updateAtomic(lockId, keyspace, tableName, primaryKey,primaryKeyValue, queryBank,planId,cascadeColumnValues,cascadeColumnName); } else { - MusicCore.releaseLock(lockId, true); + MusicCore.destroyLockRef(lockId); return lockAcqResult; } } catch (Exception e) { - MusicCore.releaseLock(lockId, true); + MusicCore.destroyLockRef(lockId); return new ReturnType(ResultType.FAILURE, e.getMessage()); } @@ -206,7 +202,6 @@ public class MusicContional { }else { return new ReturnType(ResultType.FAILURE,"Cannot find data related to key: "+primaryKey); } - MusicCore.getDSHandle().executePut(queryBank.get(MusicUtil.UPSERT), "critical"); return new ReturnType(ResultType.SUCCESS, "update success"); @@ -248,7 +243,6 @@ public class MusicContional { } - public static PreparedQueryObject extractQuery(Map<String, Object> valuesMap, TableMetadata tableInfo, String tableName, String keySpaceName,String primaryKeyName,String primaryKey,String casscadeColumn,Object casscadeColumnValues) throws Exception { @@ -356,4 +350,4 @@ public class MusicContional { } -} +}
\ No newline at end of file diff --git a/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditonalAPI.java b/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditionalAPI.java index c13dd621..eb466754 100644 --- a/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditonalAPI.java +++ b/src/main/java/org/onap/music/conductor/conditionals/RestMusicConditionalAPI.java @@ -49,6 +49,8 @@ import org.onap.music.main.ResultType; import org.onap.music.main.ReturnType; import org.onap.music.response.jsonobjects.JsonResponse; import org.onap.music.rest.RestMusicAdminAPI; +import org.onap.music.conductor.*; + import com.datastax.driver.core.DataType; import com.datastax.driver.core.TableMetadata; @@ -58,13 +60,11 @@ import io.swagger.annotations.ApiParam; @Path("/v2/conditional") @Api(value = "Conditional Api", hidden = true) -public class RestMusicConditonalAPI { +public class RestMusicConditionalAPI { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicAdminAPI.class); private static final String XMINORVERSION = "X-minorVersion"; private static final String XPATCHVERSION = "X-patchVersion"; private static final String NS = "ns"; - private static final String USERID = "userId"; - private static final String PASSWORD = "password"; private static final String VERSION = "v2"; @POST @@ -77,8 +77,7 @@ public class RestMusicConditonalAPI { @ApiParam(value = "Patch Version", required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam("Authorization") String authorization, @ApiParam(value = "Major Version", required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Major Version", required = true) @PathParam("tablename") String tablename, JsonConditional jsonObj) throws Exception { @@ -98,6 +97,9 @@ public class RestMusicConditonalAPI { .setError(String.valueOf("One or more input values missing")).toMap()).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = null; try { @@ -128,7 +130,7 @@ public class RestMusicConditonalAPI { status.put("nonexists", conditions.get("nonexists").get("status").toString()); ReturnType out = null; - out = MusicContional.conditionalInsert(keyspace, tablename, casscadeColumnName, casscadeColumnData, + out = MusicConditional.conditionalInsert(keyspace, tablename, casscadeColumnName, casscadeColumnData, primaryKeyValue, valuesMap, status); return response.status(Status.OK).entity(new JsonResponse(out.getResult()).setMessage(out.getMessage()).toMap()) .build(); @@ -146,8 +148,7 @@ public class RestMusicConditonalAPI { @ApiParam(value = "Patch Version", required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam("Authorization") String authorization, @ApiParam(value = "Major Version", required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Major Version", required = true) @PathParam("tablename") String tablename, JsonConditional upObj) throws Exception { @@ -167,6 +168,9 @@ public class RestMusicConditonalAPI { .setError(String.valueOf("One or more input values missing")).toMap()).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = null; try { @@ -194,17 +198,15 @@ public class RestMusicConditonalAPI { DataType primaryIdType = tableInfo.getPrimaryKey().get(0).getType(); String primaryId = tableInfo.getPrimaryKey().get(0).getName(); - PreparedQueryObject upsert = MusicContional.extractQuery(tableValues, tableInfo, tablename, keyspace, primaryKey, primaryKeyValue, null, null); - PreparedQueryObject select = new PreparedQueryObject(); select.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " where " + primaryId + " = ?"); select.addValue(MusicUtil.convertToActualDataType(primaryIdType, primaryKeyValue)); + PreparedQueryObject upsert = MusicConditional.extractQuery(tableValues, tableInfo, tablename, keyspace, primaryKey, primaryKeyValue, null, null); Map<String,PreparedQueryObject> queryBank = new HashMap<>(); - //queryBank.put(MusicUtil.UPDATE, update); - queryBank.put(MusicUtil.UPSERT, upsert); queryBank.put(MusicUtil.SELECT, select); - ReturnType result = MusicContional.update(queryBank, keyspace, tablename, primaryKey,primaryKeyValue,planId,casscadeColumnName,casscadeColumnValueMap); + queryBank.put(MusicUtil.UPSERT, upsert); + ReturnType result = MusicConditional.update(queryBank, keyspace, tablename, primaryKey,primaryKeyValue,planId,casscadeColumnName,casscadeColumnValueMap); if (result.getResult() == ResultType.SUCCESS) { return response.status(Status.OK) .entity(new JsonResponse(result.getResult()).setMessage(result.getMessage()).toMap()).build(); @@ -215,4 +217,4 @@ public class RestMusicConditonalAPI { } -} +}
\ No newline at end of file diff --git a/src/main/java/org/onap/music/datastore/MusicDataStore.java b/src/main/java/org/onap/music/datastore/MusicDataStore.java index e9356f9d..563e07f5 100644 --- a/src/main/java/org/onap/music/datastore/MusicDataStore.java +++ b/src/main/java/org/onap/music/datastore/MusicDataStore.java @@ -24,6 +24,7 @@ package org.onap.music.datastore; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -51,6 +52,7 @@ import com.datastax.driver.core.TableMetadata; import com.datastax.driver.core.exceptions.AlreadyExistsException; import com.datastax.driver.core.exceptions.InvalidQueryException; import com.datastax.driver.core.exceptions.NoHostAvailableException; +import com.sun.jersey.core.util.Base64; /** * @author nelson24 @@ -259,6 +261,12 @@ public class MusicDataStore { return null; } } + + public byte[] getBlobValue(Row row, String colName, DataType colType) { + ByteBuffer bb = row.getBytes(colName); + byte[] data = bb.array(); + return data; + } public boolean doesRowSatisfyCondition(Row row, Map<String, Object> condition) throws Exception { ColumnDefinitions colInfo = row.getColumnDefinitions(); @@ -288,9 +296,15 @@ public class MusicDataStore { ColumnDefinitions colInfo = row.getColumnDefinitions(); HashMap<String, Object> resultOutput = new HashMap<String, Object>(); for (Definition definition : colInfo) { - if (!definition.getName().equals("vector_ts")) - resultOutput.put(definition.getName(), + if (!definition.getName().equals("vector_ts")) { + if(definition.getType().toString().toLowerCase().contains("blob")) { + resultOutput.put(definition.getName(), + getBlobValue(row, definition.getName(), definition.getType())); + } + else + resultOutput.put(definition.getName(), getColValue(row, definition.getName(), definition.getType())); + } } resultMap.put("row " + counter, resultOutput); counter++; @@ -326,10 +340,15 @@ public class MusicDataStore { + queryObject.getValues()); PreparedStatement preparedInsert = null; try { - preparedInsert = session.prepare(queryObject.getQuery()); + + preparedInsert = session.prepare(queryObject.getQuery()); + } catch(InvalidQueryException iqe) { - logger.error(EELFLoggerDelegate.errorLogger, iqe.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger, iqe.getMessage(),AppMessages.QUERYERROR, ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); throw new MusicQueryException(iqe.getMessage()); + }catch(Exception e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.QUERYERROR, ErrorSeverity.CRITICAL, ErrorTypes.QUERYERROR); + throw new MusicQueryException(e.getMessage()); } try { diff --git a/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java b/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java new file mode 100644 index 00000000..8de0a2cd --- /dev/null +++ b/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java @@ -0,0 +1,37 @@ +package org.onap.music.datastore.jsonobjects; +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================= + * ==================================================================== + */ + + +public class JSONObject { + + private String data; + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + +} 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 a58552c6..9630abe0 100644 --- a/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java +++ b/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java @@ -43,7 +43,18 @@ public class JsonInsert implements Serializable { private String timestamp; private Map<String, Object> row_specification; private Map<String, String> consistencyInfo; - + private byte[] data; + private Map<String, byte[]> objectMap; + + @ApiModelProperty(value = "objectMap") + public Map<String, byte[]> getObjectMap() { + return objectMap; + } + + public void setObjectMap(Map<String, byte[]> objectMap) { + this.objectMap = objectMap; + } + @ApiModelProperty(value = "keyspace") public String getKeyspaceName() { return keyspaceName; diff --git a/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java b/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java index 5d508adb..2e0a5ded 100644 --- a/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java +++ b/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java @@ -38,6 +38,9 @@ public class JsonTable { private Map<String, Object> properties; private String primaryKey; private String sortingKey; + private String partitionKey; + private String clusteringKey; + private String filteringKey; private String clusteringOrder; private Map<String, String> consistencyInfo; @@ -113,5 +116,29 @@ public class JsonTable { this.primaryKey = primaryKey; } + public String getClusteringKey() { + return clusteringKey; + } + + public void setClusteringKey(String clusteringKey) { + this.clusteringKey = clusteringKey; + } + + public String getFilteringKey() { + return filteringKey; + } + + public void setFilteringKey(String filteringKey) { + this.filteringKey = filteringKey; + } + + public String getPartitionKey() { + return partitionKey; + } + + public void setPartitionKey(String partitionKey) { + this.partitionKey = partitionKey; + } + } diff --git a/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java b/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java new file mode 100644 index 00000000..9c3e842e --- /dev/null +++ b/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java @@ -0,0 +1,149 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================= + * ==================================================================== + */ +package org.onap.music.eelf.healthcheck; + +import java.util.UUID; + +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.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.lockingservice.MusicLockingService; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; + +import com.datastax.driver.core.ConsistencyLevel; + +/** + * @author inam + * + */ +public class MusicHealthCheck { + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class); + + private String cassandrHost; + private String zookeeperHost; + + public String getCassandraStatus(String consistency) { + logger.info(EELFLoggerDelegate.applicationLogger, "Getting Status for Cassandra"); + + boolean result = false; + try { + result = getAdminKeySpace(consistency); + } catch(Exception e) { + if(e.getMessage().toLowerCase().contains("unconfigured table healthcheck")) { + System.out.println("Creating table...."); + boolean ksresult = createKeyspace(); + if(ksresult) + try { + result = getAdminKeySpace(consistency); + } catch (MusicServiceException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } else { + return "One or more nodes are down or not responding."; + } + } + if (result) { + return "ACTIVE"; + } else { + logger.info(EELFLoggerDelegate.applicationLogger, "Cassandra Service is not responding"); + return "INACTIVE"; + } + } + + private Boolean getAdminKeySpace(String consistency) throws MusicServiceException { + + + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("insert into admin.healthcheck (id) values (?)"); + pQuery.addValue(UUID.randomUUID()); + ResultType rs = MusicCore.nonKeyRelatedPut(pQuery, consistency); + System.out.println(rs); + if (rs != null) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + + + } + + private boolean createKeyspace() { + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("CREATE TABLE admin.healthcheck (id uuid PRIMARY KEY)"); + ResultType rs = null ; + try { + rs = MusicCore.nonKeyRelatedPut(pQuery, ConsistencyLevel.ONE.toString()); + } catch (MusicServiceException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(rs.getResult().toLowerCase().contains("success")) + return true; + else + return false; + } + + public String getZookeeperStatus() { + + String host = MusicUtil.getMyZkHost(); + logger.info(EELFLoggerDelegate.applicationLogger, "Getting Status for Zookeeper Host: " + host); + try { + MusicLockingService lockingService = MusicCore.getLockingServiceHandle(); + // additionally need to call the ZK to create,aquire and delete lock + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.LOCKINGERROR, + ErrorTypes.CONNECTIONERROR, ErrorSeverity.CRITICAL); + return "INACTIVE"; + } + + logger.info(EELFLoggerDelegate.applicationLogger, "Zookeeper is Active and Running"); + return "ACTIVE"; + + // return "Zookeeper is not responding"; + + } + + public String getCassandrHost() { + return cassandrHost; + } + + public void setCassandrHost(String cassandrHost) { + this.cassandrHost = cassandrHost; + } + + public String getZookeeperHost() { + return zookeeperHost; + } + + public void setZookeeperHost(String zookeeperHost) { + this.zookeeperHost = zookeeperHost; + } + +} diff --git a/src/main/java/org/onap/music/lockingservice/MusicLockState.java b/src/main/java/org/onap/music/lockingservice/MusicLockState.java index 448a36e5..6c31410f 100644 --- a/src/main/java/org/onap/music/lockingservice/MusicLockState.java +++ b/src/main/java/org/onap/music/lockingservice/MusicLockState.java @@ -134,11 +134,4 @@ public class MusicLockState implements Serializable { } return (MusicLockState) o; } - - @Override - public String toString() { - // TODO Auto-generated method stub - return "lockStatus:"+ (lockStatus == null ? null : lockStatus.toString())+" |needToSyncQuorum:"+needToSyncQuorum+" |lockHolder:"+lockHolder - +" |leasePeriod:"+leasePeriod+" |leaseStartTime:"+leaseStartTime; - } } diff --git a/src/main/java/org/onap/music/lockingservice/MusicLockingService.java b/src/main/java/org/onap/music/lockingservice/MusicLockingService.java index d0c33000..ae026903 100644 --- a/src/main/java/org/onap/music/lockingservice/MusicLockingService.java +++ b/src/main/java/org/onap/music/lockingservice/MusicLockingService.java @@ -19,8 +19,6 @@ package org.onap.music.lockingservice; import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.StringTokenizer; import java.util.concurrent.CountDownLatch; @@ -99,12 +97,7 @@ public class MusicLockingService implements Watcher { try{ data = zkLockHandle.getNodeData(lockName); }catch (Exception ex){ - StringWriter sw = new StringWriter(); - ex.printStackTrace(); - ex.printStackTrace(new PrintWriter(sw)); - String exceptionAsString = sw.toString(); - logger.error(EELFLoggerDelegate.errorLogger,exceptionAsString); - throw new MusicLockingException(exceptionAsString); + logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR); } if(data !=null) return MusicLockState.deSerialize(data); diff --git a/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java b/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java index e99df255..38c873af 100644 --- a/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java +++ b/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java @@ -28,10 +28,15 @@ import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Stat; +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.main.MusicCore; +import org.onap.music.main.MusicUtil; + +import com.datastax.driver.core.DataType; /** * A <a href="package.html">protocol to implement an exclusive write lock or to elect a leader</a>. @@ -288,8 +293,28 @@ public class ZkStatelessLockService extends ProtocolSupport { if (logger.isDebugEnabled()) { logger.debug(EELFLoggerDelegate.debugLogger, "Created id: " + id); } - if (id != null) + if (id != null) { + Stat stat = null; + try { + stat = zookeeper.exists(id, false); + } catch (KeeperException | InterruptedException e1) { + e1.printStackTrace(); + } + Long ctime = stat.getCtime(); + System.out.println("Created id ....####"+ctime+"##.......id...:"+id); + MusicUtil.zkNodeMap.put(id, ctime); + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "INSERT INTO admin.locks(lock_id, ctime) VALUES (?,?)"); + try { + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), id)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), ctime)); + MusicCore.eventualPut(pQuery); + } catch (Exception e) { + e.printStackTrace(); + } break; + } } if (id != null) { List<String> names = zookeeper.getChildren(dir, false); diff --git a/src/main/java/org/onap/music/main/CachingUtil.java b/src/main/java/org/onap/music/main/CachingUtil.java index b34721bb..d3654118 100755 --- a/src/main/java/org/onap/music/main/CachingUtil.java +++ b/src/main/java/org/onap/music/main/CachingUtil.java @@ -33,6 +33,7 @@ import org.apache.commons.codec.binary.Base64; import org.apache.commons.jcs.JCS; import org.apache.commons.jcs.access.CacheAccess; import org.codehaus.jackson.map.ObjectMapper; +import org.mindrot.jbcrypt.BCrypt; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.datastore.jsonobjects.AAFResponse; import org.onap.music.eelf.logging.EELFLoggerDelegate; @@ -101,8 +102,8 @@ public class CachingUtil implements Runnable { String keySpace = row.getString("application_name"); try { userAttempts.put(nameSpace, 0); - boolean aafRresponse = triggerAAF(nameSpace, userId, password); - if (aafRresponse) { + AAFResponse responseObj = triggerAAF(nameSpace, userId, password); + if (responseObj.getNs().size() > 0) { map = new HashMap<>(); map.put(userId, password); aafCache.put(nameSpace, map); @@ -133,9 +134,9 @@ public class CachingUtil implements Runnable { String keySpace) throws Exception { if (aafCache.get(nameSpace) != null) { - /* if (keySpace != null && !musicCache.get(keySpace).equals(nameSpace)) { + if (keySpace != null && !musicCache.get(keySpace).equals(nameSpace)) { logger.info(EELFLoggerDelegate.applicationLogger,"Create new application for the same namespace."); - } else */if (aafCache.get(nameSpace).get(userId).equals(password)) { + } else if (aafCache.get(nameSpace).get(userId).equals(password)) { logger.info(EELFLoggerDelegate.applicationLogger,"Authenticated with cache value.."); // reset invalid attempts to 0 userAttempts.put(nameSpace, 0); @@ -163,21 +164,20 @@ public class CachingUtil implements Runnable { } } - boolean aafRresponse = triggerAAF(nameSpace, userId, password); - if (aafRresponse) { - //TODO + AAFResponse responseObj = triggerAAF(nameSpace, userId, password); + if (responseObj.getNs().size() > 0) { //if (responseObj.getNs().get(0).getAdmin().contains(userId)) { - Map<String, String> map = new HashMap<>(); - map.put(userId, password); - aafCache.put(nameSpace, map); + //Map<String, String> map = new HashMap<>(); + //map.put(userId, password); + //aafCache.put(nameSpace, map); return true; //} } logger.info(EELFLoggerDelegate.applicationLogger,"Invalid user. Cache not updated"); - return aafRresponse; + return false; } - private static boolean triggerAAF(String nameSpace, String userId, String password) + private static AAFResponse triggerAAF(String nameSpace, String userId, String password) throws Exception { if (MusicUtil.getAafEndpointUrl() == null) { logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); @@ -195,9 +195,7 @@ public class CachingUtil implements Runnable { ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON) .header("Authorization", "Basic " + base64Creds) .header("content-type", "application/json").get(ClientResponse.class); - if(response.getStatus() == 200) - return true; - else if (response.getStatus() != 200) { + if (response.getStatus() != 200) { if (userAttempts.get(nameSpace) == null) userAttempts.put(nameSpace, 0); if ((Integer) userAttempts.get(nameSpace) >= 2) { @@ -212,14 +210,14 @@ public class CachingUtil implements Runnable { // TODO Allow for 2-3 times and forbid any attempt to trigger AAF with invalid values // for specific time. } - /*response.getHeaders().put(HttpHeaders.CONTENT_TYPE, + response.getHeaders().put(HttpHeaders.CONTENT_TYPE, Arrays.asList(MediaType.APPLICATION_JSON)); // AAFResponse output = response.getEntity(AAFResponse.class); response.bufferEntity(); String x = response.getEntity(String.class); - AAFResponse responseObj = new ObjectMapper().readValue(x, AAFResponse.class);*/ + AAFResponse responseObj = new ObjectMapper().readValue(x, AAFResponse.class); - return false; + return responseObj; } public static void updateMusicCache(String keyspace, String nameSpace) { @@ -352,7 +350,7 @@ public class CachingUtil implements Runnable { logger.error(EELFLoggerDelegate.errorLogger,"Application is not onboarded. Please contact admin."); resultMap.put("Exception", "Application is not onboarded. Please contact admin."); } else { - if(!(rs.getString("username").equals(userId)) || !(rs.getString("password").equals(password))) { + if(!(rs.getString("username").equals(userId)) || !(BCrypt.checkpw(password, rs.getString("password")))) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); logger.error(EELFLoggerDelegate.errorLogger,"Namespace, UserId and password doesn't match. namespace: "+ns+" and userId: "+userId); resultMap.put("Exception", "Namespace, UserId and password doesn't match. namespace: "+ns+" and userId: "+userId); @@ -365,13 +363,14 @@ public class CachingUtil implements Runnable { public static Map<String, Object> authenticateAIDUser(String nameSpace, String userId, String password, String keyspace) { Map<String, Object> resultMap = new HashMap<>(); + String pwd = null; if((musicCache.get(keyspace) != null) && (musicValidateCache.get(nameSpace) != null) && (musicValidateCache.get(nameSpace).containsKey(userId))) { if(!musicCache.get(keyspace).equals(nameSpace)) { resultMap.put("Exception", "Namespace and keyspace doesn't match"); return resultMap; } - if(!musicValidateCache.get(nameSpace).get(userId).equals(password)) { + if(!BCrypt.checkpw(password,musicValidateCache.get(nameSpace).get(userId))) { resultMap.put("Exception", "Namespace, userId and password doesn't match"); return resultMap; } @@ -399,7 +398,7 @@ public class CachingUtil implements Runnable { } else { String user = rs.getString("username"); - String pwd = rs.getString("password"); + pwd = rs.getString("password"); String ns = rs.getString("application_name"); if(!ns.equals(nameSpace)) { resultMap.put("Exception", "Namespace and keyspace doesn't match"); @@ -409,13 +408,13 @@ public class CachingUtil implements Runnable { resultMap.put("Exception", "Invalid userId :"+userId); return resultMap; } - if(!pwd.equals(password)) { + if(!BCrypt.checkpw(password, pwd)) { resultMap.put("Exception", "Invalid password"); return resultMap; } } CachingUtil.updateMusicCache(keyspace, nameSpace); - CachingUtil.updateMusicValidateCache(nameSpace, userId, password); + CachingUtil.updateMusicValidateCache(nameSpace, userId, pwd); return resultMap; } } diff --git a/src/main/java/org/onap/music/main/CronJobManager.java b/src/main/java/org/onap/music/main/CronJobManager.java index fb4a2ac3..5b7a8de4 100644 --- a/src/main/java/org/onap/music/main/CronJobManager.java +++ b/src/main/java/org/onap/music/main/CronJobManager.java @@ -21,6 +21,9 @@ */ package org.onap.music.main; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -28,6 +31,13 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; +import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.exceptions.MusicLockingException; +import org.onap.music.exceptions.MusicServiceException; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; + @WebListener public class CronJobManager implements ServletContextListener { @@ -37,11 +47,92 @@ public class CronJobManager implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { scheduler = Executors.newSingleThreadScheduledExecutor(); scheduler.scheduleAtFixedRate(new CachingUtil(), 0, 24, TimeUnit.HOURS); + PreparedQueryObject pQuery = new PreparedQueryObject(); + String consistency = MusicUtil.EVENTUAL; + pQuery.appendQueryString("CREATE TABLE IF NOT EXISTS admin.locks ( lock_id text PRIMARY KEY, ctime text)"); + try { + ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency); + } catch (MusicServiceException e1) { + e1.printStackTrace(); + } + + pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "select * from admin.locks"); + try { + ResultSet rs = MusicCore.get(pQuery); + Iterator<Row> it = rs.iterator(); + StringBuilder deleteKeys = new StringBuilder(); + Boolean expiredKeys = false; + while (it.hasNext()) { + Row row = (Row) it.next(); + String id = row.getString("lock_id"); + long ctime = Long.parseLong(row.getString("ctime")); + if(System.currentTimeMillis() >= ctime + 24 * 60 * 60 * 1000) { + expiredKeys = true; + String new_id = id.substring(1); + MusicCore.deleteLock(new_id); + deleteKeys.append(id).append(","); + } + else { + MusicUtil.zkNodeMap.put(id, ctime); + } + }; + if(expiredKeys) { + deleteKeys.deleteCharAt(deleteKeys.length()-1); + deleteKeysFromDB(deleteKeys); + } + } catch (MusicServiceException e) { + e.printStackTrace(); + } catch (MusicLockingException e) { + e.printStackTrace(); + } + + //Zookeeper cleanup + scheduler.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + Iterator<Entry<String, Long>> it = MusicUtil.zkNodeMap.entrySet().iterator(); + StringBuilder deleteKeys = new StringBuilder(); + Boolean expiredKeys = false; + while (it.hasNext()) { + Map.Entry<String, Long> pair = (Map.Entry<String, Long>)it.next(); + long ctime = pair.getValue(); + if (System.currentTimeMillis() >= ctime + 24 * 60 * 60 * 1000) { + try { + expiredKeys = true; + String id = pair.getKey(); + deleteKeys.append("'").append(id).append("'").append(","); + MusicCore.deleteLock(id.substring(1)); + MusicUtil.zkNodeMap.remove(id); + + } catch (MusicLockingException e) { + e.printStackTrace(); + } + } + } + if(expiredKeys) { + deleteKeys.deleteCharAt(deleteKeys.length()-1); + deleteKeysFromDB(deleteKeys); + } + } + } , 0, 24, TimeUnit.HOURS); } @Override public void contextDestroyed(ServletContextEvent event) { scheduler.shutdownNow(); } + + public void deleteKeysFromDB(StringBuilder deleteKeys) { + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString( + "DELETE FROM admin.locks WHERE lock_id IN ("+deleteKeys+")"); + try { + MusicCore.nonKeyRelatedPut(pQuery, "eventual"); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/org/onap/music/main/MusicCore.java b/src/main/java/org/onap/music/main/MusicCore.java index 661d7adc..dfc93ccc 100644 --- a/src/main/java/org/onap/music/main/MusicCore.java +++ b/src/main/java/org/onap/music/main/MusicCore.java @@ -22,7 +22,6 @@ package org.onap.music.main; -import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; @@ -294,10 +293,6 @@ public class MusicCore { logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!"); return new ReturnType(ResultType.SUCCESS, "You already have the lock!"); } - if (currentMls.getLockStatus() != MusicLockState.LockStatus.UNLOCKED || currentMls.getLockHolder() != null) { - logger.info("In acquire lock: the previous lock has not been released yet! current mls:"+currentMls.toString()); - return new ReturnType(ResultType.FAILURE, "The previous lock has not been released yet."); - } } catch (NullPointerException e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } @@ -515,14 +510,6 @@ public class MusicCore { public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{ try { getLockingServiceHandle().unlockAndDeleteId(lockId); - String lockName = getLockNameFromId(lockId); - String lockHolder = null; - MusicLockState mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder); - try { - getLockingServiceHandle().setLockState(lockName, mls); - } catch (MusicLockingException e) { - logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); - } } catch (KeeperException.NoNodeException e) { // ??? No way } @@ -653,7 +640,6 @@ public class MusicCore { try { MusicLockState mls = getLockingServiceHandle() .getLockState(keyspaceName + "." + tableName + "." + primaryKey); - logger.info("Got MusicLockState object... :"+mls.toString()); if (mls.getLockHolder().equals(lockId) == true) { if (conditionInfo != null) try { @@ -678,7 +664,6 @@ public class MusicCore { "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n" + e.getMessage()); }catch(MusicLockingException ex){ - logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage()); return new ReturnType(ResultType.FAILURE,ex.getMessage()); } @@ -775,7 +760,7 @@ public class MusicCore { ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, queryObject, lockId, conditionInfo); long criticalPutTime = System.currentTimeMillis(); - releaseLock(lockId, true); + voluntaryReleaseLock(lockId); long lockDeleteTime = System.currentTimeMillis(); String timingInfo = "|lock creation time:" + (lockCreationTime - start) + "|lock accquire time:" + (lockAcqTime - lockCreationTime) @@ -785,7 +770,7 @@ public class MusicCore { return criticalPutResult; } else { logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); - releaseLock(lockId, true);; + destroyLockRef(lockId); return lockAcqResult; } } @@ -855,10 +840,10 @@ public class MusicCore { logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId); - releaseLock(lockId, true); + voluntaryReleaseLock(lockId); return result; } else { - releaseLock(lockId, true); + destroyLockRef(lockId); logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); return null; } diff --git a/src/main/java/org/onap/music/main/MusicUtil.java b/src/main/java/org/onap/music/main/MusicUtil.java index 20bb0a48..a161fd56 100755 --- a/src/main/java/org/onap/music/main/MusicUtil.java +++ b/src/main/java/org/onap/music/main/MusicUtil.java @@ -24,16 +24,25 @@ package org.onap.music.main; import java.io.File; import java.io.FileNotFoundException; import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; +import java.util.StringTokenizer; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; + import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.eelf.logging.EELFLoggerDelegate; + import com.datastax.driver.core.DataType; +import com.sun.jersey.core.util.Base64; /** * @author nelson24 @@ -58,6 +67,9 @@ public class MusicUtil { public static final String INSERT = "insert"; public static final String UPDATE = "update"; public static final String UPSERT = "upsert"; + public static final String USERID = "userId"; + public static final String PASSWORD = "password"; + public static final String AUTHORIZATION = "Authorization"; private static final String LOCALHOST = "localhost"; private static final String PROPERTIES_FILE = "/opt/app/music/etc/music.properties"; @@ -81,6 +93,7 @@ public class MusicUtil { private static String cassName = "cassandra"; private static String cassPwd; private static String aafEndpointUrl = null; + public static ConcurrentMap<String, Long> zkNodeMap = new ConcurrentHashMap<>(); private MusicUtil() { throw new IllegalStateException("Utility Class"); @@ -402,7 +415,8 @@ public class MusicUtil { MusicUtil.cassPwd = cassPwd; } - public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception { + @SuppressWarnings("unchecked") + public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception { String value = ""; switch (type.getName()) { @@ -416,8 +430,7 @@ public class MusicUtil { value = "'" + valueString + "'"; break; case MAP: { - @SuppressWarnings("unchecked") - Map<String, Object> otMap = (Map<String, Object>) valueObj; + Map<String, Object> otMap = (Map<String, Object>) valueObj; value = "{" + jsonMaptoSqlString(otMap, ",") + "}"; break; } @@ -440,29 +453,34 @@ public class MusicUtil { public static Object convertToActualDataType(DataType colType, Object valueObj) throws Exception { String valueObjString = valueObj + ""; switch (colType.getName()) { - case UUID: - return UUID.fromString(valueObjString); - case VARINT: - return BigInteger.valueOf(Long.parseLong(valueObjString)); - case BIGINT: - return Long.parseLong(valueObjString); - case INT: - return Integer.parseInt(valueObjString); - case FLOAT: - return Float.parseFloat(valueObjString); - case DOUBLE: - return Double.parseDouble(valueObjString); - case BOOLEAN: - return Boolean.parseBoolean(valueObjString); - case MAP: - return (Map<String, Object>) valueObj; - case LIST: - return (List<String>)valueObj; - default: - return valueObjString; + case UUID: + return UUID.fromString(valueObjString); + case VARINT: + return BigInteger.valueOf(Long.parseLong(valueObjString)); + case BIGINT: + return Long.parseLong(valueObjString); + case INT: + return Integer.parseInt(valueObjString); + case FLOAT: + return Float.parseFloat(valueObjString); + case DOUBLE: + return Double.parseDouble(valueObjString); + case BOOLEAN: + return Boolean.parseBoolean(valueObjString); + case MAP: + return (Map<String, Object>) valueObj; + case BLOB: + + default: + return valueObjString; } } + public static ByteBuffer convertToActualDataType(DataType colType, byte[] valueObj) { + ByteBuffer buffer = ByteBuffer.wrap(valueObj); + return buffer; + } + /** * * Utility function to parse json map into sql like string @@ -489,6 +507,7 @@ public class MusicUtil { return sqlString.toString(); } + @SuppressWarnings("unused") public static String buildVersion(String major, String minor, String patch) { if (minor != null) { major += "." + minor; @@ -530,8 +549,18 @@ public class MusicUtil { logger.info(EELFLoggerDelegate.applicationLogger,"Version In:" + versionIn); return response; } - - + public static Map<String,String> extractBasicAuthentication(String authorization){ + + Map<String,String> authValues = new HashMap<>(); + authorization = authorization.replaceFirst("Basic", ""); + String decoded = Base64.base64Decode(authorization); + StringTokenizer token = new StringTokenizer(decoded, ":"); + authValues.put(MusicUtil.USERID, token.nextToken().toString()); + authValues.put(MusicUtil.PASSWORD,token.nextToken()); + return authValues; + + } + } diff --git a/src/main/java/org/onap/music/main/PropertiesListener.java b/src/main/java/org/onap/music/main/PropertiesListener.java index afd35387..8b00e473 100755 --- a/src/main/java/org/onap/music/main/PropertiesListener.java +++ b/src/main/java/org/onap/music/main/PropertiesListener.java @@ -30,26 +30,22 @@ import java.util.Arrays; import java.util.Properties; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; 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; -@WebListener public class PropertiesListener implements ServletContextListener { private Properties prop; - private static EELFLoggerDelegate logger = - EELFLoggerDelegate.getLogger(PropertiesListener.class); + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PropertiesListener.class); @Override public void contextInitialized(ServletContextEvent servletContextEvent) { prop = new Properties(); Properties projectProp = new Properties(); URL resource = getClass().getResource("/"); - String musicPropertiesFilePath = resource.getPath().replace("WEB-INF/classes/", - "WEB-INF/classes/project.properties"); + String musicPropertiesFilePath = resource.getPath().replace("WEB-INF/classes/","WEB-INF/classes/project.properties"); // Open the file try { diff --git a/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java b/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java index c66944cb..d1e82337 100755 --- a/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java @@ -37,7 +37,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; + +import org.mindrot.jbcrypt.BCrypt; import org.onap.music.datastore.PreparedQueryObject; +import org.onap.music.datastore.jsonobjects.JSONObject; import org.onap.music.datastore.jsonobjects.JsonOnboard; import org.onap.music.eelf.logging.EELFLoggerDelegate; import org.onap.music.eelf.logging.format.AppMessages; @@ -107,7 +110,7 @@ public class RestMusicAdminAPI { MusicUtil.DEFAULTKEYSPACENAME)); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName)); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); @@ -142,7 +145,7 @@ public class RestMusicAdminAPI { ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); resultMap.put("Exception", "Unauthorized: Please check the request parameters. Enter atleast one of the following parameters: appName(ns), aid, isAAF."); - return Response.status(Status.UNAUTHORIZED).entity(resultMap).build(); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); } PreparedQueryObject pQuery = new PreparedQueryObject(); @@ -348,7 +351,7 @@ public class RestMusicAdminAPI { if (userId != null) pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); if (password != null) - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password)); + pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt()))); if (isAAF != null) pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); @@ -367,4 +370,14 @@ public class RestMusicAdminAPI { return Response.status(Status.OK).entity(resultMap).build(); } + + @POST + @Path("/callbackOps") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String callbackOps(JSONObject inputJsonObj) throws Exception { + + System.out.println("Input JSON: "+inputJsonObj.getData()); + return "Success"; + } } diff --git a/src/main/java/org/onap/music/rest/RestMusicDataAPI.java b/src/main/java/org/onap/music/rest/RestMusicDataAPI.java index 39d5a890..30656350 100755 --- a/src/main/java/org/onap/music/rest/RestMusicDataAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicDataAPI.java @@ -21,10 +21,13 @@ */ package org.onap.music.rest; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; + +import javax.servlet.http.HttpServletResponse; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -42,6 +45,9 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; + +import org.apache.commons.lang3.StringUtils; +import org.mindrot.jbcrypt.BCrypt; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.datastore.jsonobjects.JsonDelete; import org.onap.music.datastore.jsonobjects.JsonInsert; @@ -66,6 +72,7 @@ import com.datastax.driver.core.DataType; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.datastax.driver.core.TableMetadata; + import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -102,8 +109,6 @@ public class RestMusicDataAPI { private static final String XMINORVERSION = "X-minorVersion"; private static final String XPATCHVERSION = "X-patchVersion"; private static final String NS = "ns"; - private static final String USERID = "userId"; - private static final String PASSWORD = "password"; private static final String VERSION = "v2"; private class RowIdentifier { @@ -141,13 +146,15 @@ public class RestMusicDataAPI { @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, JsonKeySpace kspObject, @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password); if (!authMap.isEmpty()) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR); @@ -160,6 +167,7 @@ public class RestMusicDataAPI { return response.entity(authMap).build(); } + try { authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, "createKeySpace"); @@ -229,6 +237,7 @@ public class RestMusicDataAPI { try { boolean isAAF = Boolean.valueOf(CachingUtil.isAAFApplication(ns)); + String hashedpwd = BCrypt.hashpw(password, BCrypt.gensalt()); queryObject = new PreparedQueryObject(); queryObject.appendQueryString( "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " @@ -237,11 +246,11 @@ public class RestMusicDataAPI { queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspaceName)); queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns)); queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); - queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), password)); + queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), hashedpwd)); queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); CachingUtil.updateMusicCache(keyspaceName, ns); - CachingUtil.updateMusicValidateCache(ns, userId, password); + CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd); MusicCore.eventualPut(queryObject); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); @@ -268,12 +277,14 @@ public class RestMusicDataAPI { @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, @ApiParam(value = "Keyspace Name",required = true) @PathParam("name") String keyspaceName) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace"); if (authMap.containsKey("aid")) authMap.remove("aid"); @@ -343,12 +354,14 @@ public class RestMusicDataAPI { @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, JsonTable tableObj, @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "createTable"); if (authMap.containsKey("aid")) @@ -359,30 +372,116 @@ public class RestMusicDataAPI { } String consistency = MusicUtil.EVENTUAL; // for now this needs only eventual consistency + + String primaryKey = null; + String partitionKey = tableObj.getPartitionKey(); + String clusterKey = tableObj.getClusteringKey(); + String filteringKey = tableObj.getFilteringKey(); + if(filteringKey != null) { + clusterKey = clusterKey + "," + filteringKey; + } + primaryKey = tableObj.getPrimaryKey(); // get primaryKey if available + PreparedQueryObject queryObject = new PreparedQueryObject(); // first read the information about the table fields Map<String, String> fields = tableObj.getFields(); StringBuilder fieldsString = new StringBuilder("(vector_ts text,"); int counter = 0; - String primaryKey; for (Map.Entry<String, String> entry : fields.entrySet()) { - if (entry.getKey().equals("PRIMARY KEY")) { - if(! entry.getValue().contains("(")) - primaryKey = entry.getValue(); - else { - primaryKey = entry.getValue().substring(entry.getValue().indexOf('(') + 1); - primaryKey = primaryKey.substring(0, primaryKey.indexOf(')')); + primaryKey = entry.getValue(); // replaces primaryKey + primaryKey.trim(); + } else { + if (counter == 0 ) fieldsString.append("" + entry.getKey() + " " + entry.getValue() + ""); + else fieldsString.append("," + entry.getKey() + " " + entry.getValue() + ""); + } + + if (counter != (fields.size() - 1) ) { + + //logger.info("cjc2 field="+entry.getValue()+"counter=" + counter+"fieldsize-1="+(fields.size() -1) + ","); + counter = counter + 1; + } else { + //logger.info("cjc3 field="+entry.getValue()+"counter=" + counter+"fieldsize="+fields.size() + ","); + if((primaryKey != null) && (partitionKey == null)) { + primaryKey.trim(); + int count1 = StringUtils.countMatches(primaryKey, ')'); + int count2 = StringUtils.countMatches(primaryKey, '('); + if (count1 != count2) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Create Table Error: primary key '(' and ')' do not match, primary key=" + primaryKey) + .toMap()).build(); + } + + if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(")") +1) == primaryKey.length() ) ) + { + if (primaryKey.contains(",") ) { + partitionKey= primaryKey.substring(0,primaryKey.indexOf(",")); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusterKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index + clusterKey=clusterKey.replaceAll("[)]+", ""); + } else { + partitionKey=primaryKey; + partitionKey=partitionKey.replaceAll("[\\)]+",""); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusterKey=""; + } + } else { // not null and has ) before the last char + partitionKey= primaryKey.substring(0,primaryKey.indexOf(')')); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + partitionKey.trim(); + clusterKey= primaryKey.substring(primaryKey.indexOf(')')); + clusterKey=clusterKey.replaceAll("[\\(]+",""); + clusterKey=clusterKey.replaceAll("[\\)]+",""); + clusterKey.trim(); + if (clusterKey.indexOf(",") == 0) clusterKey=clusterKey.substring(1); + clusterKey.trim(); + if (clusterKey.equals(",") ) clusterKey=""; // print error if needed ( ... ),) + + } + + if (!(partitionKey.isEmpty() || clusterKey.isEmpty()) + && (partitionKey.equalsIgnoreCase(clusterKey) || + clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) + { + logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey + " and primary key=" + primaryKey ); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError( + "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ") of" + + " primary key=" + primaryKey) + .toMap()).build(); + + } + + if (partitionKey.isEmpty() ) primaryKey=""; + else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")"; + else primaryKey=" (" + partitionKey + ")," + clusterKey; + + //if (primaryKey != null) fieldsString.append("" + entry.getKey() + " (" + primaryKey + " )"); + if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )"); + + } // end of length > 0 + else { + if (!(partitionKey.isEmpty() || clusterKey.isEmpty()) + && (partitionKey.equalsIgnoreCase(clusterKey) || + clusterKey.contains(partitionKey) || partitionKey.contains(clusterKey)) ) + { + logger.error("DataAPI createTable partition/cluster key ERROR: partitionKey="+partitionKey+", clusterKey=" + clusterKey); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError( + "Create Table primary key error: clusterKey(" + clusterKey + ") equals/contains/overlaps partitionKey(" +partitionKey+ ")") + .toMap()).build(); } - fieldsString.append("" + entry.getKey() + " (" + primaryKey + ")"); - } else - fieldsString.append("" + entry.getKey() + " " + entry.getValue() + ""); - if (counter == fields.size() - 1) - fieldsString.append(")"); - else - fieldsString.append(","); - counter = counter + 1; - } + + if (partitionKey.isEmpty() ) primaryKey=""; + else if (clusterKey.isEmpty() ) primaryKey=" (" + partitionKey + ")"; + else primaryKey=" (" + partitionKey + ")," + clusterKey; + + //if (primaryKey != null) fieldsString.append("" + entry.getKey() + " (" + primaryKey + " )"); + if (primaryKey != null) fieldsString.append(", PRIMARY KEY (" + primaryKey + " )"); + } + fieldsString.append(")"); + + } // end of last field check + + } // end of for each // information about the name-value style properties Map<String, Object> propertiesMap = tableObj.getProperties(); StringBuilder propertiesString = new StringBuilder(); @@ -407,16 +506,48 @@ public class RestMusicDataAPI { } } - queryObject.appendQueryString( - "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString); + String clusteringOrder = tableObj.getClusteringOrder(); - if (propertiesMap != null) - queryObject.appendQueryString(" WITH " + propertiesString); + if (clusteringOrder != null && !(clusteringOrder.isEmpty())) { + String[] arrayClusterOrder = clusteringOrder.split("[,]+"); + for (int i = 0; i < arrayClusterOrder.length; i++) + { + String[] clusterS = arrayClusterOrder[i].trim().split("[ ]+"); + if ( (clusterS.length ==2) && (clusterS[1].equalsIgnoreCase("ASC") || clusterS[1].equalsIgnoreCase("DESC"))) continue; + else { + //logger.error("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:\"+ clusteringOrder+\".\"", " valid clustering order is ASC or DESC; please correct clusteringOrder:"+ clusteringOrder+"."); + // logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + // ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("createTable/Clustering Order vlaue ERROR: valid clustering order is ASC or DESC or expecting colname order; please correct clusteringOrder:"+ clusteringOrder+".") + .toMap()).build(); + } + // add validation for column names in cluster key + } + + if (!(clusterKey.isEmpty())) + { + clusteringOrder = "CLUSTERING ORDER BY (" +clusteringOrder +")"; + //cjc check if propertiesString.length() >0 instead propertiesMap + if (propertiesMap != null) propertiesString.append(" AND "+ clusteringOrder); + else propertiesString.append(clusteringOrder); + } else { + logger.warn("Skipping clustering order=("+clusteringOrder+ ") since clustering key is empty "); + } + } //if non empty + + queryObject.appendQueryString( + "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString); + + + if (propertiesString != null && propertiesString.length()>0 ) + queryObject.appendQueryString(" WITH " + propertiesString); queryObject.appendQueryString(";"); ResultType result = ResultType.FAILURE; - try { + //logger.info("cjc query="+queryObject.getQuery()); result = MusicCore.nonKeyRelatedPut(queryObject, consistency); } catch (MusicServiceException ex) { logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR); @@ -447,14 +578,16 @@ public class RestMusicDataAPI { @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "Keyspace Name",required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Table Name",required = true) @PathParam("tablename") String tablename, @ApiParam(value = "Field Name",required = true) @PathParam("field") String fieldName, @Context UriInfo info) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex"); if (authMap.containsKey("aid")) authMap.remove("aid"); @@ -468,7 +601,7 @@ public class RestMusicDataAPI { if (rowParams.getFirst("index_name") != null) indexName = rowParams.getFirst("index_name"); PreparedQueryObject query = new PreparedQueryObject(); - query.appendQueryString("Create index " + indexName + " if not exists on " + keyspace + "." + query.appendQueryString("Create index if not exists " + indexName + " on " + keyspace + "." + tablename + " (" + fieldName + ");"); ResultType result = ResultType.FAILURE; @@ -480,9 +613,9 @@ public class RestMusicDataAPI { return response.entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); } if ( result.equals(ResultType.SUCCESS) ) { - return response.entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build(); + return response.status(Status.OK).entity(new JsonResponse(result).setMessage("Index Created on " + keyspace+"."+tablename+"."+fieldName).toMap()).build(); } else { - return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build(); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build(); } } @@ -505,8 +638,7 @@ public class RestMusicDataAPI { @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace",required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId",required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password",required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, JsonInsert insObj, @ApiParam(value = "Keyspace Name", required = true) @PathParam("keyspace") String keyspace, @@ -514,6 +646,9 @@ public class RestMusicDataAPI { required = true) @PathParam("tablename") String tablename) { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = null; try { @@ -550,7 +685,7 @@ public class RestMusicDataAPI { queryObject.addValue(vectorTs); int counter = 0; String primaryKey = ""; - + Map<String, byte[]> objectMap = insObj.getObjectMap(); for (Map.Entry<String, Object> entry : valuesMap.entrySet()) { fieldsString.append("" + entry.getKey()); Object valueObj = entry.getValue(); @@ -573,6 +708,7 @@ public class RestMusicDataAPI { logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); } valueString.append("?"); + queryObject.addValue(formattedValue); if (counter == valuesMap.size() - 1) { @@ -585,11 +721,48 @@ public class RestMusicDataAPI { counter = counter + 1; } + //blobs.. + if(objectMap != null) { + for (Map.Entry<String, byte[]> 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; + /*if (counter == valuesMap.size() - 1) { + fieldsString.append(")"); + valueString.append(")"); + } else {*/ + fieldsString.append(","); + valueString.append(","); + //} + } } + if(primaryKey == null || primaryKey.length() <= 0) { logger.error(EELFLoggerDelegate.errorLogger, "Some required partition key parts are missing: "+primaryKeyName ); return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.SYNTAXERROR).setError("Some required partition key parts are missing: "+primaryKeyName).toMap()).build(); } + fieldsString.replace(fieldsString.length()-1, fieldsString.length(), ")"); + valueString.replace(valueString.length()-1, valueString.length(), ")"); + queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " " + fieldsString + " VALUES " + valueString); @@ -675,10 +848,7 @@ public class RestMusicDataAPI { @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, JsonUpdate updateObj, @ApiParam(value = "Keyspace Name", required = true) @PathParam("keyspace") String keyspace, @@ -687,6 +857,9 @@ public class RestMusicDataAPI { @Context UriInfo info) { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap; try { authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, @@ -888,10 +1061,7 @@ public class RestMusicDataAPI { @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, JsonDelete delObj, @ApiParam(value = "Keyspace Name", required = true) @PathParam("keyspace") String keyspace, @@ -900,6 +1070,9 @@ public class RestMusicDataAPI { @Context UriInfo info) { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = null; try { authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, @@ -1031,16 +1204,16 @@ public class RestMusicDataAPI { @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "Keyspace Name", required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Table Name", required = true) @PathParam("tablename") String tablename) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable"); if (authMap.containsKey("aid")) @@ -1085,10 +1258,7 @@ public class RestMusicDataAPI { @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, JsonInsert selObj, @ApiParam(value = "Keyspace Name", required = true) @PathParam("keyspace") String keyspace, @@ -1097,6 +1267,9 @@ public class RestMusicDataAPI { @Context UriInfo info) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical"); if (authMap.containsKey("aid")) authMap.remove("aid"); @@ -1138,11 +1311,12 @@ public class RestMusicDataAPI { else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) { results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject); } - if(results!=null && results.getAvailableWithoutFetching() >0) { return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build(); } - return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").setDataResult(MusicCore.marshallResults(results)).toMap()).build(); + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").toMap()).build(); + + } /** @@ -1167,10 +1341,7 @@ public class RestMusicDataAPI { @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam(NS) String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam(USERID) String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam(PASSWORD) String password, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "Keyspace Name", required = true) @PathParam("keyspace") String keyspace, @ApiParam(value = "Table Name", @@ -1178,6 +1349,9 @@ public class RestMusicDataAPI { @Context UriInfo info) throws Exception { ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select"); if (authMap.containsKey("aid")) @@ -1203,10 +1377,10 @@ public class RestMusicDataAPI { try { ResultSet results = MusicCore.get(queryObject); - if(results!=null && results.getAvailableWithoutFetching() >0) { + if(results.getAvailableWithoutFetching() >0) { return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build(); } - return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").setDataResult(MusicCore.marshallResults(results)).toMap()).build(); + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setError("No data found").toMap()).build(); } catch (MusicServiceException ex) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build(); diff --git a/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java b/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java new file mode 100644 index 00000000..895f0abf --- /dev/null +++ b/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java @@ -0,0 +1,120 @@ +/* + * ============LICENSE_START========================================== + * org.onap.music + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ============LICENSE_END============================================= + * ==================================================================== + */ +package org.onap.music.rest; + +import java.util.HashMap; +/** + * @author inam + * + */ +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.Consumes; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + + +import org.onap.music.response.jsonobjects.JsonResponse; +import org.onap.music.eelf.healthcheck.MusicHealthCheck; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.datastax.driver.core.ConsistencyLevel; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; + + + + +@Path("/v{version: [0-9]+}/service") +@Api(value="Healthcheck Api") +public class RestMusicHealthCheckAPI { + + + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class); + + + @GET + @Path("/pingCassandra/{consistency}") + @ApiOperation(value = "Get Health Status", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response cassandraStatus(@Context HttpServletResponse response, @ApiParam(value = "Consistency level", + required = true) @PathParam("consistency") String consistency) { + logger.info(EELFLoggerDelegate.applicationLogger,"Replying to request for MUSIC Health Check status for Cassandra"); + + Map<String, Object> resultMap = new HashMap<>(); + if(ConsistencyLevel.valueOf(consistency) == null) { + resultMap.put("INVALID", "Consistency level is invalid..."); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + MusicHealthCheck cassHealthCheck = new MusicHealthCheck(); + String status = cassHealthCheck.getCassandraStatus(consistency); + if(status.equals("ACTIVE")) { + resultMap.put("ACTIVE", "Cassandra Running and Listening to requests"); + return Response.status(Status.OK).entity(resultMap).build(); + } else { + resultMap.put("INACTIVE", "One or more nodes in the Cluster is/are down or not responding."); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + + + + } + + @GET + @Path("/pingZookeeper") + @ApiOperation(value = "Get Health Status", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + public Response ZKStatus(@Context HttpServletResponse response) { + logger.info(EELFLoggerDelegate.applicationLogger,"Replying to request for MUSIC Health Check status for Zookeeper"); + Map<String, Object> resultMap = new HashMap<>(); + MusicHealthCheck ZKHealthCheck = new MusicHealthCheck(); + String status = ZKHealthCheck.getZookeeperStatus(); + if(status.equals("ACTIVE")) { + resultMap.put("ACTIVE", "Zookeeper is Active and Running"); + return Response.status(Status.OK).entity(resultMap).build(); + }else { + resultMap.put("INACTIVE", "Zookeeper is not responding"); + return Response.status(Status.BAD_REQUEST).entity(resultMap).build(); + } + } + + + + + + + +} diff --git a/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java b/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java index 22112ddf..70583baa 100644 --- a/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java @@ -81,19 +81,19 @@ public class RestMusicLocksAPI { @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", - required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam("userId") String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam("password") String password) throws Exception{ + required = true) @HeaderParam("ns") String ns) throws Exception{ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); Map<String, Object> resultMap = MusicCore.validateLock(lockName); if (resultMap.containsKey("Exception")) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); String keyspaceName = (String) resultMap.get("keyspace"); resultMap.remove("keyspace"); resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, @@ -133,19 +133,19 @@ public class RestMusicLocksAPI { @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", - required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam("userId") String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam("password") String password) throws Exception{ + required = true) @HeaderParam("ns") String ns) throws Exception{ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); Map<String, Object> resultMap = MusicCore.validateLock(lockId); if (resultMap.containsKey("Exception")) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); String keyspaceName = (String) resultMap.get("keyspace"); resultMap.remove("keyspace"); resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, @@ -183,19 +183,19 @@ public class RestMusicLocksAPI { @ApiParam(value="Lock Reference",required=true) @PathParam("lockreference") String lockId, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", - required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam("userId") String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam("password") String password) throws Exception{ + required = true) @HeaderParam("ns") String ns) throws Exception{ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); Map<String, Object> resultMap = MusicCore.validateLock(lockId); if (resultMap.containsKey("Exception")) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); String keyspaceName = (String) resultMap.get("keyspace"); resultMap.remove("keyspace"); resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, @@ -230,19 +230,19 @@ public class RestMusicLocksAPI { @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", - required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam("userId") String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam("password") String password) throws Exception{ + required = true) @HeaderParam("ns") String ns) throws Exception{ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); Map<String, Object> resultMap = MusicCore.validateLock(lockName); if (resultMap.containsKey("Exception")) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); String keyspaceName = (String) resultMap.get("keyspace"); resultMap.remove("keyspace"); resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, @@ -275,6 +275,7 @@ public class RestMusicLocksAPI { @ApiParam(value="Lock Name",required=true) @PathParam("lockname") String lockName, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, @@ -332,19 +333,19 @@ public class RestMusicLocksAPI { public Response unLock(@PathParam("lockreference") String lockId, @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, @ApiParam(value = "Application namespace", - required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam("userId") String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam("password") String password) throws Exception{ + required = true) @HeaderParam("ns") String ns) throws Exception{ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); Map<String, Object> resultMap = MusicCore.validateLock(lockId); if (resultMap.containsKey("Exception")) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); String keyspaceName = (String) resultMap.get("keyspace"); resultMap.remove("keyspace"); resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, @@ -390,18 +391,18 @@ public class RestMusicLocksAPI { @ApiParam(value = "Minor Version",required = false) @HeaderParam(XMINORVERSION) String minorVersion, @ApiParam(value = "Patch Version",required = false) @HeaderParam(XPATCHVERSION) String patchVersion, @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, @ApiParam(value = "Application namespace", - required = true) @HeaderParam("ns") String ns, - @ApiParam(value = "userId", - required = true) @HeaderParam("userId") String userId, - @ApiParam(value = "Password", - required = true) @HeaderParam("password") String password) throws Exception{ + required = true) @HeaderParam("ns") String ns) throws Exception{ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion); Map<String, Object> resultMap = MusicCore.validateLock(lockName); if (resultMap.containsKey("Exception")) { logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR); return response.status(Status.BAD_REQUEST).entity(resultMap).build(); } + Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization); + String userId = userCredentials.get(MusicUtil.USERID); + String password = userCredentials.get(MusicUtil.PASSWORD); String keyspaceName = (String) resultMap.get("keyspace"); resultMap.remove("keyspace"); resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid, diff --git a/src/main/java/org/onap/music/rest/RestMusicQAPI.java b/src/main/java/org/onap/music/rest/RestMusicQAPI.java index e08adaf7..8af334c7 100755 --- a/src/main/java/org/onap/music/rest/RestMusicQAPI.java +++ b/src/main/java/org/onap/music/rest/RestMusicQAPI.java @@ -1,31 +1,24 @@ /* - * ============LICENSE_START========================================== - * org.onap.music - * =================================================================== - * Copyright (c) 2017 AT&T Intellectual Property - * =================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * ============LICENSE_START========================================== org.onap.music + * =================================================================== Copyright (c) 2017 AT&T + * Intellectual Property =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. * * ============LICENSE_END============================================= * ==================================================================== */ package org.onap.music.rest; - - import java.util.HashMap; import java.util.Map; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -37,215 +30,472 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; - +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; +// cjcimport javax.servlet.http.HttpServletResponse; import org.onap.music.datastore.jsonobjects.JsonDelete; import org.onap.music.datastore.jsonobjects.JsonInsert; import org.onap.music.datastore.jsonobjects.JsonTable; import org.onap.music.datastore.jsonobjects.JsonUpdate; import org.onap.music.eelf.logging.EELFLoggerDelegate; -import org.onap.music.main.MusicCore; +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.apache.commons.lang3.StringUtils; import org.onap.music.datastore.PreparedQueryObject; import com.datastax.driver.core.ResultSet; - +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.main.MusicCore; +import org.onap.music.main.MusicUtil; +import org.onap.music.main.ResultType; +// cjc import org.onap.music.main.ReturnType; +import org.onap.music.response.jsonobjects.JsonResponse; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -//@Path("/v{version: [0-9]+}/priorityq/") -@Path("/priorityq/") -@Api(value="Q Api") +// import io.swagger.models.Response; +// @Path("/v{version: [0-9]+}/priorityq/") +@Path("{version}/priorityq/") +@Api(value = "Q Api") public class RestMusicQAPI { - - private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicDataAPI.class); + private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicQAPI.class); + // private static String xLatestVersion = "X-latestVersion"; + /* + * private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicDataAPI.class); + * private static final String XMINORVERSION = "X-minorVersion"; private static final String + * XPATCHVERSION = "X-patchVersion"; private static final String NS = "ns"; private static final + * String USERID = "userId"; private static final String PASSWORD = "password"; + * */ + // private static final String VERSION = "v2"; - /** - * - * @param tableObj - * @param keyspace - * @param tablename - * @throws Exception - */ - @POST - @Path("/keyspaces/{keyspace}/{qname}") - @ApiOperation(value = "", response = Void.class) - @Consumes(MediaType.APPLICATION_JSON) - public Response createQ( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, - @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonTable tableObj, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename) throws Exception{ - return new RestMusicDataAPI().createTable(version,minorVersion,patchVersion,aid, ns, userId, password, tableObj, keyspace, tablename); + /** + * + * @param tableObj + * @param keyspace + * @param tablename + * @throws Exception + */ + + @POST + @Path("/keyspaces/{keyspace}/{qname}") // is it same as tablename?down + @ApiOperation(value = "Create Q", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + + /* old + @POST + @Path("/keyspaces/{keyspace}/{qname}") + @ApiOperation(value = "", response = Void.class) + @Consumes(MediaType.APPLICATION_JSON) + */ + public Response createQ( + // public Map<String,Object> createQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonTable tableObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) + throws Exception { + //logger.info(logger, "cjc before start in q 1** major version=" + version); + + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + + Map<String, String> fields = tableObj.getFields(); + if (fields == null) { // || (!fields.containsKey("order")) ){ + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ/Required table fields are empty or not set").toMap()) + .build(); } - /** - * - * @param insObj - * @param keyspace - * @param tablename - * @throws Exception - */ - @POST - @Path("/keyspaces/{keyspace}/{qname}/rows") - @ApiOperation(value = "", response = Void.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response insertIntoQ( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonInsert insObj, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename) throws Exception{ - return new RestMusicDataAPI().insertIntoTable(version,minorVersion,patchVersion,aid, ns, userId, password, insObj, keyspace, tablename); + String primaryKey = tableObj.getPrimaryKey(); + String partitionKey = tableObj.getPartitionKey(); + String clusteringKey = tableObj.getClusteringKey(); + String filteringKey = tableObj.getFilteringKey(); + String clusteringOrder = tableObj.getClusteringOrder(); + + if(primaryKey == null) { + primaryKey = tableObj.getFields().get("PRIMARY KEY"); } - /** - * - * @param updateObj - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception - */ - @PUT - @Path("/keyspaces/{keyspace}/{qname}/rows") - @ApiOperation(value = "", response = String.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response updateQ( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonUpdate updateObj, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, - @Context UriInfo info) throws Exception{ - return new RestMusicDataAPI().updateTable(version,minorVersion,patchVersion,aid, ns, userId, password, updateObj, keyspace, tablename, info); + if ((primaryKey == null) && (partitionKey == null)) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Partition key cannot be empty").toMap()) + .build(); + } + + if ((primaryKey == null) && (clusteringKey == null)) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Clustering key cannot be empty").toMap()) + .build(); + } + + if (clusteringOrder == null) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Clustering Order cannot be empty").toMap()) + .build(); + } + + if ((primaryKey!=null) && (partitionKey == null)) { + primaryKey.trim(); + int count1 = StringUtils.countMatches(primaryKey, ')'); + int count2 = StringUtils.countMatches(primaryKey, '('); + if (count1 != count2) { + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ Error: primary key '(' and ')' do not match, primary key=" + primaryKey) + .toMap()).build(); + } + + if ( primaryKey.indexOf('(') == -1 || ( count2 == 1 && (primaryKey.lastIndexOf(")") +1) == primaryKey.length() ) ) + { + if (primaryKey.contains(",") ) { + partitionKey= primaryKey.substring(0,primaryKey.indexOf(",")); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusteringKey=primaryKey.substring(primaryKey.indexOf(',')+1); // make sure index + clusteringKey=clusteringKey.replaceAll("[)]+", ""); + } else { + partitionKey=primaryKey; + partitionKey=partitionKey.replaceAll("[\\)]+",""); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + clusteringKey=""; + } + } else { + partitionKey= primaryKey.substring(0,primaryKey.indexOf(')')); + partitionKey=partitionKey.replaceAll("[\\(]+",""); + partitionKey.trim(); + clusteringKey= primaryKey.substring(primaryKey.indexOf(')')); + clusteringKey=clusteringKey.replaceAll("[\\(]+",""); + clusteringKey=clusteringKey.replaceAll("[\\)]+",""); + clusteringKey.trim(); + if (clusteringKey.indexOf(",") == 0) clusteringKey=clusteringKey.substring(1); + clusteringKey.trim(); + if (clusteringKey.equals(",") ) clusteringKey=""; // print error if needed ( ... ),) + } } - /** - * - * @param delObj - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception - */ - @DELETE - @Path("/keyspaces/{keyspace}/{qname}/rows") - @ApiOperation(value = "", response = String.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public Response deleteFromQ( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, - @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonDelete delObj, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, - @Context UriInfo info) throws Exception{ - return new RestMusicDataAPI().deleteFromTable(version,minorVersion,patchVersion,aid, ns, userId, password, delObj, keyspace, tablename, info); + if (partitionKey.trim().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Partition key cannot be empty").toMap()) + .build(); + } + + if (clusteringKey.trim().isEmpty()) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Clustering key cannot be empty").toMap()) + .build(); + } + + if((filteringKey != null) && (filteringKey.equalsIgnoreCase(partitionKey))) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE) + .setError("CreateQ: Filtering key cannot be same as Partition Key").toMap()) + .build(); + } + + return new RestMusicDataAPI().createTable(version, minorVersion, patchVersion, aid, ns, authorization, tableObj, keyspace, tablename); + } + + /** + * + * @param insObj + * @param keyspace + * @param tablename + * @throws Exception + */ + @POST + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "", response = Void.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + // public Map<String, Object> insertIntoQ( + public Response insertIntoQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonInsert insObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) + throws Exception { + // ,@Context HttpServletResponse response) throws Exception { + + // Map<String, Object> valuesMap = insObj.getValues(); + // check valuesMap.isEmpty and proceed + // if(valuesMap.isEmpty() ) { + // response.addHeader(xLatestVersion, MusicUtil.getVersion()); + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + if (insObj.getValues().isEmpty()) { + // response.status(404); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("Required HTTP Request body is missing.").toMap()).build(); + } + return new RestMusicDataAPI().insertIntoTable(version, minorVersion, patchVersion, aid, ns, + authorization, insObj, keyspace, tablename); + } + + /** + * + * @param updateObj + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @PUT + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "updateQ", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + JsonUpdate updateObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + @Context UriInfo info) throws Exception { + + //logger.info(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, ErrorSeverity.CRITICAL, + // ErrorTypes.DATAERROR); + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + if (updateObj.getValues().isEmpty()) { + // response.status(404); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE).setError( + "Required HTTP Request body is missing. JsonUpdate updateObj.getValues() is empty. ") + .toMap()) + .build(); + + + } + return new RestMusicDataAPI().updateTable(version, minorVersion, patchVersion, aid, ns, + authorization,updateObj, keyspace, tablename, info); + } + + /** + * + * @param delObj + * @param keyspace + * @param tablename + * @param info + * + * @return + * @throws Exception + */ + + @DELETE + @Path("/keyspaces/{keyspace}/{qname}/rows") + @ApiOperation(value = "deleteQ", response = String.class) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response deleteFromQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + // @ApiParam(value = "userId", required = true) @HeaderParam("userId") String userId, + // @ApiParam(value = "Password", required = true) @HeaderParam("password") String password, + JsonDelete delObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + @Context UriInfo info) throws Exception { + // added checking as per RestMusicDataAPI + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + if (delObj == null) { + // response.status(404); + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA, + ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR); + return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE) + .setError("deleteFromQ JsonDelete delObjis empty").toMap()).build(); } - /** - * - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception + return new RestMusicDataAPI().deleteFromTable(version, minorVersion, patchVersion, aid, ns, + authorization, delObj, keyspace, tablename, info); + } + + /** + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/keyspaces/{keyspace}/{qname}/peek") + @ApiOperation(value = "", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + //public Map<String, HashMap<String, Object>> peek( + public Response peek( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + @Context UriInfo info) throws Exception { + int limit =1; //peek must return just the top row + Map<String ,String> auth = new HashMap<>(); + String userId =auth.get(MusicUtil.USERID); + String password =auth.get(MusicUtil.PASSWORD); + ResponseBuilder response = MusicUtil.buildVersionResponse(version, minorVersion, patchVersion); + + PreparedQueryObject queryObject = new PreparedQueryObject(); + if (info.getQueryParameters() == null ) //|| info.getQueryParameters().isEmpty()) + queryObject.appendQueryString( + "SELECT * FROM " + keyspace + "." + tablename + " LIMIT " + limit + ";"); + else { + + try { + queryObject = new RestMusicDataAPI().selectSpecificQuery(version, minorVersion, + patchVersion, aid, ns, userId, password, keyspace, tablename, info, limit); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR, + ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()) + .build(); + } + } + + try { + ResultSet results = MusicCore.get(queryObject); + return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS) + .setDataResult(MusicCore.marshallResults(results)).toMap()).build(); + } catch (MusicServiceException ex) { + logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.UNKNOWNERROR, + ErrorSeverity.ERROR, ErrorTypes.MUSICSERVICEERROR); + return response.status(Status.BAD_REQUEST) + .entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()) + .build(); + } + } + + /** + * + * + * @param keyspace + * @param tablename + * @param info + * @return + * @throws Exception + */ + @GET + @Path("/keyspaces/{keyspace}/{qname}/filter") + @ApiOperation(value = "filter", response = Map.class) + @Produces(MediaType.APPLICATION_JSON) + // public Map<String, HashMap<String, Object>> filter( + public Response filter( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + // @ApiParam(value = "userId", required = true) @HeaderParam("userId") String userId, + //@ApiParam(value = "Password", required = true) @HeaderParam("password") String password, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename, + @Context UriInfo info) throws Exception { + //int limit = -1; + /* + * PreparedQueryObject query = new RestMusicDataAPI().selectSpecificQuery(version, minorVersion, + * patchVersion, aid, ns, userId, password, keyspace, tablename, info, limit); ResultSet results + * = MusicCore.get(query); return MusicCore.marshallResults(results); */ - @GET - @Path("/keyspaces/{keyspace}/{qname}/peek") - @ApiOperation(value = "", response = Map.class) - @Produces(MediaType.APPLICATION_JSON) - public Map<String, HashMap<String, Object>> peek( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, - @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, - @Context UriInfo info) throws Exception{ - int limit =1; //peek must return just the top row - PreparedQueryObject query = new RestMusicDataAPI().selectSpecificQuery(version,minorVersion,patchVersion,aid, ns, userId, password,keyspace,tablename,info,limit); - ResultSet results = MusicCore.get(query); - return MusicCore.marshallResults(results); - - } + /* Map<String ,String> auth = new HashMap<>(); + String userId =auth.get(MusicUtil.USERID); + String password =auth.get(MusicUtil.PASSWORD); + */ + return new RestMusicDataAPI().select(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename, info);// , limit) - /** - * - * - * @param keyspace - * @param tablename - * @param info - * @return - * @throws Exception - */ - @GET - @Path("/keyspaces/{keyspace}/{qname}/filter") - @ApiOperation(value = "", response = Map.class) - @Produces(MediaType.APPLICATION_JSON) - public Map<String, HashMap<String, Object>> filter( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, - @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename, - @Context UriInfo info) throws Exception{ - int limit =-1; - PreparedQueryObject query = new RestMusicDataAPI().selectSpecificQuery(version,minorVersion,patchVersion,aid, ns, userId, password,keyspace,tablename,info,limit); - ResultSet results = MusicCore.get(query); - return MusicCore.marshallResults(results); - } - - /** - * - * @param tabObj - * @param keyspace - * @param tablename - * @throws Exception - */ - @DELETE - @ApiOperation(value = "", response = Void.class) - @Path("/keyspaces/{keyspace}/{qname}") - public Response dropQ( - @ApiParam(value="Major Version",required=true) @PathParam("version") String version, - @ApiParam(value="Minor Version",required=false) @HeaderParam("X-minorVersion") String minorVersion, - @ApiParam(value="Patch Version",required=false) @HeaderParam("X-patchVersion") String patchVersion, - @ApiParam(value="AID",required=true) @HeaderParam("aid") String aid, - @ApiParam(value="Application namespace",required=true) @HeaderParam("ns") String ns, - @ApiParam(value="userId",required=true) @HeaderParam("userId") String userId, - @ApiParam(value="Password",required=true) @HeaderParam("password") String password, JsonTable tabObj, - @ApiParam(value="Key Space",required=true) @PathParam("keyspace") String keyspace, - @ApiParam(value="Table Name",required=true) @PathParam("tablename") String tablename) throws Exception{ - return new RestMusicDataAPI().dropTable(version,minorVersion,patchVersion,aid, ns, userId, password, keyspace, tablename); - } + } + + /** + * + * @param tabObj + * @param keyspace + * @param tablename + * @throws Exception + */ + @DELETE + @ApiOperation(value = "DropQ", response = String.class) + @Path("/keyspaces/{keyspace}/{qname}") + @Produces(MediaType.APPLICATION_JSON) + public Response dropQ( + @ApiParam(value = "Major Version", required = true) @PathParam("version") String version, + @ApiParam(value = "Minor Version", + required = false) @HeaderParam("X-minorVersion") String minorVersion, + @ApiParam(value = "Patch Version", + required = false) @HeaderParam("X-patchVersion") String patchVersion, + @ApiParam(value = "AID", required = true) @HeaderParam("aid") String aid, + @ApiParam(value = "Application namespace", required = true) @HeaderParam("ns") String ns, + @ApiParam(value = "Authorization", required = true) @HeaderParam(MusicUtil.AUTHORIZATION) String authorization, + // @ApiParam(value = "userId", required = true) @HeaderParam("userId") String userId, + //@ApiParam(value = "Password", required = true) @HeaderParam("password") String password, + // cjc JsonTable tabObj, + @ApiParam(value = "Key Space", required = true) @PathParam("keyspace") String keyspace, + @ApiParam(value = "Table Name", required = true) @PathParam("qname") String tablename) + throws Exception { + // @Context HttpServletResponse response) throws Exception { + // tabObj never in use & thus no need to verify + + + return new RestMusicDataAPI().dropTable(version, minorVersion, patchVersion, aid, ns, authorization, keyspace, tablename); + } } |