aboutsummaryrefslogtreecommitdiffstats
path: root/jar/src/main
diff options
context:
space:
mode:
authorThomas Nelson Jr (arthurdent3) tn1381@att.com <tn1381@att.com>2018-06-05 14:09:02 -0400
committerThomas Nelson Jr (arthurdent3) tn1381@att.com <tn1381@att.com>2018-06-05 14:09:02 -0400
commit03ade18ac83ab02ee1ce0d6d43725b96513b4577 (patch)
tree79ccb24c5599169ba3ac764b1ede71fb42c3069e /jar/src/main
parent932c9e80911645798712a77e4cee9230a4b59408 (diff)
Update Master to include jar folder.
This will put jar folder form separate branch into this where it belongs and we can build properly for beijing. Cassablanca will have a parent pom approach. Change-Id: Ieae3fce5ab42faddf4964285533fdc59d8b963de Issue-ID: MUSIC-79 Signed-off-by: Thomas Nelson Jr (arthurdent3) tn1381@att.com <tn1381@att.com>
Diffstat (limited to 'jar/src/main')
-rw-r--r--jar/src/main/java/LICENSE.txt24
-rw-r--r--jar/src/main/java/org/onap/music/datastore/MusicDataStore.java469
-rw-r--r--jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java79
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java42
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java37
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java87
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java122
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java77
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java52
-rwxr-xr-xjar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java83
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java59
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java117
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java132
-rw-r--r--jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java47
-rw-r--r--jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java175
-rw-r--r--jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java354
-rw-r--r--jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java183
-rw-r--r--jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java106
-rw-r--r--jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java37
-rw-r--r--jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java44
-rw-r--r--jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java53
-rw-r--r--jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java74
-rw-r--r--jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java79
-rw-r--r--jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java89
-rw-r--r--jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java84
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/LockListener.java39
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java137
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java184
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java208
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java118
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java339
-rw-r--r--jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java42
-rwxr-xr-xjar/src/main/java/org/onap/music/main/CachingUtil.java420
-rw-r--r--jar/src/main/java/org/onap/music/main/CronJobManager.java47
-rw-r--r--jar/src/main/java/org/onap/music/main/MusicCore.java992
-rw-r--r--jar/src/main/java/org/onap/music/main/MusicDigest.java78
-rwxr-xr-xjar/src/main/java/org/onap/music/main/MusicUtil.java560
-rwxr-xr-xjar/src/main/java/org/onap/music/main/PropertiesListener.java151
-rw-r--r--jar/src/main/java/org/onap/music/main/ResultType.java41
-rw-r--r--jar/src/main/java/org/onap/music/main/ReturnType.java74
-rw-r--r--jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java265
-rwxr-xr-xjar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java372
-rw-r--r--jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java307
-rwxr-xr-xjar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java1289
-rw-r--r--jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java113
-rw-r--r--jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java423
-rwxr-xr-xjar/src/main/java/org/onap/music/rest/RestMusicQAPI.java251
-rw-r--r--jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java67
-rw-r--r--jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java63
-rw-r--r--jar/src/main/resources/LICENSE.txt24
-rw-r--r--jar/src/main/resources/Resources.properties50
-rw-r--r--jar/src/main/resources/cache.ccf56
-rw-r--r--jar/src/main/resources/logback.xml270
-rw-r--r--jar/src/main/resources/project.properties4
54 files changed, 9689 insertions, 0 deletions
diff --git a/jar/src/main/java/LICENSE.txt b/jar/src/main/java/LICENSE.txt
new file mode 100644
index 00000000..cc6cdea5
--- /dev/null
+++ b/jar/src/main/java/LICENSE.txt
@@ -0,0 +1,24 @@
+
+The following license applies to all files in this and sub-directories. Licenses
+are included in individual source files where appropriate, and if it differs
+from this text, it supersedes this. Any file that does not have license text
+defaults to being covered by this text; not all files support the addition of
+licenses.
+#
+# -------------------------------------------------------------------------
+# 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.
+#
+# -------------------------------------------------------------------------
+# \ No newline at end of file
diff --git a/jar/src/main/java/org/onap/music/datastore/MusicDataStore.java b/jar/src/main/java/org/onap/music/datastore/MusicDataStore.java
new file mode 100644
index 00000000..71006f73
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/MusicDataStore.java
@@ -0,0 +1,469 @@
+/*
+ * ============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.datastore;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+import org.onap.music.eelf.logging.format.AppMessages;
+import org.onap.music.eelf.logging.format.ErrorSeverity;
+import org.onap.music.eelf.logging.format.ErrorTypes;
+import org.onap.music.exceptions.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.main.MusicUtil;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ColumnDefinitions;
+import com.datastax.driver.core.ColumnDefinitions.Definition;
+import com.datastax.driver.core.ConsistencyLevel;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.KeyspaceMetadata;
+import com.datastax.driver.core.Metadata;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+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.datastax.driver.core.policies.RoundRobinPolicy;
+import com.datastax.driver.core.HostDistance;
+import com.datastax.driver.core.PoolingOptions;
+
+
+/**
+ * @author nelson24
+ *
+ */
+public class MusicDataStore {
+
+ private Session session;
+ private Cluster cluster;
+
+
+
+ /**
+ * @param session
+ */
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+ /**
+ * @param session
+ */
+ public Session getSession() {
+ return session;
+ }
+
+ /**
+ * @param cluster
+ */
+ public void setCluster(Cluster cluster) {
+ this.cluster = cluster;
+ }
+
+
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicDataStore.class);
+
+ /**
+ *
+ */
+ public MusicDataStore() {
+ connectToCassaCluster();
+ }
+
+
+ /**
+ * @param cluster
+ * @param session
+ */
+ public MusicDataStore(Cluster cluster, Session session) {
+ this.session = session;
+ this.cluster = cluster;
+ }
+
+ /**
+ *
+ * @param remoteIp
+ * @throws MusicServiceException
+ */
+ public MusicDataStore(String remoteIp) {
+ try {
+ connectToCassaCluster(remoteIp);
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ private ArrayList<String> getAllPossibleLocalIps() {
+ ArrayList<String> allPossibleIps = new ArrayList<String>();
+ try {
+ Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
+ while (en.hasMoreElements()) {
+ NetworkInterface ni = (NetworkInterface) en.nextElement();
+ Enumeration<InetAddress> ee = ni.getInetAddresses();
+ while (ee.hasMoreElements()) {
+ InetAddress ia = (InetAddress) ee.nextElement();
+ allPossibleIps.add(ia.getHostAddress());
+ }
+ }
+ } catch (SocketException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.CONNCECTIVITYERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR);
+ }catch(Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR);
+ }
+ return allPossibleIps;
+ }
+
+ /**
+ * This method iterates through all available IP addresses and connects to multiple cassandra
+ * clusters.
+ */
+ private void connectToCassaCluster() {
+ Iterator<String> it = getAllPossibleLocalIps().iterator();
+ String address = "localhost";
+ String[] addresses = null;
+ address = MusicUtil.getMyCassaHost();
+ addresses = address.split(",");
+
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Connecting to cassa cluster: Iterating through possible ips:"
+ + getAllPossibleLocalIps());
+ PoolingOptions poolingOptions = new PoolingOptions();
+ poolingOptions
+ .setConnectionsPerHost(HostDistance.LOCAL, 4, 10)
+ .setConnectionsPerHost(HostDistance.REMOTE, 2, 4);
+ while (it.hasNext()) {
+ try {
+ if(MusicUtil.getCassName() != null && MusicUtil.getCassPwd() != null) {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Building with credentials "+MusicUtil.getCassName()+" & "+MusicUtil.getCassPwd());
+ cluster = Cluster.builder().withPort(9042)
+ .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd())
+ //.withLoadBalancingPolicy(new RoundRobinPolicy())
+ .withPoolingOptions(poolingOptions)
+ .addContactPoints(addresses).build();
+ }
+ else
+ cluster = Cluster.builder().withPort(9042)
+ //.withLoadBalancingPolicy(new RoundRobinPolicy())
+ .addContactPoints(addresses).build();
+
+ Metadata metadata = cluster.getMetadata();
+ logger.info(EELFLoggerDelegate.applicationLogger, "Connected to cassa cluster "
+ + metadata.getClusterName() + " at " + address);
+ session = cluster.connect();
+
+ break;
+ } catch (NoHostAvailableException e) {
+ address = it.next();
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.HOSTUNAVAILABLE, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ public void close() {
+ session.close();
+ }
+
+ /**
+ * This method connects to cassandra cluster on specific address.
+ *
+ * @param address
+ */
+ private void connectToCassaCluster(String address) throws MusicServiceException {
+ String[] addresses = null;
+ addresses = address.split(",");
+ PoolingOptions poolingOptions = new PoolingOptions();
+ poolingOptions
+ .setConnectionsPerHost(HostDistance.LOCAL, 4, 10)
+ .setConnectionsPerHost(HostDistance.REMOTE, 2, 4);
+ if(MusicUtil.getCassName() != null && MusicUtil.getCassPwd() != null) {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Building with credentials "+MusicUtil.getCassName()+" & "+MusicUtil.getCassPwd());
+ cluster = Cluster.builder().withPort(9042)
+ .withCredentials(MusicUtil.getCassName(), MusicUtil.getCassPwd())
+ //.withLoadBalancingPolicy(new RoundRobinPolicy())
+ .withPoolingOptions(poolingOptions)
+ .addContactPoints(addresses).build();
+ }
+ else {
+ cluster = Cluster.builder().withPort(9042)
+ //.withLoadBalancingPolicy(new RoundRobinPolicy())
+ .withPoolingOptions(poolingOptions)
+ .addContactPoints(addresses).build();
+ }
+ Metadata metadata = cluster.getMetadata();
+ logger.info(EELFLoggerDelegate.applicationLogger, "Connected to cassa cluster "
+ + metadata.getClusterName() + " at " + address);
+ try {
+ session = cluster.connect();
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.CASSANDRACONNECTIVITY, ErrorSeverity.ERROR, ErrorTypes.SERVICEUNAVAILABLE);
+ throw new MusicServiceException(
+ "Error while connecting to Cassandra cluster.. " + ex.getMessage());
+ }
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tableName
+ * @param columnName
+ * @return DataType
+ */
+ public DataType returnColumnDataType(String keyspace, String tableName, String columnName) {
+ KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace);
+ TableMetadata table = ks.getTable(tableName);
+ return table.getColumn(columnName).getType();
+
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tableName
+ * @return TableMetadata
+ */
+ public TableMetadata returnColumnMetadata(String keyspace, String tableName) {
+ KeyspaceMetadata ks = cluster.getMetadata().getKeyspace(keyspace);
+ return ks.getTable(tableName);
+ }
+
+
+ /**
+ * Utility function to return the Java specific object type.
+ *
+ * @param row
+ * @param colName
+ * @param colType
+ * @return
+ */
+ public Object getColValue(Row row, String colName, DataType colType) {
+
+ switch (colType.getName()) {
+ case VARCHAR:
+ return row.getString(colName);
+ case UUID:
+ return row.getUUID(colName);
+ case VARINT:
+ return row.getVarint(colName);
+ case BIGINT:
+ return row.getLong(colName);
+ case INT:
+ return row.getInt(colName);
+ case FLOAT:
+ return row.getFloat(colName);
+ case DOUBLE:
+ return row.getDouble(colName);
+ case BOOLEAN:
+ return row.getBool(colName);
+ case MAP:
+ return row.getMap(colName, String.class, String.class);
+ default:
+ return null;
+ }
+ }
+
+ public boolean doesRowSatisfyCondition(Row row, Map<String, Object> condition) throws Exception {
+ ColumnDefinitions colInfo = row.getColumnDefinitions();
+
+ for (Map.Entry<String, Object> entry : condition.entrySet()) {
+ String colName = entry.getKey();
+ DataType colType = colInfo.getType(colName);
+ Object columnValue = getColValue(row, colName, colType);
+ Object conditionValue = MusicUtil.convertToActualDataType(colType, entry.getValue());
+ if (columnValue.equals(conditionValue) == false)
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Utility function to store ResultSet values in to a MAP for output.
+ *
+ * @param results
+ * @return MAP
+ */
+ public Map<String, HashMap<String, Object>> marshalData(ResultSet results) {
+ Map<String, HashMap<String, Object>> resultMap =
+ new HashMap<String, HashMap<String, Object>>();
+ int counter = 0;
+ for (Row row : results) {
+ 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(),
+ getColValue(row, definition.getName(), definition.getType()));
+ }
+ resultMap.put("row " + counter, resultOutput);
+ counter++;
+ }
+ return resultMap;
+ }
+
+
+ // Prepared Statements 1802 additions
+ /**
+ * This Method performs DDL and DML operations on Cassandra using specified consistency level
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ * @param consistency Specify consistency level for data synchronization across cassandra
+ * replicas
+ * @return Boolean Indicates operation success or failure
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public boolean executePut(PreparedQueryObject queryObject, String consistency)
+ throws MusicServiceException, MusicQueryException {
+
+ boolean result = false;
+
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, queryObject.getQuery(),AppMessages.QUERYERROR, ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Ill formed queryObject for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "In preprared Execute Put: the actual insert query:"
+ + queryObject.getQuery() + "; the values"
+ + queryObject.getValues());
+ PreparedStatement preparedInsert = null;
+ try {
+
+ preparedInsert = session.prepare(queryObject.getQuery());
+
+ } catch(InvalidQueryException iqe) {
+ 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 {
+ if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Executing critical put query");
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.QUORUM);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Executing simple put query");
+ preparedInsert.setConsistencyLevel(ConsistencyLevel.ONE);
+ }
+
+ ResultSet rs = session.execute(preparedInsert.bind(queryObject.getValues().toArray()));
+ result = rs.wasApplied();
+
+ }
+ catch (AlreadyExistsException ae) {
+ logger.error(EELFLoggerDelegate.errorLogger, ae.getMessage(),AppMessages.SESSIONFAILED+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicServiceException(ae.getMessage());
+ }
+ catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.SESSIONFAILED+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Executing Session Failure for Request = " + "["
+ + queryObject.getQuery() + "]" + " Reason = " + e.getMessage());
+ }
+
+
+ return result;
+ }
+
+ /**
+ * This method performs DDL operations on Cassandra using consistency level ONE.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ * @return ResultSet
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public ResultSet executeEventualGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Ill formed queryObject for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Executing Eventual get query:" + queryObject.getQuery());
+
+ ResultSet results = null;
+ try {
+ PreparedStatement preparedEventualGet = session.prepare(queryObject.getQuery());
+ preparedEventualGet.setConsistencyLevel(ConsistencyLevel.ONE);
+ results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray()));
+
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ return results;
+ }
+
+ /**
+ *
+ * This method performs DDL operation on Cassandra using consistency level QUORUM.
+ *
+ * @param queryObject Object containing cassandra prepared query and values.
+ * @return ResultSet
+ * @throws MusicServiceException
+ * @throws MusicQueryException
+ */
+ public ResultSet executeCriticalGet(PreparedQueryObject queryObject)
+ throws MusicServiceException, MusicQueryException {
+ if (!MusicUtil.isValidQueryObject(!queryObject.getValues().isEmpty(), queryObject)) {
+ logger.error(EELFLoggerDelegate.errorLogger, "",AppMessages.QUERYERROR+ " [" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicQueryException("Error processing Prepared Query Object for the request = " + "["
+ + queryObject.getQuery() + "]");
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Executing Critical get query:" + queryObject.getQuery());
+ PreparedStatement preparedEventualGet = session.prepare(queryObject.getQuery());
+ preparedEventualGet.setConsistencyLevel(ConsistencyLevel.QUORUM);
+ ResultSet results = null;
+ try {
+ results = session.execute(preparedEventualGet.bind(queryObject.getValues().toArray()));
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR+ "[" + queryObject.getQuery() + "]", ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ return results;
+
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java b/jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java
new file mode 100644
index 00000000..694d9acd
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/PreparedQueryObject.java
@@ -0,0 +1,79 @@
+/*
+ * ============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.datastore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author srupane
+ *
+ */
+public class PreparedQueryObject {
+
+
+ private List<Object> values;
+ private StringBuilder query;
+
+
+
+ /**
+ *
+ */
+ public PreparedQueryObject() {
+
+ this.values = new ArrayList<>();
+ this.query = new StringBuilder();
+ }
+
+ /**
+ * @return
+ */
+ public List<Object> getValues() {
+ return values;
+ }
+
+ /**
+ * @param o
+ */
+ public void addValue(Object o) {
+ this.values.add(o);
+ }
+
+ /**
+ * @param s
+ */
+ public void appendQueryString(String s) {
+ this.query.append(s);
+ }
+
+ /**
+ * @return
+ */
+ public String getQuery() {
+ return this.query.toString();
+ }
+
+
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java
new file mode 100644
index 00000000..df6089ee
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/AAFResponse.java
@@ -0,0 +1,42 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.util.ArrayList;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Reponse class for AAF request")
+public class AAFResponse {
+
+ private ArrayList<NameSpace> ns = null;
+
+ @ApiModelProperty(value = "Namespace value")
+ public ArrayList<NameSpace> getNs() {
+ return ns;
+ }
+
+ public void setNs(ArrayList<NameSpace> ns) {
+ this.ns = ns;
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JSONObject.java
new file mode 100644
index 00000000..8de0a2cd
--- /dev/null
+++ b/jar/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/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java
new file mode 100644
index 00000000..a5db4be5
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonDelete.java
@@ -0,0 +1,87 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model for delete")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonDelete {
+
+ private ArrayList<String> columns = null;
+ private Map<String, String> consistencyInfo;
+ private Map<String, Object> conditions;
+ String ttl, timestamp;
+
+
+ @ApiModelProperty(value = "Conditions")
+ public Map<String, Object> getConditions() {
+ return conditions;
+ }
+
+ public void setConditions(Map<String, Object> conditions) {
+ this.conditions = conditions;
+ }
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Column values")
+ public ArrayList<String> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(ArrayList<String> columns) {
+ this.columns = columns;
+ }
+
+
+ @ApiModelProperty(value = "Time to live information")
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ @ApiModelProperty(value = "Time stamp")
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java
new file mode 100644
index 00000000..a58552c6
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonInsert.java
@@ -0,0 +1,122 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model for table vlaues insert")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonInsert implements Serializable {
+ private String keyspaceName;
+ private String tableName;
+ private Map<String, Object> values;
+ private String ttl;
+ private String timestamp;
+ private Map<String, Object> row_specification;
+ private Map<String, String> consistencyInfo;
+
+ @ApiModelProperty(value = "keyspace")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ @ApiModelProperty(value = "Table name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Time to live information")
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ @ApiModelProperty(value = "Time stamp")
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @ApiModelProperty(value = "values returned")
+ public Map<String, Object> getValues() {
+ return values;
+ }
+
+ public void setValues(Map<String, Object> values) {
+ this.values = values;
+ }
+
+ @ApiModelProperty(value = "Information for selecting specific rows for insert")
+ public Map<String, Object> getRow_specification() {
+ return row_specification;
+ }
+
+ public void setRow_specification(Map<String, Object> row_specification) {
+ this.row_specification = row_specification;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bos.toByteArray();
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java
new file mode 100644
index 00000000..54de02fd
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonKeySpace.java
@@ -0,0 +1,77 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model creating new keyspace")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonKeySpace {
+ private String keyspaceName;
+ private Map<String, Object> replicationInfo;
+ private String durabilityOfWrites;
+ private Map<String, String> consistencyInfo;
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Replication information")
+ public Map<String, Object> getReplicationInfo() {
+ return replicationInfo;
+ }
+
+ public void setReplicationInfo(Map<String, Object> replicationInfo) {
+ this.replicationInfo = replicationInfo;
+ }
+
+ @ApiModelProperty(value = "Durability", allowableValues = "true,false")
+ public String getDurabilityOfWrites() {
+ return durabilityOfWrites;
+ }
+
+ public void setDurabilityOfWrites(String durabilityOfWrites) {
+ this.durabilityOfWrites = durabilityOfWrites;
+ }
+
+ @ApiModelProperty(value = "Keyspace name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java
new file mode 100644
index 00000000..497e17d1
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonLeasedLock.java
@@ -0,0 +1,52 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "model for leased lock")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonLeasedLock {
+ long leasePeriod;
+ String notifyUrl;
+
+ @ApiModelProperty(value = "Lease period")
+ public long getLeasePeriod() {
+ return leasePeriod;
+ }
+
+ public void setLeasePeriod(long leasePeriod) {
+ this.leasePeriod = leasePeriod;
+ }
+
+ @ApiModelProperty(value = "URL to be notified")
+ public String getNotifyUrl() {
+ return notifyUrl;
+ }
+
+ public void setNotifyUrl(String notifyUrl) {
+ this.notifyUrl = notifyUrl;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java
new file mode 100755
index 00000000..0bac1e31
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonOnboard.java
@@ -0,0 +1,83 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonOnboard", description = "Defines the Json for Onboarding an application.")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonOnboard {
+ private String appname;
+ private String userId;
+ private String password;
+ private String isAAF;
+ private String aid;
+
+ @ApiModelProperty(value = "Application Password")
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @ApiModelProperty(value = "Application UUID")
+ public String getAid() {
+ return aid;
+ }
+
+ public void setAid(String aid) {
+ this.aid = aid;
+ }
+
+ @ApiModelProperty(value = "Application name")
+ public String getAppname() {
+ return appname;
+ }
+
+ public void setAppname(String appname) {
+ this.appname = appname;
+ }
+
+ @ApiModelProperty(value = "User Id")
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ @ApiModelProperty(value = "Is AAF Application", allowableValues = "true, false")
+ public String getIsAAF() {
+ return isAAF;
+ }
+
+ public void setIsAAF(String isAAF) {
+ this.isAAF = isAAF;
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java
new file mode 100644
index 00000000..64bc3887
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonSelect.java
@@ -0,0 +1,59 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonSelect implements Serializable {
+ private Map<String, String> consistencyInfo;
+
+
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return bos.toByteArray();
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java
new file mode 100644
index 00000000..5d508adb
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonTable.java
@@ -0,0 +1,117 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Defines the Json for Creating a new Table.")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonTable {
+ private String keyspaceName;
+ private String tableName;
+
+ private Map<String, String> fields;
+ private Map<String, Object> properties;
+ private String primaryKey;
+ private String sortingKey;
+ private String clusteringOrder;
+ private Map<String, String> consistencyInfo;
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Properties")
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ @ApiModelProperty(value = "Fields")
+ public Map<String, String> getFields() {
+ return fields;
+ }
+
+ public void setFields(Map<String, String> fields) {
+ this.fields = fields;
+ }
+
+ @ApiModelProperty(value = "KeySpace Name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ @ApiModelProperty(value = "Table Name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @ApiModelProperty(value = "Sorting Key")
+ public String getSortingKey() {
+ return sortingKey;
+ }
+
+ public void setSortingKey(String sortingKey) {
+ this.sortingKey = sortingKey;
+ }
+
+ @ApiModelProperty(value = "Clustering Order", notes = "")
+ public String getClusteringOrder() {
+ return clusteringOrder;
+ }
+
+ public void setClusteringOrder(String clusteringOrder) {
+ this.clusteringOrder = clusteringOrder;
+ }
+
+ @ApiModelProperty(value = "Primary Key")
+ public String getPrimaryKey() {
+ return primaryKey;
+ }
+
+ public void setPrimaryKey(String primaryKey) {
+ this.primaryKey = primaryKey;
+ }
+
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java
new file mode 100644
index 00000000..3ab5ea0d
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/JsonUpdate.java
@@ -0,0 +1,132 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonTable", description = "Json model for table update")
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class JsonUpdate implements Serializable {
+ private String keyspaceName;
+ private String tableName;
+ private Map<String, Object> values;
+ private String ttl, timestamp;
+ private Map<String, String> consistencyInfo;
+ private Map<String, Object> conditions;
+ private Map<String, Object> row_specification;
+
+ @ApiModelProperty(value = "Conditions")
+ public Map<String, Object> getConditions() {
+ return conditions;
+ }
+
+ public void setConditions(Map<String, Object> conditions) {
+ this.conditions = conditions;
+ }
+
+ @ApiModelProperty(value = "Information for selecting sepcific rows")
+ public Map<String, Object> getRow_specification() {
+ return row_specification;
+ }
+
+ public void setRow_specification(Map<String, Object> row_specification) {
+ this.row_specification = row_specification;
+ }
+
+
+ @ApiModelProperty(value = "Keyspace name")
+ public String getKeyspaceName() {
+ return keyspaceName;
+ }
+
+ public void setKeyspaceName(String keyspaceName) {
+ this.keyspaceName = keyspaceName;
+ }
+
+ @ApiModelProperty(value = "Table name")
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @ApiModelProperty(value = "Consistency level", allowableValues = "eventual,critical,atomic")
+ public Map<String, String> getConsistencyInfo() {
+ return consistencyInfo;
+ }
+
+ public void setConsistencyInfo(Map<String, String> consistencyInfo) {
+ this.consistencyInfo = consistencyInfo;
+ }
+
+ @ApiModelProperty(value = "Time to live value")
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ @ApiModelProperty(value = "Time stamp")
+ public String getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(String timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @ApiModelProperty(value = "Column values")
+ public Map<String, Object> getValues() {
+ return values;
+ }
+
+ public void setValues(Map<String, Object> values) {
+ this.values = values;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bos.toByteArray();
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java b/jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java
new file mode 100644
index 00000000..232353c1
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/datastore/jsonobjects/NameSpace.java
@@ -0,0 +1,47 @@
+/*
+ * ============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.datastore.jsonobjects;
+
+import java.util.List;
+
+
+public class NameSpace {
+ private String name;
+ private List<String> admin;
+
+ public List<String> getAdmin() {
+ return admin;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setAdmin(List<String> admin) {
+ this.admin = admin;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java b/jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java
new file mode 100644
index 00000000..1f4abea1
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/eelf/healthcheck/MusicHealthCheck.java
@@ -0,0 +1,175 @@
+/*
+ * ============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.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.mindrot.jbcrypt.BCrypt;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonOnboard;
+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.lockingservice.MusicLockingService;
+import org.onap.music.main.CachingUtil;
+import org.onap.music.main.MusicCore;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.main.ResultType;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.ResultSet;
+
+
+
+
+/**
+ * @author inam
+ *
+ */
+public class MusicHealthCheck {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
+
+ private String cassandrHost;
+ private String zookeeperHost;
+
+
+
+
+
+
+
+
+ public String getCassandraStatus() {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Getting Status for Cassandra");
+ if(this.getAdminKeySpace()) {
+ return "ACTIVE";
+ }else {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Cassandra Service is not responding");
+ return "INACTIVE";
+ }
+ }
+
+
+ private Boolean getAdminKeySpace() {
+
+ String appName = "";
+
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "select * from admin.keyspace_master");
+ //pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ try {
+ ResultSet rs = MusicCore.get(pQuery);
+
+ if(rs != null) {
+ return Boolean.TRUE;
+ }else {
+ return Boolean.FALSE;
+ }
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(),AppMessages.CASSANDRACONNECTIVITY, ErrorTypes.CONNECTIONERROR, ErrorSeverity.CRITICAL);
+ }
+
+ return Boolean.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/jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java b/jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java
new file mode 100644
index 00000000..0c290b6f
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/eelf/logging/EELFLoggerDelegate.java
@@ -0,0 +1,354 @@
+/*
+ * ============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.logging;
+
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.servlet.http.HttpServletRequest;
+import org.slf4j.MDC;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.configuration.SLF4jWrapper;
+
+public class EELFLoggerDelegate extends SLF4jWrapper implements EELFLogger {
+
+ public static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+ public static final EELFLogger applicationLogger =
+ EELFManager.getInstance().getApplicationLogger();
+ public static final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
+ public static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ public static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger();
+
+ private String className;
+ private static ConcurrentMap<String, EELFLoggerDelegate> classMap = new ConcurrentHashMap<>();
+
+ public EELFLoggerDelegate(final String className) {
+ super(className);
+ this.className = className;
+ }
+
+ /**
+ * Convenience method that gets a logger for the specified class.
+ *
+ * @see #getLogger(String)
+ *
+ * @param clazz
+ * @return Instance of EELFLoggerDelegate
+ */
+ public static EELFLoggerDelegate getLogger(Class<?> clazz) {
+ return getLogger(clazz.getName());
+ }
+
+ /**
+ * Gets a logger for the specified class name. If the logger does not already exist in the map,
+ * this creates a new logger.
+ *
+ * @param className If null or empty, uses EELFLoggerDelegate as the class name.
+ * @return Instance of EELFLoggerDelegate
+ */
+ public static EELFLoggerDelegate getLogger(final String className) {
+ String classNameNeverNull = className == null || "".equals(className)
+ ? EELFLoggerDelegate.class.getName()
+ : className;
+ EELFLoggerDelegate delegate = classMap.get(classNameNeverNull);
+ if (delegate == null) {
+ delegate = new EELFLoggerDelegate(className);
+ classMap.put(className, delegate);
+ }
+ return delegate;
+ }
+
+ /**
+ * Logs a message at the lowest level: trace.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void trace(EELFLogger logger, String msg) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(msg);
+ }
+ }
+
+ /**
+ * Logs a message with parameters at the lowest level: trace.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void trace(EELFLogger logger, String msg, Object... arguments) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(msg, arguments);
+ }
+ }
+
+ /**
+ * Logs a message and throwable at the lowest level: trace.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void trace(EELFLogger logger, String msg, Throwable th) {
+ if (logger.isTraceEnabled()) {
+ logger.trace(msg, th);
+ }
+ }
+
+ /**
+ * Logs a message at the second-lowest level: debug.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void debug(EELFLogger logger, String msg) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg);
+ }
+ }
+
+ /**
+ * Logs a message with parameters at the second-lowest level: debug.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void debug(EELFLogger logger, String msg, Object... arguments) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg, arguments);
+ }
+ }
+
+ /**
+ * Logs a message and throwable at the second-lowest level: debug.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void debug(EELFLogger logger, String msg, Throwable th) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(msg, th);
+ }
+ }
+
+ /**
+ * Logs a message at info level.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void info(EELFLogger logger, String msg) {
+ logger.info(className + " - "+msg);
+ }
+
+ /**
+ * Logs a message with parameters at info level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void info(EELFLogger logger, String msg, Object... arguments) {
+ logger.info(msg, arguments);
+ }
+
+ /**
+ * Logs a message and throwable at info level.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void info(EELFLogger logger, String msg, Throwable th) {
+ logger.info(msg, th);
+ }
+
+ /**
+ * Logs a message at warn level.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void warn(EELFLogger logger, String msg) {
+ logger.warn(msg);
+ }
+
+ /**
+ * Logs a message with parameters at warn level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void warn(EELFLogger logger, String msg, Object... arguments) {
+ logger.warn(msg, arguments);
+ }
+
+ /**
+ * Logs a message and throwable at warn level.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void warn(EELFLogger logger, String msg, Throwable th) {
+ logger.warn(msg, th);
+ }
+
+ /**
+ * Logs a message at error level.
+ *
+ * @param logger
+ * @param msg
+ */
+ public void error(EELFLogger logger, String msg) {
+ logger.error(className+ " - " + msg);
+ }
+
+ /**
+ * Logs a message with parameters at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param arguments
+ */
+ public void error(EELFLogger logger, String msg, Object... arguments) {
+ logger.warn(msg, arguments);
+ }
+
+ /**
+ * Logs a message and throwable at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param th
+ */
+ public void error(EELFLogger logger, String msg, Throwable th) {
+ logger.warn(msg, th);
+ }
+
+ /**
+ * Logs a message with the associated alarm severity at error level.
+ *
+ * @param logger
+ * @param msg
+ * @param severtiy
+ */
+ public void error(EELFLogger logger, String msg, Object /* AlarmSeverityEnum */ severtiy) {
+ logger.error(msg);
+ }
+
+ /**
+ * Initializes the logger context.
+ */
+ public void init() {
+ setGlobalLoggingContext();
+ final String msg =
+ "############################ Logging is started. ############################";
+ // These loggers emit the current date-time without being told.
+ info(applicationLogger, msg);
+ error(errorLogger, msg);
+ debug(debugLogger, msg);
+ info(auditLogger, msg);
+ info(metricsLogger, msg);
+ }
+
+ /**
+ * Builds a message using a template string and the arguments.
+ *
+ * @param message
+ * @param args
+ * @return
+ */
+ private String formatMessage(String message, Object... args) {
+ StringBuilder sbFormattedMessage = new StringBuilder();
+ if (args != null && args.length > 0 && message != null && message != "") {
+ MessageFormat mf = new MessageFormat(message);
+ sbFormattedMessage.append(mf.format(args));
+ } else {
+ sbFormattedMessage.append(message);
+ }
+
+ return sbFormattedMessage.toString();
+ }
+
+ /**
+ * Loads all the default logging fields into the MDC context.
+ */
+ private void setGlobalLoggingContext() {
+ MDC.put(MDC_SERVICE_INSTANCE_ID, "");
+ try {
+ MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName());
+ MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+ } catch (Exception e) {
+ errorLogger.error("setGlobalLoggingContext failed", e);
+ }
+ }
+
+ public static void mdcPut(String key, String value) {
+ MDC.put(key, value);
+ }
+
+ public static String mdcGet(String key) {
+ return MDC.get(key);
+ }
+
+ public static void mdcRemove(String key) {
+ MDC.remove(key);
+ }
+
+ /**
+ * Loads the RequestId/TransactionId into the MDC which it should be receiving with an each
+ * incoming REST API request. Also, configures few other request based logging fields into the
+ * MDC context.
+ *
+ * @param req
+ * @param appName
+ */
+ public void setRequestBasedDefaultsIntoGlobalLoggingContext(HttpServletRequest req,
+ String appName) {
+ // Load the default fields
+ setGlobalLoggingContext();
+
+ // Load the request based fields
+ if (req != null) {
+ // Rest Path
+ MDC.put(MDC_SERVICE_NAME, req.getServletPath());
+
+ // Client IPAddress i.e. IPAddress of the remote host who is making
+ // this request.
+ String clientIPAddress = req.getHeader("X-FORWARDED-FOR");
+ if (clientIPAddress == null) {
+ clientIPAddress = req.getRemoteAddr();
+ }
+ }
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java b/jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java
new file mode 100644
index 00000000..2c7952b2
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/eelf/logging/format/AppMessages.java
@@ -0,0 +1,183 @@
+/*
+ * ============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.logging.format;
+
+/**
+ * @author inam
+ *
+ */
+public enum AppMessages {
+
+
+
+ /*
+ * 100-199 Security/Permission Related - Authentication problems
+ * [ERR100E] Missing Information
+ * [ERR101E] Authentication error occured
+ *
+ * 200-299 Availability/Timeout Related/IO - connectivity error - connection timeout
+ * [ERR200E] Connectivity
+ * [ERR201E] Host not available
+ * [ERR202E] Error while connecting to Cassandra cluster
+ * [ERR203E] IO Error has occured
+ * [ERR204E] Execution Interrupted
+ * [ERR205E] Session Expired
+ * [ERR206E] Cache not authenticated
+ *
+ *
+ * 300-399 Data Access/Integrity Related
+ * [ERR300E] Incorrect data
+ *
+ * 400-499 - Cassandra Query Related
+ * [ERR400E] Error while processing prepared query object
+ * [ERR401E] Executing Session Failure for Request
+ * [ERR402E] Ill formed queryObject for the request
+ * [ERR403E] Error processing Prepared Query Object
+ *
+ * 500-599 - Zookeepr/Locking Related
+ * [ERR500E] Invalid lock
+ * [ERR501E] Locking Error has occured
+ * [ERR502E] Zookeeper error has occured
+ * [ERR503E] Failed to aquire lock store handle
+ * [ERR504E] Failed to create Lock Reference
+ * [ERR505E] Lock does not exist
+ * [ERR506E] Failed to aquire lock
+ * [ERR507E] Lock not aquired
+ * [ERR508E] Lock state not set
+ * [ERR509E] Lock not destroyed
+ * [ERR510E] Lock not released
+ * [ERR511E] Lock not deleted
+ * [ERR512E] Failed to get ZK Lock Handle
+ *
+ *
+ * 600 - 699 - Music Service Errors
+ * [ERR600E] Error initializing the cache
+ *
+ * 700-799 Schema Interface Type/Validation - received Pay-load checksum is
+ * invalid - received JSON is not valid
+ *
+ * 800-899 Business/Flow Processing Related - check out to service is not
+ * allowed - Roll-back is done - failed to generate heat file
+ *
+ *
+ * 900-999 Unknown Errors - Unexpected exception
+ * [ERR900E] Unexpected error occured
+ * [ERR901E] Number format exception
+ *
+ *
+ * 1000-1099 Reserved - do not use
+ *
+ */
+
+
+
+
+ MISSINGINFO("[ERR100E]", "Missing Information ","Details: NA", "Please check application credentials and/or headers"),
+ AUTHENTICATIONERROR("[ERR101E]", "Authentication error occured ","Details: NA", "Please verify application credentials"),
+ CONNCECTIVITYERROR("[ERR200E]"," Connectivity error","Details: NA ","Please check connectivity to external resources"),
+ HOSTUNAVAILABLE("[ERR201E]","Host not available","Details: NA","Please verify the host details"),
+ CASSANDRACONNECTIVITY("[ERR202E]","Error while connecting to Cassandra cluster",""," Please check cassandra cluster details"),
+ IOERROR("[ERR203E]","IO Error has occured","","Please check IO"),
+ EXECUTIONINTERRUPTED("[ERR204E]"," Execution Interrupted","",""),
+ SESSIONEXPIRED("[ERR205E]"," Session Expired","","Session has expired."),
+ CACHEAUTHENTICATION("[ERR206E]","Cache not authenticated",""," Cache not authenticated"),
+
+ INCORRECTDATA("[ERR300E]"," Incorrect data",""," Please verify the request payload and try again"),
+ MULTIPLERECORDS("[ERR301E]"," Multiple records found",""," Please verify the request payload and try again"),
+ ALREADYEXIST("[ERR302E]"," Record already exist",""," Please verify the request payload and try again"),
+ MISSINGDATA("[ERR300E]"," Incorrect data",""," Please verify the request payload and try again"),
+
+ QUERYERROR("[ERR400E]","Error while processing prepared query object",""," Please verify the query"),
+ SESSIONFAILED("[ERR401E]","Executing Session Failure for Request","","Please verify the session and request"),
+
+ INVALIDLOCK("[ERR500E]"," Invalid lock or acquire failed",""," Lock is not valid to aquire"),
+ LOCKINGERROR("[ERR501E]"," Locking Error has occured",""," Locking Error has occured"),
+ KEEPERERROR("[ERR502E]"," Zookeeper error has occured","","Please check zookeeper details"),
+ LOCKHANDLE("[ERR503E]","Failed to aquire lock store handle",""," Failed to aquire lock store handle"),
+ CREATELOCK("[ERR504E]","Failed to aquire lock store handle ","","Failed to aquire lock store handle "),
+ LOCKSTATE("[ERR508E]"," Lock state not set",""," Lock state not set"),
+ DESTROYLOCK("[ERR509E]"," Lock not destroyed",""," Lock not destroyed"),
+ RELEASELOCK("[ERR510E]"," Lock not released",""," Lock not released"),
+ DELTELOCK("[ERR511E]",""," Lock not deleted "," Lock not deleted "),
+ CACHEERROR("[ERR600E]"," Error initializing the cache",""," Error initializing the cache"),
+
+ UNKNOWNERROR("[ERR900E]"," Unexpected error occured",""," Please check logs for details");
+
+
+
+ ErrorTypes eType;
+ ErrorSeverity alarmSeverity;
+ ErrorSeverity errorSeverity;
+ String errorCode;
+ String errorDescription;
+ String details;
+ String resolution;
+
+
+ AppMessages(String errorCode, String errorDescription, String details,String resolution) {
+
+ this.errorCode = errorCode;
+ this.errorDescription = errorDescription;
+ this.details = details;
+ this.resolution = resolution;
+ }
+
+
+
+
+ AppMessages(ErrorTypes eType, ErrorSeverity alarmSeverity,
+ ErrorSeverity errorSeverity, String errorCode, String errorDescription, String details,
+ String resolution) {
+
+ this.eType = eType;
+ this.alarmSeverity = alarmSeverity;
+ this.errorSeverity = errorSeverity;
+ this.errorCode = errorCode;
+ this.errorDescription = errorDescription;
+ this.details = details;
+ this.resolution = resolution;
+ }
+
+ public String getDetails() {
+ return this.details;
+ }
+
+ public String getResolution() {
+ return this.resolution;
+ }
+
+ public String getErrorCode() {
+ return this.errorCode;
+ }
+
+ public String getErrorDescription() {
+ return this.errorDescription;
+ }
+
+
+
+
+
+
+
+}
diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java
new file mode 100644
index 00000000..b18c1771
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorCodes.java
@@ -0,0 +1,106 @@
+/*
+ * ============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.logging.format;
+
+
+
+/**
+ * @author inam
+ *
+ */
+public enum ErrorCodes {
+
+
+ /*
+ * 100-199 Security/Permission Related - Authentication problems
+ * [ERR100E] Missing Information
+ * [ERR101E] Authentication error occured
+ *
+ * 200-299 Availability/Timeout Related/IO - connectivity error - connection timeout
+ * [ERR200E] Connectivity
+ * [ERR201E] Host not available
+ * [ERR202E] Error while connecting to Cassandra cluster
+ * [ERR203E] IO Error has occured
+ * [ERR204E] Execution Interrupted
+ * [ERR205E] Session Expired
+ * [ERR206E] Cache not authenticated
+ *
+ *
+ * 300-399 Data Access/Integrity Related
+ *
+ * 400-499 - Cassandra Query Related
+ * [ERR400E] Error while processing prepared query object
+ * [ERR401E] Executing Session Failure for Request
+ * [ERR402E] Ill formed queryObject for the request
+ * [ERR403E] Error processing Prepared Query Object
+ *
+ * 500-599 - Zookeepr/Locking Related
+ * [ERR500E] Invalid lock
+ * [ERR501E] Locking Error has occured
+ * [ERR502E] Zookeeper error has occured
+ * [ERR503E] Failed to aquire lock store handle
+ * [ERR504E] Failed to create Lock Reference
+ * [ERR505E] Lock does not exist
+ * [ERR506E] Failed to aquire lock
+ * [ERR507E] Lock not aquired
+ * [ERR508E] Lock state not set
+ * [ERR509E] Lock not destroyed
+ * [ERR510E] Lock not released
+ * [ERR511E] Lock not deleted
+ * [ERR512E] Failed to get ZK Lock Handle
+ *
+ *
+ * 600 - 699 - Music Service Errors
+ * [ERR600E] Error initializing the cache
+ *
+ * 700-799 Schema Interface Type/Validation - received Pay-load checksum is
+ * invalid - received JSON is not valid
+ *
+ * 800-899 Business/Flow Processing Related - check out to service is not
+ * allowed - Roll-back is done - failed to generate heat file
+ *
+ *
+ * 900-999 Unknown Errors - Unexpected exception
+ * [ERR900E] Unexpected error occured
+ * [ERR901E] Number format exception
+ *
+ *
+ * 1000-1099 Reserved - do not use
+ *
+ */
+
+ /*SUCCESS("Success"), FAILURE("Failure");
+
+ private String result;
+
+ ResultType(String result) {
+ this.result = result;
+ }
+
+ public String getResult() {
+ return result;
+ }
+*/
+
+
+
+}
diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java
new file mode 100644
index 00000000..cda5dd31
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorSeverity.java
@@ -0,0 +1,37 @@
+/*
+ * ============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.logging.format;
+
+/**
+ * @author inam
+ *
+ */
+public enum ErrorSeverity {
+ INFO,
+ WARN,
+ ERROR,
+ FATAL,
+ CRITICAL,
+ MAJOR,
+ MINOR,
+ NONE,
+}
diff --git a/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java
new file mode 100644
index 00000000..2536f4a4
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/eelf/logging/format/ErrorTypes.java
@@ -0,0 +1,44 @@
+/*
+ * ============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.logging.format;
+
+import com.att.eelf.i18n.EELFResolvableErrorEnum;
+
+/**
+ * @author inam
+ *
+ */
+public enum ErrorTypes implements EELFResolvableErrorEnum {
+
+
+ CONNECTIONERROR,
+ SESSIONEXPIRED,
+ AUTHENTICATIONERROR,
+ SERVICEUNAVAILABLE,
+ QUERYERROR,
+ DATAERROR,
+ GENERALSERVICEERROR,
+ MUSICSERVICEERROR,
+ LOCKINGERROR,
+ UNKNOWN,
+
+}
diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java b/jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java
new file mode 100644
index 00000000..14a23d1f
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/exceptions/MusicExceptionMapper.java
@@ -0,0 +1,53 @@
+/*
+ * ============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.exceptions;
+
+import java.io.EOFException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import org.codehaus.jackson.map.exc.UnrecognizedPropertyException;
+import org.onap.music.main.ResultType;
+import org.onap.music.response.jsonobjects.JsonResponse;
+
+@Provider
+public class MusicExceptionMapper implements ExceptionMapper<Exception> {
+ @Override
+ public Response toResponse(Exception exception) {
+ if(exception instanceof UnrecognizedPropertyException) {
+ return Response.status(Response.Status.BAD_REQUEST).
+ entity(new JsonResponse(ResultType.FAILURE).setError("Unknown field :"+((UnrecognizedPropertyException) exception).getUnrecognizedPropertyName()).toMap()).
+ build();
+ }
+ else if(exception instanceof EOFException) {
+ return Response.status(Response.Status.BAD_REQUEST).
+ entity(new JsonResponse(ResultType.FAILURE).setError("Request body cannot be empty").toMap()).
+ build();
+ }
+ else {
+ return Response.status(Response.Status.BAD_REQUEST).
+ entity(new JsonResponse(ResultType.FAILURE).setError(exception.getMessage()).toMap()).
+ build();
+ }
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java b/jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java
new file mode 100644
index 00000000..1a9e45d9
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/exceptions/MusicLockingException.java
@@ -0,0 +1,74 @@
+/*
+ * ============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.exceptions;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicLockingException extends Exception {
+
+ /**
+ *
+ */
+ public MusicLockingException() {
+
+ }
+
+ /**
+ * @param message
+ */
+ public MusicLockingException(String message) {
+ super(message);
+
+ }
+
+ /**
+ * @param cause
+ */
+ public MusicLockingException(Throwable cause) {
+ super(cause);
+
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MusicLockingException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+ /**
+ * @param message
+ * @param cause
+ * @param enableSuppression
+ * @param writableStackTrace
+ */
+ public MusicLockingException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java b/jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java
new file mode 100644
index 00000000..bade21a4
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/exceptions/MusicPolicyVoilationException.java
@@ -0,0 +1,79 @@
+/*
+ * ============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.exceptions;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicPolicyVoilationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ *
+ */
+ public MusicPolicyVoilationException() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param message
+ */
+ public MusicPolicyVoilationException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param cause
+ */
+ public MusicPolicyVoilationException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MusicPolicyVoilationException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param message
+ * @param cause
+ * @param enableSuppression
+ * @param writableStackTrace
+ */
+ public MusicPolicyVoilationException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java b/jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java
new file mode 100644
index 00000000..24b8568b
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/exceptions/MusicQueryException.java
@@ -0,0 +1,89 @@
+/*
+ * ============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.exceptions;
+
+
+
+/**
+ * @author inam
+ *
+ */
+public class MusicQueryException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private int errorCode;
+
+
+ /**
+ *
+ */
+ public MusicQueryException() {
+ super();
+ }
+
+ /**
+ * @param message
+ */
+ public MusicQueryException(String message) {
+ super(message);
+ }
+
+
+
+ /**
+ * @param message
+ */
+ public MusicQueryException(String message, int errorCode) {
+ super(message);
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * @param cause
+ */
+ public MusicQueryException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public MusicQueryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * @param message
+ * @param cause
+ * @param enableSuppression
+ * @param writableStackTrace
+ */
+ public MusicQueryException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java b/jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java
new file mode 100644
index 00000000..a3b1fc56
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/exceptions/MusicServiceException.java
@@ -0,0 +1,84 @@
+/*
+ * ============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.exceptions;
+
+/**
+ * @author inam
+ *
+ */
+public class MusicServiceException extends Exception {
+
+
+ private int errorCode;
+ private String errorMessage;
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+
+ public MusicServiceException() {
+ super();
+ }
+
+
+ public MusicServiceException(String message) {
+ super(message);
+
+ }
+
+
+ public MusicServiceException(Throwable cause) {
+ super(cause);
+
+ }
+
+
+ public MusicServiceException(String message, Throwable cause) {
+ super(message, cause);
+
+ }
+
+
+ public MusicServiceException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/lockingservice/LockListener.java b/jar/src/main/java/org/onap/music/lockingservice/LockListener.java
new file mode 100644
index 00000000..33188e60
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/LockListener.java
@@ -0,0 +1,39 @@
+/*
+ * ============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.lockingservice;
+
+/**
+ * This class has two methods which are call back methods when a lock is acquired and when the lock
+ * is released.
+ *
+ */
+public interface LockListener {
+ /**
+ * call back called when the lock is acquired
+ */
+ public void lockAcquired();
+
+ /**
+ * call back called when the lock is released.
+ */
+ public void lockReleased();
+}
diff --git a/jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java b/jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java
new file mode 100644
index 00000000..6c31410f
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/MusicLockState.java
@@ -0,0 +1,137 @@
+/*
+ * ============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.lockingservice;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+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;
+
+// the state variable that will be stored in zookeeper, capturing the transitions of
+public class MusicLockState implements Serializable {
+ public enum LockStatus {
+ UNLOCKED, BEING_LOCKED, LOCKED
+ };// captures the state of the lock
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicLockState.class);
+ LockStatus lockStatus;
+ boolean needToSyncQuorum = false;
+ String lockHolder;
+ long leasePeriod = Long.MAX_VALUE, leaseStartTime = -1;
+
+ private String errorMessage = null;
+
+ public MusicLockState(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public MusicLockState(LockStatus lockStatus, String lockHolder) {
+ this.lockStatus = lockStatus;
+ this.lockHolder = lockHolder;
+ }
+
+ public MusicLockState(LockStatus lockStatus, String lockHolder, boolean needToSyncQuorum) {
+ this.lockStatus = lockStatus;
+ this.lockHolder = lockHolder;
+ this.needToSyncQuorum = needToSyncQuorum;
+ }
+
+
+ public long getLeasePeriod() {
+ return leasePeriod;
+ }
+
+ public boolean isNeedToSyncQuorum() {
+ return needToSyncQuorum;
+ }
+
+
+
+ public void setLeasePeriod(long leasePeriod) {
+ this.leasePeriod = leasePeriod;
+ }
+
+
+ public long getLeaseStartTime() {
+ return leaseStartTime;
+ }
+
+
+ public void setLeaseStartTime(long leaseStartTime) {
+ this.leaseStartTime = leaseStartTime;
+ }
+
+
+
+ public LockStatus getLockStatus() {
+ return lockStatus;
+ }
+
+ public void setLockStatus(LockStatus lockStatus) {
+ this.lockStatus = lockStatus;
+ }
+
+ public String getLockHolder() {
+ return lockHolder;
+ }
+
+ public void setLockHolder(String lockHolder) {
+ this.lockHolder = lockHolder;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public byte[] serialize() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = null;
+ try {
+ out = new ObjectOutputStream(bos);
+ out.writeObject(this);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR);
+ }
+ return bos.toByteArray();
+ }
+
+ public static MusicLockState deSerialize(byte[] data) {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ Object o = null;
+ ObjectInput in = null;
+ try {
+ in = new ObjectInputStream(bis);
+ o = in.readObject();
+ } catch (ClassNotFoundException | IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.UNKNOWN);
+ }
+ return (MusicLockState) o;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java b/jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java
new file mode 100644
index 00000000..4070238a
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/MusicLockingService.java
@@ -0,0 +1,184 @@
+/*
+ * ============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.lockingservice;
+
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooKeeper;
+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.main.MusicUtil;
+import java.util.concurrent.TimeUnit;
+
+
+public class MusicLockingService implements Watcher {
+
+
+ private static final int SESSION_TIMEOUT = 180000;
+ ZkStatelessLockService zkLockHandle = null;
+ private CountDownLatch connectedSignal = new CountDownLatch(1);
+ private static EELFLoggerDelegate logger =
+ EELFLoggerDelegate.getLogger(MusicLockingService.class);
+
+ public MusicLockingService() throws MusicServiceException {
+ try {
+ ZooKeeper zk = new ZooKeeper(MusicUtil.getMyZkHost(), SESSION_TIMEOUT, this);
+ connectedSignal.await();
+ zkLockHandle = new ZkStatelessLockService(zk);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR);
+ throw new MusicServiceException("IO Error has occured" + e.getMessage());
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ throw new MusicServiceException("Exception Occured " + e.getMessage());
+ }
+ }
+
+ public MusicLockingService(int timeout) throws MusicServiceException {
+ CountDownLatch connectedSignal1 = new CountDownLatch(1);
+ try {
+ ZooKeeper zk1 = new ZooKeeper(MusicUtil.getMyZkHost(), SESSION_TIMEOUT, this);
+ connectedSignal1.await(timeout, TimeUnit.SECONDS);
+ if(!zk1.getState().isConnected()) {
+ throw new MusicServiceException("Unable to Connect. Some nodes are down.");
+ }
+ } catch (IOException e ) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR);
+ throw new MusicServiceException("IO Error has occured" + e.getMessage());
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ throw new MusicServiceException("Exception Occured " + e.getMessage());
+ }
+ }
+
+ public ZkStatelessLockService getzkLockHandle() {
+ return zkLockHandle;
+ }
+
+ public MusicLockingService(String lockServer) {
+ try {
+ ZooKeeper zk = new ZooKeeper(lockServer, SESSION_TIMEOUT, this);
+ connectedSignal.await();
+ zkLockHandle = new ZkStatelessLockService(zk);
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.IOERROR, ErrorSeverity.ERROR, ErrorTypes.CONNECTIONERROR);
+ }catch( InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch(Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ }
+
+ public void createLockaIfItDoesNotExist(String lockName) {
+ if (!zkLockHandle.checkIfLockExists(lockName)) {
+ String lockHolder = null;
+ MusicLockState ml = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
+ byte[] data = ml.serialize();
+ zkLockHandle.createLock(lockName, data);
+ }
+ }
+
+ public void setLockState(String lockName, MusicLockState mls) {
+ byte[] data = mls.serialize();
+ zkLockHandle.setNodeData(lockName, data);
+ }
+
+ public MusicLockState getLockState(String lockName) throws MusicLockingException {
+
+ byte[] data = null;
+ try{
+ data = zkLockHandle.getNodeData(lockName);
+ }catch (Exception ex){
+ logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ if(data !=null)
+ return MusicLockState.deSerialize(data);
+ else {
+ logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.INVALIDLOCK, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ throw new MusicLockingException("Invalid lock or acquire failed");
+ }
+ }
+
+ public String createLockId(String lockName) {
+ String lockIdWithSlash = zkLockHandle.createLockId(lockName);
+ return lockIdWithSlash.replace('/', '$');
+ }
+
+ public boolean isMyTurn(String lockIdWithDollar) {
+ String lockId = lockIdWithDollar.replace('$', '/');
+ StringTokenizer st = new StringTokenizer(lockId);
+ String lockName = "/" + st.nextToken("/");
+ try {
+ return zkLockHandle.lock(lockName, lockId);
+ } catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.LOCKINGERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch( InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch(Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ return false;
+ }
+
+ public void unlockAndDeleteId(String lockIdWithDollar) throws KeeperException.NoNodeException {
+ String lockId = lockIdWithDollar.replace('$', '/');
+ zkLockHandle.unlock(lockId);
+ }
+
+ public void deleteLock(String lockName) throws MusicLockingException {
+ if(lockIdExists(lockName))
+ zkLockHandle.deleteLock(lockName);
+ else{
+ throw new MusicLockingException("Lock does not exist.Please check the lock: " + lockName + " and try again");
+ }
+ }
+
+ public String whoseTurnIsIt(String lockName) {
+ String lockHolder = zkLockHandle.currentLockHolder(lockName);
+ return lockHolder.replace('/', '$');
+
+ }
+
+ public void process(WatchedEvent event) { // Watcher interface
+ if (event.getState() == KeeperState.SyncConnected) {
+ connectedSignal.countDown();
+ }
+ }
+
+
+ public void close() {
+ zkLockHandle.close();
+ }
+
+ public boolean lockIdExists(String lockIdWithDollar) {
+ String lockId = lockIdWithDollar.replace('$', '/');
+ return zkLockHandle.checkIfLockExists(lockId);
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java b/jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java
new file mode 100644
index 00000000..4082b3b8
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/ProtocolSupport.java
@@ -0,0 +1,208 @@
+/*
+ * ============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.lockingservice;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+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.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.lockingservice.ZooKeeperOperation;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A base class for protocol implementations which provides a number of higher level helper methods
+ * for working with ZooKeeper along with retrying synchronous operations if the connection to
+ * ZooKeeper closes such as {@link #retryOperation(ZooKeeperOperation)}
+ *
+ */
+class ProtocolSupport {
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ProtocolSupport.class);
+
+ protected ZooKeeper zookeeper;
+ private AtomicBoolean closed = new AtomicBoolean(false);
+ private long retryDelay = 500L;
+ private int retryCount = 10;
+ private List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;
+
+ /**
+ * Closes this strategy and releases any ZooKeeper resources; but keeps the ZooKeeper instance
+ * open
+ */
+ public void close() {
+ if (closed.compareAndSet(false, true)) {
+ doClose();
+ }
+ }
+
+ /**
+ * return zookeeper client instance
+ *
+ * @return zookeeper client instance
+ */
+ public ZooKeeper getZookeeper() {
+ return zookeeper;
+ }
+
+ /**
+ * return the acl its using
+ *
+ * @return the acl.
+ */
+ public List<ACL> getAcl() {
+ return acl;
+ }
+
+ /**
+ * set the acl
+ *
+ * @param acl the acl to set to
+ */
+ public void setAcl(List<ACL> acl) {
+ this.acl = acl;
+ }
+
+ /**
+ * get the retry delay in milliseconds
+ *
+ * @return the retry delay
+ */
+ public long getRetryDelay() {
+ return retryDelay;
+ }
+
+ /**
+ * Sets the time waited between retry delays
+ *
+ * @param retryDelay the retry delay
+ */
+ public void setRetryDelay(long retryDelay) {
+ this.retryDelay = retryDelay;
+ }
+
+ /**
+ * Allow derived classes to perform some custom closing operations to release resources
+ */
+ protected void doClose() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ /**
+ * Perform the given operation, retrying if the connection fails
+ *
+ * @return object. it needs to be cast to the callee's expected return type.
+ * @param operation FILL IN
+ * @throws KeeperException FILL IN
+ * @throws InterruptedException FILL IN
+ */
+ protected Object retryOperation(ZooKeeperOperation operation)
+ throws KeeperException, InterruptedException {
+ KeeperException exception = null;
+ for (int i = 0; i < retryCount; i++) {
+ try {
+ return operation.execute();
+ } catch (KeeperException.SessionExpiredException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.SESSIONEXPIRED+" for: " + zookeeper + " so reconnecting due to: " + e, ErrorSeverity.ERROR, ErrorTypes.SESSIONEXPIRED);
+ throw e;
+ } catch (KeeperException.ConnectionLossException e) {
+ if (exception == null) {
+ exception = e;
+ }
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.CONNCECTIVITYERROR, ErrorSeverity.ERROR, ErrorTypes.SESSIONEXPIRED);
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Attempt " + i + " failed with connection loss so attempting to reconnect: " + e);
+
+ retryDelay(i);
+ }
+ }
+ throw exception;
+ }
+
+ /**
+ * Ensures that the given path exists with no data, the current ACL and no flags
+ *
+ * @param path the lock path
+ */
+ protected void ensurePathExists(String path) {
+ ensureExists(path, null, acl, CreateMode.PERSISTENT);
+ }
+
+ /**
+ * Ensures that the given path exists with the given data, ACL and flags
+ *
+ * @param path the lock path
+ * @param data the data
+ * @param acl list of ACLs applying to the path
+ * @param flags create mode flags
+ */
+ protected void ensureExists(final String path, final byte[] data, final List<ACL> acl,
+ final CreateMode flags) {
+ try {
+ retryOperation(new ZooKeeperOperation() {
+ public boolean execute() throws KeeperException, InterruptedException {
+ Stat stat = zookeeper.exists(path, false);
+ if (stat != null) {
+ return true;
+ }
+ zookeeper.create(path, data, acl, flags);
+ return true;
+ }
+ });
+ } catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ }
+
+ /**
+ * Returns true if this protocol has been closed
+ *
+ * @return true if this protocol is closed
+ */
+ protected boolean isClosed() {
+ return closed.get();
+ }
+
+ /**
+ * Performs a retry delay if this is not the first attempt
+ *
+ * @param attemptCount the number of the attempts performed so far
+ */
+ protected void retryDelay(int attemptCount) {
+ if (attemptCount > 0) {
+ try {
+ Thread.sleep(attemptCount * retryDelay);
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR);
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Thread failed to sleep: " + e);
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java b/jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java
new file mode 100644
index 00000000..0c190f14
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/ZNodeName.java
@@ -0,0 +1,118 @@
+/*
+ * ============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.lockingservice;
+
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+import org.onap.music.eelf.logging.format.ErrorSeverity;
+import org.onap.music.eelf.logging.format.ErrorTypes;
+
+/**
+ * Represents an ephemeral znode name which has an ordered sequence number and can be sorted in
+ * order
+ *
+ */
+class ZNodeName implements Comparable<ZNodeName> {
+ private final String name;
+ private String prefix;
+ private int sequence = -1;
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ZNodeName.class);
+
+ public ZNodeName(String name) {
+ if (name == null) {
+ throw new NullPointerException("id cannot be null");
+ }
+ this.name = name;
+ this.prefix = name;
+ int idx = name.lastIndexOf('-');
+ if (idx >= 0) {
+ this.prefix = name.substring(0, idx);
+ try {
+ this.sequence = Integer.parseInt(name.substring(idx + 1));
+ // If an exception occurred we misdetected a sequence suffix,
+ // so return -1.
+ } catch (NumberFormatException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Number format exception "+idx, ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Array out of bounds for "+idx, ErrorSeverity.ERROR, ErrorTypes.GENERALSERVICEERROR);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return name.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ ZNodeName sequence = (ZNodeName) o;
+
+ if (!name.equals(sequence.name))
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode() + 37;
+ }
+
+ public int compareTo(ZNodeName that) {
+ int answer = this.prefix.compareTo(that.prefix);
+ if (answer == 0) {
+ int s1 = this.sequence;
+ int s2 = that.sequence;
+ if (s1 == -1 && s2 == -1) {
+ return this.name.compareTo(that.name);
+ }
+ answer = s1 == -1 ? 1 : s2 == -1 ? -1 : s1 - s2;
+ }
+ return answer;
+ }
+
+ /**
+ * Returns the name of the znode
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the sequence number
+ */
+ public int getZNodeName() {
+ return sequence;
+ }
+
+ /**
+ * Returns the text prefix before the sequence number
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java b/jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java
new file mode 100644
index 00000000..e99df255
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/ZkStatelessLockService.java
@@ -0,0 +1,339 @@
+/*
+ * ============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.lockingservice;
+
+
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NoNodeException;
+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.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;
+
+/**
+ * A <a href="package.html">protocol to implement an exclusive write lock or to elect a leader</a>.
+ * <p/>
+ * You invoke {@link #lock()} to start the process of grabbing the lock; you may get the lock then
+ * or it may be some time later.
+ * <p/>
+ * You can register a listener so that you are invoked when you get the lock; otherwise you can ask
+ * if you have the lock by calling {@link #isOwner()}
+ *
+ */
+public class ZkStatelessLockService extends ProtocolSupport {
+ public ZkStatelessLockService(ZooKeeper zk) {
+ zookeeper = zk;
+ }
+
+ private static EELFLoggerDelegate logger =
+ EELFLoggerDelegate.getLogger(ZkStatelessLockService.class);
+
+ protected void createLock(final String path, final byte[] data) {
+ final List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;
+ try {
+ retryOperation(new ZooKeeperOperation() {
+ public boolean execute() throws KeeperException, InterruptedException {
+ zookeeper.create(path, data, acl, CreateMode.PERSISTENT);
+ return true;
+ }
+ });
+ }catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ }
+
+ public void close() {
+ try {
+ zookeeper.close();
+ }catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ }
+
+ public void setNodeData(final String lockName, final byte[] data) {
+ try {
+ retryOperation(new ZooKeeperOperation() {
+ public boolean execute() throws KeeperException, InterruptedException {
+ zookeeper.getSessionId();
+ zookeeper.setData("/" + lockName, data, -1);
+ return true;
+ }
+ });
+ }catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+
+ }
+
+ public byte[] getNodeData(final String lockName) {
+ try {
+ if (zookeeper.exists("/" + lockName, null) != null)
+ return zookeeper.getData("/" + lockName, false, null);
+ else
+ return null;
+
+ }catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ return null;
+ }
+
+ public boolean checkIfLockExists(String lockName) {
+ boolean result = false;
+ try {
+ Stat stat = zookeeper.exists(lockName, false);
+ if (stat != null) {
+ result = true;
+ }
+ }catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ return result;
+ }
+
+ public void createNode(String nodeName) {
+ ensurePathExists(nodeName);
+ }
+
+ public String createLockId(String dir) {
+ ensurePathExists(dir);
+ LockZooKeeperOperation zop = new LockZooKeeperOperation(dir);
+ try {
+ retryOperation(zop);
+ }catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ }
+ return zop.getId();
+ }
+
+ /**
+ * Attempts to acquire the exclusive write lock returning whether or not it was acquired. Note
+ * that the exclusive lock may be acquired some time later after this method has been invoked
+ * due to the current lock owner going away.
+ */
+ public synchronized boolean lock(String dir, String lockId)
+ throws KeeperException, InterruptedException {
+ if (isClosed()) {
+ return false;
+ }
+ LockZooKeeperOperation zop = new LockZooKeeperOperation(dir, lockId);
+ return (Boolean) retryOperation(zop);
+ }
+
+ /**
+ * Removes the lock or associated znode if you no longer require the lock. this also removes
+ * your request in the queue for locking in case you do not already hold the lock.
+ *
+ * @throws RuntimeException throws a runtime exception if it cannot connect to zookeeper.
+ * @throws NoNodeException
+ */
+ public synchronized void unlock(String lockId) throws RuntimeException, KeeperException.NoNodeException {
+ final String id = lockId;
+ if (!isClosed() && id != null) {
+ try {
+ ZooKeeperOperation zopdel = new ZooKeeperOperation() {
+ public boolean execute() throws KeeperException, InterruptedException {
+ zookeeper.delete(id, -1);
+ return Boolean.TRUE;
+ }
+ };
+ zopdel.execute();
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ // set that we have been interrupted.
+ Thread.currentThread().interrupt();
+ } catch (KeeperException.NoNodeException e) {
+ // do nothing
+ throw new KeeperException.NoNodeException("Lock doesn't exists. Release lock operation failed.");
+ } catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e);
+ }
+ }
+ }
+
+ public synchronized String currentLockHolder(String mainLock) {
+ final String id = mainLock;
+ if (!isClosed() && id != null) {
+ List<String> names;
+ try {
+ names = zookeeper.getChildren(id, false);
+ if (names.isEmpty())
+ return "";
+ SortedSet<ZNodeName> sortedNames = new TreeSet<ZNodeName>();
+ for (String name : names) {
+ sortedNames.add(new ZNodeName(id + "/" + name));
+ }
+ return sortedNames.first().getName();
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ // set that we have been interrupted.
+ Thread.currentThread().interrupt();
+ } catch (KeeperException.NoNodeException e) {
+ // do nothing
+ } catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e);
+ }
+ }
+ return "No lock holder!";
+ }
+
+ public synchronized void deleteLock(String mainLock) {
+ final String id = mainLock;
+ if (!isClosed() && id != null) {
+ try {
+ ZooKeeperOperation zopdel = new ZooKeeperOperation() {
+ public boolean execute() throws KeeperException, InterruptedException {
+ List<String> names = zookeeper.getChildren(id, false);
+ for (String name : names) {
+ zookeeper.delete(id + "/" + name, -1);
+ }
+ zookeeper.delete(id, -1);
+ return Boolean.TRUE;
+ }
+ };
+ zopdel.execute();
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.EXECUTIONINTERRUPTED, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ // set that we have been interrupted.
+ Thread.currentThread().interrupt();
+ } catch (KeeperException.NoNodeException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ // do nothing
+ } catch (KeeperException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.KEEPERERROR, ErrorSeverity.ERROR, ErrorTypes.LOCKINGERROR);
+ throw (RuntimeException) new RuntimeException(e.getMessage()).initCause(e);
+ }
+ }
+
+ }
+
+ /**
+ * a zoookeeper operation that is mainly responsible for all the magic required for locking.
+ */
+ private class LockZooKeeperOperation implements ZooKeeperOperation {
+
+ /**
+ * find if we have been created earlier if not create our node
+ *
+ * @param prefix the prefix node
+ * @param zookeeper the zookeeper client
+ * @param dir the dir parent
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ private String dir;
+ private String id = null;
+
+ public String getId() {
+ return id;
+ }
+
+ public LockZooKeeperOperation(String dir) {
+ this.dir = dir;
+ }
+
+ public LockZooKeeperOperation(String dir, String id) {
+ this.dir = dir;
+ this.id = id;
+ }
+
+ /**
+ * the command that is run and retried for actually obtaining the lock
+ *
+ * @return if the command was successful or not
+ */
+ public boolean execute() throws KeeperException, InterruptedException {
+ do {
+ if (id == null) {
+ String prefix = "x-";
+ byte[] data = {0x12, 0x34};
+ id = zookeeper.create(dir + "/" + prefix, data, getAcl(),
+ CreateMode.PERSISTENT_SEQUENTIAL);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "Created id: " + id);
+ }
+ if (id != null)
+ break;
+ }
+ if (id != null) {
+ List<String> names = zookeeper.getChildren(dir, false);
+ if (names.isEmpty()) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "No children in: " + dir
+ + " when we've just " + "created one! Lets recreate it...");
+ // lets force the recreation of the id
+ id = null;
+ return Boolean.FALSE;
+
+ } else {
+ // lets sort them explicitly (though they do seem to come back in order
+ // ususally :)
+ ZNodeName idName = new ZNodeName(id);
+ SortedSet<ZNodeName> sortedNames = new TreeSet<ZNodeName>();
+ for (String name : names) {
+ sortedNames.add(new ZNodeName(dir + "/" + name));
+ }
+ if (!sortedNames.contains(idName))
+ return Boolean.FALSE;
+
+ SortedSet<ZNodeName> lessThanMe = sortedNames.headSet(idName);
+ if (!lessThanMe.isEmpty()) {
+ ZNodeName lastChildName = lessThanMe.last();
+ String lastChildId = lastChildName.getName();
+ if (logger.isDebugEnabled()) {
+ logger.debug(EELFLoggerDelegate.debugLogger, "watching less than me node: " + lastChildId);
+ }
+ Stat stat = zookeeper.exists(lastChildId, false);
+ if (stat != null) {
+ return Boolean.FALSE;
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Could not find the" + " stats for less than me: "
+ + lastChildName.getName());
+ }
+ } else
+ return Boolean.TRUE;
+ }
+ }
+ } while (id == null);
+ return Boolean.FALSE;
+ }
+ }
+
+}
+
diff --git a/jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java b/jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java
new file mode 100644
index 00000000..7020d14d
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/lockingservice/ZooKeeperOperation.java
@@ -0,0 +1,42 @@
+/*
+ * ============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.lockingservice;
+
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * A callback object which can be used for implementing retry-able operations in the
+ * {@link org.onap.music.lockingservice.ProtocolSupport} class
+ *
+ */
+public interface ZooKeeperOperation {
+
+ /**
+ * Performs the operation - which may be involved multiple times if the connection
+ * to ZooKeeper closes during this operation
+ *
+ * @return the result of the operation or null
+ * @throws KeeperException FILL IN
+ * @throws InterruptedException FILL IN
+ */
+ public boolean execute() throws KeeperException, InterruptedException;
+}
diff --git a/jar/src/main/java/org/onap/music/main/CachingUtil.java b/jar/src/main/java/org/onap/music/main/CachingUtil.java
new file mode 100755
index 00000000..aa06aae2
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/CachingUtil.java
@@ -0,0 +1,420 @@
+/*
+ * ============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.main;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+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;
+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.MusicServiceException;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.exceptions.InvalidQueryException;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+
+/**
+ * All Caching related logic is handled by this class and a schedule cron runs to update cache.
+ *
+ * @author Vikram
+ *
+ */
+public class CachingUtil implements Runnable {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CachingUtil.class);
+
+ private static CacheAccess<String, String> musicCache = JCS.getInstance("musicCache");
+ private static CacheAccess<String, Map<String, String>> aafCache = JCS.getInstance("aafCache");
+ private static CacheAccess<String, String> appNameCache = JCS.getInstance("appNameCache");
+ private static CacheAccess<String, Map<String, String>> musicValidateCache = JCS.getInstance("musicValidateCache");
+ private static Map<String, Number> userAttempts = new HashMap<>();
+ private static Map<String, Calendar> lastFailedTime = new HashMap<>();
+
+ public boolean isCacheRefreshNeeded() {
+ if (aafCache.get("initBlankMap") == null)
+ return true;
+ return false;
+ }
+
+ public void initializeMusicCache() {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Initializing Music Cache...");
+ musicCache.put("isInitialized", "true");
+ }
+
+ public void initializeAafCache() throws MusicServiceException {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Resetting and initializing AAF Cache...");
+
+ String query = "SELECT uuid, application_name, keyspace_name, username, password FROM admin.keyspace_master WHERE is_api = ? allow filtering";
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(query);
+ try {
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), false));
+ } catch (Exception e1) {
+ logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.CACHEERROR, ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ e1.printStackTrace();
+ }
+ ResultSet rs = MusicCore.get(pQuery);
+ Iterator<Row> it = rs.iterator();
+ Map<String, String> map = null;
+ while (it.hasNext()) {
+ Row row = it.next();
+ String nameSpace = row.getString("keyspace_name");
+ String userId = row.getString("username");
+ String password = row.getString("password");
+ String keySpace = row.getString("application_name");
+ try {
+ userAttempts.put(nameSpace, 0);
+ AAFResponse responseObj = triggerAAF(nameSpace, userId, password);
+ if (responseObj.getNs().size() > 0) {
+ map = new HashMap<>();
+ map.put(userId, password);
+ aafCache.put(nameSpace, map);
+ musicCache.put(keySpace, nameSpace);
+ logger.debug("Cronjob: Cache Updated with AAF response for namespace "
+ + nameSpace);
+ }
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.INFO, ErrorTypes.GENERALSERVICEERROR);
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Something at AAF was changed for ns: " + nameSpace+" So not updating Cache for the namespace. ");
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ @Override
+ public void run() {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Scheduled task invoked. Refreshing Cache...");
+ try {
+ initializeAafCache();
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.INFO, ErrorTypes.GENERALSERVICEERROR);
+ }
+ }
+
+ public static boolean authenticateAAFUser(String nameSpace, String userId, String password,
+ String keySpace) throws Exception {
+
+ if (aafCache.get(nameSpace) != null) {
+ 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)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Authenticated with cache value..");
+ // reset invalid attempts to 0
+ userAttempts.put(nameSpace, 0);
+ return true;
+ } else {
+ // call AAF update cache with new password
+ if (userAttempts.get(nameSpace) == null)
+ userAttempts.put(nameSpace, 0);
+ if ((Integer) userAttempts.get(nameSpace) >= 3) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Reached max attempts. Checking if time out..");
+ logger.info(EELFLoggerDelegate.applicationLogger,"Failed time: "+lastFailedTime.get(nameSpace).getTime());
+ Calendar calendar = Calendar.getInstance();
+ long delayTime = (calendar.getTimeInMillis()-lastFailedTime.get(nameSpace).getTimeInMillis());
+ logger.info(EELFLoggerDelegate.applicationLogger,"Delayed time: "+delayTime);
+ if( delayTime > 120000) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Resetting failed attempt.");
+ userAttempts.put(nameSpace, 0);
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger,"No more attempts allowed. Please wait for atleast 2 min.");
+ throw new Exception("No more attempts allowed. Please wait for atleast 2 min.");
+ }
+ }
+ logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.CACHEAUTHENTICATION,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ logger.info(EELFLoggerDelegate.applicationLogger,"Check AAF again...");
+ }
+ }
+
+ 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);
+ return true;
+ }
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,"Invalid user. Cache not updated");
+ return false;
+ }
+
+ 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);
+ throw new Exception("AAF endpoint is not set. Please specify in the properties file.");
+ }
+ Client client = Client.create();
+ // WebResource webResource =
+ // client.resource("https://aaftest.test.att.com:8095/proxy/authz/nss/"+nameSpace);
+ WebResource webResource = client.resource(MusicUtil.getAafEndpointUrl().concat(nameSpace));
+ String plainCreds = userId + ":" + password;
+ byte[] plainCredsBytes = plainCreds.getBytes();
+ byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
+ String base64Creds = new String(base64CredsBytes);
+
+ ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON)
+ .header("Authorization", "Basic " + base64Creds)
+ .header("content-type", "application/json").get(ClientResponse.class);
+ if (response.getStatus() != 200) {
+ if (userAttempts.get(nameSpace) == null)
+ userAttempts.put(nameSpace, 0);
+ if ((Integer) userAttempts.get(nameSpace) >= 2) {
+ lastFailedTime.put(nameSpace, Calendar.getInstance());
+ userAttempts.put(nameSpace, ((Integer) userAttempts.get(nameSpace) + 1));
+ throw new Exception(
+ "Reached max invalid attempts. Please contact admin and retry with valid credentials.");
+ }
+ userAttempts.put(nameSpace, ((Integer) userAttempts.get(nameSpace) + 1));
+ throw new Exception(
+ "Unable to authenticate. Please check the AAF credentials against namespace.");
+ // 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,
+ 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);
+
+ return responseObj;
+ }
+
+ public static void updateMusicCache(String keyspace, String nameSpace) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for keyspace " + keyspace + " with nameSpace " + nameSpace);
+ musicCache.put(keyspace, nameSpace);
+ }
+
+ public static void updateMusicValidateCache(String nameSpace, String userId, String password) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for nameSpacce " + nameSpace + " with userId " + userId);
+ Map<String, String> map = new HashMap<>();
+ map.put(userId, password);
+ musicValidateCache.put(nameSpace, map);
+ }
+
+ public static void updateisAAFCache(String namespace, String isAAF) {
+ appNameCache.put(namespace, isAAF);
+ }
+
+ public static String isAAFApplication(String namespace) throws MusicServiceException {
+ String isAAF = appNameCache.get(namespace);
+ if (isAAF == null) {
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "SELECT is_aaf from admin.keyspace_master where application_name = '"
+ + namespace + "' allow filtering");
+ Row rs = null;
+ try {
+ rs = MusicCore.get(pQuery).one();
+ } catch(InvalidQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+e.getMessage());
+ throw new MusicServiceException("Please make sure admin.keyspace_master table is configured.");
+ }
+ try {
+ isAAF = String.valueOf(rs.getBool("is_aaf"));
+ if(isAAF != null)
+ appNameCache.put(namespace, isAAF);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR,ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ e.printStackTrace();
+ }
+ }
+ return isAAF;
+ }
+
+ public static String getUuidFromMusicCache(String keyspace) throws MusicServiceException {
+ String uuid = null;
+ if (uuid == null) {
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "SELECT uuid from admin.keyspace_master where keyspace_name = '"
+ + keyspace + "' allow filtering");
+ Row rs = MusicCore.get(pQuery).one();
+ try {
+ uuid = rs.getUUID("uuid").toString();
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Exception occured during uuid retrieval from DB."+e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ return uuid;
+ }
+
+ public static String getAppName(String keyspace) throws MusicServiceException {
+ String appName = null;
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "SELECT application_name from admin.keyspace_master where keyspace_name = '"
+ + keyspace + "' allow filtering");
+ Row rs = MusicCore.get(pQuery).one();
+ try {
+ appName = rs.getString("application_name");
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR, ErrorSeverity.ERROR, ErrorTypes.QUERYERROR);
+ e.printStackTrace();
+ }
+ return appName;
+ }
+
+ public static String generateUUID() {
+ String uuid = UUID.randomUUID().toString();
+ logger.info(EELFLoggerDelegate.applicationLogger,"New AID generated: "+uuid);
+ return uuid;
+ }
+
+ public static Map<String, Object> validateRequest(String nameSpace, String userId,
+ String password, String keyspace, String aid, String operation) {
+ Map<String, Object> resultMap = new HashMap<>();
+ if (!"createKeySpace".equals(operation)) {
+ if (nameSpace == null) {
+ resultMap.put("Exception", "Application namespace is mandatory.");
+ }
+ }
+ return resultMap;
+
+ }
+
+ public static Map<String, Object> verifyOnboarding(String ns, String userId, String password) {
+ Map<String, Object> resultMap = new HashMap<>();
+ if (ns == null || userId == null || password == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: "+userId+" :: password: "+password);
+ resultMap.put("Exception",
+ "One or more required headers appName(ns), userId, password is missing. Please check.");
+ return resultMap;
+ }
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(
+ "select * from admin.keyspace_master where application_name = ? allow filtering");
+ try {
+ queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
+ } catch(Exception e) {
+ resultMap.put("Exception",
+ "Unable to process input data. Invalid input data type. Please check ns, userId and password values. "+e.getMessage());
+ return resultMap;
+ }
+ Row rs = null;
+ try {
+ rs = MusicCore.get(queryObject).one();
+ } catch (MusicServiceException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ resultMap.put("Exception", "Unable to process operation. Error is "+e.getMessage());
+ return resultMap;
+ } catch (InvalidQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+e.getMessage());
+ resultMap.put("Exception", "Please make sure admin.keyspace_master table is configured.");
+ return resultMap;
+ }
+ if (rs == null) {
+ 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)) || !(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);
+ return resultMap;
+ }
+ }
+ return resultMap;
+ }
+
+ 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(!BCrypt.checkpw(password,musicValidateCache.get(nameSpace).get(userId))) {
+ resultMap.put("Exception", "Namespace, userId and password doesn't match");
+ return resultMap;
+ }
+ return resultMap;
+ }
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString(
+ "select * from admin.keyspace_master where keyspace_name = ? allow filtering");
+ try {
+ queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Row rs = null;
+ try {
+ rs = MusicCore.get(queryObject).one();
+ } catch (MusicServiceException e) {
+ e.printStackTrace();
+ resultMap.put("Exception", "Unable to process operation. Error is "+e.getMessage());
+ return resultMap;
+ }
+ if(rs == null) {
+ resultMap.put("Exception", "Please make sure keyspace:"+keyspace+" exists.");
+ return resultMap;
+ }
+ else {
+ String user = rs.getString("username");
+ pwd = rs.getString("password");
+ String ns = rs.getString("application_name");
+ if(!ns.equals(nameSpace)) {
+ resultMap.put("Exception", "Namespace and keyspace doesn't match");
+ return resultMap;
+ }
+ if(!user.equals(userId)) {
+ resultMap.put("Exception", "Invalid userId :"+userId);
+ return resultMap;
+ }
+ if(!BCrypt.checkpw(password, pwd)) {
+ resultMap.put("Exception", "Invalid password");
+ return resultMap;
+ }
+ }
+ CachingUtil.updateMusicCache(keyspace, nameSpace);
+ CachingUtil.updateMusicValidateCache(nameSpace, userId, pwd);
+ return resultMap;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/main/CronJobManager.java b/jar/src/main/java/org/onap/music/main/CronJobManager.java
new file mode 100644
index 00000000..fb4a2ac3
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/CronJobManager.java
@@ -0,0 +1,47 @@
+/*
+ * ============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.main;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class CronJobManager implements ServletContextListener {
+
+ private ScheduledExecutorService scheduler;
+
+ @Override
+ public void contextInitialized(ServletContextEvent event) {
+ scheduler = Executors.newSingleThreadScheduledExecutor();
+ scheduler.scheduleAtFixedRate(new CachingUtil(), 0, 24, TimeUnit.HOURS);
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent event) {
+ scheduler.shutdownNow();
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/main/MusicCore.java b/jar/src/main/java/org/onap/music/main/MusicCore.java
new file mode 100644
index 00000000..cad384a3
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/MusicCore.java
@@ -0,0 +1,992 @@
+/*
+ * ============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.main;
+
+
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NoNodeException;
+import org.onap.music.datastore.MusicDataStore;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+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.MusicQueryException;
+import org.onap.music.exceptions.MusicServiceException;
+import org.onap.music.lockingservice.MusicLockState;
+import org.onap.music.lockingservice.MusicLockState.LockStatus;
+import org.onap.music.lockingservice.MusicLockingService;
+
+import com.datastax.driver.core.ColumnDefinitions;
+import com.datastax.driver.core.ColumnDefinitions.Definition;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.TableMetadata;
+
+/**
+ * This class .....
+ *
+ *
+ */
+public class MusicCore {
+
+ public static MusicLockingService mLockHandle = null;
+ public static MusicDataStore mDstoreHandle = null;
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class);
+
+ public static class Condition {
+ Map<String, Object> conditions;
+ PreparedQueryObject selectQueryForTheRow;
+
+ public Condition(Map<String, Object> conditions, PreparedQueryObject selectQueryForTheRow) {
+ this.conditions = conditions;
+ this.selectQueryForTheRow = selectQueryForTheRow;
+ }
+
+ public boolean testCondition() throws Exception {
+ // first generate the row
+ ResultSet results = quorumGet(selectQueryForTheRow);
+ Row row = results.one();
+ return getDSHandle().doesRowSatisfyCondition(row, conditions);
+ }
+ }
+
+
+ public static MusicLockingService getLockingServiceHandle() throws MusicLockingException {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle");
+ long start = System.currentTimeMillis();
+
+ if (mLockHandle == null) {
+ try {
+ mLockHandle = new MusicLockingService();
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ throw new MusicLockingException("Failed to aquire Locl store handle " + e);
+ }
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
+ return mLockHandle;
+ }
+
+ /**
+ *
+ * @param remoteIp
+ * @return
+ */
+ public static MusicDataStore getDSHandle(String remoteIp) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
+ long start = System.currentTimeMillis();
+ if (mDstoreHandle == null) {
+ try {
+ MusicUtil.loadProperties();
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, "No properties file defined. Falling back to default.");
+ }
+ mDstoreHandle = new MusicDataStore(remoteIp);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
+ return mDstoreHandle;
+ }
+
+ /**
+ *
+ * @return
+ * @throws MusicServiceException
+ */
+ public static MusicDataStore getDSHandle() throws MusicServiceException {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
+ long start = System.currentTimeMillis();
+ if (mDstoreHandle == null) {
+ try {
+ MusicUtil.loadProperties();
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, "No properties file defined. Falling back to default.");
+ }
+ // Quick Fix - Best to put this into every call to getDSHandle?
+ if (! MusicUtil.getMyCassaHost().equals("localhost") ) {
+ mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost());
+ } else {
+ mDstoreHandle = new MusicDataStore();
+ }
+ }
+ if(mDstoreHandle.getSession() == null) {
+ String message = "Connection to Cassandra has not been enstablished."
+ + " Please check connection properites and reboot.";
+ logger.info(EELFLoggerDelegate.applicationLogger, message);
+ throw new MusicServiceException(message);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
+ return mDstoreHandle;
+ }
+
+ public static String createLockReference(String lockName) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
+ long start = System.currentTimeMillis();
+ String lockId = null;
+ try {
+ lockId = getLockingServiceHandle().createLockId("/" + lockName);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.CREATELOCK+lockName,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms");
+ return lockId;
+ }
+
+ /**
+ *
+ * @param key
+ * @return
+ */
+ public static boolean isTableOrKeySpaceLock(String key) {
+ String[] splitString = key.split("\\.");
+ if (splitString.length > 2)
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ *
+ * @param key
+ * @return
+ */
+ public static MusicLockState getMusicLockState(String key) {
+ long start = System.currentTimeMillis();
+ try {
+ String[] splitString = key.split("\\.");
+ String keyspaceName = splitString[0];
+ String tableName = splitString[1];
+ String primaryKey = splitString[2];
+ MusicLockState mls;
+ String lockName = keyspaceName + "." + tableName + "." + primaryKey;
+ mls = getLockingServiceHandle().getLockState(lockName);
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms");
+ return mls;
+ } catch (NullPointerException | MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ return null;
+ }
+
+ public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) {
+ try {
+ long start = System.currentTimeMillis();
+ /* check if the current lock has exceeded its lease and if yes, release that lock */
+ MusicLockState mls = getMusicLockState(key);
+ if (mls != null) {
+ if (mls.getLockStatus().equals(LockStatus.LOCKED)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder()
+ + ". Checking if it has exceeded lease");
+ long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime();
+ long currentLeasePeriod = mls.getLeasePeriod();
+ if (currentLockPeriod > currentLeasePeriod) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod
+ + " has exceeded lease period " + currentLeasePeriod);
+ boolean voluntaryRelease = false;
+ String currentLockHolder = mls.getLockHolder();
+ mls = releaseLock(currentLockHolder, voluntaryRelease);
+ }
+ }
+ } else
+ logger.error(EELFLoggerDelegate.errorLogger,key, AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+
+ /*
+ * call the traditional acquire lock now and if the result returned is true, set the
+ * begin time-stamp and lease period
+ */
+ if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) {
+ mls = getMusicLockState(key);// get latest state
+ if ( mls == null ) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null");
+ return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null");
+ }
+ if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already
+ mls.setLeaseStartTime(System.currentTimeMillis());
+ mls.setLeasePeriod(leasePeriod);
+ getLockingServiceHandle().setLockState(key, mls);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms");
+ return new ReturnType(ResultType.SUCCESS, "Accquired lock");
+ } else {
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms");
+ return new ReturnType(ResultType.FAILURE, "Could not acquire lock");
+ }
+ } catch (Exception e) {
+ StringWriter sw = new StringWriter();
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+
+ String exceptionAsString = sw.toString();
+ return new ReturnType(ResultType.FAILURE,
+ "Exception thrown in acquireLockWithLease:\n" + exceptionAsString);
+ }
+ }
+
+ public static ReturnType acquireLock(String key, String lockId) throws MusicLockingException {
+ /*
+ * first check if I am on top. Since ids are not reusable there is no need to check
+ * lockStatus If the status is unlocked, then the above call will automatically return
+ * false.
+ */
+ Boolean result = false;
+ try {
+ result = getLockingServiceHandle().isMyTurn(lockId);
+ } catch (MusicLockingException e2) {
+ logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId + " " + e2);
+ throw new MusicLockingException();
+ }
+ if (!result) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock");
+ try {
+ if (!getLockingServiceHandle().lockIdExists(lockId)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist");
+ return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist");
+ }
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ throw new MusicLockingException();
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure");
+ return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock");
+ }
+
+
+ // this is for backward compatibility where locks could also be acquired on just
+ // keyspaces or tables.
+ if (isTableOrKeySpaceLock(key)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true");
+ return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true");
+ }
+
+ // read the lock name corresponding to the key and if the status is locked or being locked,
+ // then return false
+ MusicLockState currentMls = null;
+ MusicLockState newMls = null;
+ try {
+ currentMls = getMusicLockState(key);
+ String currentLockHolder = currentMls.getLockHolder();
+ if (lockId.equals(currentLockHolder)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!");
+ return new ReturnType(ResultType.SUCCESS, "You already have the lock!");
+ }
+ } catch (NullPointerException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+
+ // change status to "being locked". This state transition is necessary to ensure syncing
+ // before granting the lock
+ String lockHolder = null;
+ boolean needToSyncQuorum = false;
+ if (currentMls != null)
+ needToSyncQuorum = currentMls.isNeedToSyncQuorum();
+
+
+ newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder,
+ needToSyncQuorum);
+ try {
+ getLockingServiceHandle().setLockState(key, newMls);
+ } catch (MusicLockingException e1) {
+ logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked");
+
+ // do syncing if this was a forced lock release
+ if (needToSyncQuorum) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!");
+ try {
+ syncQuorum(key);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e);
+ }
+ }
+
+ // change status to locked
+ lockHolder = lockId;
+ needToSyncQuorum = false;
+ newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum);
+ try {
+ getLockingServiceHandle().setLockState(key, newMls);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref "
+ + lockId + " as holder");
+
+ return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder");
+ }
+
+
+
+ /**
+ *
+ * @param keyspaceName
+ * @param kspObject
+ * @return
+ * @throws Exception
+ */
+ public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception {
+ return true;
+ }
+
+
+ private static void syncQuorum(String key) throws Exception {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
+ String[] splitString = key.split("\\.");
+ String keyspaceName = splitString[0];
+ String tableName = splitString[1];
+ String primaryKeyValue = splitString[2];
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ PreparedQueryObject updateQuery = new PreparedQueryObject();
+
+ // get the primary key d
+ TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName);
+ String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single
+ // primary key
+ DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
+ Object cqlFormattedPrimaryKeyValue =
+ MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
+
+ // get the row of data from a quorum
+ selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE "
+ + primaryKeyName + "= ?" + ";");
+ selectQuery.addValue(cqlFormattedPrimaryKeyValue);
+ ResultSet results = null;
+ try {
+ results = getDSHandle().executeCriticalGet(selectQuery);
+ // write it back to a quorum
+ Row row = results.one();
+ ColumnDefinitions colInfo = row.getColumnDefinitions();
+ int totalColumns = colInfo.size();
+ int counter = 1;
+ StringBuilder fieldValueString = new StringBuilder("");
+ for (Definition definition : colInfo) {
+ String colName = definition.getName();
+ if (colName.equals(primaryKeyName))
+ continue;
+ DataType colType = definition.getType();
+ Object valueObj = getDSHandle().getColValue(row, colName, colType);
+ Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
+ fieldValueString.append(colName + " = ?");
+ updateQuery.addValue(valueString);
+ if (counter != (totalColumns - 1))
+ fieldValueString.append(",");
+ counter = counter + 1;
+ }
+ updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET "
+ + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";");
+ updateQuery.addValue(cqlFormattedPrimaryKeyValue);
+
+ getDSHandle().executePut(updateQuery, "critical");
+ } catch (MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR);
+ }
+ }
+
+
+
+
+ /**
+ *
+ * @param query
+ * @return ResultSet
+ */
+ public static ResultSet quorumGet(PreparedQueryObject query) {
+ ResultSet results = null;
+ try {
+ results = getDSHandle().executeCriticalGet(query);
+ } catch (MusicServiceException | MusicQueryException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR);
+
+ }
+ return results;
+
+ }
+
+ /**
+ *
+ * @param results
+ * @return
+ * @throws MusicServiceException
+ */
+ public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException {
+ return getDSHandle().marshalData(results);
+ }
+
+ /**
+ *
+ * @param lockName
+ * @return
+ */
+ public static String whoseTurnIsIt(String lockName) {
+
+ try {
+ return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + "";
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ return null;
+
+
+ }
+
+ /**
+ *
+ * @param lockId
+ * @return
+ */
+ public static String getLockNameFromId(String lockId) {
+ StringTokenizer st = new StringTokenizer(lockId);
+ return st.nextToken("$");
+ }
+
+ public static void destroyLockRef(String lockId) {
+ long start = System.currentTimeMillis();
+ try {
+ getLockingServiceHandle().unlockAndDeleteId(lockId);
+ } catch (MusicLockingException | NoNodeException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
+ }
+
+ public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) {
+ long start = System.currentTimeMillis();
+ try {
+ getLockingServiceHandle().unlockAndDeleteId(lockId);
+ } catch (MusicLockingException e1) {
+ logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ } catch (KeeperException.NoNodeException nne) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Failed to release Lock " + lockId + " " + nne);
+ MusicLockState mls = new MusicLockState("Lock doesn't exists. Release lock operation failed.");
+ return mls;
+ }
+ String lockName = getLockNameFromId(lockId);
+ MusicLockState mls;
+ String lockHolder = null;
+ if (voluntaryRelease) {
+ mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
+ logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId);
+ } else {
+ boolean needToSyncQuorum = true;
+ mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder,
+ needToSyncQuorum);
+ logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId);
+ }
+ try {
+ getLockingServiceHandle().setLockState(lockName, mls);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms");
+ return mls;
+ }
+
+ public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{
+ try {
+ getLockingServiceHandle().unlockAndDeleteId(lockId);
+ } catch (KeeperException.NoNodeException e) {
+ // ??? No way
+ }
+ }
+
+ /**
+ *
+ * @param lockName
+ * @throws MusicLockingException
+ */
+ public static void deleteLock(String lockName) throws MusicLockingException {
+ long start = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName);
+ try {
+ getLockingServiceHandle().deleteLock("/" + lockName);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DELTELOCK+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ throw new MusicLockingException(e.getMessage());
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms");
+ }
+
+
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @return
+ * @throws MusicServiceException
+ */
+ public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException {
+ return getDSHandle().returnColumnMetadata(keyspace, tablename);
+ }
+
+
+ /**
+ *
+ * @param nodeName
+ */
+ public static void pureZkCreate(String nodeName) {
+ try {
+ getLockingServiceHandle().getzkLockHandle().createNode(nodeName);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ }
+
+ /**
+ *
+ * @param nodeName
+ * @param data
+ */
+ public static void pureZkWrite(String nodeName, byte[] data) {
+ long start = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName);
+ try {
+ getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName);
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
+ }
+
+ /**
+ *
+ * @param nodeName
+ * @return
+ */
+ public static byte[] pureZkRead(String nodeName) {
+ long start = System.currentTimeMillis();
+ byte[] data = null;
+ try {
+ data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
+ return data;
+ }
+
+
+
+ // Prepared Query Additions.
+
+ /**
+ *
+ * @param keyspaceName
+ * @param tableName
+ * @param primaryKey
+ * @param queryObject
+ * @return ReturnType
+ * @throws MusicServiceException
+ */
+ public static ReturnType eventualPut(PreparedQueryObject queryObject) {
+ boolean result = false;
+ try {
+ result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
+ } catch (MusicServiceException | MusicQueryException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex);
+ return new ReturnType(ResultType.FAILURE, ex.getMessage());
+ }
+ if (result) {
+ return new ReturnType(ResultType.SUCCESS, "Success");
+ } else {
+ return new ReturnType(ResultType.FAILURE, "Failure");
+ }
+ }
+
+ /**
+ *
+ * @param keyspaceName
+ * @param tableName
+ * @param primaryKey
+ * @param queryObject
+ * @param lockId
+ * @return
+ */
+ public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
+ long start = System.currentTimeMillis();
+
+ try {
+ MusicLockState mls = getLockingServiceHandle()
+ .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
+ if (mls.getLockHolder().equals(lockId) == true) {
+ if (conditionInfo != null)
+ try {
+ if (conditionInfo.testCondition() == false)
+ return new ReturnType(ResultType.FAILURE,
+ "Lock acquired but the condition is not true");
+ } catch (Exception e) {
+ return new ReturnType(ResultType.FAILURE,
+ "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
+ + e.getMessage());
+ }
+ getDSHandle().executePut(queryObject, MusicUtil.CRITICAL);
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms");
+ return new ReturnType(ResultType.SUCCESS, "Update performed");
+ } else
+ return new ReturnType(ResultType.FAILURE,
+ "Cannot perform operation since you are the not the lock holder");
+ } catch (MusicQueryException | MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
+ return new ReturnType(ResultType.FAILURE,
+ "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
+ + e.getMessage());
+ }catch(MusicLockingException ex){
+ return new ReturnType(ResultType.FAILURE,ex.getMessage());
+ }
+
+ }
+
+ /**
+ *
+ * @param queryObject
+ * @param consistency
+ * @return Boolean Indicates success or failure
+ * @throws MusicServiceException
+ *
+ *
+ */
+ public static ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException {
+ // this is mainly for some functions like keyspace creation etc which does not
+ // really need the bells and whistles of Music locking.
+ boolean result = false;
+ try {
+ result = getDSHandle().executePut(queryObject, consistency);
+ } catch (MusicQueryException | MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ throw new MusicServiceException(ex.getMessage());
+ }
+ return result?ResultType.SUCCESS:ResultType.FAILURE;
+ }
+
+ /**
+ * This method performs DDL operation on cassandra.
+ *
+ * @param queryObject query object containing prepared query and values
+ * @return ResultSet
+ * @throws MusicServiceException
+ */
+ public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
+ ResultSet results = null;
+ try {
+ results = getDSHandle().executeEventualGet(queryObject);
+ } catch (MusicQueryException | MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
+ throw new MusicServiceException(e.getMessage());
+ }
+ return results;
+ }
+
+ /**
+ * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
+ * is used to check if the resource is free.
+ *
+ * @param keyspaceName name of the keyspace
+ * @param tableName name of the table
+ * @param primaryKey primary key value
+ * @param queryObject query object containing prepared query and values
+ * @param lockId lock ID to check if the resource is free to perform the operation.
+ * @return ResultSet
+ */
+ public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
+ ResultSet results = null;
+ try {
+ MusicLockState mls = getLockingServiceHandle()
+ .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
+ if (mls.getLockHolder().equals(lockId)) {
+ results = getDSHandle().executeCriticalGet(queryObject);
+ } else
+ throw new MusicServiceException("YOU DO NOT HAVE THE LOCK");
+ } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ }
+ return results;
+ }
+
+ /**
+ * This method performs DML operation on cassandra, when the lock of the dd is acquired.
+ *
+ * @param keyspaceName name of the keyspace
+ * @param tableName name of the table
+ * @param primaryKey primary key value
+ * @param queryObject query object containing prepared query and values
+ * @return ReturnType
+ * @throws MusicLockingException
+ */
+ public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
+
+ long start = System.currentTimeMillis();
+ String key = keyspaceName + "." + tableName + "." + primaryKey;
+ String lockId = createLockReference(key);
+ long lockCreationTime = System.currentTimeMillis();
+ ReturnType lockAcqResult = acquireLock(key, lockId);
+ long lockAcqTime = System.currentTimeMillis();
+ if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
+ ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
+ queryObject, lockId, conditionInfo);
+ long criticalPutTime = System.currentTimeMillis();
+ voluntaryReleaseLock(lockId);
+ long lockDeleteTime = System.currentTimeMillis();
+ String timingInfo = "|lock creation time:" + (lockCreationTime - start)
+ + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
+ + "|critical put time:" + (criticalPutTime - lockAcqTime)
+ + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
+ criticalPutResult.setTimingInfo(timingInfo);
+ return criticalPutResult;
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
+ destroyLockRef(lockId);
+ return lockAcqResult;
+ }
+ }
+
+ /**
+ * this function is mainly for the benchmarks to see the effect of lock deletion.
+ *
+ * @param keyspaceName
+ * @param tableName
+ * @param primaryKey
+ * @param queryObject
+ * @param conditionInfo
+ * @return
+ * @throws MusicLockingException
+ */
+ public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName,
+ String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
+
+ long start = System.currentTimeMillis();
+ String key = keyspaceName + "." + tableName + "." + primaryKey;
+ String lockId = createLockReference(key);
+ long lockCreationTime = System.currentTimeMillis();
+ long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
+ ReturnType lockAcqResult = acquireLock(key, lockId);
+ long lockAcqTime = System.currentTimeMillis();
+ if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
+ ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
+ queryObject, lockId, conditionInfo);
+ long criticalPutTime = System.currentTimeMillis();
+ deleteLock(key);
+ long lockDeleteTime = System.currentTimeMillis();
+ String timingInfo = "|lock creation time:" + (lockCreationTime - start)
+ + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
+ + "|critical put time:" + (criticalPutTime - lockAcqTime)
+ + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
+ criticalPutResult.setTimingInfo(timingInfo);
+ return criticalPutResult;
+ } else {
+ logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
+ deleteLock(key);
+ return lockAcqResult;
+ }
+ }
+
+
+
+
+ /**
+ * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
+ *
+ * @param keyspaceName name of the keyspace
+ * @param tableName name of the table
+ * @param primaryKey primary key value
+ * @param queryObject query object containing prepared query and values
+ * @return ResultSet
+ * @throws MusicServiceException
+ * @throws MusicLockingException
+ */
+ public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
+ String key = keyspaceName + "." + tableName + "." + primaryKey;
+ String lockId = createLockReference(key);
+ long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
+ ReturnType lockAcqResult = acquireLock(key, lockId);
+ if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
+ ResultSet result =
+ criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
+ voluntaryReleaseLock(lockId);
+ return result;
+ } else {
+ destroyLockRef(lockId);
+ logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
+ return null;
+ }
+ }
+
+ public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
+ PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
+ String key = keyspaceName + "." + tableName + "." + primaryKey;
+ String lockId = createLockReference(key);
+ long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
+
+ ReturnType lockAcqResult = acquireLock(key, lockId);
+
+ if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
+ ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
+ deleteLock(key);
+ return result;
+ } else {
+ deleteLock(key);
+ logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
+ return null;
+ }
+ }
+
+
+
+ /**
+ * authenticate user logic
+ *
+ * @param nameSpace
+ * @param userId
+ * @param password
+ * @param keyspace
+ * @param aid
+ * @param operation
+ * @return
+ * @throws Exception
+ */
+ public static Map<String, Object> autheticateUser(String nameSpace, String userId,
+ String password, String keyspace, String aid, String operation)
+ throws Exception {
+ Map<String, Object> resultMap = new HashMap<>();
+ String uuid = null;
+ resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
+ operation);
+ if (!resultMap.isEmpty())
+ return resultMap;
+ String isAAFApp = null;
+ try {
+ isAAFApp= CachingUtil.isAAFApplication(nameSpace);
+ } catch(MusicServiceException e) {
+ resultMap.put("Exception", e.getMessage());
+ return resultMap;
+ }
+ if(isAAFApp == null) {
+ resultMap.put("Exception", "Namespace: "+nameSpace+" doesn't exist. Please make sure ns(appName)"
+ + " is correct and Application is onboarded.");
+ return resultMap;
+ }
+ boolean isAAF = Boolean.valueOf(isAAFApp);
+ if (userId == null || password == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId
+ + " :: password: " + password);
+ resultMap.put("Exception",
+ "UserId and Password are mandatory for the operation " + operation);
+ return resultMap;
+ }
+ if(!isAAF && !(operation.equals("createKeySpace"))) {
+ resultMap = CachingUtil.authenticateAIDUser(nameSpace, userId, password, keyspace);
+ if (!resultMap.isEmpty())
+ return resultMap;
+
+ }
+ if (isAAF && nameSpace != null && userId != null && password != null) {
+ boolean isValid = true;
+ try {
+ isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace);
+ resultMap.put("Exception", e.getMessage());
+ }
+ if (!isValid) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ resultMap.put("Exception", "User not authenticated...");
+ }
+ if (!resultMap.isEmpty())
+ return resultMap;
+
+ }
+
+ if (operation.equals("createKeySpace")) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
+ MusicUtil.DEFAULTKEYSPACENAME));
+
+ try {
+ Row rs = MusicCore.get(pQuery).one();
+ uuid = rs.getUUID("uuid").toString();
+ resultMap.put("uuid", "existing");
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
+ uuid = CachingUtil.generateUUID();
+ resultMap.put("uuid", "new");
+ }
+ resultMap.put("aid", uuid);
+ }
+
+ return resultMap;
+ }
+
+ /**
+ * @param lockName
+ * @return
+ */
+ public static Map<String, Object> validateLock(String lockName) {
+ Map<String, Object> resultMap = new HashMap<>();
+ String[] locks = lockName.split("\\.");
+ if(locks.length < 3) {
+ resultMap.put("Exception", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey");
+ return resultMap;
+ }
+ String keyspace= locks[0];
+ if(keyspace.startsWith("$"))
+ keyspace = keyspace.substring(1);
+ resultMap.put("keyspace",keyspace);
+ return resultMap;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/main/MusicDigest.java b/jar/src/main/java/org/onap/music/main/MusicDigest.java
new file mode 100644
index 00000000..893cb51f
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/MusicDigest.java
@@ -0,0 +1,78 @@
+/*
+ * ============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.main;
+
+/**
+ *
+ *
+ */
+public class MusicDigest {
+ private String evPutStatus;
+ private String vectorTs;
+
+ /**
+ * @param evPutStatus
+ * @param vectorTs
+ */
+ public MusicDigest(String evPutStatus, String vectorTs) {
+ this.evPutStatus = evPutStatus;
+ this.vectorTs = vectorTs;
+ }
+
+ /**
+ * @return
+ */
+ public String getEvPutStatus() {
+ return evPutStatus;
+ }
+
+ /**
+ * @param evPutStatus
+ */
+ public void setEvPutStatus(String evPutStatus) {
+ this.evPutStatus = evPutStatus;
+ }
+
+ /**
+ * @return
+ */
+ public String getVectorTs() {
+ return vectorTs;
+ }
+
+ /**
+ * @param vectorTs
+ */
+ public void setVectorTs(String vectorTs) {
+ this.vectorTs = vectorTs;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return vectorTs + "|" + evPutStatus;
+ }
+}
+
diff --git a/jar/src/main/java/org/onap/music/main/MusicUtil.java b/jar/src/main/java/org/onap/music/main/MusicUtil.java
new file mode 100755
index 00000000..f18570db
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/MusicUtil.java
@@ -0,0 +1,560 @@
+/*
+ * ============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.main;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.UUID;
+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 java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+
+/**
+ * @author nelson24
+ *
+ * Properties This will take Properties and load them into MusicUtil.
+ * This is a hack for now. Eventually it would bebest to do this in
+ * another way.
+ *
+ */
+public class MusicUtil {
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
+
+ public static final String ATOMIC = "atomic";
+ public static final String EVENTUAL = "eventual";
+ public static final String CRITICAL = "critical";
+ public static final String ATOMICDELETELOCK = "atomic_delete_lock";
+ public static final String DEFAULTKEYSPACENAME = "TBD";
+ private static final String XLATESTVERSION = "X-latestVersion";
+ private static final String XMINORVERSION = "X-minorVersion";
+ private static final String XPATCHVERSION = "X-patchVersion";
+
+ private static final String LOCALHOST = "localhost";
+ private static final String PROPERTIES_FILE = "/opt/app/music/etc/music.properties";
+
+ private static int myId = 0;
+ private static ArrayList<String> allIds = new ArrayList<>();
+ private static String publicIp = "";
+ private static ArrayList<String> allPublicIps = new ArrayList<>();
+ private static String myZkHost = LOCALHOST;
+ private static String myCassaHost = LOCALHOST;
+ private static String defaultMusicIp = LOCALHOST;
+ private static boolean debug = true;
+ private static String version = "2.3.0";
+ private static String musicRestIp = LOCALHOST;
+ private static String musicPropertiesFilePath = PROPERTIES_FILE;
+ private static long defaultLockLeasePeriod = 6000;
+ private static final String[] propKeys = new String[] { "zookeeper.host", "cassandra.host", "music.ip", "debug",
+ "version", "music.rest.ip", "music.properties", "lock.lease.period", "id", "all.ids", "public.ip",
+ "all.pubic.ips", "cassandra.user", "cassandra.password", "aaf.endpoint.url" };
+
+ private static String cassName = "cassandra";
+ private static String cassPwd = "cassandra";
+ private static String aafEndpointUrl = null;
+
+ private MusicUtil() {
+ throw new IllegalStateException("Utility Class");
+ }
+
+
+ /**
+ * @return the cassName
+ */
+ public static String getCassName() {
+ return cassName;
+ }
+
+ /**
+ * @return the cassPwd
+ */
+ public static String getCassPwd() {
+ return cassPwd;
+ }
+
+ /**
+ * @return the aafEndpointUrl
+ */
+ public static String getAafEndpointUrl() {
+ return aafEndpointUrl;
+ }
+
+ /**
+ *
+ * @param aafEndpointUrl
+ */
+ public static void setAafEndpointUrl(String aafEndpointUrl) {
+ MusicUtil.aafEndpointUrl = aafEndpointUrl;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static int getMyId() {
+ return myId;
+ }
+
+ /**
+ *
+ * @param myId
+ */
+ public static void setMyId(int myId) {
+ MusicUtil.myId = myId;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static List<String> getAllIds() {
+ return allIds;
+ }
+
+ /**
+ *
+ * @param allIds
+ */
+ public static void setAllIds(List<String> allIds) {
+ MusicUtil.allIds = (ArrayList<String>) allIds;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static String getPublicIp() {
+ return publicIp;
+ }
+
+ /**
+ *
+ * @param publicIp
+ */
+ public static void setPublicIp(String publicIp) {
+ MusicUtil.publicIp = publicIp;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static List<String> getAllPublicIps() {
+ return allPublicIps;
+ }
+
+ /**
+ *
+ * @param allPublicIps
+ */
+ public static void setAllPublicIps(List<String> allPublicIps) {
+ MusicUtil.allPublicIps = (ArrayList<String>) allPublicIps;
+ }
+
+ /**
+ * Returns An array of property names that should be in the Properties
+ * files.
+ *
+ * @return
+ */
+ public static String[] getPropkeys() {
+ return propKeys;
+ }
+
+ /**
+ * Get MusicRestIp - default = localhost property file value - music.rest.ip
+ *
+ * @return
+ */
+ public static String getMusicRestIp() {
+ return musicRestIp;
+ }
+
+ /**
+ * Set MusicRestIp
+ *
+ * @param musicRestIp
+ */
+ public static void setMusicRestIp(String musicRestIp) {
+ MusicUtil.musicRestIp = musicRestIp;
+ }
+
+ /**
+ * Get MusicPropertiesFilePath - Default = /opt/music/music.properties
+ * property file value - music.properties
+ *
+ * @return
+ */
+ public static String getMusicPropertiesFilePath() {
+ return musicPropertiesFilePath;
+ }
+
+ /**
+ * Set MusicPropertiesFilePath
+ *
+ * @param musicPropertiesFilePath
+ */
+ public static void setMusicPropertiesFilePath(String musicPropertiesFilePath) {
+ MusicUtil.musicPropertiesFilePath = musicPropertiesFilePath;
+ }
+
+ /**
+ * Get DefaultLockLeasePeriod - Default = 6000 property file value -
+ * lock.lease.period
+ *
+ * @return
+ */
+ public static long getDefaultLockLeasePeriod() {
+ return defaultLockLeasePeriod;
+ }
+
+ /**
+ * Set DefaultLockLeasePeriod
+ *
+ * @param defaultLockLeasePeriod
+ */
+ public static void setDefaultLockLeasePeriod(long defaultLockLeasePeriod) {
+ MusicUtil.defaultLockLeasePeriod = defaultLockLeasePeriod;
+ }
+
+ /**
+ * Set Debug
+ *
+ * @param debug
+ */
+ public static void setDebug(boolean debug) {
+ MusicUtil.debug = debug;
+ }
+
+ /**
+ * Is Debug - Default = true property file value - debug
+ *
+ * @return
+ */
+ public static boolean isDebug() {
+ return debug;
+ }
+
+ /**
+ * Set Version
+ *
+ * @param version
+ */
+ public static void setVersion(String version) {
+ MusicUtil.version = version;
+ }
+
+ /**
+ * Return the version property file value - version
+ *
+ * @return
+ */
+ public static String getVersion() {
+ return version;
+ }
+
+ /**
+ * Get MyZkHost - Zookeeper Hostname - Default = localhost property file
+ * value - zookeeper.host
+ *
+ * @return
+ */
+ public static String getMyZkHost() {
+ return myZkHost;
+ }
+
+ /**
+ * Set MyZkHost - Zookeeper Hostname
+ *
+ * @param myZkHost
+ */
+ public static void setMyZkHost(String myZkHost) {
+ MusicUtil.myZkHost = myZkHost;
+ }
+
+ /**
+ * Get MyCassHost - Cassandra Hostname - Default = localhost property file
+ * value - cassandra.host
+ *
+ * @return
+ */
+ public static String getMyCassaHost() {
+ return myCassaHost;
+ }
+
+ /**
+ * Set MyCassHost - Cassandra Hostname
+ *
+ * @param myCassaHost
+ */
+ public static void setMyCassaHost(String myCassaHost) {
+ MusicUtil.myCassaHost = myCassaHost;
+ }
+
+ /**
+ * Get DefaultMusicIp - Default = localhost property file value - music.ip
+ *
+ * @return
+ */
+ public static String getDefaultMusicIp() {
+ return defaultMusicIp;
+ }
+
+ /**
+ * Set DefaultMusicIp
+ *
+ * @param defaultMusicIp
+ */
+ public static void setDefaultMusicIp(String defaultMusicIp) {
+ MusicUtil.defaultMusicIp = defaultMusicIp;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static String getTestType() {
+ String testType = "";
+ try {
+ Scanner fileScanner = new Scanner(new File(""));
+ testType = fileScanner.next();// ignore the my id line
+ String batchSize = fileScanner.next();// ignore the my public ip
+ // line
+ fileScanner.close();
+ } catch (FileNotFoundException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
+ }
+ return testType;
+
+ }
+
+ /**
+ *
+ * @param time
+ */
+ public static void sleep(long time) {
+ try {
+ Thread.sleep(time);
+ } catch (InterruptedException e) {
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ * Utility function to check if the query object is valid.
+ *
+ * @param withparams
+ * @param queryObject
+ * @return
+ */
+ public static boolean isValidQueryObject(boolean withparams, PreparedQueryObject queryObject) {
+ if (withparams) {
+ int noOfValues = queryObject.getValues().size();
+ int noOfParams = 0;
+ char[] temp = queryObject.getQuery().toCharArray();
+ for (int i = 0; i < temp.length; i++) {
+ if (temp[i] == '?')
+ noOfParams++;
+ }
+ return (noOfValues == noOfParams);
+ } else {
+ return !queryObject.getQuery().isEmpty();
+ }
+
+ }
+
+ public static void setCassName(String cassName) {
+ MusicUtil.cassName = cassName;
+ }
+
+ public static void setCassPwd(String cassPwd) {
+ MusicUtil.cassPwd = cassPwd;
+ }
+
+ public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception {
+
+ String value = "";
+ switch (type.getName()) {
+ case UUID:
+ value = valueObj + "";
+ break;
+ case TEXT:
+ case VARCHAR:
+ String valueString = valueObj + "";
+ valueString = valueString.replace("'", "''");
+ value = "'" + valueString + "'";
+ break;
+ case MAP: {
+ Map<String, Object> otMap = (Map<String, Object>) valueObj;
+ value = "{" + jsonMaptoSqlString(otMap, ",") + "}";
+ break;
+ }
+ default:
+ value = valueObj + "";
+ break;
+ }
+ return value;
+ }
+
+ /**
+ *
+ * @param colType
+ * @param valueObj
+ * @return
+ * @throws MusicTypeConversionException
+ * @throws Exception
+ */
+ 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;
+ default:
+ return valueObjString;
+ }
+ }
+
+ /**
+ *
+ * Utility function to parse json map into sql like string
+ *
+ * @param jMap
+ * @param lineDelimiter
+ * @return
+ */
+
+ public static String jsonMaptoSqlString(Map<String, Object> jMap, String lineDelimiter) throws Exception{
+ StringBuilder sqlString = new StringBuilder();
+ int counter = 0;
+ for (Map.Entry<String, Object> entry : jMap.entrySet()) {
+ Object ot = entry.getValue();
+ String value = ot + "";
+ if (ot instanceof String) {
+ value = "'" + value.replace("'", "''") + "'";
+ }
+ sqlString.append("'" + entry.getKey() + "':" + value);
+ if (counter != jMap.size() - 1)
+ sqlString.append(lineDelimiter);
+ counter = counter + 1;
+ }
+ return sqlString.toString();
+ }
+
+ @SuppressWarnings("unused")
+ public static String buildVersion(String major, String minor, String patch) {
+ if (minor != null) {
+ major += "." + minor;
+ if (patch != null) {
+ major += "." + patch;
+ }
+ }
+ return major;
+ }
+
+ /**
+ * Currently this will build a header with X-latestVersion, X-minorVersion and X-pathcVersion
+ * X-latestVerstion will be equal to the latest full version.
+ * X-minorVersion - will be equal to the latest minor version.
+ * X-pathVersion - will be equal to the latest patch version.
+ * Future plans will change this.
+ * @param response
+ * @param major
+ * @param minor
+ * @param patch
+ * @return
+ */
+ public static ResponseBuilder buildVersionResponse(String major, String minor, String patch) {
+ ResponseBuilder response = Response.noContent();
+ String versionIn = buildVersion(major,minor,patch);
+ String version = MusicUtil.getVersion();
+ String[] verArray = version.split("\\.",3);
+ if ( minor != null ) {
+ response.header(XMINORVERSION,minor);
+ } else {
+ response.header(XMINORVERSION,verArray[1]);
+ }
+ if ( patch != null ) {
+ response.header(XPATCHVERSION,patch);
+ } else {
+ response.header(XPATCHVERSION,verArray[2]);
+ }
+ response.header(XLATESTVERSION,version);
+ logger.info(EELFLoggerDelegate.applicationLogger,"Version In:" + versionIn);
+ return response;
+ }
+
+
+ public static void loadProperties() throws Exception {
+ Properties prop = new Properties();
+ InputStream input = null;
+ try {
+ // load the properties file
+ input = MusicUtil.class.getClassLoader().getResourceAsStream("music.properties");
+ prop.load(input);
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Unable to find properties file.");
+ throw new Exception();
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ // get the property value and return it
+ MusicUtil.setMyCassaHost(prop.getProperty("cassandra.host"));
+ String zkHosts = prop.getProperty("zookeeper.host");
+ MusicUtil.setMyZkHost(zkHosts);
+ MusicUtil.setCassName(prop.getProperty("cassandra.user"));
+ MusicUtil.setCassPwd(prop.getProperty("cassandra.password"));
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/main/PropertiesListener.java b/jar/src/main/java/org/onap/music/main/PropertiesListener.java
new file mode 100755
index 00000000..afd35387
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/PropertiesListener.java
@@ -0,0 +1,151 @@
+/*
+ * ============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.main;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+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);
+
+ @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");
+
+ // Open the file
+ try {
+ InputStream musicProps = null;
+ projectProp.load(new FileInputStream(musicPropertiesFilePath));
+ if (projectProp.containsKey("music.properties")) {
+ musicProps = new FileInputStream(projectProp.getProperty("music.properties"));
+ } else {
+ musicProps = new FileInputStream(MusicUtil.getMusicPropertiesFilePath());
+ }
+ prop.load(musicProps);
+ musicProps.close();
+ prop.putAll(projectProp);
+ String[] propKeys = MusicUtil.getPropkeys();
+ for (int k = 0; k < propKeys.length; k++) {
+ String key = propKeys[k];
+ if (prop.containsKey(key) && prop.get(key) != null) {
+ logger.info(key + " : " + prop.getProperty(key));
+ switch (key) {
+ case "zookeeper.host":
+ MusicUtil.setMyZkHost(prop.getProperty(key));
+ break;
+ case "cassandra.host":
+ MusicUtil.setMyCassaHost(prop.getProperty(key));
+ break;
+ case "music.ip":
+ MusicUtil.setDefaultMusicIp(prop.getProperty(key));
+ break;
+ case "debug":
+ MusicUtil.setDebug(Boolean
+ .getBoolean(prop.getProperty(key).toLowerCase()));
+ break;
+ case "version":
+ MusicUtil.setVersion(prop.getProperty(key));
+ break;
+ case "music.rest.ip":
+ MusicUtil.setMusicRestIp(prop.getProperty(key));
+ break;
+ case "music.properties":
+ MusicUtil.setMusicPropertiesFilePath(prop.getProperty(key));
+ break;
+ case "lock.lease.period":
+ MusicUtil.setDefaultLockLeasePeriod(
+ Long.parseLong(prop.getProperty(key)));
+ break;
+ case "my.id":
+ MusicUtil.setMyId(Integer.parseInt(prop.getProperty(key)));
+ break;
+ case "all.ids":
+ String[] ids = prop.getProperty(key).split(":");
+ MusicUtil.setAllIds(new ArrayList<String>(Arrays.asList(ids)));
+ break;
+ case "public.ip":
+ MusicUtil.setPublicIp(prop.getProperty(key));
+ break;
+ case "all.public.ips":
+ String[] ips = prop.getProperty(key).split(":");
+ if (ips.length == 1) {
+ // Future use
+ } else if (ips.length > 1) {
+ MusicUtil.setAllPublicIps(
+ new ArrayList<String>(Arrays.asList(ips)));
+ }
+ break;
+ case "cassandra.user":
+ MusicUtil.setCassName(prop.getProperty(key));
+ break;
+ case "cassandra.password":
+ MusicUtil.setCassPwd(prop.getProperty(key));
+ break;
+ case "aaf.endpoint.url":
+ MusicUtil.setAafEndpointUrl(prop.getProperty(key));
+ break;
+ default:
+ logger.error(EELFLoggerDelegate.errorLogger,
+ "No case found for " + key);
+ }
+ }
+ }
+ } catch (IOException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.IOERROR ,ErrorSeverity.CRITICAL, ErrorTypes.CONNECTIONERROR);
+ logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
+ }
+
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Starting MUSIC " + MusicUtil.getVersion() + " on node with id "
+ + MusicUtil.getMyId() + " and public ip "
+ + MusicUtil.getPublicIp() + "...");
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "List of all MUSIC ids:" + MusicUtil.getAllIds().toString());
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "List of all MUSIC public ips:" + MusicUtil.getAllPublicIps().toString());
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent servletContextEvent) {
+ prop = null;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/main/ResultType.java b/jar/src/main/java/org/onap/music/main/ResultType.java
new file mode 100644
index 00000000..61ba0295
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/ResultType.java
@@ -0,0 +1,41 @@
+/*
+ * ============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.main;
+
+public enum ResultType {
+ SUCCESS("Success"), FAILURE("Failure"),
+ SYNTAXERROR("SyntaxError"), EXCEPTION("Exception"),
+ BODYMISSING("Incomplete Request body. Please correct your input request and retry.");
+
+ private String result;
+
+ ResultType(String result) {
+ this.result = result;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+}
+
+
diff --git a/jar/src/main/java/org/onap/music/main/ReturnType.java b/jar/src/main/java/org/onap/music/main/ReturnType.java
new file mode 100644
index 00000000..1453a1bf
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/main/ReturnType.java
@@ -0,0 +1,74 @@
+/*
+ * ============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.main;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ReturnType {
+ private ResultType result;
+ private String message;
+
+ public ReturnType(ResultType result, String message) {
+ super();
+ this.result = result;
+ this.message = message;
+ }
+
+ public String getTimingInfo() {
+ return timingInfo;
+ }
+
+ public void setTimingInfo(String timingInfo) {
+ this.timingInfo = timingInfo;
+ }
+
+ private String timingInfo;
+
+ public ResultType getResult() {
+ return result;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String toJson() {
+ return "{ \"result\":\"" + result.getResult() + "\", \"message\":\"" + message + "\"}";
+ }
+
+ public String toString() {
+ return result + " | " + message;
+ }
+
+ public Map<String, Object> toMap() {
+ Map<String, Object> newMap = new HashMap<>();
+ newMap.put("result", result.getResult());
+ newMap.put("message", message);
+ return newMap;
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java b/jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java
new file mode 100644
index 00000000..a406afce
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/response/jsonobjects/JsonResponse.java
@@ -0,0 +1,265 @@
+/*
+ * ============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.response.jsonobjects;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.music.lockingservice.MusicLockState.LockStatus;
+import org.onap.music.main.ResultType;
+import org.powermock.core.spi.testresult.Result;
+
+import com.datastax.driver.core.ColumnDefinitions;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.ColumnDefinitions.Definition;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "JsonResponse", description = "General Response JSON")
+public class JsonResponse {
+
+ /* Status is required */
+ private ResultType status;
+
+ /* Standard informational fields */
+ private String error;
+ private String message;
+
+ /* versioning */
+ private String musicVersion;
+
+ /* Data Fields */
+ private Map<String, HashMap<String, Object>> dataResult;
+
+ /* Locking fields */
+ private String lock;
+ private LockStatus lockStatus;
+ private String lockHolder;
+ private String lockLease;
+
+
+ /**
+ * Create a JSONLock Response
+ * Use setters to provide more information as in
+ * JsonLockResponse(ResultType.SUCCESS).setMessage("We did it").setLock(mylockname)
+ * @param status
+ */
+ public JsonResponse(ResultType status) {
+ this.status = status;
+ }
+
+ /**
+ *
+ * @return
+ */
+ @ApiModelProperty(value = "Overall status of the response.",
+ allowableValues = "Success,Failure")
+ public ResultType getStatus() {
+ return status;
+ }
+
+ /**
+ *
+ * @param status
+ */
+ public JsonResponse setStatus(ResultType status) {
+ this.status = status;
+ return this;
+ }
+
+ /**
+ *
+ * @return the error
+ */
+ @ApiModelProperty(value = "Error value")
+ public String getError() {
+ return error;
+ }
+
+ /**
+ *
+ * @param error
+ */
+ public JsonResponse setError(String error) {
+ this.error = error;
+ return this;
+ }
+
+ /**
+ *
+ * @return the message
+ */
+ @ApiModelProperty(value = "Message value")
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ *
+ * @param message
+ */
+ public JsonResponse setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+
+ /**
+ *
+ * @return the music version
+ */
+ public String getMusicVersion() {
+ return this.musicVersion;
+ }
+
+ /**
+ *
+ * @param version of music
+ * @return
+ */
+ public JsonResponse setMusicVersion(String version) {
+ this.musicVersion = version;
+ return this;
+ }
+
+ public Map<String, HashMap<String, Object>> getDataResult() {
+ return this.dataResult;
+ }
+
+ public JsonResponse setDataResult(Map<String, HashMap<String, Object>> map) {
+ this.dataResult = map;
+ return this;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getLock() {
+ return lock;
+ }
+
+ /**
+ *
+ * @param lock
+ */
+ public JsonResponse setLock(String lock) {
+ this.lock = lock;
+ return this;
+ }
+
+ /**
+ *
+ * @return the lockStatus
+ */
+ @ApiModelProperty(value = "Status of the lock")
+ public LockStatus getLockStatus() {
+ return lockStatus;
+ }
+
+ /**
+ *
+ * @param lockStatus
+ */
+ public JsonResponse setLockStatus(LockStatus lockStatus) {
+ this.lockStatus = lockStatus;
+ return this;
+ }
+
+ /**
+ *
+ *
+ * @return the lockHolder
+ */
+ @ApiModelProperty(value = "Holder of the Lock")
+ public String getLockHolder() {
+ return lockHolder;
+ }
+
+ /**
+ *
+ * @param lockHolder
+ */
+ public JsonResponse setLockHolder(String lockHolder) {
+ this.lockHolder = lockHolder;
+ return this;
+ }
+
+
+
+ /**
+ * @return the lockLease
+ */
+ public String getLockLease() {
+ return lockLease;
+ }
+
+ /**
+ * @param lockLease the lockLease to set
+ */
+ public JsonResponse setLockLease(String lockLease) {
+ this.lockLease = lockLease;
+ return this;
+ }
+
+ /**
+ * Convert to Map
+ *
+ * @return
+ */
+ public Map<String, Object> toMap() {
+ Map<String, Object> fullMap = new HashMap<>();
+ fullMap.put("status", status);
+ if (error!=null) {fullMap.put("error", error);}
+ if (message!=null) {fullMap.put("message", message);}
+
+ if (musicVersion!=null) {fullMap.put("version", musicVersion);}
+
+ if (dataResult!=null) {
+ fullMap.put("result", dataResult);
+ }
+
+ if (lock!=null) {
+ Map<String, Object> lockMap = new HashMap<>();
+ if (lock!=null) {lockMap.put("lock", lock);}
+ if (lockStatus!=null) {lockMap.put("lock-status", lockStatus);}
+ if (lockHolder!=null) {lockMap.put("lock-holder", lockHolder);}
+ if (lockLease!=null) {lockMap.put("lock-lease", lockLease);}
+ fullMap.put("lock", lockMap);
+ }
+
+ return fullMap;
+ }
+
+ /**
+ * Convert to String
+ */
+ @Override
+ public String toString() {
+ return "JsonLockResponse [status=" + status + ", error=" + error + ", message=" + message
+ + ", lock=" + lock + ", lockStatus=" + lockStatus + ", lockHolder="
+ + lockHolder + "]";
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java
new file mode 100755
index 00000000..e7c7fb6c
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicAdminAPI.java
@@ -0,0 +1,372 @@
+/*
+ * ============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;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+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.JsonOnboard;
+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.CachingUtil;
+import org.onap.music.main.MusicCore;
+import org.onap.music.main.MusicUtil;
+import org.onap.music.main.ResultType;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Path("/v2/admin")
+// @Path("/v{version: [0-9]+}/admin")
+// @Path("/admin")
+@Api(value = "Admin Api", hidden = true)
+public class RestMusicAdminAPI {
+ private static EELFLoggerDelegate logger =
+ EELFLoggerDelegate.getLogger(RestMusicAdminAPI.class);
+
+ /*
+ * API to onboard an application with MUSIC. This is the mandatory first step.
+ *
+ */
+ @POST
+ @Path("/onboardAppWithMusic")
+ @ApiOperation(value = "Onboard application", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response onboardAppWithMusic(JsonOnboard jsonObj) throws Exception {
+ ResponseBuilder response =
+ Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
+ Map<String, Object> resultMap = new HashMap<>();
+ String appName = jsonObj.getAppname();
+ String userId = jsonObj.getUserId();
+ String isAAF = jsonObj.getIsAAF();
+ String password = jsonObj.getPassword();
+ if (appName == null || userId == null || isAAF == null || password == null) {
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO,
+ ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ resultMap.put("Exception",
+ "Unauthorized: Please check the request parameters. Some of the required values appName(ns), userId, password, isAAF are missing.");
+ return Response.status(Status.UNAUTHORIZED).entity(resultMap).build();
+ }
+
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "select uuid from admin.keyspace_master where application_name = ? allow filtering");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ ResultSet rs = MusicCore.get(pQuery);
+ if (!rs.all().isEmpty()) {
+ resultMap.put("Exception", "Application " + appName
+ + " has already been onboarded. Please contact admin.");
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+
+ pQuery = new PreparedQueryObject();
+ String uuid = CachingUtil.generateUUID();
+ pQuery.appendQueryString(
+ "INSERT INTO admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
+ + "password, username, is_aaf) VALUES (?,?,?,?,?,?,?)");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
+ MusicUtil.DEFAULTKEYSPACENAME));
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
+ 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));
+
+ String returnStr = MusicCore.eventualPut(pQuery).toString();
+ if (returnStr.contains("Failure")) {
+ resultMap.put("Exception",
+ "Oops. Something wrong with onboarding process. Please retry later or contact admin.");
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ CachingUtil.updateisAAFCache(appName, isAAF);
+ resultMap.put("Success", "Your application " + appName + " has been onboarded with MUSIC.");
+ resultMap.put("Generated AID", uuid);
+ return Response.status(Status.OK).entity(resultMap).build();
+ }
+
+
+ @POST
+ @Path("/search")
+ @ApiOperation(value = "Search Onboard application", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getOnboardedInfoSearch(JsonOnboard jsonObj) throws Exception {
+ Map<String, Object> resultMap = new HashMap<>();
+ ResponseBuilder response =
+ Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
+ String appName = jsonObj.getAppname();
+ String uuid = jsonObj.getAid();
+ String isAAF = jsonObj.getIsAAF();
+
+ if (appName == null && uuid == null && isAAF == null) {
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO,
+ 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();
+ }
+
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ String cql = "select uuid, keyspace_name from admin.keyspace_master where ";
+ if (appName != null)
+ cql = cql + "application_name = ? AND ";
+ if (uuid != null)
+ cql = cql + "uuid = ? AND ";
+ if (isAAF != null)
+ cql = cql + "is_aaf = ?";
+
+ if (cql.endsWith("AND "))
+ cql = cql.trim().substring(0, cql.length() - 4);
+ System.out.println("Query is: " + cql);
+ cql = cql + " allow filtering";
+ System.out.println("Get OnboardingInfo CQL: " + cql);
+ pQuery.appendQueryString(cql);
+ if (appName != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ if (uuid != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
+ if (isAAF != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(),
+ Boolean.parseBoolean(isAAF)));
+ ResultSet rs = MusicCore.get(pQuery);
+ Iterator<Row> it = rs.iterator();
+ while (it.hasNext()) {
+ Row row = (Row) it.next();
+ resultMap.put(row.getUUID("uuid").toString(), row.getString("keyspace_name"));
+ }
+ if (resultMap.isEmpty()) {
+ if (uuid != null) {
+ resultMap.put("Exception",
+ "Please make sure Aid is correct and application is onboarded.");
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ } else {
+ resultMap.put("Exception",
+ "Application is not onboarded. Please make sure all the information is correct.");
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ }
+ return Response.status(Status.OK).entity(resultMap).build();
+ }
+
+
+ @DELETE
+ @Path("/onboardAppWithMusic")
+ @ApiOperation(value = "Delete Onboard application", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response deleteOnboardApp(JsonOnboard jsonObj) throws Exception {
+ Map<String, Object> resultMap = new HashMap<>();
+ ResponseBuilder response =
+ Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
+ String appName = jsonObj.getAppname();
+ String aid = jsonObj.getAid();
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ String consistency = MusicUtil.EVENTUAL;;
+ if (appName == null && aid == null) {
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGINFO,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ resultMap.put("Exception", "Please make sure either appName(ns) or Aid is present");
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ if (aid != null) {
+ pQuery.appendQueryString(
+ "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
+ UUID.fromString(aid)));
+ Row row = MusicCore.get(pQuery).one();
+ if (row != null) {
+ String ks = row.getString("keyspace_name");
+ if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) {
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("DROP KEYSPACE IF EXISTS " + ks + ";");
+ MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ }
+ }
+ pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ? IF EXISTS");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
+ UUID.fromString(aid)));
+ ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency);
+ if (result == ResultType.SUCCESS) {
+ resultMap.put("Success", "Your application has been deleted successfully");
+ } else {
+ resultMap.put("Exception",
+ "Oops. Something went wrong. Please make sure Aid is correct or Application is onboarded");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+
+ }
+ return Response.status(Status.OK).entity(resultMap).build();
+ }
+
+ pQuery.appendQueryString(
+ "select uuid from admin.keyspace_master where application_name = ? allow filtering");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ ResultSet rs = MusicCore.get(pQuery);
+ List<Row> rows = rs.all();
+ String uuid = null;
+ if (rows.size() == 0) {
+ resultMap.put("Exception",
+ "Application not found. Please make sure Application exists.");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ } else if (rows.size() == 1) {
+ uuid = rows.get(0).getUUID("uuid").toString();
+ pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "SELECT keyspace_name FROM admin.keyspace_master WHERE uuid = ?");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
+ UUID.fromString(uuid)));
+ Row row = MusicCore.get(pQuery).one();
+ String ks = row.getString("keyspace_name");
+ if (!ks.equals(MusicUtil.DEFAULTKEYSPACENAME)) {
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("DROP KEYSPACE " + ks + ";");
+ MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ }
+
+ pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(),
+ UUID.fromString(uuid)));
+ MusicCore.eventualPut(pQuery);
+ resultMap.put("Success", "Your application " + appName + " has been deleted.");
+ return Response.status(Status.OK).entity(resultMap).build();
+ } else {
+ resultMap.put("Failure",
+ "More than one Aid exists for this application, so please provide Aid.");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MULTIPLERECORDS,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ }
+
+
+ @PUT
+ @Path("/onboardAppWithMusic")
+ @ApiOperation(value = "Update Onboard application", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response updateOnboardApp(JsonOnboard jsonObj) throws Exception {
+ Map<String, Object> resultMap = new HashMap<>();
+ ResponseBuilder response =
+ Response.noContent().header("X-latestVersion", MusicUtil.getVersion());
+ String aid = jsonObj.getAid();
+ String appName = jsonObj.getAppname();
+ String userId = jsonObj.getUserId();
+ String isAAF = jsonObj.getIsAAF();
+ String password = jsonObj.getPassword();
+ String consistency = "eventual";
+ PreparedQueryObject pQuery;
+
+ if (aid == null) {
+ resultMap.put("Exception", "Please make sure Aid is present");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+
+ if (appName == null && userId == null && password == null && isAAF == null) {
+ resultMap.put("Exception",
+ "No parameters found to update. Please update atleast one parameter.");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.MISSINGDATA,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+
+ if (appName != null) {
+ pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "select uuid from admin.keyspace_master where application_name = ? allow filtering");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ ResultSet rs = MusicCore.get(pQuery);
+ if (!rs.all().isEmpty()) {
+ resultMap.put("Exception", "Application " + appName
+ + " has already been onboarded. Please contact admin.");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.ALREADYEXIST,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ }
+
+ pQuery = new PreparedQueryObject();
+ StringBuilder preCql = new StringBuilder("UPDATE admin.keyspace_master SET ");
+ if (appName != null)
+ preCql.append(" application_name = ?,");
+ if (userId != null)
+ preCql.append(" username = ?,");
+ if (password != null)
+ preCql.append(" password = ?,");
+ if (isAAF != null)
+ preCql.append(" is_aaf = ?,");
+ preCql.deleteCharAt(preCql.length() - 1);
+ preCql.append(" WHERE uuid = ? IF EXISTS");
+ pQuery.appendQueryString(preCql.toString());
+ if (appName != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ if (userId != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
+ if (password != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), BCrypt.hashpw(password, BCrypt.gensalt())));
+ if (isAAF != null)
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
+
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), UUID.fromString(aid)));
+ ResultType result = MusicCore.nonKeyRelatedPut(pQuery, consistency);
+
+ if (result == ResultType.SUCCESS) {
+ resultMap.put("Success", "Your application has been updated successfully");
+ } else {
+ resultMap.put("Exception",
+ "Oops. Something went wrong. Please make sure Aid is correct and application is onboarded");
+ logger.error(EELFLoggerDelegate.errorLogger, "", AppMessages.INCORRECTDATA,
+ ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+
+ return Response.status(Status.OK).entity(resultMap).build();
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java
new file mode 100644
index 00000000..55eb47f2
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicBmAPI.java
@@ -0,0 +1,307 @@
+/*
+ * ============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.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+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.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+import org.onap.music.datastore.jsonobjects.JsonInsert;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+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.datastore.PreparedQueryObject;
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TableMetadata;
+import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import io.swagger.annotations.ApiParam;
+
+/*
+ * These are functions created purely for benchmarking purposes. Commented out Swagger - This should
+ * be undocumented API
+ *
+ */
+@Path("/v{version: [0-9]+}/benchmarks/")
+@Api(value = "Benchmark API", hidden = true)
+public class RestMusicBmAPI {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicBmAPI.class);
+
+ // pure zk calls...
+
+ /**
+ *
+ * @param nodeName
+ * @throws Exception
+ */
+ @POST
+ @Path("/purezk/{name}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void pureZkCreate(@PathParam("name") String nodeName) throws Exception {
+ MusicCore.pureZkCreate("/" + nodeName);
+ }
+
+
+ /**
+ *
+ * @param insObj
+ * @param nodeName
+ * @throws Exception
+ */
+ @PUT
+ @Path("/purezk/{name}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void pureZkUpdate(JsonInsert insObj, @PathParam("name") String nodeName)
+ throws Exception {
+ logger.info(EELFLoggerDelegate.applicationLogger,"--------------Zk normal update-------------------------");
+ long start = System.currentTimeMillis();
+ MusicCore.pureZkWrite(nodeName, insObj.serialize());
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Total time taken for Zk normal update:" + (end - start) + " ms");
+ }
+
+ /**
+ *
+ * @param nodeName
+ * @return
+ * @throws Exception
+ */
+ @GET
+ @Path("/purezk/{name}")
+ @Consumes(MediaType.TEXT_PLAIN)
+ public byte[] pureZkGet(@PathParam("name") String nodeName) throws Exception {
+ return MusicCore.pureZkRead(nodeName);
+ }
+
+ /**
+ *
+ * @param insObj
+ * @param lockName
+ * @param nodeName
+ * @throws Exception
+ */
+ @PUT
+ @Path("/purezk/atomic/{lockname}/{name}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void pureZkAtomicPut(JsonInsert updateObj, @PathParam("lockname") String lockname,
+ @PathParam("name") String nodeName) throws Exception {
+ long startTime = System.currentTimeMillis();
+ String operationId = UUID.randomUUID().toString();// just for debugging purposes.
+ String consistency = updateObj.getConsistencyInfo().get("type");
+
+ logger.info(EELFLoggerDelegate.applicationLogger,"--------------Zookeeper " + consistency + " update-" + operationId
+ + "-------------------------");
+
+ byte[] data = updateObj.serialize();
+ long jsonParseCompletionTime = System.currentTimeMillis();
+
+ String lockId = MusicCore.createLockReference(lockname);
+
+ long lockCreationTime = System.currentTimeMillis();
+
+ long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
+ ReturnType lockAcqResult = MusicCore.acquireLockWithLease(lockname, lockId, leasePeriod);
+ long lockAcqTime = System.currentTimeMillis();
+ long zkPutTime = 0, lockReleaseTime = 0;
+
+ if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
+ MusicCore.pureZkWrite(lockname, data);
+ zkPutTime = System.currentTimeMillis();
+ boolean voluntaryRelease = true;
+ if (consistency.equals("atomic"))
+ MusicCore.releaseLock(lockId, voluntaryRelease);
+ else if (consistency.equals("atomic_delete_lock"))
+ MusicCore.deleteLock(lockname);
+ lockReleaseTime = System.currentTimeMillis();
+ } else {
+ MusicCore.destroyLockRef(lockId);
+ }
+
+ long actualUpdateCompletionTime = System.currentTimeMillis();
+
+
+ long endTime = System.currentTimeMillis();
+
+ String lockingInfo = "|lock creation time:" + (lockCreationTime - jsonParseCompletionTime)
+ + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
+ + "|zk put time:" + (zkPutTime - lockAcqTime);
+
+ if (consistency.equals("atomic"))
+ lockingInfo = lockingInfo + "|lock release time:" + (lockReleaseTime - zkPutTime) + "|";
+ else if (consistency.equals("atomic_delete_lock"))
+ lockingInfo = lockingInfo + "|lock delete time:" + (lockReleaseTime - zkPutTime) + "|";
+
+ String timingString = "Time taken in ms for Zookeeper " + consistency + " update-"
+ + operationId + ":" + "|total operation time:" + (endTime - startTime)
+ + "|json parsing time:" + (jsonParseCompletionTime - startTime)
+ + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
+ + lockingInfo;
+
+ logger.info(EELFLoggerDelegate.applicationLogger,timingString);
+ }
+
+ /**
+ *
+ * @param insObj
+ * @param lockName
+ * @param nodeName
+ * @throws Exception
+ */
+ @GET
+ @Path("/purezk/atomic/{lockname}/{name}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void pureZkAtomicGet(JsonInsert insObj, @PathParam("lockname") String lockName,
+ @PathParam("name") String nodeName) throws Exception {
+ logger.info("--------------Zk atomic read-------------------------");
+ long start = System.currentTimeMillis();
+ String lockId = MusicCore.createLockReference(lockName);
+ long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
+ ReturnType lockAcqResult = MusicCore.acquireLockWithLease(lockName, lockId, leasePeriod);
+ if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
+ logger.info("acquired lock with id " + lockId);
+ MusicCore.pureZkRead(nodeName);
+ boolean voluntaryRelease = true;
+ MusicCore.releaseLock(lockId, voluntaryRelease);
+ } else {
+ MusicCore.destroyLockRef(lockId);
+ }
+
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,"Total time taken for Zk atomic read:" + (end - start) + " ms");
+ }
+
+ /**
+ *
+ * doing an update directly to cassa but through the rest api
+ *
+ * @param insObj
+ * @param keyspace
+ * @param tablename
+ * @param info
+ * @return
+ * @throws Exception
+ */
+ @PUT
+ @Path("/cassa/keyspaces/{keyspace}/tables/{tablename}/rows")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public boolean updateTableCassa(JsonInsert insObj, @PathParam("keyspace") String keyspace,
+ @PathParam("tablename") String tablename, @Context UriInfo info)
+ throws Exception {
+ long startTime = System.currentTimeMillis();
+ String operationId = UUID.randomUUID().toString();// just for debugging purposes.
+ String consistency = insObj.getConsistencyInfo().get("type");
+ logger.info(EELFLoggerDelegate.applicationLogger,"--------------Cassandra " + consistency + " update-" + operationId
+ + "-------------------------");
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ Map<String, Object> valuesMap = insObj.getValues();
+ TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
+ String vectorTs = "'" + Thread.currentThread().getId() + System.currentTimeMillis() + "'";
+ String fieldValueString = "vector_ts= ? ,";
+ queryObject.addValue(vectorTs);
+
+ int counter = 0;
+ for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
+ Object valueObj = entry.getValue();
+ DataType colType = tableInfo.getColumn(entry.getKey()).getType();
+ Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
+ fieldValueString = fieldValueString + entry.getKey() + "= ?";
+ queryObject.addValue(valueString);
+ if (counter != valuesMap.size() - 1)
+ fieldValueString = fieldValueString + ",";
+ counter = counter + 1;
+ }
+
+ // get the row specifier
+ String rowSpec = "";
+ counter = 0;
+ queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
+ MultivaluedMap<String, String> rowParams = info.getQueryParameters();
+ String primaryKey = "";
+ for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
+ String keyName = entry.getKey();
+ List<String> valueList = entry.getValue();
+ String indValue = valueList.get(0);
+ DataType colType = tableInfo.getColumn(entry.getKey()).getType();
+ Object formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
+ primaryKey = primaryKey + indValue;
+ rowSpec = rowSpec + keyName + "= ? ";
+ queryObject.addValue(formattedValue);
+ if (counter != rowParams.size() - 1)
+ rowSpec = rowSpec + " AND ";
+ counter = counter + 1;
+ }
+
+
+ String ttl = insObj.getTtl();
+ String timestamp = insObj.getTimestamp();
+
+ if ((ttl != null) && (timestamp != null)) {
+
+ logger.info(EELFLoggerDelegate.applicationLogger,"both there");
+ queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ if ((ttl != null) && (timestamp == null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"ONLY TTL there");
+ queryObject.appendQueryString(" USING TTL ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ }
+
+ if ((ttl == null) && (timestamp != null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"ONLY timestamp there");
+ queryObject.appendQueryString(" USING TIMESTAMP ?");
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+ queryObject.appendQueryString(" SET " + fieldValueString + " WHERE " + rowSpec + ";");
+
+ long jsonParseCompletionTime = System.currentTimeMillis();
+
+ boolean operationResult = true;
+ MusicCore.getDSHandle().executePut(queryObject, insObj.getConsistencyInfo().get("type"));
+
+ long actualUpdateCompletionTime = System.currentTimeMillis();
+
+ long endTime = System.currentTimeMillis();
+
+ String timingString = "Time taken in ms for Cassandra " + consistency + " update-"
+ + operationId + ":" + "|total operation time:" + (endTime - startTime)
+ + "|json parsing time:" + (jsonParseCompletionTime - startTime)
+ + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
+ + "|";
+ logger.info(EELFLoggerDelegate.applicationLogger,timingString);
+
+ return operationResult;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java
new file mode 100755
index 00000000..47d1eae7
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicDataAPI.java
@@ -0,0 +1,1289 @@
+/*
+ * ============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.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+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.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+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.mindrot.jbcrypt.BCrypt;
+import org.onap.music.datastore.PreparedQueryObject;
+import org.onap.music.datastore.jsonobjects.JsonDelete;
+import org.onap.music.datastore.jsonobjects.JsonInsert;
+import org.onap.music.datastore.jsonobjects.JsonKeySpace;
+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.exceptions.MusicLockingException;
+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.MusicServiceException;
+import org.onap.music.main.CachingUtil;
+import org.onap.music.main.MusicCore;
+import org.onap.music.main.MusicCore.Condition;
+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 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;
+
+/* Version 2 Class */
+//@Path("/v{version: [0-9]+}/keyspaces")
+@Path("/v2/keyspaces")
+@Api(value = "Data Api")
+public class RestMusicDataAPI {
+ /*
+ * Header values for Versioning X-minorVersion *** - Used to request or communicate a MINOR
+ * version back from the client to the server, and from the server back to the client - This
+ * will be the MINOR version requested by the client, or the MINOR version of the last MAJOR
+ * version (if not specified by the client on the request) - Contains a single position value
+ * (e.g. if the full version is 1.24.5, X-minorVersion = "24") - Is optional for the client on
+ * request; however, this header should be provided if the client needs to take advantage of
+ * MINOR incremented version functionality - Is mandatory for the server on response
+ *
+ *** X-patchVersion *** - Used only to communicate a PATCH version in a response for
+ * troubleshooting purposes only, and will not be provided by the client on request - This will
+ * be the latest PATCH version of the MINOR requested by the client, or the latest PATCH version
+ * of the MAJOR (if not specified by the client on the request) - Contains a single position
+ * value (e.g. if the full version is 1.24.5, X-patchVersion = "5") - Is mandatory for the
+ * server on response (CURRENTLY NOT USED)
+ *
+ *** X-latestVersion *** - Used only to communicate an API's latest version - Is mandatory for the
+ * server on response, and shall include the entire version of the API (e.g. if the full version
+ * is 1.24.5, X-latestVersion = "1.24.5") - Used in the response to inform clients that they are
+ * not using the latest version of the API (CURRENTLY NOT USED)
+ *
+ */
+
+ 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";
+
+ private class RowIdentifier {
+ public String primarKeyValue;
+ public StringBuilder rowIdString;
+ @SuppressWarnings("unused")
+ public PreparedQueryObject queryObject;// the string with all the row
+ // identifiers separated by AND
+
+ public RowIdentifier(String primaryKeyValue, StringBuilder rowIdString,
+ PreparedQueryObject queryObject) {
+ this.primarKeyValue = primaryKeyValue;
+ this.rowIdString = rowIdString;
+ this.queryObject = queryObject;
+ }
+ }
+
+
+ /**
+ * Create Keyspace REST
+ *
+ * @param kspObject
+ * @param keyspaceName
+ * @return
+ * @throws Exception
+ */
+ @POST
+ @Path("/{name}")
+ @ApiOperation(value = "Create Keyspace", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ //public Map<String, Object> createKeySpace(
+ public Response createKeySpace(
+ @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
+ @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 = "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, Object> authMap = CachingUtil.verifyOnboarding(ns, userId, password);
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ response.status(Status.UNAUTHORIZED);
+ return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ if(kspObject == null || kspObject.getReplicationInfo() == null) {
+ authMap.put(ResultType.EXCEPTION.getResult(), ResultType.BODYMISSING.getResult());
+ response.status(Status.BAD_REQUEST);
+ return response.entity(authMap).build();
+ }
+
+ try {
+ authMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "createKeySpace");
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ response.status(Status.BAD_REQUEST);
+ return response.entity(new JsonResponse(ResultType.FAILURE).setError("Unable to authenticate.").toMap()).build();
+ }
+ String newAid = null;
+ if (!authMap.isEmpty()) {
+ if (authMap.containsKey("aid")) {
+ newAid = (String) authMap.get("aid");
+ } else {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ response.status(Status.UNAUTHORIZED);
+ return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ }
+
+ String consistency = MusicUtil.EVENTUAL;// for now this needs only
+ // eventual consistency
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ long start = System.currentTimeMillis();
+ Map<String, Object> replicationInfo = kspObject.getReplicationInfo();
+ String repString = null;
+ try {
+ repString = "{" + MusicUtil.jsonMaptoSqlString(replicationInfo, ",") + "}";
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+
+ }
+ queryObject.appendQueryString(
+ "CREATE KEYSPACE " + keyspaceName + " WITH replication = " + repString);
+ if (kspObject.getDurabilityOfWrites() != null) {
+ queryObject.appendQueryString(
+ " AND durable_writes = " + kspObject.getDurabilityOfWrites());
+ }
+
+ queryObject.appendQueryString(";");
+ long end = System.currentTimeMillis();
+ logger.info(EELFLoggerDelegate.applicationLogger,
+ "Time taken for setting up query in create keyspace:" + (end - start));
+
+ ResultType result = ResultType.FAILURE;
+ try {
+ result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ logger.info(EELFLoggerDelegate.applicationLogger, "result = " + result);
+ } catch ( MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("err:" + ex.getMessage()).toMap()).build();
+ }
+
+ try {
+ queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("CREATE ROLE IF NOT EXISTS '" + userId
+ + "' WITH PASSWORD = '" + password + "' AND LOGIN = true;");
+ MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("GRANT ALL PERMISSIONS on KEYSPACE " + keyspaceName
+ + " to '" + userId + "'");
+ queryObject.appendQueryString(";");
+ MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ }
+
+ 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, "
+ + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
+ queryObject.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), newAid));
+ 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(), hashedpwd));
+ queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
+ queryObject.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
+ CachingUtil.updateMusicCache(keyspaceName, ns);
+ CachingUtil.updateMusicValidateCache(ns, userId, hashedpwd);
+ MusicCore.eventualPut(queryObject);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Response.Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+
+ return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Created").toMap()).build();
+ }
+
+ /**
+ *
+ * @param kspObject
+ * @param keyspaceName
+ * @return
+ * @throws Exception
+ */
+ @DELETE
+ @Path("/{name}")
+ @ApiOperation(value = "Delete Keyspace", response = String.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ //public Map<String, Object> dropKeySpace(
+ public Response dropKeySpace(
+ @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
+ @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 = "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, Object> authMap = MusicCore.autheticateUser(ns, userId, password,keyspaceName, aid, "dropKeySpace");
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ return response.status(Status.UNAUTHORIZED).entity(authMap).build();
+ }
+
+ String consistency = MusicUtil.EVENTUAL;// for now this needs only
+ // eventual
+ // consistency
+ String appName = CachingUtil.getAppName(keyspaceName);
+ String uuid = CachingUtil.getUuidFromMusicCache(keyspaceName);
+ PreparedQueryObject pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "select count(*) as count from admin.keyspace_master where application_name=? allow filtering;");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), appName));
+ Row row = MusicCore.get(pQuery).one();
+ long count = row.getLong(0);
+
+ if (count == 0) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Keyspace not found. Please make sure keyspace exists.").toMap()).build();
+ // Admin Functions:
+ } else if (count == 1) {
+ pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString(
+ "UPDATE admin.keyspace_master SET keyspace_name=? where uuid = ?;");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
+ MusicUtil.DEFAULTKEYSPACENAME));
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
+ MusicCore.nonKeyRelatedPut(pQuery, consistency);
+ } else {
+ pQuery = new PreparedQueryObject();
+ pQuery.appendQueryString("delete from admin.keyspace_master where uuid = ?");
+ pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
+ MusicCore.nonKeyRelatedPut(pQuery, consistency);
+ }
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ queryObject.appendQueryString("DROP KEYSPACE " + keyspaceName + ";");
+ ResultType result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ if ( result.equals(ResultType.FAILURE) ) {
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Deleteing Keyspace " + keyspaceName).toMap()).build();
+ }
+ return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("Keyspace " + keyspaceName + " Deleted").toMap()).build();
+ }
+
+ /**
+ *
+ * @param tableObj
+ * @param version
+ * @param keyspace
+ * @param tablename
+ * @param headers
+ * @return
+ * @throws Exception
+ */
+ @POST
+ @Path("/{keyspace}/tables/{tablename}")
+ @ApiOperation(value = "Create Table", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ //public Map<String, Object> createTable(
+ public Response createTable(
+ @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
+ @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 = "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 = "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, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
+ aid, "createTable");
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ String consistency = MusicUtil.EVENTUAL;
+ // for now this needs only eventual consistency
+ 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(')'));
+ }
+ 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;
+ }
+ // information about the name-value style properties
+ Map<String, Object> propertiesMap = tableObj.getProperties();
+ StringBuilder propertiesString = new StringBuilder();
+ if (propertiesMap != null) {
+ counter = 0;
+ for (Map.Entry<String, Object> entry : propertiesMap.entrySet()) {
+ Object ot = entry.getValue();
+ String value = ot + "";
+ if (ot instanceof String) {
+ value = "'" + value + "'";
+ } else if (ot instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> otMap = (Map<String, Object>) ot;
+ value = "{" + MusicUtil.jsonMaptoSqlString(otMap, ",") + "}";
+ }
+
+ propertiesString.append(entry.getKey() + "=" + value + "");
+ if (counter != propertiesMap.size() - 1)
+ propertiesString.append(" AND ");
+
+ counter = counter + 1;
+ }
+ }
+
+ queryObject.appendQueryString(
+ "CREATE TABLE " + keyspace + "." + tablename + " " + fieldsString);
+
+ if (propertiesMap != null)
+ queryObject.appendQueryString(" WITH " + propertiesString);
+
+ queryObject.appendQueryString(";");
+ ResultType result = ResultType.FAILURE;
+
+ try {
+ result = MusicCore.nonKeyRelatedPut(queryObject, consistency);
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.MUSICSERVICEERROR);
+ response.status(Status.BAD_REQUEST);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
+ }
+ if ( result.equals(ResultType.FAILURE) ) {
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(result).setError("Error Creating Table " + tablename).toMap()).build();
+ }
+ return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setMessage("TableName " + tablename + " Created under keyspace " + keyspace).toMap()).build();
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param fieldName
+ * @param info
+ * @throws Exception
+ */
+ @POST
+ @Path("/{keyspace}/tables/{tablename}/index/{field}")
+ @ApiOperation(value = "Create Index", response = String.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createIndex(
+ @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
+ @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 = "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("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, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "createIndex");
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ response.status(Status.UNAUTHORIZED);
+ return response.entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ MultivaluedMap<String, String> rowParams = info.getQueryParameters();
+ String indexName = "";
+ 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 + "."
+ + tablename + " (" + fieldName + ");");
+
+ ResultType result = ResultType.FAILURE;
+ try {
+ result = MusicCore.nonKeyRelatedPut(query, "eventual");
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ response.status(Status.BAD_REQUEST);
+ 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();
+ } else {
+ return response.entity(new JsonResponse(result).setError("Unknown Error in create index.").toMap()).build();
+ }
+ }
+
+ /**
+ *
+ * @param insObj
+ * @param keyspace
+ * @param tablename
+ * @return
+ * @throws Exception
+ */
+ @POST
+ @Path("/{keyspace}/tables/{tablename}/rows")
+ @ApiOperation(value = "Insert Into Table", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response insertIntoTable(
+ @ApiParam(value = "Major Version",required = true) @PathParam("version") String version,
+ @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 = "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 = "Keyspace Name",
+ required = true) @PathParam("keyspace") String keyspace,
+ @ApiParam(value = "Table Name",
+ required = true) @PathParam("tablename") String tablename) {
+ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
+
+ Map<String, Object> authMap = null;
+
+ try {
+ authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
+ aid, "insertIntoTable");
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+
+ Map<String, Object> valuesMap = insObj.getValues();
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ TableMetadata tableInfo = null;
+ try {
+ tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
+ if(tableInfo == null) {
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Table name doesn't exists. Please check the table name.").toMap()).build();
+ }
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();
+ StringBuilder fieldsString = new StringBuilder("(vector_ts,");
+ String vectorTs =
+ String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
+ StringBuilder valueString = new StringBuilder("(" + "?" + ",");
+ queryObject.addValue(vectorTs);
+ int counter = 0;
+ String primaryKey = "";
+
+ for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
+ fieldsString.append("" + entry.getKey());
+ Object valueObj = entry.getValue();
+ if (primaryKeyName.equals(entry.getKey())) {
+ primaryKey = entry.getValue() + "";
+ primaryKey = primaryKey.replace("'", "''");
+ }
+ DataType colType = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ } catch(NullPointerException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() +" Invalid column name : "+entry.getKey(), AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.DATAERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
+ }
+
+ Object formattedValue = null;
+ try {
+ formattedValue = MusicUtil.convertToActualDataType(colType, valueObj);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
+ }
+ valueString.append("?");
+ queryObject.addValue(formattedValue);
+
+ if (counter == valuesMap.size() - 1) {
+ fieldsString.append(")");
+ valueString.append(")");
+ } else {
+ fieldsString.append(",");
+ valueString.append(",");
+ }
+ counter = counter + 1;
+ }
+
+ 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();
+ }
+
+ queryObject.appendQueryString("INSERT INTO " + keyspace + "." + tablename + " "
+ + fieldsString + " VALUES " + valueString);
+
+ String ttl = insObj.getTtl();
+ String timestamp = insObj.getTimestamp();
+
+ if ((ttl != null) && (timestamp != null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "both there");
+ queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ if ((ttl != null) && (timestamp == null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "ONLY TTL there");
+ queryObject.appendQueryString(" USING TTL ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ }
+
+ if ((ttl == null) && (timestamp != null)) {
+ logger.info(EELFLoggerDelegate.applicationLogger, "ONLY timestamp there");
+ queryObject.appendQueryString(" USING TIMESTAMP ?");
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ queryObject.appendQueryString(";");
+
+ ReturnType result = null;
+ String consistency = insObj.getConsistencyInfo().get("type");
+ try {
+ if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
+ result = MusicCore.eventualPut(queryObject);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ String lockId = insObj.getConsistencyInfo().get("lockId");
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
+ }
+ result = MusicCore.criticalPut(keyspace, tablename, primaryKey, queryObject, lockId,null);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ result = MusicCore.atomicPut(keyspace, tablename, primaryKey, queryObject, null);
+
+ }
+ else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
+ result = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, primaryKey, queryObject, null);
+
+ }
+ } catch (Exception ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
+ }
+
+ if (result==null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
+ }
+ return response.status(Status.OK).entity(new JsonResponse(result.getResult()).setMessage("Insert Successful").toMap()).build();
+ }
+
+ /**
+ *
+ * @param insObj
+ * @param keyspace
+ * @param tablename
+ * @param info
+ * @return
+ * @throws Exception
+ */
+ @PUT
+ @Path("/{keyspace}/tables/{tablename}/rows")
+ @ApiOperation(value = "Update Table", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response updateTable(
+ @ApiParam(value = "Major Version",
+ required = true) @PathParam("version") String version,
+ @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 = "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 = "Keyspace Name",
+ required = true) @PathParam("keyspace") String keyspace,
+ @ApiParam(value = "Table Name",
+ required = true) @PathParam("tablename") String tablename,
+ @Context UriInfo info) {
+ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
+
+ Map<String, Object> authMap;
+ try {
+ authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
+ aid, "updateTable");
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ long startTime = System.currentTimeMillis();
+ String operationId = UUID.randomUUID().toString();// just for infoging
+ // purposes.
+ String consistency = updateObj.getConsistencyInfo().get("type");
+ logger.info(EELFLoggerDelegate.applicationLogger, "--------------Music " + consistency
+ + " update-" + operationId + "-------------------------");
+ // obtain the field value pairs of the update
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ Map<String, Object> valuesMap = updateObj.getValues();
+
+ TableMetadata tableInfo;
+ try {
+ tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
+ } catch (MusicServiceException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
+ .setError("Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename).toMap()).build();
+ }
+ String vectorTs =
+ String.valueOf(Thread.currentThread().getId() + System.currentTimeMillis());
+ StringBuilder fieldValueString = new StringBuilder("vector_ts=?,");
+ queryObject.addValue(vectorTs);
+ int counter = 0;
+ for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
+ Object valueObj = entry.getValue();
+ DataType colType = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ } catch(NullPointerException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger, "Invalid column name : "+entry.getKey());
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Invalid column name : "+entry.getKey()).toMap()).build();
+ }
+ Object valueString = null;
+ try {
+ valueString = MusicUtil.convertToActualDataType(colType, valueObj);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
+ }
+ fieldValueString.append(entry.getKey() + "= ?");
+ queryObject.addValue(valueString);
+ if (counter != valuesMap.size() - 1)
+ fieldValueString.append(",");
+ counter = counter + 1;
+ }
+ String ttl = updateObj.getTtl();
+ String timestamp = updateObj.getTimestamp();
+
+ queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
+ if ((ttl != null) && (timestamp != null)) {
+
+ logger.info("both there");
+ queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+
+ if ((ttl != null) && (timestamp == null)) {
+ logger.info("ONLY TTL there");
+ queryObject.appendQueryString(" USING TTL ?");
+ queryObject.addValue(Integer.parseInt(ttl));
+ }
+
+ if ((ttl == null) && (timestamp != null)) {
+ logger.info("ONLY timestamp there");
+ queryObject.appendQueryString(" USING TIMESTAMP ?");
+ queryObject.addValue(Long.parseLong(timestamp));
+ }
+ // get the row specifier
+ RowIdentifier rowId = null;
+ try {
+ rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
+ if(rowId == null || rowId.primarKeyValue.isEmpty()) {
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
+ .setError("Mandatory WHERE clause is missing. Please check the input request.").toMap()).build();
+ }
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
+ }
+
+ queryObject.appendQueryString(
+ " SET " + fieldValueString + " WHERE " + rowId.rowIdString + ";");
+
+ // get the conditional, if any
+ Condition conditionInfo;
+ if (updateObj.getConditions() == null)
+ conditionInfo = null;
+ else {// to avoid parsing repeatedly, just send the select query to
+ // obtain row
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
+ + rowId.rowIdString + ";");
+ selectQuery.addValue(rowId.primarKeyValue);
+ conditionInfo = new MusicCore.Condition(updateObj.getConditions(), selectQuery);
+ }
+
+ ReturnType operationResult = null;
+ long jsonParseCompletionTime = System.currentTimeMillis();
+
+ if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
+ operationResult = MusicCore.eventualPut(queryObject);
+ else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ String lockId = updateObj.getConsistencyInfo().get("lockId");
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
+ }
+ operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
+ queryObject, lockId, conditionInfo);
+ } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
+ // this function is mainly for the benchmarks
+ try {
+ operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename,
+ rowId.primarKeyValue, queryObject, conditionInfo);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ try {
+ operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
+ queryObject, conditionInfo);
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ }
+ long actualUpdateCompletionTime = System.currentTimeMillis();
+
+ long endTime = System.currentTimeMillis();
+ String timingString = "Time taken in ms for Music " + consistency + " update-" + operationId
+ + ":" + "|total operation time:" + (endTime - startTime)
+ + "|json parsing time:" + (jsonParseCompletionTime - startTime)
+ + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
+ + "|";
+
+ if (operationResult != null && operationResult.getTimingInfo() != null) {
+ String lockManagementTime = operationResult.getTimingInfo();
+ timingString = timingString + lockManagementTime;
+ }
+ logger.info(EELFLoggerDelegate.applicationLogger, timingString);
+
+ if (operationResult==null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Null result - Please Contact admin", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
+ }
+ if ( operationResult.getResult() == ResultType.SUCCESS ) {
+ return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
+ } else {
+ logger.error(EELFLoggerDelegate.errorLogger,operationResult.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(operationResult.getResult()).setError(operationResult.getMessage()).toMap()).build();
+ }
+
+ }
+
+ /**
+ *
+ * @param delObj
+ * @param keyspace
+ * @param tablename
+ * @param info
+ * @return
+ * @throws Exception
+ */
+ @DELETE
+ @Path("/{keyspace}/tables/{tablename}/rows")
+ @ApiOperation(value = "Delete From table", response = String.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response deleteFromTable(
+ @ApiParam(value = "Major Version",
+ required = true) @PathParam("version") String version,
+ @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 = "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 = "Keyspace Name",
+ required = true) @PathParam("keyspace") String keyspace,
+ @ApiParam(value = "Table Name",
+ required = true) @PathParam("tablename") String tablename,
+ @Context UriInfo info) {
+ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
+
+ Map<String, Object> authMap = null;
+ try {
+ authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,
+ aid, "deleteFromTable");
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ if(delObj == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGDATA ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Required HTTP Request body is missing.").toMap()).build();
+ }
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ StringBuilder columnString = new StringBuilder();
+
+ int counter = 0;
+ ArrayList<String> columnList = delObj.getColumns();
+ if (columnList != null) {
+ for (String column : columnList) {
+ columnString.append(column);
+ if (counter != columnList.size() - 1)
+ columnString.append(",");
+ counter = counter + 1;
+ }
+ }
+
+ // get the row specifier
+ RowIdentifier rowId = null;
+ try {
+ rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
+ }
+ String rowSpec = rowId.rowIdString.toString();
+
+ if ((columnList != null) && (!rowSpec.isEmpty())) {
+ queryObject.appendQueryString("DELETE " + columnString + " FROM " + keyspace + "."
+ + tablename + " WHERE " + rowSpec + ";");
+ }
+
+ if ((columnList == null) && (!rowSpec.isEmpty())) {
+ queryObject.appendQueryString("DELETE FROM " + keyspace + "." + tablename + " WHERE "
+ + rowSpec + ";");
+ }
+
+ if ((columnList != null) && (rowSpec.isEmpty())) {
+ queryObject.appendQueryString(
+ "DELETE " + columnString + " FROM " + keyspace + "." + rowSpec + ";");
+ }
+ // get the conditional, if any
+ Condition conditionInfo;
+ if (delObj.getConditions() == null)
+ conditionInfo = null;
+ else {// to avoid parsing repeatedly, just send the select query to
+ // obtain row
+ PreparedQueryObject selectQuery = new PreparedQueryObject();
+ selectQuery.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + " WHERE "
+ + rowId.rowIdString + ";");
+ selectQuery.addValue(rowId.primarKeyValue);
+ conditionInfo = new MusicCore.Condition(delObj.getConditions(), selectQuery);
+ }
+
+ String consistency = delObj.getConsistencyInfo().get("type");
+
+ ReturnType operationResult = null;
+ try {
+ if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
+ operationResult = MusicCore.eventualPut(queryObject);
+ else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ String lockId = delObj.getConsistencyInfo().get("lockId");
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
+ }
+ operationResult = MusicCore.criticalPut(keyspace, tablename, rowId.primarKeyValue,
+ queryObject, lockId, conditionInfo);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ operationResult = MusicCore.atomicPut(keyspace, tablename, rowId.primarKeyValue,
+ queryObject, conditionInfo);
+ }
+ else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
+ operationResult = MusicCore.atomicPutWithDeleteLock(keyspace, tablename, rowId.primarKeyValue,
+ queryObject, conditionInfo);
+ }
+ } catch (MusicLockingException e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE)
+ .setError("Unable to perform Delete operation. Exception from music").toMap()).build();
+ }
+ if (operationResult==null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Null result - Please Contact admin").toMap()).build();
+ }
+ if (operationResult.getResult().equals(ResultType.SUCCESS)) {
+ return response.status(Status.OK).entity(new JsonResponse(operationResult.getResult()).setMessage(operationResult.getMessage()).toMap()).build();
+ } else {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(operationResult.getMessage()).toMap()).build();
+ }
+ }
+
+ /**
+ *
+ * @param tabObj
+ * @param keyspace
+ * @param tablename
+ * @throws Exception
+ */
+ @DELETE
+ @Path("/{keyspace}/tables/{tablename}")
+ @ApiOperation(value = "Drop Table", response = String.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response dropTable(
+ @ApiParam(value = "Major Version",
+ required = true) @PathParam("version") String version,
+ @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 = "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("keyspace") String keyspace,
+ @ApiParam(value = "Table Name",
+ required = true) @PathParam("tablename") String tablename) throws Exception {
+ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
+
+ Map<String, Object> authMap =
+ MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "dropTable");
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ String consistency = "eventual";// for now this needs only eventual
+ // consistency
+ PreparedQueryObject query = new PreparedQueryObject();
+ query.appendQueryString("DROP TABLE " + keyspace + "." + tablename + ";");
+ try {
+ return response.status(Status.OK).entity(new JsonResponse(MusicCore.nonKeyRelatedPut(query, consistency)).toMap()).build();
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
+ }
+
+ }
+
+ /**
+ *
+ * @param selObj
+ * @param keyspace
+ * @param tablename
+ * @param info
+ * @return
+ */
+ @PUT
+ @Path("/{keyspace}/tables/{tablename}/rows/criticalget")
+ @ApiOperation(value = "Select Critical", response = Map.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response selectCritical(
+ @ApiParam(value = "Major Version",
+ required = true) @PathParam("version") String version,
+ @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 = "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 selObj,
+ @ApiParam(value = "Keyspace Name",
+ required = true) @PathParam("keyspace") String keyspace,
+ @ApiParam(value = "Table Name",
+ required = true) @PathParam("tablename") String tablename,
+ @Context UriInfo info) throws Exception {
+ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
+
+ Map<String, Object> authMap = MusicCore.autheticateUser(ns, userId, password, keyspace,aid, "selectCritical");
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"Error while authentication... ", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ String lockId = selObj.getConsistencyInfo().get("lockId");
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ RowIdentifier rowId = null;
+ try {
+ rowId = getRowIdentifier(keyspace, tablename, info.getQueryParameters(), queryObject);
+ } catch (MusicServiceException ex) {
+ logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(ex.getMessage()).toMap()).build();
+ }
+ queryObject.appendQueryString(
+ "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowId.rowIdString + ";");
+
+ ResultSet results = null;
+
+ String consistency = selObj.getConsistencyInfo().get("type");
+
+ if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
+ if(lockId == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
+ + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("LockId cannot be null. Create lock "
+ + "and acquire lock or use ATOMIC instead of CRITICAL").toMap()).build();
+ }
+ results = MusicCore.criticalGet(keyspace, tablename, rowId.primarKeyValue, queryObject,
+ lockId);
+ } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
+ results = MusicCore.atomicGet(keyspace, tablename, rowId.primarKeyValue, queryObject);
+ }
+
+ else if (consistency.equalsIgnoreCase(MusicUtil.ATOMICDELETELOCK)) {
+ results = MusicCore.atomicGetWithDeleteLock(keyspace, tablename, rowId.primarKeyValue, queryObject);
+ }
+
+ return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).setDataResult(MusicCore.marshallResults(results)).toMap()).build();
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param info
+ * @return
+ * @throws Exception
+ */
+ @GET
+ @Path("/{keyspace}/tables/{tablename}/rows")
+ @ApiOperation(value = "Select All or Select Specific", response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response select(
+ @ApiParam(value = "Major Version",
+ required = true) @PathParam("version") String version,
+ @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 = "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("keyspace") String keyspace,
+ @ApiParam(value = "Table Name",
+ required = true) @PathParam("tablename") String tablename,
+ @Context UriInfo info) throws Exception {
+ ResponseBuilder response = MusicUtil.buildVersionResponse(VERSION, minorVersion, patchVersion);
+
+ Map<String, Object> authMap =
+ MusicCore.autheticateUser(ns, userId, password, keyspace, aid, "select");
+ if (authMap.containsKey("aid"))
+ authMap.remove("aid");
+ if (!authMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(new JsonResponse(ResultType.FAILURE).setError(String.valueOf(authMap.get("Exception"))).toMap()).build();
+ }
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+
+ if (info.getQueryParameters().isEmpty())// select all
+ queryObject.appendQueryString("SELECT * FROM " + keyspace + "." + tablename + ";");
+ else {
+ int limit = -1; // do not limit the number of results
+ try {
+ queryObject = 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
+ * @param limit
+ * @return
+ * @throws MusicServiceException
+ */
+ public PreparedQueryObject selectSpecificQuery(String version, String minorVersion,
+ String patchVersion, String aid, String ns, String userId, String password,
+ String keyspace, String tablename, UriInfo info, int limit)
+ throws MusicServiceException {
+
+ PreparedQueryObject queryObject = new PreparedQueryObject();
+ StringBuilder rowIdString = getRowIdentifier(keyspace, tablename, info.getQueryParameters(),
+ queryObject).rowIdString;
+
+ queryObject.appendQueryString(
+ "SELECT * FROM " + keyspace + "." + tablename + " WHERE " + rowIdString);
+
+ if (limit != -1) {
+ queryObject.appendQueryString(" LIMIT " + limit);
+ }
+
+ queryObject.appendQueryString(";");
+ return queryObject;
+
+ }
+
+ /**
+ *
+ * @param keyspace
+ * @param tablename
+ * @param rowParams
+ * @param queryObject
+ * @return
+ * @throws MusicServiceException
+ */
+ private RowIdentifier getRowIdentifier(String keyspace, String tablename,
+ MultivaluedMap<String, String> rowParams, PreparedQueryObject queryObject)
+ throws MusicServiceException {
+ StringBuilder rowSpec = new StringBuilder();
+ int counter = 0;
+ TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
+ if (tableInfo == null) {
+ logger.error(EELFLoggerDelegate.errorLogger,
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ throw new MusicServiceException(
+ "Table information not found. Please check input for table name= "
+ + keyspace + "." + tablename);
+ }
+ StringBuilder primaryKey = new StringBuilder();
+ for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
+ String keyName = entry.getKey();
+ List<String> valueList = entry.getValue();
+ String indValue = valueList.get(0);
+ DataType colType = null;
+ Object formattedValue = null;
+ try {
+ colType = tableInfo.getColumn(entry.getKey()).getType();
+ formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
+ }
+ primaryKey.append(indValue);
+ rowSpec.append(keyName + "= ?");
+ queryObject.addValue(formattedValue);
+ if (counter != rowParams.size() - 1)
+ rowSpec.append(" AND ");
+ counter = counter + 1;
+ }
+ return new RowIdentifier(primaryKey.toString(), rowSpec, queryObject);
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java
new file mode 100644
index 00000000..752a538b
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicHealthCheckAPI.java
@@ -0,0 +1,113 @@
+/*
+ * ============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.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 io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+
+
+
+@Path("/v{version: [0-9]+}/service")
+@Api(value="Healthcheck Api")
+public class RestMusicHealthCheckAPI {
+
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
+
+
+ @GET
+ @Path("/cs")
+ @ApiOperation(value = "Get Health Status", response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response cassandraStatus(@Context HttpServletResponse response) {
+ logger.info(EELFLoggerDelegate.applicationLogger,"Replying to request for MUSIC Health Check status for Cassandra");
+
+ Map<String, Object> resultMap = new HashMap<>();
+
+ MusicHealthCheck cassHealthCheck = new MusicHealthCheck();
+ String status = cassHealthCheck.getCassandraStatus();
+ 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", "Cassandra Service is not responding");
+ return Response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+
+
+
+ }
+
+ @GET
+ @Path("/zk")
+ @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/jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java
new file mode 100644
index 00000000..22112ddf
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicLocksAPI.java
@@ -0,0 +1,423 @@
+/*
+ * ============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.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+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.onap.music.datastore.jsonobjects.JsonLeasedLock;
+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.lockingservice.MusicLockState;
+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 io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+
+@Path("/v2/locks/")
+@Api(value="Lock Api")
+public class RestMusicLocksAPI {
+
+ private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicLocksAPI.class);
+ private static final String XMINORVERSION = "X-minorVersion";
+ private static final String XPATCHVERSION = "X-patchVersion";
+ private static final String VERSION = "v2";
+
+ /**
+ * Puts the requesting process in the q for this lock. The corresponding
+ * node will be created in zookeeper if it did not already exist
+ *
+ * @param lockName
+ * @return
+ * @throws Exception
+ */
+ @POST
+ @Path("/create/{lockname}")
+ @ApiOperation(value = "Create Lock",
+ notes = "Puts the requesting process in the q for this lock." +
+ " The corresponding node will be created in zookeeper if it did not already exist." +
+ " Lock Name is the \"key\" of the form keyspaceName.tableName.rowId",
+ response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createLockReference(
+ @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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "createLockReference");
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.CRITICAL, ErrorTypes.AUTHENTICATIONERROR);
+ return response.status(Status.UNAUTHORIZED).entity(resultMap).build();
+ }
+ ResultType status = ResultType.SUCCESS;
+ String lockId = MusicCore.createLockReference(lockName);
+
+ if (lockId == null) {
+ status = ResultType.FAILURE;
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError("Lock Id is null").toMap()).build();
+ }
+ return response.status(Status.OK).entity(new JsonResponse(status).setLock(lockId).toMap()).build();
+ }
+
+ /**
+ *
+ * Checks if the node is in the top of the queue and hence acquires the lock
+ *
+ * @param lockId
+ * @return
+ * @throws Exception
+ */
+ @GET
+ @Path("/acquire/{lockreference}")
+ @ApiOperation(value = "Aquire Lock",
+ notes = "Checks if the node is in the top of the queue and hence acquires the lock",
+ response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response accquireLock(
+ @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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "accquireLock");
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ try {
+ String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
+ ReturnType lockStatus = MusicCore.acquireLock(lockName,lockId);
+ if ( lockStatus.getResult().equals(ResultType.SUCCESS)) {
+ response.status(Status.OK);
+ } else {
+ response.status(Status.BAD_REQUEST);
+ }
+ return response.entity(new JsonResponse(lockStatus.getResult()).setLock(lockId).setMessage(lockStatus.getMessage()).toMap()).build();
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId, ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError("Unable to aquire lock").toMap()).build();
+ }
+ }
+
+
+
+
+ @POST
+ @Path("/acquire-with-lease/{lockreference}")
+ @ApiOperation(value = "Aquire Lock with Lease", response = Map.class)
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response accquireLockWithLease(JsonLeasedLock lockObj,
+ @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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "accquireLockWithLease");
+
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ String lockName = lockId.substring(lockId.indexOf('$')+1, lockId.lastIndexOf('$'));
+ ReturnType lockLeaseStatus = MusicCore.acquireLockWithLease(lockName, lockId, lockObj.getLeasePeriod());
+ if ( lockLeaseStatus.getResult().equals(ResultType.SUCCESS)) {
+ response.status(Status.OK);
+ } else {
+ response.status(Status.BAD_REQUEST);
+ }
+ return response.entity(new JsonResponse(lockLeaseStatus.getResult()).setLock(lockName)
+ .setMessage(lockLeaseStatus.getMessage())
+ .setLockLease(String.valueOf(lockObj.getLeasePeriod())).toMap()).build();
+ }
+
+
+ @GET
+ @Path("/enquire/{lockname}")
+ @ApiOperation(value = "Get Lock Holder",
+ notes = "Gets the current Lock Holder",
+ response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response currentLockHolder(
+ @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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "currentLockHolder");
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ String who = MusicCore.whoseTurnIsIt(lockName);
+ ResultType status = ResultType.SUCCESS;
+ String error = "";
+ if ( who == null ) {
+ status = ResultType.FAILURE;
+ error = "There was a problem getting the lock holder";
+ logger.error(EELFLoggerDelegate.errorLogger,"There was a problem getting the lock holder", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
+ }
+ return response.status(Status.OK).entity(new JsonResponse(status).setError(error).setLock(lockName).setLockHolder(who).toMap()).build();
+ }
+
+ @GET
+ @Path("/{lockname}")
+ @ApiOperation(value = "Lock State",
+ notes = "Returns current Lock State and Holder.",
+ response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response currentLockState(
+ @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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "currentLockState");
+
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+
+ MusicLockState mls = MusicCore.getMusicLockState(lockName);
+ Map<String,Object> returnMap = null;
+ JsonResponse jsonResponse = new JsonResponse(ResultType.FAILURE).setLock(lockName);
+ if(mls == null) {
+ jsonResponse.setError("");
+ jsonResponse.setMessage("No lock object created yet..");
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(jsonResponse.toMap()).build();
+ } else {
+ jsonResponse.setStatus(ResultType.SUCCESS);
+ jsonResponse.setLockStatus(mls.getLockStatus());
+ jsonResponse.setLockHolder(mls.getLockHolder());
+ return response.status(Status.OK).entity(jsonResponse.toMap()).build();
+ }
+ }
+
+ /**
+ *
+ * deletes the process from the zk queue
+ *
+ * @param lockId
+ * @throws Exception
+ */
+ @DELETE
+ @Path("/release/{lockreference}")
+ @ApiOperation(value = "Release Lock",
+ notes = "deletes the process from the zk queue",
+ response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ 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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "unLock");
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ boolean voluntaryRelease = true;
+ MusicLockState mls = MusicCore.releaseLock(lockId,voluntaryRelease);
+ if(mls.getErrorMessage() != null) {
+ resultMap.put(ResultType.EXCEPTION.getResult(), mls.getErrorMessage());
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.INCORRECTDATA ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ Map<String,Object> returnMap = null;
+ if (mls.getLockStatus() == MusicLockState.LockStatus.UNLOCKED) {
+ returnMap = new JsonResponse(ResultType.SUCCESS).setLock(lockId)
+ .setLockStatus(mls.getLockStatus()).toMap();
+ response.status(Status.OK);
+ }
+ if (mls.getLockStatus() == MusicLockState.LockStatus.LOCKED) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.LOCKINGERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ returnMap = new JsonResponse(ResultType.FAILURE).setLock(lockId)
+ .setLockStatus(mls.getLockStatus()).toMap();
+ response.status(Status.BAD_REQUEST);
+ }
+ return response.entity(returnMap).build();
+ }
+
+ /**
+ *
+ * @param lockName
+ * @throws Exception
+ */
+ @DELETE
+ @Path("/delete/{lockname}")
+ @ApiOperation(value = "Delete Lock", response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response deleteLock(@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 = "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{
+ 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();
+ }
+ String keyspaceName = (String) resultMap.get("keyspace");
+ resultMap.remove("keyspace");
+ resultMap = MusicCore.autheticateUser(ns, userId, password, keyspaceName, aid,
+ "deleteLock");
+ if (resultMap.containsKey("aid"))
+ resultMap.remove("aid");
+ if (!resultMap.isEmpty()) {
+ logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.UNKNOWNERROR ,ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR);
+ return response.status(Status.BAD_REQUEST).entity(resultMap).build();
+ }
+ try{
+ MusicCore.deleteLock(lockName);
+ }catch (Exception e) {
+ return response.status(Status.BAD_REQUEST).entity(new JsonResponse(ResultType.FAILURE).setError(e.getMessage()).toMap()).build();
+ }
+ return response.status(Status.OK).entity(new JsonResponse(ResultType.SUCCESS).toMap()).build();
+ }
+
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java
new file mode 100755
index 00000000..e08adaf7
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicQAPI.java
@@ -0,0 +1,251 @@
+/*
+ * ============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;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+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.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+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.datastore.PreparedQueryObject;
+import com.datastax.driver.core.ResultSet;
+
+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")
+public class RestMusicQAPI {
+
+ private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicDataAPI.class);
+
+
+ /**
+ *
+ * @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 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);
+ }
+
+ /**
+ *
+ * @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);
+ }
+
+ /**
+ *
+ * @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);
+ }
+
+ /**
+ *
+ * @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(
+ @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);
+
+ }
+
+ /**
+ *
+ *
+ * @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);
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java
new file mode 100644
index 00000000..287fa176
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicTestAPI.java
@@ -0,0 +1,67 @@
+/*
+ * ============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;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+import org.onap.music.main.MusicUtil;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+
+@Path("/v{version: [0-9]+}/test")
+@Api(value="Test Api")
+public class RestMusicTestAPI {
+
+ @SuppressWarnings("unused")
+ private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicTestAPI.class);
+
+ /**
+ * Returns a test JSON. This will confirm that REST is working.
+ * @return
+ */
+ @GET
+ @ApiOperation(value = "Get Test", response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Map<String, HashMap<String, String>> simpleTests(
+ @Context HttpServletResponse response) {
+ response.addHeader("X-latestVersion",MusicUtil.getVersion());
+ Map<String, HashMap<String, String>> testMap = new HashMap<>();
+ for(int i=0; i < 3; i++){
+ HashMap<String, String> innerMap = new HashMap<>();
+ innerMap.put(i+"", i+1+"");
+ innerMap.put(i+1+"", i+2+"");
+ testMap.put(i+"", innerMap);
+ }
+ return testMap;
+ }
+}
diff --git a/jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java b/jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java
new file mode 100644
index 00000000..a5f2ac49
--- /dev/null
+++ b/jar/src/main/java/org/onap/music/rest/RestMusicVersionAPI.java
@@ -0,0 +1,63 @@
+/*
+ * ============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.Map;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+import org.onap.music.response.jsonobjects.JsonResponse;
+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 io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+
+@Path("/v{version: [0-9]+}/version")
+@Api(value="Version Api")
+public class RestMusicVersionAPI {
+
+ private EELFLoggerDelegate logger =EELFLoggerDelegate.getLogger(RestMusicVersionAPI.class);
+
+ /**
+ * Get the version of MUSIC
+ * @return
+ */
+ @GET
+ @ApiOperation(value = "Get Version", response = Map.class)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Map<String,Object> version(@Context HttpServletResponse response) {
+ logger.info("Replying to request for MUSIC version with MUSIC:" + MusicUtil.getVersion());
+ response.addHeader("X-latestVersion",MusicUtil.getVersion());
+ return new JsonResponse(ResultType.SUCCESS).setMusicVersion("MUSIC:" + MusicUtil.getVersion()).toMap();
+ }
+} \ No newline at end of file
diff --git a/jar/src/main/resources/LICENSE.txt b/jar/src/main/resources/LICENSE.txt
new file mode 100644
index 00000000..cc6cdea5
--- /dev/null
+++ b/jar/src/main/resources/LICENSE.txt
@@ -0,0 +1,24 @@
+
+The following license applies to all files in this and sub-directories. Licenses
+are included in individual source files where appropriate, and if it differs
+from this text, it supersedes this. Any file that does not have license text
+defaults to being covered by this text; not all files support the addition of
+licenses.
+#
+# -------------------------------------------------------------------------
+# 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.
+#
+# -------------------------------------------------------------------------
+# \ No newline at end of file
diff --git a/jar/src/main/resources/Resources.properties b/jar/src/main/resources/Resources.properties
new file mode 100644
index 00000000..72269cb8
--- /dev/null
+++ b/jar/src/main/resources/Resources.properties
@@ -0,0 +1,50 @@
+#============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=============================================
+#====================================================================
+#Resource key=Error Code|Message text|Resolution text |Description text
+LOADING_DEFAULT_LOG_CONFIGURATION=\
+ EELF0001I|\
+ Loading default logging configuration from system resource file "{0}"|\
+ No external logging configurations were defined or found, So verify the default logging configuration from system resource file (../logback.xml). |\
+ Loading default logging configuration from system resource file
+LOADING_LOG_CONFIGURATION=EELF0002I|\
+ Loading logging configuration from file "{0}"|\
+ Verify the correct logging configuration file is loaded. |\
+ Loading logging configuration for specific file
+LOGGING_ALREADY_INITIALIZED=\
+ EELF0003W|\
+ Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.|\
+ Verify the container logging definitions to ensure they represent your desired logging configuration. |\
+ Logging has already been initialized, check the container logging definitions to ensure they represent your desired logging configuration.
+NO_LOG_CONFIGURATION=\
+ EELF0004E|\
+ No log configuration could be found or defaulted!|\
+ No external and default logging configuration file. |\
+ No log configuration could be found or defaulted!
+SEARCHING_LOG_CONFIGURATION=\
+ EELF0005I|\
+ Searching path "{0}" for log configuration file "{1}"|\
+ Verify the correct Path({user.home};etc;../etc) and filename (eelf.logging.file).|\
+ Searching path for specific log configuration file.
+UNSUPPORTED_LOGGING_FRAMEWORK=\
+ EELF0006E|\
+ An unsupported logging framework is bound to SLF4J. |\
+ Verify your logging frameworks.|\
+ An unsupported logging framework is bound to SLF4J.
+
diff --git a/jar/src/main/resources/cache.ccf b/jar/src/main/resources/cache.ccf
new file mode 100644
index 00000000..acc6831c
--- /dev/null
+++ b/jar/src/main/resources/cache.ccf
@@ -0,0 +1,56 @@
+# DEFAULT CACHE REGION
+jcs.default=
+jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.default.cacheattributes.MaxObjects=1000
+jcs.default.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.default.cacheattributes.UseMemoryShrinker=false
+jcs.default.cacheattributes.MaxMemoryIdleTime=3600
+jcs.default.cacheattributes.ShrinkerInterval=60
+jcs.default.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.default.elementattributes.IsEternal=false
+jcs.default.elementattributes.MaxLife=21600
+jcs.default.elementattributes.IdleTime=1800
+jcs.default.elementattributes.IsSpool=true
+jcs.default.elementattributes.IsRemote=true
+jcs.default.elementattributes.IsLateral=true
+
+# PRE-DEFINED CACHE REGIONS
+jcs.region.musicCache=
+jcs.region.musicCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.musicCache.cacheattributes.MaxObjects=1000
+jcs.region.musicCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.musicCache.cacheattributes.UseMemoryShrinker=false
+jcs.region.musicCache.cacheattributes.MaxMemoryIdleTime=3600
+jcs.region.musicCache.cacheattributes.ShrinkerInterval=60
+jcs.region.musicCache.cacheattributes.MaxSpoolPerRun=500
+jcs.region.musicCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.musicCache.elementattributes.IsEternal=false
+
+
+# PRE-DEFINED CACHE REGIONS
+jcs.region.aafCache=
+jcs.region.aafCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.aafCache.cacheattributes.MaxObjects=1000
+jcs.region.aafCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.aafCache.cacheattributes.UseMemoryShrinker=false
+jcs.region.aafCache.cacheattributes.MaxMemoryIdleTime=3600
+jcs.region.aafCache.cacheattributes.ShrinkerInterval=60
+jcs.region.aafCache.cacheattributes.MaxSpoolPerRun=500
+jcs.region.aafCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.aafCache.elementattributes.IsEternal=false
+
+# PRE-DEFINED CACHE REGIONS
+jcs.region.appNameCache=
+jcs.region.appNameCache.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes
+jcs.region.appNameCache.cacheattributes.MaxObjects=1000
+jcs.region.appNameCache.cacheattributes.MemoryCacheName=org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.appNameCache.cacheattributes.UseMemoryShrinker=false
+jcs.region.appNameCache.cacheattributes.MaxMemoryIdleTime=3600
+jcs.region.appNameCache.cacheattributes.ShrinkerInterval=60
+jcs.region.appNameCache.cacheattributes.MaxSpoolPerRun=500
+jcs.region.appNameCache.elementattributes=org.apache.commons.jcs.engine.ElementAttributes
+jcs.region.appNameCache.elementattributes.IsEternal=false
+
+
+
+
diff --git a/jar/src/main/resources/logback.xml b/jar/src/main/resources/logback.xml
new file mode 100644
index 00000000..fe7f54ae
--- /dev/null
+++ b/jar/src/main/resources/logback.xml
@@ -0,0 +1,270 @@
+<!--
+ ============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=============================================
+ ====================================================================
+-->
+<configuration scan="true" scanPeriod="3 seconds">
+ <!--<jmxConfigurator /> -->
+ <!-- directory path for all other type logs -->
+ <property name="logDir" value="/opt/app/music/logs" />
+
+ <!-- directory path for debugging type logs -->
+ <property name="debugDir" value="debug-logs" />
+
+ <!-- specify the component name -->
+ <!-- <property name="componentName" value="EELF"></property> -->
+ <property name="componentName" value="MUSIC"></property>
+
+ <!-- log file names -->
+ <property name="generalLogName" value="music" />
+ <property name="securityLogName" value="security" />
+ <property name="errorLogName" value="error" />
+ <property name="metricsLogName" value="metrics" />
+ <property name="auditLogName" value="audit" />
+ <property name="debugLogName" value="debug" />
+ <property name="defaultPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
+ <property name="applicationLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n" />
+ <property name="auditLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" />
+ <property name="metricsLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" />
+ <property name="errorLoggerPattern" value= "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n " />
+ <property name="debugLoggerPattern" value="%date{ISO8601,UTC}|%X{RequestId}| %msg%n" ></property>
+ <property name="logDirectory" value="${logDir}/${componentName}" />
+ <property name="debugLogDirectory" value="${debugDir}/${componentName}" />
+ <!-- Example evaluator filter applied against console appender -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <!-- <encoder>
+ <pattern>${defaultPattern}</pattern>
+ </encoder> -->
+ <layout class="">
+ <pattern>
+ %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </layout>
+ </appender>
+
+ <!-- ============================================================================ -->
+ <!-- EELF Appenders -->
+ <!-- ============================================================================ -->
+ <appender name="EELF"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${generalLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${generalLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${applicationLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <includeCallerData>true</includeCallerData>
+ <appender-ref ref="EELF" />
+ </appender>
+
+ <!-- EELF Security Appender. This appender is used to record security events
+ to the security log file. Security events are separate from other loggers
+ in EELF so that security log records can be captured and managed in a secure
+ way separate from the other logs. This appender is set to never discard any
+ events. -->
+ <appender name="EELFSecurity"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${securityLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${securityLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n </pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELFSecurity" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <discardingThreshold>0</discardingThreshold>
+ <appender-ref ref="EELFSecurity" />
+ </appender>
+
+
+
+
+ <!-- EELF Audit Appender. This appender is used to record audit engine
+ related logging events. The audit logger and appender are specializations
+ of the EELF application root logger and appender. This can be used to segregate
+ Policy engine events from other components, or it can be eliminated to record
+ these events as part of the application root log. -->
+
+ <appender name="EELFAudit"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${auditLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${auditLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFAudit" />
+ </appender>
+
+<appender name="EELFMetrics"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${metricsLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>${metricsLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+
+ <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFMetrics"/>
+ </appender>
+
+ <appender name="EELFError"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${errorLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${errorLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFError"/>
+ </appender>
+
+ <appender name="EELFDebug"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${debugLogDirectory}/${debugLogName}.log</file>
+ <rollingPolicy
+ class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${debugLogDirectory}/${debugLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy
+ class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${debugLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFDebug" />
+ <includeCallerData>true</includeCallerData>
+ </appender>
+
+
+ <!-- ============================================================================ -->
+ <!-- EELF loggers -->
+ <!-- ============================================================================ -->
+ <logger name="com.att.eelf" level="info" additivity="false">
+ <appender-ref ref="asyncEELF" />
+
+ </logger>
+ <logger name="com.att.eelf.security" level="info" additivity="false">
+ <appender-ref ref="asyncEELFSecurity" />
+
+ </logger>
+
+
+ <logger name="com.att.eelf.audit" level="info" additivity="false">
+ <appender-ref ref="asyncEELFAudit" />
+
+ </logger>
+
+ <logger name="com.att.eelf.metrics" level="info" additivity="false">
+ <appender-ref ref="asyncEELFMetrics" />
+
+ </logger>
+
+
+ <logger name="com.att.eelf.error" level="error" additivity="false">
+ <appender-ref ref="asyncEELFError" />
+
+ </logger>
+
+ <logger name="com.att.eelf.debug" level="debug" additivity="false">
+ <appender-ref ref="asyncEELFDebug" />
+
+ </logger>
+
+
+
+
+ <root level="INFO">
+ <appender-ref ref="asyncEELF" />
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
diff --git a/jar/src/main/resources/project.properties b/jar/src/main/resources/project.properties
new file mode 100644
index 00000000..199afa33
--- /dev/null
+++ b/jar/src/main/resources/project.properties
@@ -0,0 +1,4 @@
+version=${project.version}
+artifactId=${project.artifactId}
+music.properties=/opt/app/music/etc/music.properties
+