summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openecomp/sparky/dal
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openecomp/sparky/dal')
-rw-r--r--src/main/java/org/openecomp/sparky/dal/NetworkTransaction.java135
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryAdapter.java418
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryDataProvider.java91
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryEntityStatistics.java307
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java139
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryConfig.java159
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryRestConfig.java283
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventorySslConfig.java217
-rw-r--r--src/main/java/org/openecomp/sparky/dal/aai/enums/RestAuthenticationMode.java69
-rw-r--r--src/main/java/org/openecomp/sparky/dal/cache/EntityCache.java63
-rw-r--r--src/main/java/org/openecomp/sparky/dal/cache/InMemoryEntityCache.java101
-rw-r--r--src/main/java/org/openecomp/sparky/dal/cache/PersistentEntityCache.java305
-rw-r--r--src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchAdapter.java165
-rw-r--r--src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchDataProvider.java66
-rw-r--r--src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java274
-rw-r--r--src/main/java/org/openecomp/sparky/dal/elasticsearch/HashQueryResponse.java59
-rw-r--r--src/main/java/org/openecomp/sparky/dal/elasticsearch/SearchAdapter.java122
-rw-r--r--src/main/java/org/openecomp/sparky/dal/elasticsearch/config/ElasticSearchConfig.java543
-rw-r--r--src/main/java/org/openecomp/sparky/dal/exception/ElasticSearchOperationException.java54
-rw-r--r--src/main/java/org/openecomp/sparky/dal/rest/HttpMethod.java34
-rw-r--r--src/main/java/org/openecomp/sparky/dal/rest/OperationResult.java198
-rw-r--r--src/main/java/org/openecomp/sparky/dal/rest/RestClientBuilder.java148
-rw-r--r--src/main/java/org/openecomp/sparky/dal/rest/RestDataProvider.java112
-rw-r--r--src/main/java/org/openecomp/sparky/dal/rest/RestOperationalStatistics.java256
-rw-r--r--src/main/java/org/openecomp/sparky/dal/rest/RestfulDataAccessor.java357
-rw-r--r--src/main/java/org/openecomp/sparky/dal/sas/config/SearchServiceConfig.java224
-rw-r--r--src/main/java/org/openecomp/sparky/dal/servlet/ResettableStreamHttpServletRequest.java129
27 files changed, 5028 insertions, 0 deletions
diff --git a/src/main/java/org/openecomp/sparky/dal/NetworkTransaction.java b/src/main/java/org/openecomp/sparky/dal/NetworkTransaction.java
new file mode 100644
index 0000000..0a679cf
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/NetworkTransaction.java
@@ -0,0 +1,135 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal;
+
+import org.openecomp.sparky.config.oxm.OxmEntityDescriptor;
+import org.openecomp.sparky.dal.rest.HttpMethod;
+import org.openecomp.sparky.dal.rest.OperationResult;
+
+/**
+ * The Class NetworkTransaction.
+ */
+public class NetworkTransaction {
+
+ private OperationResult operationResult;
+
+ private String entityType;
+
+ private String link;
+
+ private HttpMethod operationType;
+
+ private OxmEntityDescriptor descriptor;
+
+ private long createdTimeStampInMs;
+
+ private long taskAgeInMs;
+
+ /**
+ * Instantiates a new network transaction.
+ */
+ public NetworkTransaction() {
+ this.createdTimeStampInMs = System.currentTimeMillis();
+ }
+
+ /**
+ * Instantiates a new network transaction.
+ *
+ * @param method the method
+ * @param entityType the entity type
+ * @param or the or
+ */
+ public NetworkTransaction(HttpMethod method, String entityType, OperationResult or) {
+ this();
+ this.operationType = method;
+ this.entityType = entityType;
+ this.operationResult = or;
+ }
+
+ public HttpMethod getOperationType() {
+ return operationType;
+ }
+
+ public long getTaskAgeInMs() {
+ return taskAgeInMs;
+ }
+
+ /**
+ * Sets the task age in ms.
+ */
+ public void setTaskAgeInMs() {
+ this.taskAgeInMs = (System.currentTimeMillis() - createdTimeStampInMs);
+ }
+
+ public void setOperationType(HttpMethod operationType) {
+ this.operationType = operationType;
+ }
+
+ public OperationResult getOperationResult() {
+ return operationResult;
+ }
+
+ public void setOperationResult(OperationResult operationResult) {
+ this.operationResult = operationResult;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public void setEntityType(String entityType) {
+ this.entityType = entityType;
+ }
+
+ public String getLink() {
+ return link;
+ }
+
+ public void setLink(String link) {
+ this.link = link;
+ }
+
+ public OxmEntityDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ public void setDescriptor(OxmEntityDescriptor descriptor) {
+ this.descriptor = descriptor;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "NetworkTransaction [operationResult=" + operationResult.toString() + ", entityType="
+ + entityType + ", link=" + link + ", operationType=" + operationType + ", descriptor="
+ + descriptor.toString() + ", createdTimeStampInMs=" + createdTimeStampInMs
+ + ", taskAgeInMs=" + taskAgeInMs + "]";
+ }
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryAdapter.java b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryAdapter.java
new file mode 100644
index 0000000..de2085c
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryAdapter.java
@@ -0,0 +1,418 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.http.client.utils.URIBuilder;
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sparky.config.oxm.OxmEntityDescriptor;
+import org.openecomp.sparky.config.oxm.OxmModelLoader;
+import org.openecomp.sparky.dal.aai.config.ActiveInventoryConfig;
+import org.openecomp.sparky.dal.aai.config.ActiveInventoryRestConfig;
+import org.openecomp.sparky.dal.aai.enums.RestAuthenticationMode;
+import org.openecomp.sparky.dal.exception.ElasticSearchOperationException;
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.dal.rest.RestClientBuilder;
+import org.openecomp.sparky.dal.rest.RestfulDataAccessor;
+import org.openecomp.sparky.logging.AaiUiMsgs;
+import org.openecomp.sparky.security.SecurityContextFactory;
+import org.openecomp.sparky.util.NodeUtils;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource.Builder;
+
+
+/**
+ * The Class ActiveInventoryAdapter.
+ */
+
+/**
+ * @author davea
+ *
+ */
+public class ActiveInventoryAdapter extends RestfulDataAccessor
+ implements ActiveInventoryDataProvider {
+
+ private static final Logger LOG =
+ LoggerFactory.getInstance().getLogger(ActiveInventoryAdapter.class);
+
+ private static final String HEADER_TRANS_ID = "X-TransactionId";
+ private static final String HEADER_FROM_APP_ID = "X-FromAppId";
+ private static final String HEADER_AUTHORIZATION = "Authorization";
+
+ private static final String TRANSACTION_ID_PREFIX = "txnId-";
+ private static final String UI_APP_NAME = "AAI-UI";
+
+
+ private ActiveInventoryConfig config;
+
+ /**
+ * Instantiates a new active inventory adapter.
+ *
+ * @param restClientBuilder the rest client builder
+ * @throws ElasticSearchOperationException the elastic search operation exception
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ public ActiveInventoryAdapter(RestClientBuilder restClientBuilder)
+ throws ElasticSearchOperationException, IOException {
+ super(restClientBuilder);
+
+ try {
+ this.config = ActiveInventoryConfig.getConfig();
+ } catch (Exception exc) {
+ throw new ElasticSearchOperationException("Error getting active inventory configuration",
+ exc);
+ }
+
+ clientBuilder.setUseHttps(true);
+
+ clientBuilder.setValidateServerHostname(config.getAaiSslConfig().isValidateServerHostName());
+
+ SecurityContextFactory sslContextFactory = clientBuilder.getSslContextFactory();
+
+ sslContextFactory.setServerCertificationChainValidationEnabled(
+ config.getAaiSslConfig().isValidateServerCertificateChain());
+
+ if (config.getAaiRestConfig().getAuthenticationMode() == RestAuthenticationMode.SSL_CERT) {
+ sslContextFactory.setClientCertFileName(config.getAaiSslConfig().getKeystoreFilename());
+ sslContextFactory.setClientCertPassword(config.getAaiSslConfig().getKeystorePassword());
+ sslContextFactory.setTrustStoreFileName(config.getAaiSslConfig().getTruststoreFilename());
+ }
+
+ clientBuilder.setConnectTimeoutInMs(config.getAaiRestConfig().getConnectTimeoutInMs());
+ clientBuilder.setReadTimeoutInMs(config.getAaiRestConfig().getReadTimeoutInMs());
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestfulDataAccessor#setClientDefaults(com.sun.jersey.api.client.Client, java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ protected Builder setClientDefaults(Client client, String url, String payloadContentType,
+ String acceptContentType) {
+ Builder builder = super.setClientDefaults(client, url, payloadContentType, acceptContentType);
+
+ builder = builder.header(HEADER_FROM_APP_ID, UI_APP_NAME);
+ byte bytes[] = new byte[6];
+ txnIdGenerator.nextBytes(bytes);
+ builder =
+ builder.header(HEADER_TRANS_ID, TRANSACTION_ID_PREFIX + ByteBuffer.wrap(bytes).getInt());
+
+ if (config.getAaiRestConfig().getAuthenticationMode() == RestAuthenticationMode.SSL_BASIC) {
+ builder = builder.header(HEADER_AUTHORIZATION,
+ config.getAaiSslConfig().getBasicAuthenticationCredentials());
+ }
+
+ return builder;
+ }
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+
+ // TODO Auto-generated method stub
+ RestClientBuilder builder = new RestClientBuilder();
+ RestfulDataAccessor accessor;
+ try {
+ accessor = new ActiveInventoryAdapter(builder);
+ OperationResult or =
+ accessor.doGet("/cloud-infrastructure/pservers/pserver/SQLTEST006", "application/json");
+ String jsonPatch = "{ \"hostname\" : \"SQLTEST006\", \"prov-status\" : \"PREPROV\","
+ + " \"in-maint\" : \"false\", \"is-closed-loop\" : \"false\" }";
+ or = accessor.doPatch("/cloud-infrastructure/pservers/pserver/SQLTEST006", jsonPatch,
+ "application/json");
+ // System.out.println("PATCH or = " + or.getResultCode() + " : " + or.toString());
+ } catch (ElasticSearchOperationException | IOException exc) {
+ // TODO Auto-generated catch block
+ exc.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Gets the full url.
+ *
+ * @param resourceUrl the resource url
+ * @return the full url
+ * @throws Exception the exception
+ */
+ private String getFullUrl(String resourceUrl) throws Exception {
+ ActiveInventoryRestConfig aaiRestConfig = ActiveInventoryConfig.getConfig().getAaiRestConfig();
+ final String host = aaiRestConfig.getHost();
+ final String port = aaiRestConfig.getPort();
+ final String basePath = aaiRestConfig.getResourceBasePath();
+ return String.format("https://%s:%s%s%s", host, port, basePath, resourceUrl);
+ }
+
+ public String getGenericQueryForSelfLink(String startNodeType, List<String> queryParams) throws Exception {
+
+ URIBuilder urlBuilder = new URIBuilder(getFullUrl("/search/generic-query"));
+
+ for( String queryParam : queryParams) {
+ urlBuilder.addParameter("key", queryParam);
+ }
+
+ urlBuilder.addParameter("start-node-type", startNodeType);
+ urlBuilder.addParameter("include", startNodeType);
+
+ final String constructedLink = urlBuilder.toString();
+
+ // TODO: debug log for constructed link
+
+ return constructedLink;
+
+}
+
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.aai.ActiveInventoryDataProvider#getSelfLinksByEntityType(java.lang.String)
+ */
+ @Override
+ public OperationResult getSelfLinksByEntityType(String entityType) throws Exception {
+
+ /*
+ * For this one, I want to dynamically construct the nodes-query for self-link discovery as a
+ * utility method that will use the OXM model entity data to drive the query as well.
+ */
+
+ if (entityType == null) {
+ throw new NullPointerException(
+ "Failed to getSelfLinksByEntityType() because entityType is null");
+ }
+
+ OxmEntityDescriptor entityDescriptor =
+ OxmModelLoader.getInstance().getEntityDescriptor(entityType);
+
+ if (entityDescriptor == null) {
+ throw new NoSuchElementException("Failed to getSelfLinksByEntityType() because could"
+ + " not find entity descriptor from OXM with type = " + entityType);
+ }
+
+ String link = null;
+ final String primaryKeyStr =
+ NodeUtils.concatArray(entityDescriptor.getPrimaryKeyAttributeName(), "/");
+
+ link = getFullUrl("/search/nodes-query?search-node-type=" + entityType + "&filter="
+ + primaryKeyStr + ":EXISTS");
+
+
+
+ return doGet(link, "application/json");
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.aai.ActiveInventoryDataProvider#getSelfLinkForEntity(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult getSelfLinkForEntity(String entityType, String primaryKeyName,
+ String primaryKeyValue) throws Exception {
+
+ if (entityType == null) {
+ throw new NullPointerException("Failed to getSelfLinkForEntity() because entityType is null");
+ }
+
+ if (primaryKeyName == null) {
+ throw new NullPointerException(
+ "Failed to getSelfLinkForEntity() because primaryKeyName is null");
+ }
+
+ if (primaryKeyValue == null) {
+ throw new NullPointerException(
+ "Failed to getSelfLinkForEntity() because primaryKeyValue is null");
+ }
+
+ // https://aai-int1.test.att.com:8443/aai/v8/search/generic-query?key=complex.physical-location-id:atlngade&start-node-type=complex
+
+ /*
+ * Try to protect ourselves from illegal URI formatting exceptions caused by characters that
+ * aren't natively supported in a URI, but can be escaped to make them legal.
+ */
+
+ String encodedEntityType = URLEncoder.encode(entityType, "UTF-8");
+ String encodedPrimaryKeyName = URLEncoder.encode(primaryKeyName, "UTF-8");
+ String encodedPrimaryKeyValue = URLEncoder.encode(primaryKeyValue, "UTF-8");
+
+ String link = null;
+
+ if ("service-instance".equals(entityType)) {
+
+ link = getFullUrl("/search/generic-query?key=" + encodedEntityType + "."
+ + encodedPrimaryKeyName + ":" + encodedPrimaryKeyValue + "&start-node-type="
+ + encodedEntityType + "&include=customer&depth=2");
+
+ } else {
+
+ link =
+ getFullUrl("/search/generic-query?key=" + encodedEntityType + "." + encodedPrimaryKeyName
+ + ":" + encodedPrimaryKeyValue + "&start-node-type=" + encodedEntityType);
+
+ }
+
+ return queryActiveInventoryWithRetries(link, "application/json",
+ this.config.getAaiRestConfig().getNumRequestRetries());
+
+ }
+
+
+ /**
+ * Our retry conditions should be very specific.
+ *
+ * @param r the r
+ * @return true, if successful
+ */
+ private boolean shouldRetryRequest(OperationResult r) {
+
+ if (r == null) {
+ return true;
+ }
+
+ int rc = r.getResultCode();
+
+ if (rc == 200) {
+ return false;
+ }
+
+ if (rc == 404) {
+ return false;
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Query active inventory.
+ *
+ * @param url the url
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ // package protected for test classes instead of private
+ OperationResult queryActiveInventory(String url, String acceptContentType) {
+ return doGet(url, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.aai.ActiveInventoryDataProvider#queryActiveInventoryWithRetries(java.lang.String, java.lang.String, int)
+ */
+ @Override
+ public OperationResult queryActiveInventoryWithRetries(String url, String responseType,
+ int numRetries) {
+
+ OperationResult result = null;
+
+ for (int x = 0; x < numRetries; x++) {
+
+ LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_SEQ, url, String.valueOf(x + 1));
+
+ result = queryActiveInventory(url, responseType);
+
+ /**
+ * Record number of times we have attempted the request to later summarize how many times we
+ * are generally retrying over thousands of messages in a sync.
+ *
+ * If the number of retries is surprisingly high, then we need to understand why that is as
+ * the number of retries is also causing a heavier load on AAI beyond the throttling controls
+ * we already have in place in term of the transaction rate controller and number of
+ * parallelized threads per task processor.
+ */
+
+ result.setNumRequestRetries(x);
+
+ if (!shouldRetryRequest(result)) {
+
+ /*
+ * if (myConfig.getAaiRestConfig().isCacheEnabled()) {
+ *
+ * CachedHttpRequest cachedRequest = new CachedHttpRequest();
+ * cachedRequest.setHttpRequestMethod("GET"); cachedRequest.setPayload("");
+ * cachedRequest.setPayloadMimeType(""); cachedRequest.setUrl(url);
+ * cachedRequest.setOperationType( TransactionStorageType.ACTIVE_INVENTORY_QUERY.getIndex()
+ * );
+ *
+ * CachedHttpResponse cachedResponse = new CachedHttpResponse();
+ * cachedResponse.setPayload(result.getResult());
+ * cachedResponse.setPayloadMimeType("application/json");
+ * cachedResponse.setStatusCode(result.getResultCode());
+ *
+ * CachedHttpTransaction txn = new CachedHttpTransaction(cachedRequest, cachedResponse);
+ * storageProvider.persistTransaction(txn);
+ *
+ * }
+ */
+
+
+ result.setResolvedLinkFromServer(true);
+ LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_DONE_SEQ, url, String.valueOf(x + 1));
+
+ return result;
+ }
+
+ try {
+ /*
+ * Sleep between re-tries to be nice to the target system.
+ */
+ Thread.sleep(50);
+ } catch (InterruptedException exc) {
+ LOG.error(AaiUiMsgs.QUERY_AAI_WAIT_INTERRUPTION, exc.getLocalizedMessage());
+ break;
+ }
+ LOG.error(AaiUiMsgs.QUERY_AAI_RETRY_FAILURE_WITH_SEQ, url, String.valueOf(x + 1));
+ }
+
+
+ result.setResolvedLinkFailure(true);
+ LOG.info(AaiUiMsgs.QUERY_AAI_RETRY_MAXED_OUT, url);
+
+ return result;
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestfulDataAccessor#shutdown()
+ */
+ @Override
+ public void shutdown() {
+ // TODO Auto-generated method stub
+
+ if (entityCache != null) {
+ entityCache.shutdown();
+ }
+
+ }
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryDataProvider.java b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryDataProvider.java
new file mode 100644
index 0000000..8be4a65
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryDataProvider.java
@@ -0,0 +1,91 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai;
+
+import java.util.List;
+
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.dal.rest.RestDataProvider;
+
+/**
+ * The Interface ActiveInventoryDataProvider.
+ */
+public interface ActiveInventoryDataProvider extends RestDataProvider {
+
+ /**
+ * Gets the self links by entity type.
+ *
+ * @param entityType the entity type
+ * @return the self links by entity type
+ * @throws Exception the exception
+ */
+ /*
+ * This one will do the nodes-query and understand enough to make that happen
+ */
+ OperationResult getSelfLinksByEntityType(String entityType) throws Exception;
+
+ /**
+ * Gets the self link for entity.
+ *
+ * @param entityType the entity type
+ * @param primaryKeyName the primary key name
+ * @param primaryKeyValue the primary key value
+ * @return the self link for entity
+ * @throws Exception the exception
+ */
+ OperationResult getSelfLinkForEntity(String entityType, String primaryKeyName,
+ String primaryKeyValue) throws Exception;
+
+ /**
+ * Query active inventory with retries.
+ *
+ * @param url the url
+ * @param responseType the response type
+ * @param numRetries the num retries
+ * @return the operation result
+ */
+ OperationResult queryActiveInventoryWithRetries(String url, String responseType, int numRetries);
+
+
+ /**
+ * Determines the self-link for an entity with passed-in key-value pairs.
+ *
+ * @param startNodeType
+ * @param keyParams
+ * @return
+ * @throws Exception
+ */
+ String getGenericQueryForSelfLink(String startNodeType, List<String> queryKeyParams) throws Exception;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#shutdown()
+ */
+ @Override
+ void shutdown();
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryEntityStatistics.java b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryEntityStatistics.java
new file mode 100644
index 0000000..0671b3e
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryEntityStatistics.java
@@ -0,0 +1,307 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.openecomp.sparky.config.oxm.OxmEntityDescriptor;
+import org.openecomp.sparky.config.oxm.OxmModelLoader;
+import org.openecomp.sparky.dal.NetworkTransaction;
+import org.openecomp.sparky.dal.rest.OperationResult;
+
+/**
+ * The Class ActiveInventoryEntityStatistics.
+ */
+public class ActiveInventoryEntityStatistics {
+
+ private static final String TOTAL = "Total";
+
+ private static final String FOUND = "Found";
+
+ private static final String NO_PAYLOAD = "NoPayload";
+
+ private static final String NOT_FOUND = "NotFound";
+
+ private static final String NUM_RETRIES = "NumRetries";
+
+ private static final String ERROR = "Error";
+
+ private OxmModelLoader loader;
+
+
+ private Map<String, HashMap<String, AtomicInteger>> activeInventoryEntityStatistics;
+
+ /**
+ * Creates the entity op stats.
+ *
+ * @return the hash map
+ */
+ private HashMap<String, AtomicInteger> createEntityOpStats() {
+
+ HashMap<String, AtomicInteger> opStats = new HashMap<String, AtomicInteger>();
+
+ opStats.put(TOTAL, new AtomicInteger());
+ opStats.put(FOUND, new AtomicInteger());
+ opStats.put(NO_PAYLOAD, new AtomicInteger());
+ opStats.put(NOT_FOUND, new AtomicInteger());
+ opStats.put(NUM_RETRIES, new AtomicInteger());
+ opStats.put(ERROR, new AtomicInteger());
+
+ return opStats;
+
+ }
+
+ /*
+ * private void createSearchableActiveInventoryEntityStatistics() {
+ *
+ * Map<String,OxmEntityDescriptor> descriptors = loader.getSearchableEntityDescriptors();
+ *
+ * if(descriptors == null) { return; }
+ *
+ * OxmEntityDescriptor d = null; for ( String key : descriptors.keySet() ) { d =
+ * descriptors.get(key); activeInventoryEntityStatistics.put(d.getEntityName(),
+ * createEntityOpStats()); }
+ *
+ * }
+ */
+
+ /*
+ * private void createCrossEntityReferenceActiveInventoryEntityStatistics() {
+ *
+ * Map<String,OxmEntityDescriptor> descriptors = loader.getCrossReferenceEntityDescriptors();
+ *
+ *
+ * }
+ */
+
+
+ /**
+ * Initializecreate active inventory entity statistics.
+ */
+ private void initializecreateActiveInventoryEntityStatistics() {
+ Set<String> keys = activeInventoryEntityStatistics.keySet();
+
+ Set<String> opStatKeySet = null;
+ Map<String, AtomicInteger> opStats = null;
+
+ for (String k : keys) {
+
+ opStats = activeInventoryEntityStatistics.get(k);
+
+ opStatKeySet = opStats.keySet();
+
+ for (String opStatKey : opStatKeySet) {
+ opStats.get(opStatKey).set(0);
+ }
+ }
+ }
+
+ /**
+ * Instantiates a new active inventory entity statistics.
+ *
+ * @param loader the loader
+ */
+ public ActiveInventoryEntityStatistics(OxmModelLoader loader) {
+ this.loader = loader;
+ activeInventoryEntityStatistics = new HashMap<String, HashMap<String, AtomicInteger>>();
+ // createSearchableActiveInventoryEntityStatistics();
+ // createCrossEntityReferenceActiveInventoryEntityStatistics();
+ reset();
+ }
+
+ /**
+ * Initialize counters from oxm entity descriptors.
+ *
+ * @param descriptors the descriptors
+ */
+ public void initializeCountersFromOxmEntityDescriptors(
+ Map<String, OxmEntityDescriptor> descriptors) {
+
+ if (descriptors == null) {
+ return;
+ }
+
+ OxmEntityDescriptor descriptor = null;
+ for (String key : descriptors.keySet()) {
+ descriptor = descriptors.get(key);
+ activeInventoryEntityStatistics.put(descriptor.getEntityName(), createEntityOpStats());
+ }
+ }
+
+
+ /**
+ * Reset.
+ */
+ public void reset() {
+ initializecreateActiveInventoryEntityStatistics();
+ }
+
+ /**
+ * Gets the result code.
+ *
+ * @param txn the txn
+ * @return the result code
+ */
+ private int getResultCode(NetworkTransaction txn) {
+
+
+ if (txn == null) {
+ return -1;
+ }
+
+ OperationResult or = txn.getOperationResult();
+
+ if (or == null) {
+ return -1;
+ }
+
+ return or.getResultCode();
+
+ }
+
+ /**
+ * Update active inventory entity counters.
+ *
+ * @param txn the txn
+ */
+ private void updateActiveInventoryEntityCounters(NetworkTransaction txn) {
+
+ if (txn == null) {
+ return;
+ }
+
+ Map<String, AtomicInteger> opStats = activeInventoryEntityStatistics.get(txn.getEntityType());
+
+ int rc = getResultCode(txn);
+
+ switch (txn.getOperationType()) {
+
+ case GET: {
+
+ opStats.get(TOTAL).incrementAndGet();
+
+ if (200 <= rc && rc <= 299) {
+ opStats.get(FOUND).incrementAndGet();
+ } else if (rc == 404) {
+ opStats.get(NOT_FOUND).incrementAndGet();
+ } else {
+ opStats.get(ERROR).incrementAndGet();
+ }
+
+ break;
+ }
+
+ default: {
+ // nothing else for now
+ }
+
+ }
+
+ OperationResult or = txn.getOperationResult();
+
+ if (or != null && or.wasSuccessful()) {
+
+ if (or.getResult() == null || or.getResult().length() == 0) {
+ opStats.get(NO_PAYLOAD).incrementAndGet();
+ }
+
+ if (or.getNumRequestRetries() > 0) {
+ opStats.get(NUM_RETRIES).addAndGet(or.getNumRequestRetries());
+ }
+
+ }
+
+
+ }
+
+ /**
+ * Update counters.
+ *
+ * @param txn the txn
+ */
+ public void updateCounters(NetworkTransaction txn) {
+
+ updateActiveInventoryEntityCounters(txn);
+
+ }
+
+ public String getStatisticsReport() {
+
+ StringBuilder sb = new StringBuilder(128);
+
+ /*
+ * sort entities, then sort nested op codes
+ */
+
+ TreeMap<String, HashMap<String, AtomicInteger>> activeInventoryEntitySortedTreeMap =
+ new TreeMap<String, HashMap<String, AtomicInteger>>(new Comparator<String>() {
+
+ @Override
+ public int compare(String o1, String o2) {
+ return o1.toLowerCase().compareTo(o2.toLowerCase());
+ }
+ });
+
+ activeInventoryEntitySortedTreeMap.putAll(activeInventoryEntityStatistics);
+
+ for (String counterEntityKey : activeInventoryEntitySortedTreeMap.keySet()) {
+
+ HashMap<String, AtomicInteger> entityCounters =
+ activeInventoryEntitySortedTreeMap.get(counterEntityKey);
+
+ AtomicInteger total = entityCounters.get(TOTAL);
+ AtomicInteger found = entityCounters.get(FOUND);
+ AtomicInteger noPayload = entityCounters.get(NO_PAYLOAD);
+ AtomicInteger notFound = entityCounters.get(NOT_FOUND);
+ AtomicInteger numRetries = entityCounters.get(NUM_RETRIES);
+ AtomicInteger error = entityCounters.get(ERROR);
+
+ int totalValue = (total == null) ? 0 : total.get();
+ int foundValue = (found == null) ? 0 : found.get();
+ int noPayloadValue = (noPayload == null) ? 0 : noPayload.get();
+ int notFoundValue = (notFound == null) ? 0 : notFound.get();
+ int numRetriesValue = (numRetries == null) ? 0 : numRetries.get();
+ int errorValue = (error == null) ? 0 : error.get();
+
+ sb.append("\n ")
+ .append(String.format(
+ "%-30s TOTAL: %-12d FOUND: %-12d NO_PAYLOAD:"
+ + " %-12d NOT_FOUND: %-12d NUM_RETRIES: %-12d ERROR: %-12d",
+ counterEntityKey, totalValue, foundValue, noPayloadValue, notFoundValue,
+ numRetriesValue, errorValue));
+ }
+
+ return sb.toString();
+ }
+
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java
new file mode 100644
index 0000000..7a61972
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java
@@ -0,0 +1,139 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sparky.analytics.AbstractStatistics;
+import org.openecomp.sparky.dal.NetworkTransaction;
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.logging.AaiUiMsgs;
+
+/**
+ * The Class ActiveInventoryProcessingExceptionStatistics.
+ */
+public class ActiveInventoryProcessingExceptionStatistics extends AbstractStatistics {
+
+ private static final Logger LOG =
+ LoggerFactory.getInstance().getLogger(ActiveInventoryAdapter.class);
+
+ private static final String NATIVE_SOCKET_CONNECT_EXCEPTION = "NativeSocketConnectException";
+ private static final String NATIVE_SOCKET_CONNECTION_RESET = "NativeSocketConnectionReset";
+ private static final String NATIVE_SOCKET_CONNECTION_REFUSED = "NativeSocketConnectionRefused";
+ private static final String CLIENT_TIMEOUT_EXCEPTION = "JerseyClientTimoutException";
+ private static final String UNKNOWN_EXCEPTION = "UnknownException";
+
+ /**
+ * Creates the counters.
+ */
+ private void createCounters() {
+ addCounter(NATIVE_SOCKET_CONNECT_EXCEPTION);
+ addCounter(NATIVE_SOCKET_CONNECTION_RESET);
+ addCounter(NATIVE_SOCKET_CONNECTION_REFUSED);
+ addCounter(CLIENT_TIMEOUT_EXCEPTION);
+ addCounter(UNKNOWN_EXCEPTION);
+ }
+
+ /**
+ * Instantiates a new active inventory processing exception statistics.
+ */
+ public ActiveInventoryProcessingExceptionStatistics() {
+ createCounters();
+ reset();
+ }
+
+ /**
+ * Update counters.
+ *
+ * @param txn the txn
+ */
+ public void updateCounters(NetworkTransaction txn) {
+
+ if (txn == null) {
+ return;
+ }
+
+ OperationResult or = txn.getOperationResult();
+
+ if (or != null && !or.wasSuccessful()) {
+
+ if (or.getResultCode() != 404) {
+
+ String result = or.getResult();
+
+ if (result != null) {
+
+ /*
+ * Try to classify exceptions and peg counters
+ */
+
+ if (result.contains("java.net.SocketTimeoutException: connect timed out")) {
+ pegCounter(CLIENT_TIMEOUT_EXCEPTION);
+ } else if (result.contains("java.net.ConnectException: Connection timed out: connect")) {
+ pegCounter(NATIVE_SOCKET_CONNECT_EXCEPTION);
+ } else if (result.contains("java.net.ConnectException: Connection refused: connect")) {
+ pegCounter(NATIVE_SOCKET_CONNECTION_REFUSED);
+ } else if (result.contains("java.net.SocketException: Connection reset")) {
+ pegCounter(NATIVE_SOCKET_CONNECTION_RESET);
+ } else {
+ pegCounter(UNKNOWN_EXCEPTION);
+ LOG.error(AaiUiMsgs.PEGGING_ERROR, result.toString());
+ }
+
+ }
+ }
+
+ }
+
+ }
+
+ public String getStatisticsReport() {
+
+ StringBuilder sb = new StringBuilder(128);
+
+ int nativeConnect = getCounterValue(NATIVE_SOCKET_CONNECT_EXCEPTION);
+ int nativeCxnReset = getCounterValue(NATIVE_SOCKET_CONNECTION_RESET);
+ int nativeCxnRefused = getCounterValue(NATIVE_SOCKET_CONNECTION_REFUSED);
+ int clientTimeout = getCounterValue(CLIENT_TIMEOUT_EXCEPTION);
+ int unknown = getCounterValue(UNKNOWN_EXCEPTION);
+
+ sb.append("\n ")
+ .append(String.format("%-40s: %-12d", NATIVE_SOCKET_CONNECT_EXCEPTION, nativeConnect));
+ sb.append("\n ")
+ .append(String.format("%-40s: %-12d", NATIVE_SOCKET_CONNECTION_RESET, nativeCxnReset));
+ sb.append("\n ")
+ .append(String.format("%-40s: %-12d", NATIVE_SOCKET_CONNECTION_REFUSED, nativeCxnRefused));
+ sb.append("\n ")
+ .append(String.format("%-40s: %-12d", CLIENT_TIMEOUT_EXCEPTION, clientTimeout));
+ sb.append("\n ").append(String.format("%-40s: %-12d", UNKNOWN_EXCEPTION, unknown));
+
+ return sb.toString();
+
+ }
+
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryConfig.java b/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryConfig.java
new file mode 100644
index 0000000..c0f5db8
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryConfig.java
@@ -0,0 +1,159 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai.config;
+
+import java.net.URI;
+import java.util.Properties;
+
+import javax.ws.rs.core.UriBuilder;
+
+import org.openecomp.sparky.synchronizer.config.TaskProcessorConfig;
+import org.openecomp.sparky.util.ConfigHelper;
+import org.openecomp.sparky.util.Encryptor;
+import org.openecomp.sparky.viewandinspect.config.TierSupportUiConstants;
+
+/**
+ * The Class ActiveInventoryConfig.
+ */
+public class ActiveInventoryConfig {
+
+
+
+ public static final String CONFIG_FILE =
+ TierSupportUiConstants.DYNAMIC_CONFIG_APP_LOCATION + "aai.properties";
+ private static ActiveInventoryConfig instance;
+
+ private static final String HTTP_SCHEME = "http";
+ private static final String HTTPS_SCHEME = "https";
+
+ public static ActiveInventoryConfig getConfig() throws Exception {
+ if (instance == null) {
+ instance = new ActiveInventoryConfig();
+ }
+
+ return instance;
+ }
+
+ private ActiveInventoryRestConfig aaiRestConfig;
+ private ActiveInventorySslConfig aaiSslConfig;
+ private TaskProcessorConfig taskProcessorConfig;
+
+ /**
+ * Instantiates a new active inventory config.
+ *
+ * @throws Exception the exception
+ */
+ protected ActiveInventoryConfig() throws Exception {
+
+ Properties props = ConfigHelper.loadConfigFromExplicitPath(CONFIG_FILE);
+ aaiRestConfig = new ActiveInventoryRestConfig(props);
+ aaiSslConfig = new ActiveInventorySslConfig(props, new Encryptor());
+
+ taskProcessorConfig = new TaskProcessorConfig();
+ taskProcessorConfig
+ .initializeFromProperties(ConfigHelper.getConfigWithPrefix("aai.taskProcessor", props));
+
+
+ }
+
+ protected ActiveInventoryConfig(Properties props) throws Exception {
+
+ aaiRestConfig = new ActiveInventoryRestConfig(props);
+ aaiSslConfig = new ActiveInventorySslConfig(props, new Encryptor());
+
+ taskProcessorConfig = new TaskProcessorConfig();
+ taskProcessorConfig
+ .initializeFromProperties(ConfigHelper.getConfigWithPrefix("aai.taskProcessor", props));
+
+
+ }
+
+ public TaskProcessorConfig getTaskProcessorConfig() {
+ return taskProcessorConfig;
+ }
+
+ public void setTaskProcessorConfig(TaskProcessorConfig taskProcessorConfig) {
+ this.taskProcessorConfig = taskProcessorConfig;
+ }
+
+
+ public ActiveInventoryRestConfig getAaiRestConfig() {
+ return aaiRestConfig;
+ }
+
+ public void setAaiRestConfig(ActiveInventoryRestConfig aaiRestConfig) {
+ this.aaiRestConfig = aaiRestConfig;
+ }
+
+ public ActiveInventorySslConfig getAaiSslConfig() {
+ return aaiSslConfig;
+ }
+
+ public void setAaiSslConfig(ActiveInventorySslConfig aaiSslConfig) {
+ this.aaiSslConfig = aaiSslConfig;
+ }
+
+ public String repairSelfLink(String selflink) {
+
+ if (selflink == null) {
+ return selflink;
+ }
+
+ UriBuilder builder = UriBuilder.fromPath(selflink).host(aaiRestConfig.getHost())
+ .port(Integer.parseInt(aaiRestConfig.getPort()));
+
+ switch (aaiRestConfig.getAuthenticationMode()) {
+
+ case SSL_BASIC:
+ case SSL_CERT: {
+ builder.scheme(HTTPS_SCHEME);
+ break;
+ }
+
+ default: {
+ builder.scheme(HTTP_SCHEME);
+ }
+ }
+
+ return builder.build().toString();
+
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "ActiveInventoryConfig [aaiRestConfig=" + aaiRestConfig + ", aaiSslConfig="
+ + aaiSslConfig + "]";
+ }
+
+ public URI getBaseUri() {
+ return UriBuilder.fromUri("https://" + aaiRestConfig.getHost() + ":" + aaiRestConfig.getPort()
+ + aaiRestConfig.getResourceBasePath()).build();
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryRestConfig.java b/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryRestConfig.java
new file mode 100644
index 0000000..d609f16
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryRestConfig.java
@@ -0,0 +1,283 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai.config;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.openecomp.sparky.dal.aai.enums.RestAuthenticationMode;
+import org.openecomp.sparky.util.ConfigHelper;
+
+/**
+ * The Class ActiveInventoryRestConfig.
+ */
+public class ActiveInventoryRestConfig {
+
+ private String host;
+
+ private String port;
+
+ private int connectTimeoutInMs;
+
+ private int readTimeoutInMs;
+
+ private int numRequestRetries;
+
+ private int numResolverWorkers;
+
+ private boolean useCacheOnly;
+
+ private boolean cacheEnabled;
+
+ private boolean cacheFailures;
+
+ private String storageFolderOverride;
+
+ int numCacheWorkers;
+
+ private long maxTimeToLiveInMs;
+
+ private String resourceBasePath;
+
+ private List<String> shallowEntities;
+
+ private RestAuthenticationMode authenticationMode;
+
+ public List<String> getShallowEntities() {
+ return shallowEntities;
+ }
+
+ /**
+ * Instantiates a new active inventory rest config.
+ *
+ * @param props the props
+ */
+ public ActiveInventoryRestConfig(Properties props) {
+
+ if (props == null) {
+ return;
+ }
+
+ Properties restProps = ConfigHelper.getConfigWithPrefix("aai.rest", props);
+
+ resourceBasePath = restProps.getProperty("resourceBasePath", "/aai/v7");
+ host = restProps.getProperty("host", "localhost");
+ port = restProps.getProperty("port", "8443");
+ numRequestRetries = Integer.parseInt(restProps.getProperty("numRequestRetries", "5"));
+ numResolverWorkers = Integer.parseInt(restProps.getProperty("numResolverWorkers", "15"));
+
+ connectTimeoutInMs = Integer.parseInt(restProps.getProperty("connectTimeoutInMs", "5000"));
+ readTimeoutInMs = Integer.parseInt(restProps.getProperty("readTimeoutInMs", "10000"));
+
+ String shallowEntitiesProperty = restProps.getProperty("shallowEntities", "");
+ shallowEntities = Arrays.asList(shallowEntitiesProperty.split(","));
+
+ Properties cacheProps = ConfigHelper.getConfigWithPrefix("aai.rest.cache", props);
+ cacheEnabled = Boolean.parseBoolean(cacheProps.getProperty("enabled", "false"));
+ storageFolderOverride = cacheProps.getProperty("storageFolderOverride", null);
+ cacheFailures = Boolean.parseBoolean(cacheProps.getProperty("cacheFailures", "false"));
+ useCacheOnly = Boolean.parseBoolean(cacheProps.getProperty("useCacheOnly", "false"));
+ numCacheWorkers = Integer.parseInt(cacheProps.getProperty("numWorkers", "5"));
+
+
+ if (storageFolderOverride != null && storageFolderOverride.length() == 0) {
+ storageFolderOverride = null;
+ }
+ /*
+ * The expectation of this parameter is that if the value > 0, then the cached resources will be
+ * served back instead of dipping AAI/DataLayer as long as the current resource age from the
+ * cached instance is < maxTimeToLiveInMs.
+ */
+ maxTimeToLiveInMs = Long.parseLong(cacheProps.getProperty("maxTimeToLiveInMs", "-1"));
+ authenticationMode = RestAuthenticationMode.getRestAuthenticationMode(restProps.getProperty("authenticationMode", RestAuthenticationMode.SSL_CERT.getAuthenticationModeLabel()));
+
+ /*
+ * In any kind of error scenario, set the authentication mode to SSL_CERT as our default.
+ * This is an arbitrary default, but was chosen based on the way this code worked before
+ * introduction of the SSL Basic Auth settings.
+ */
+ if ( authenticationMode == RestAuthenticationMode.UNKNOWN_MODE) {
+ authenticationMode = RestAuthenticationMode.SSL_CERT;
+ }
+
+ }
+
+ public RestAuthenticationMode getAuthenticationMode() {
+ return authenticationMode;
+ }
+
+ public void setAuthenticationMode(RestAuthenticationMode authenticationMode) {
+ this.authenticationMode = authenticationMode;
+ }
+
+ public int getNumCacheWorkers() {
+ return numCacheWorkers;
+ }
+
+ public void setNumCacheWorkers(int numCacheWorkers) {
+ this.numCacheWorkers = numCacheWorkers;
+ }
+
+ /**
+ * Should cache failures.
+ *
+ * @return true, if successful
+ */
+ public boolean shouldCacheFailures() {
+ return cacheFailures;
+ }
+
+ public void setShouldCacheFailures(boolean enabled) {
+ this.cacheFailures = enabled;
+ }
+
+ /**
+ * Checks if is shallow entity.
+ *
+ * @param entityType the entity type
+ * @return true, if is shallow entity
+ */
+ public boolean isShallowEntity(String entityType) {
+ if (entityType == null) {
+ return false;
+ }
+
+ for (String entity : shallowEntities) {
+ if (entityType.equalsIgnoreCase(entity)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isUseCacheOnly() {
+ return useCacheOnly;
+ }
+
+ public void setUseCacheOnly(boolean useCacheOnly) {
+ this.useCacheOnly = useCacheOnly;
+ }
+
+ public int getNumResolverWorkers() {
+ return numResolverWorkers;
+ }
+
+ public void setNumResolverWorkers(int numResolverWorkers) {
+ this.numResolverWorkers = numResolverWorkers;
+ }
+
+ public long getMaxTimeToLiveInMs() {
+ return maxTimeToLiveInMs;
+ }
+
+ public void setMaxTimeToLiveInMs(long maxTimeToLiveInMs) {
+ this.maxTimeToLiveInMs = maxTimeToLiveInMs;
+ }
+
+ public boolean isCacheEnabled() {
+ return cacheEnabled;
+ }
+
+ public void setCacheEnabled(boolean cacheEnabled) {
+ this.cacheEnabled = cacheEnabled;
+ }
+
+ public String getStorageFolderOverride() {
+ return storageFolderOverride;
+ }
+
+ public void setStorageFolderOverride(String storageFolderOverride) {
+ this.storageFolderOverride = storageFolderOverride;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public String getResourceBasePath() {
+ return resourceBasePath;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+
+
+ public void setResourceBasePath(String resourceBasePath) {
+ this.resourceBasePath = resourceBasePath;
+ }
+
+ @Override
+ public String toString() {
+ return "ActiveInventoryRestConfig [host=" + host + ", port=" + port + ", connectTimeoutInMs="
+ + connectTimeoutInMs + ", readTimeoutInMs=" + readTimeoutInMs + ", numRequestRetries="
+ + numRequestRetries + ", numResolverWorkers=" + numResolverWorkers + ", useCacheOnly="
+ + useCacheOnly + ", cacheEnabled=" + cacheEnabled + ", cacheFailures=" + cacheFailures
+ + ", storageFolderOverride=" + storageFolderOverride + ", numCacheWorkers="
+ + numCacheWorkers + ", maxTimeToLiveInMs=" + maxTimeToLiveInMs + ", resourceBasePath="
+ + resourceBasePath + ", shallowEntities=" + shallowEntities + ", authenticationMode="
+ + authenticationMode + "]";
+ }
+
+ public int getConnectTimeoutInMs() {
+ return connectTimeoutInMs;
+ }
+
+ public void setConnectTimeoutInMs(int connectTimeoutInMs) {
+ this.connectTimeoutInMs = connectTimeoutInMs;
+ }
+
+ public int getReadTimeoutInMs() {
+ return readTimeoutInMs;
+ }
+
+ public void setReadTimeoutInMs(int readTimeoutInMs) {
+ this.readTimeoutInMs = readTimeoutInMs;
+ }
+
+ public int getNumRequestRetries() {
+ return numRequestRetries;
+ }
+
+ public void setNumRequestRetries(int numRequestRetries) {
+ this.numRequestRetries = numRequestRetries;
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventorySslConfig.java b/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventorySslConfig.java
new file mode 100644
index 0000000..272e351
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventorySslConfig.java
@@ -0,0 +1,217 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai.config;
+
+import java.util.Properties;
+
+import org.eclipse.jetty.util.security.Password;
+import org.openecomp.sparky.util.ConfigHelper;
+import org.openecomp.sparky.util.Encryptor;
+import org.openecomp.sparky.viewandinspect.config.TierSupportUiConstants;
+
+/**
+ * The Class ActiveInventorySslConfig.
+ */
+public class ActiveInventorySslConfig {
+
+ private Encryptor encryptor;
+
+ private boolean enableSslDebug;
+ private boolean validateServerHostName;
+ private boolean validateServerCertificateChain;
+
+ private String keystoreType;
+ private String keystoreFilename;
+ private String keystorePassword;
+ private String truststoreType;
+ private String truststoreFilename;
+
+ private String basicAuthUsername;
+ private String basicAuthPassword;
+
+ /**
+ * Instantiates a new active inventory ssl config.
+ *
+ * @param props the props
+ */
+ public ActiveInventorySslConfig(Properties props, Encryptor encryptor) {
+
+ if (props == null) {
+ return;
+ }
+
+ Properties sslProps = ConfigHelper.getConfigWithPrefix("aai.ssl", props);
+
+ enableSslDebug = Boolean.parseBoolean(sslProps.getProperty("enableDebug", "false"));
+ validateServerHostName =
+ Boolean.parseBoolean(sslProps.getProperty("validateServerHostName", "false"));
+ validateServerCertificateChain =
+ Boolean.parseBoolean(sslProps.getProperty("validateServerCertificateChain", "false"));
+
+ if (enableSslDebug) {
+ System.setProperty("javax.net.debug", "ssl");
+ } else {
+ System.setProperty("javax.net.debug", "");
+ }
+
+ this.encryptor = encryptor;
+
+
+ keystoreType = sslProps.getProperty("keystore.type", "pkcs12");
+
+ keystoreFilename =
+ TierSupportUiConstants.CONFIG_AUTH_LOCATION + sslProps.getProperty("keystore.filename");
+ keystorePassword = encryptor.decryptValue(sslProps.getProperty("keystore.pass", ""));
+ truststoreType = sslProps.getProperty("truststore.type", "jks");
+
+ truststoreFilename =
+ TierSupportUiConstants.CONFIG_AUTH_LOCATION + sslProps.getProperty("truststore.filename");
+
+ basicAuthUsername = sslProps.getProperty("basicAuth.username");
+ basicAuthPassword = decryptPassword(sslProps.getProperty("basicAuth.password"));
+
+ }
+
+ private String decryptPassword(String encryptedPassword) {
+
+ try {
+
+ if (encryptedPassword == null) {
+ return null;
+ }
+
+ return Password.deobfuscate(encryptedPassword);
+
+ } catch (Exception exc) {
+
+ return encryptedPassword;
+
+ }
+
+ }
+
+ public String getBasicAuthUsername() {
+ return basicAuthUsername;
+ }
+
+ public void setBasicAuthUsername(String basicAuthUsername) {
+ this.basicAuthUsername = basicAuthUsername;
+ }
+
+ public String getBasicAuthPassword() {
+ return basicAuthPassword;
+ }
+
+ public void setBasicAuthPassword(String basicAuthPassword) {
+ this.basicAuthPassword = basicAuthPassword;
+ }
+
+
+ public Encryptor getEncryptor() {
+ return encryptor;
+ }
+
+ public void setEncryptor(Encryptor encryptor) {
+ this.encryptor = encryptor;
+ }
+
+ public String getKeystoreType() {
+ return keystoreType;
+ }
+
+ public void setKeystoreType(String keystoreType) {
+ this.keystoreType = keystoreType;
+ }
+
+ public String getKeystoreFilename() {
+ return keystoreFilename;
+ }
+
+ public void setKeystoreFilename(String keystoreFilename) {
+ this.keystoreFilename = keystoreFilename;
+ }
+
+ public String getKeystorePassword() {
+ return keystorePassword;
+ }
+
+ public void setKeystorePassword(String keystorePassword) {
+ this.keystorePassword = keystorePassword;
+ }
+
+ public String getTruststoreType() {
+ return truststoreType;
+ }
+
+ public void setTruststoreType(String truststoreType) {
+ this.truststoreType = truststoreType;
+ }
+
+ public String getTruststoreFilename() {
+ return truststoreFilename;
+ }
+
+ public void setTruststoreFilename(String truststoreFilename) {
+ this.truststoreFilename = truststoreFilename;
+ }
+
+ public boolean isValidateServerHostName() {
+ return validateServerHostName;
+ }
+
+ public void setValidateServerHostName(boolean validateServerHostName) {
+ this.validateServerHostName = validateServerHostName;
+ }
+
+ public boolean isValidateServerCertificateChain() {
+ return validateServerCertificateChain;
+ }
+
+ public void setValidateServerCertificateChain(boolean validateServerCertificateChain) {
+ this.validateServerCertificateChain = validateServerCertificateChain;
+ }
+
+ public String getBasicAuthenticationCredentials() {
+
+ String usernameAndPassword = getBasicAuthUsername() + ":"
+ + getBasicAuthPassword();
+ return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "ActiveInventorySslConfig [enableSslDebug=" + enableSslDebug
+ + ", validateServerHostName=" + validateServerHostName + ", validateServerCertificateChain="
+ + validateServerCertificateChain + ", keystoreType=" + keystoreType + ", keystoreFilename="
+ + keystoreFilename + ", truststoreType=" + truststoreType + ", truststoreFilename="
+ + truststoreFilename + "]";
+ }
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/aai/enums/RestAuthenticationMode.java b/src/main/java/org/openecomp/sparky/dal/aai/enums/RestAuthenticationMode.java
new file mode 100644
index 0000000..af2f884
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/aai/enums/RestAuthenticationMode.java
@@ -0,0 +1,69 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.aai.enums;
+
+/**
+ * Authentication Modes:
+ * <li>HTTP_NOAUTH - intended to represent basic HTTP no authentication
+ * <li>SSL_BASIC - HTTP/S with username/password
+ * <li>SSL_CERT - HTTP/S with client cert
+ */
+
+public enum RestAuthenticationMode {
+ HTTP_NOAUTH("HTTP_NO_AUTH"),
+ SSL_BASIC("SSL_BASIC"),
+ SSL_CERT("SSL_CERT"),
+ UNKNOWN_MODE("UNKNOWN_MODE");
+
+ private String authenticationModeLabel;
+
+ private RestAuthenticationMode(String authModelLabel) {
+ this.authenticationModeLabel = authModelLabel;
+ }
+
+ public String getAuthenticationModeLabel() {
+ return authenticationModeLabel;
+ }
+
+ public static RestAuthenticationMode getRestAuthenticationMode(String authenticationMode) {
+
+ RestAuthenticationMode mappedMode = RestAuthenticationMode.UNKNOWN_MODE;
+
+ if (authenticationMode == null) {
+ return mappedMode;
+ }
+
+ try {
+ mappedMode = RestAuthenticationMode.valueOf(authenticationMode);
+ } catch ( Exception exc) {
+ mappedMode = RestAuthenticationMode.UNKNOWN_MODE;
+ }
+
+ return mappedMode;
+
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/cache/EntityCache.java b/src/main/java/org/openecomp/sparky/dal/cache/EntityCache.java
new file mode 100644
index 0000000..ccecc2d
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/cache/EntityCache.java
@@ -0,0 +1,63 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.cache;
+
+import org.openecomp.sparky.dal.rest.OperationResult;
+
+/**
+ * The Interface EntityCache.
+ *
+ * @author davea.
+ */
+public interface EntityCache {
+
+ /**
+ * Gets the.
+ *
+ * @param entityKey the entity key
+ * @param link the link
+ * @return the operation result
+ */
+ public OperationResult get(String entityKey, String link);
+
+ /**
+ * Put.
+ *
+ * @param entityKey the entity key
+ * @param result the result
+ */
+ public void put(String entityKey, OperationResult result);
+
+ /**
+ * Shutdown.
+ */
+ public void shutdown();
+
+ /**
+ * Clear.
+ */
+ public void clear();
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/cache/InMemoryEntityCache.java b/src/main/java/org/openecomp/sparky/dal/cache/InMemoryEntityCache.java
new file mode 100644
index 0000000..68378db
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/cache/InMemoryEntityCache.java
@@ -0,0 +1,101 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.cache;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.logging.AaiUiMsgs;
+
+/**
+ * The Class InMemoryEntityCache.
+ *
+ * @author davea.
+ */
+public class InMemoryEntityCache implements EntityCache {
+
+ private ConcurrentHashMap<String, OperationResult> cachedEntityData;
+ private static final Logger LOG =
+ LoggerFactory.getInstance().getLogger(InMemoryEntityCache.class);
+
+ /**
+ * Instantiates a new in memory entity cache.
+ */
+ public InMemoryEntityCache() {
+ cachedEntityData = new ConcurrentHashMap<String, OperationResult>();
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#put(java.lang.String, org.openecomp.sparky.dal.rest.OperationResult)
+ */
+ @Override
+ public void put(String key, OperationResult data) {
+ if (data == null) {
+ return;
+ }
+
+ if (cachedEntityData.putIfAbsent(key, data) != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(AaiUiMsgs.DATA_CACHE_SUCCESS, key);
+ }
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#get(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult get(String entityKey, String link) {
+
+ if (link != null) {
+ return cachedEntityData.get(link);
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#shutdown()
+ */
+ @Override
+ public void shutdown() {
+ // TODO Auto-generated method stub
+ // nothing to do
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#clear()
+ */
+ @Override
+ public void clear() {
+ cachedEntityData.clear();
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/cache/PersistentEntityCache.java b/src/main/java/org/openecomp/sparky/dal/cache/PersistentEntityCache.java
new file mode 100644
index 0000000..1456b05
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/cache/PersistentEntityCache.java
@@ -0,0 +1,305 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.cache;
+
+import static java.util.concurrent.CompletableFuture.supplyAsync;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sparky.dal.aai.ActiveInventoryAdapter;
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.logging.AaiUiMsgs;
+import org.openecomp.sparky.synchronizer.task.PersistOperationResultToDisk;
+import org.openecomp.sparky.synchronizer.task.RetrieveOperationResultFromDisk;
+import org.openecomp.sparky.util.NodeUtils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * The Class PersistentEntityCache.
+ */
+public class PersistentEntityCache implements EntityCache {
+
+ private static final Logger LOG =
+ LoggerFactory.getInstance().getLogger(ActiveInventoryAdapter.class);
+
+ /*
+ * TODO: <li>implement time-to-live on the cache, maybe pull in one of Guava's eviction caches?
+ * <li>implement abstract-base-cache to hold common cach-y things (like ttl)
+ */
+
+ private static final String DEFAULT_OUTPUT_PATH = "offlineEntityCache";
+ private ExecutorService persistentExecutor;
+ private ObjectMapper mapper;
+ private String storagePath;
+
+ /**
+ * Instantiates a new persistent entity cache.
+ */
+ public PersistentEntityCache() {
+ this(null, 10);
+ }
+
+ /**
+ * Instantiates a new persistent entity cache.
+ *
+ * @param numWorkers the num workers
+ */
+ public PersistentEntityCache(int numWorkers) {
+ this(null, numWorkers);
+ }
+
+ /**
+ * Instantiates a new persistent entity cache.
+ *
+ * @param storageFolderOverride the storage folder override
+ * @param numWorkers the num workers
+ */
+ public PersistentEntityCache(String storageFolderOverride, int numWorkers) {
+ persistentExecutor = NodeUtils.createNamedExecutor("PEC", numWorkers, LOG);
+ mapper = new ObjectMapper();
+
+ if (storageFolderOverride != null && storageFolderOverride.length() > 0) {
+ this.storagePath = storageFolderOverride;
+ } else {
+ this.storagePath = DEFAULT_OUTPUT_PATH;
+ }
+ }
+
+ /**
+ * Generate offline storage path from uri.
+ *
+ * @param link the link
+ * @return the string
+ */
+ private String generateOfflineStoragePathFromUri(String link) {
+
+ try {
+ URI uri = new URI(link);
+
+ String modHost = uri.getHost().replace(".", "_");
+
+ String[] tokens = uri.getPath().split("\\/");
+ List<String> resourcePathAndDomain = new ArrayList<String>();
+
+ if (tokens.length >= 4) {
+
+ int numElements = 0;
+ for (String w : tokens) {
+
+ if (numElements > 3) {
+ break;
+ }
+
+ if (w.length() > 0) {
+ resourcePathAndDomain.add(w);
+ numElements++;
+ }
+
+ }
+ } else {
+ return this.storagePath + "\\";
+ }
+
+ return this.storagePath + "\\" + modHost + "\\"
+ + NodeUtils.concatArray(resourcePathAndDomain, "_") + "\\";
+
+ } catch (Exception exc) {
+ LOG.error(AaiUiMsgs.OFFLINE_STORAGE_PATH_ERROR, link, exc.getMessage());
+ }
+
+ return this.storagePath + "\\";
+
+ }
+
+ /**
+ * Creates the dirs.
+ *
+ * @param directoryPath the directory path
+ */
+ private void createDirs(String directoryPath) {
+ if (directoryPath == null) {
+ return;
+ }
+
+ Path path = Paths.get(directoryPath);
+ // if directory exists?
+ if (!Files.exists(path)) {
+ try {
+ Files.createDirectories(path);
+ } catch (IOException exc) {
+ LOG.error(AaiUiMsgs.DISK_CREATE_DIR_IO_ERROR, exc.getMessage());
+ }
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#get(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult get(String key, String link) {
+
+ final String storagePath = generateOfflineStoragePathFromUri(link);
+ createDirs(storagePath);
+ final String persistentFileName = storagePath + "\\" + key + ".json";
+
+ CompletableFuture<OperationResult> task = supplyAsync(
+ new RetrieveOperationResultFromDisk(persistentFileName, mapper, LOG), persistentExecutor);
+
+ try {
+ /*
+ * this will do a blocking get, but it will be blocking only on the thread that executed this
+ * method which should be one of the persistentWorker threads from the executor.
+ */
+ return task.get();
+ } catch (InterruptedException | ExecutionException exc) {
+ // TODO Auto-generated catch block
+ LOG.error(AaiUiMsgs.DISK_NAMED_DATA_READ_IO_ERROR, "txn", exc.getMessage());
+ }
+
+ return null;
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#put(java.lang.String, org.openecomp.sparky.dal.rest.OperationResult)
+ */
+ @Override
+ public void put(String key, OperationResult data) {
+
+ final String storagePath = generateOfflineStoragePathFromUri(data.getRequestLink());
+ createDirs(storagePath);
+ final String persistentFileName = storagePath + "\\" + key + ".json";
+
+ Path persistentFilePath = Paths.get(persistentFileName);
+
+ if (!Files.exists(persistentFilePath, LinkOption.NOFOLLOW_LINKS)) {
+
+ supplyAsync(new PersistOperationResultToDisk(persistentFileName, data, mapper, LOG),
+ persistentExecutor).whenComplete((opResult, error) -> {
+
+ if (error != null) {
+ LOG.error(AaiUiMsgs.DISK_DATA_WRITE_IO_ERROR, "entity", error.getMessage());
+ }
+
+ });
+ }
+
+ }
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ * @throws URISyntaxException the URI syntax exception
+ */
+ public static void main(String[] args) throws URISyntaxException {
+
+ OperationResult or = new OperationResult();
+ or.setResult("asdjashdkajsdhaksdj");
+ or.setResultCode(200);
+
+ String url1 = "https://aai-int1.dev.att.com:8443/aai/v8/search/nodes-query?"
+ + "search-node-type=tenant&filter=tenant-id:EXISTS";
+
+ or.setRequestLink(url1);
+
+ PersistentEntityCache pec = new PersistentEntityCache("e:\\my_special_folder", 5);
+ String k1 = NodeUtils.generateUniqueShaDigest(url1);
+ pec.put(k1, or);
+
+ String url2 =
+ "https://aai-int1.dev.att.com:8443/aai/v8/network/vnfcs/vnfc/trial-vnfc?nodes-only";
+ or.setRequestLink(url2);
+ String k2 = NodeUtils.generateUniqueShaDigest(url2);
+ pec.put(k2, or);
+
+ String url3 = "https://1.2.3.4:8443/aai/v8/network/vnfcs/vnfc/trial-vnfc?nodes-only";
+ or.setRequestLink(url3);
+ String k3 = NodeUtils.generateUniqueShaDigest(url3);
+ pec.put(k3, or);
+
+ pec.shutdown();
+
+ /*
+ * URI uri1 = new URI(url1);
+ *
+ * System.out.println("schemea = " + uri1.getScheme()); System.out.println("host = " +
+ * uri1.getHost());
+ *
+ * String host = uri1.getHost(); String[] tokens = host.split("\\.");
+ * System.out.println(Arrays.asList(tokens)); ArrayList<String> tokenList = new
+ * ArrayList(Arrays.asList(tokens)); //tokenList.remove(tokens.length-1); String
+ * hostAsPathElement = NodeUtils.concatArray(tokenList, "_");
+ *
+ * System.out.println("hostAsPathElement = " + hostAsPathElement);
+ *
+ *
+ * System.out.println("port = " + uri1.getPort()); System.out.println("path = " +
+ * uri1.getPath()); System.out.println("query = " + uri1.getQuery()); System.out.println(
+ * "fragment = " + uri1.getFragment());
+ */
+
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#shutdown()
+ */
+ @Override
+ public void shutdown() {
+ if (persistentExecutor != null) {
+ persistentExecutor.shutdown();
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.cache.EntityCache#clear()
+ */
+ @Override
+ public void clear() {
+ /*
+ * do nothing for this one, as it is not clear if we we really want to clear on the on-disk
+ * cache or not
+ */
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchAdapter.java b/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchAdapter.java
new file mode 100644
index 0000000..f2df3ab
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchAdapter.java
@@ -0,0 +1,165 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.elasticsearch;
+
+import org.openecomp.sparky.dal.elasticsearch.config.ElasticSearchConfig;
+import org.openecomp.sparky.dal.rest.HttpMethod;
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.dal.rest.RestDataProvider;
+import org.openecomp.sparky.dal.rest.RestfulDataAccessor;
+
+/**
+ * The Class ElasticSearchAdapter.
+ *
+ * @author davea.
+ */
+public class ElasticSearchAdapter implements ElasticSearchDataProvider {
+
+ private static final String BULK_IMPORT_INDEX_TEMPLATE =
+ "{\"index\":{\"_index\":\"%s\",\"_type\":\"%s\",\"_id\":\"%s\", \"_version\":\"%s\"}}\n";
+
+ private final RestDataProvider restDataProvider;
+ private final ElasticSearchConfig esConfig;
+
+ /**
+ * Instantiates a new elastic search adapter.
+ *
+ * @param provider the provider
+ */
+ public ElasticSearchAdapter(RestDataProvider provider, ElasticSearchConfig esConfig) {
+ this.restDataProvider = provider;
+ this.esConfig = esConfig;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doGet(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doGet(String url, String acceptContentType) {
+ return restDataProvider.doGet(url, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doDelete(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doDelete(String url, String acceptContentType) {
+ return restDataProvider.doDelete(url, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPost(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doPost(String url, String jsonPayload, String acceptContentType) {
+ return restDataProvider.doPost(url, jsonPayload, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPut(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doPut(String url, String jsonPayload, String acceptContentType) {
+ return restDataProvider.doPut(url, jsonPayload, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPatch(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doPatch(String url, String jsonPayload, String acceptContentType) {
+ return restDataProvider.doPatch(url, jsonPayload, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doHead(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doHead(String url, String acceptContentType) {
+ return restDataProvider.doHead(url, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#clearCache()
+ */
+ @Override
+ public void clearCache() {
+ restDataProvider.clearCache();
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.elasticsearch.ElasticSearchDataProvider#doBulkOperation(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doBulkOperation(String url, String payload) {
+
+ return doRestfulOperation(HttpMethod.PUT, url, payload,
+ RestfulDataAccessor.APPLICATION_X_WWW_FORM_URL_ENCODED,
+ RestfulDataAccessor.APPLICATION_JSON);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.elasticsearch.ElasticSearchDataProvider#shutdown()
+ */
+ @Override
+ public void shutdown() {
+ restDataProvider.shutdown();
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doRestfulOperation(org.openecomp.sparky.dal.rest.HttpMethod, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doRestfulOperation(HttpMethod method, String url, String payload,
+ String payloadType, String acceptContentType) {
+ return restDataProvider.doRestfulOperation(method, url, payload, payloadType,
+ acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.elasticsearch.ElasticSearchDataProvider#buildBulkImportOperationRequest(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public String buildBulkImportOperationRequest(String index, String type, String id,
+ String version, String payload) {
+
+ StringBuilder requestPayload = new StringBuilder(128);
+
+ requestPayload.append(String.format(BULK_IMPORT_INDEX_TEMPLATE, index, type, id, version));
+ requestPayload.append(payload).append("\n");
+
+ return requestPayload.toString();
+
+ }
+
+ @Override
+ public OperationResult retrieveEntityById(String entityId) throws Exception {
+
+ String url = esConfig.getElasticFullUrl("/" +entityId);
+ return doGet( url, "application/json");
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchDataProvider.java b/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchDataProvider.java
new file mode 100644
index 0000000..97c4f4d
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchDataProvider.java
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.elasticsearch;
+
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.dal.rest.RestDataProvider;
+
+/**
+ * The Interface ElasticSearchDataProvider.
+ */
+public interface ElasticSearchDataProvider extends RestDataProvider {
+
+ /**
+ * Builds the bulk import operation request.
+ *
+ * @param index the index
+ * @param type the type
+ * @param id the id
+ * @param version the version
+ * @param payload the payload
+ * @return the string
+ */
+ String buildBulkImportOperationRequest(String index, String type, String id, String version,
+ String payload);
+
+ /**
+ * Do bulk operation.
+ *
+ * @param url the url
+ * @param payload the payload
+ * @return the operation result
+ */
+ OperationResult doBulkOperation(String url, String payload);
+
+ OperationResult retrieveEntityById(String entityId) throws Exception;
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#shutdown()
+ */
+ @Override
+ void shutdown();
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java b/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java
new file mode 100644
index 0000000..6194027
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java
@@ -0,0 +1,274 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.elasticsearch;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.openecomp.sparky.config.oxm.OxmEntityDescriptor;
+import org.openecomp.sparky.config.oxm.OxmModelLoader;
+import org.openecomp.sparky.dal.NetworkTransaction;
+import org.openecomp.sparky.dal.rest.HttpMethod;
+import org.openecomp.sparky.dal.rest.OperationResult;
+
+/**
+ * The Class ElasticSearchEntityStatistics.
+ */
+public class ElasticSearchEntityStatistics {
+
+ private static final String TOTAL = "Total";
+ private static final String CREATED = "Created";
+ private static final String MODIFIED = "Modified";
+ private static final String OTHERSUCCESS = "OTHERSUCCESS";
+ private static final String DELETED = "DELETED";
+ private static final String ERROR = "ERROR";
+
+ private Map<String, HashMap<String, AtomicInteger>> entityStatistics;
+ private OxmModelLoader loader;
+
+ /**
+ * Creates the entity op stats.
+ *
+ * @return the hash map
+ */
+ private HashMap<String, AtomicInteger> createEntityOpStats() {
+
+ HashMap<String, AtomicInteger> opStats = new HashMap<String, AtomicInteger>();
+
+ opStats.put(TOTAL, new AtomicInteger());
+ opStats.put(CREATED, new AtomicInteger());
+ opStats.put(MODIFIED, new AtomicInteger());
+ opStats.put(OTHERSUCCESS, new AtomicInteger());
+ opStats.put(DELETED, new AtomicInteger());
+ opStats.put(ERROR, new AtomicInteger());
+
+ return opStats;
+
+ }
+
+ /*
+ * private void createActiveInventoryEntityStatistics() {
+ *
+ * Map<String,OxmEntityDescriptor> descriptors = loader.getSearchableEntityDescriptors();
+ *
+ * if(descriptors == null) { return; }
+ *
+ * OxmEntityDescriptor d = null; for ( String key : descriptors.keySet() ) { d =
+ * descriptors.get(key); entityStatistics.put(d.getEntityName(), createEntityOpStats()); }
+ *
+ * }
+ */
+
+ /**
+ * Initializecreate active inventory entity statistics.
+ */
+ private void initializecreateActiveInventoryEntityStatistics() {
+ Set<String> keys = entityStatistics.keySet();
+
+ Set<String> opStatKeySet = null;
+ Map<String, AtomicInteger> opStats = null;
+
+ for (String k : keys) {
+
+ opStats = entityStatistics.get(k);
+
+ opStatKeySet = opStats.keySet();
+
+ for (String opStatKey : opStatKeySet) {
+ opStats.get(opStatKey).set(0);
+ }
+ }
+ }
+
+ /**
+ * Instantiates a new elastic search entity statistics.
+ *
+ * @param loader the loader
+ */
+ public ElasticSearchEntityStatistics(OxmModelLoader loader) {
+ this.loader = loader;
+ entityStatistics = new HashMap<String, HashMap<String, AtomicInteger>>();
+ // createActiveInventoryEntityStatistics();
+ reset();
+ }
+
+ /**
+ * Initialize counters from oxm entity descriptors.
+ *
+ * @param descriptors the descriptors
+ */
+ public void initializeCountersFromOxmEntityDescriptors(
+ Map<String, OxmEntityDescriptor> descriptors) {
+
+ if (descriptors == null) {
+ return;
+ }
+
+ OxmEntityDescriptor descriptor = null;
+ for (String key : descriptors.keySet()) {
+ descriptor = descriptors.get(key);
+ entityStatistics.put(descriptor.getEntityName(), createEntityOpStats());
+ }
+ }
+
+ /**
+ * Reset.
+ */
+ public void reset() {
+ initializecreateActiveInventoryEntityStatistics();
+ }
+
+ /**
+ * Gets the result code.
+ *
+ * @param txn the txn
+ * @return the result code
+ */
+ private int getResultCode(NetworkTransaction txn) {
+
+
+ if (txn == null) {
+ return -1;
+ }
+
+ OperationResult or = txn.getOperationResult();
+
+ if (or == null) {
+ return -1;
+ }
+
+ return or.getResultCode();
+
+ }
+
+ /**
+ * Update elastic search entity counters.
+ *
+ * @param txn the txn
+ */
+ private void updateElasticSearchEntityCounters(NetworkTransaction txn) {
+
+ if (txn == null) {
+ return;
+ }
+
+ Map<String, AtomicInteger> entityOpStats = entityStatistics.get(txn.getEntityType());
+
+ int resultCode = getResultCode(txn);
+
+ if (txn.getOperationType() == HttpMethod.PUT) {
+
+ entityOpStats.get(TOTAL).incrementAndGet();
+
+ if (resultCode == 201) {
+ entityOpStats.get(CREATED).incrementAndGet();
+ } else if (resultCode == 200) {
+ entityOpStats.get(MODIFIED).incrementAndGet();
+ } else if (202 <= resultCode && resultCode <= 299) {
+ entityOpStats.get(OTHERSUCCESS).incrementAndGet();
+ } else {
+ entityOpStats.get(ERROR).incrementAndGet();
+ }
+
+ } else if (txn.getOperationType() == HttpMethod.DELETE) {
+
+ entityOpStats.get(TOTAL).incrementAndGet();
+
+ if (200 <= resultCode && resultCode <= 299) {
+ entityOpStats.get(DELETED).incrementAndGet();
+ } else {
+ entityOpStats.get(ERROR).incrementAndGet();
+ }
+ }
+
+ }
+
+ /**
+ * Update counters.
+ *
+ * @param txn the txn
+ */
+ public void updateCounters(NetworkTransaction txn) {
+
+ updateElasticSearchEntityCounters(txn);
+
+ }
+
+ public String getStatisticsReport() {
+
+ StringBuilder sb = new StringBuilder(128);
+
+ /*
+ * sort entities, then sort nested op codes
+ */
+
+ TreeMap<String, HashMap<String, AtomicInteger>> elasticEntitySortedTreeMap =
+ new TreeMap<String, HashMap<String, AtomicInteger>>(new Comparator<String>() {
+
+ @Override
+ public int compare(String o1, String o2) {
+ return o1.toLowerCase().compareTo(o2.toLowerCase());
+ }
+ });
+
+ elasticEntitySortedTreeMap.putAll(entityStatistics);
+
+ for (String counterEntityKey : elasticEntitySortedTreeMap.keySet()) {
+
+ HashMap<String, AtomicInteger> entityCounters =
+ elasticEntitySortedTreeMap.get(counterEntityKey);
+
+ AtomicInteger total = entityCounters.get(TOTAL);
+ AtomicInteger created = entityCounters.get(CREATED);
+ AtomicInteger modified = entityCounters.get(MODIFIED);
+ AtomicInteger otherSuccess = entityCounters.get(OTHERSUCCESS);
+ AtomicInteger deleted = entityCounters.get(DELETED);
+ AtomicInteger error = entityCounters.get(ERROR);
+
+ int totalValue = (total == null) ? 0 : total.get();
+ int createdValue = (created == null) ? 0 : created.get();
+ int modifiedValue = (modified == null) ? 0 : modified.get();
+ int otherSuccessValue = (otherSuccess == null) ? 0 : otherSuccess.get();
+ int deletedValue = (deleted == null) ? 0 : deleted.get();
+ int errorValue = (error == null) ? 0 : error.get();
+
+ sb.append("\n ")
+ .append(String.format(
+ "%-30s TOTAL: %-12d CREATED: %-12d MODIFIED:"
+ + " %-12d OTHER_2XX: %-12d DELETED: %-12d ERROR: %-12d",
+ counterEntityKey, totalValue, createdValue, modifiedValue, otherSuccessValue,
+ deletedValue, errorValue));
+ }
+ return sb.toString();
+ }
+
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/elasticsearch/HashQueryResponse.java b/src/main/java/org/openecomp/sparky/dal/elasticsearch/HashQueryResponse.java
new file mode 100644
index 0000000..a376add
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/elasticsearch/HashQueryResponse.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+package org.openecomp.sparky.dal.elasticsearch;
+
+import org.json.JSONObject;
+import org.openecomp.sparky.dal.rest.OperationResult;
+
+public class HashQueryResponse {
+ private String jsonPayload = null;
+ private OperationResult opResult = null;
+
+ public HashQueryResponse() {
+ this(null, null);
+ }
+
+ public HashQueryResponse(String jsonPayload, OperationResult opResult) {
+ this.jsonPayload = jsonPayload;
+ this.opResult = opResult;
+ }
+
+ public String getJsonPayload() {
+ return jsonPayload;
+ }
+ public void setJsonPayload(String jsonPayload) {
+ this.jsonPayload = jsonPayload;
+ }
+ public OperationResult getOpResult() {
+ return opResult;
+ }
+ public void setOpResult(OperationResult opResult) {
+ this.opResult = opResult;
+ }
+ @Override
+ public String toString() {
+ return "HashQueryResponse [jsonPayload=" + jsonPayload + ", opResult=" + opResult + "]";
+ }
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/elasticsearch/SearchAdapter.java b/src/main/java/org/openecomp/sparky/dal/elasticsearch/SearchAdapter.java
new file mode 100644
index 0000000..9479a8f
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/elasticsearch/SearchAdapter.java
@@ -0,0 +1,122 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.elasticsearch;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sparky.dal.rest.OperationResult;
+import org.openecomp.sparky.dal.sas.config.SearchServiceConfig;
+import org.openecomp.sparky.util.Encryptor;
+import org.openecomp.sparky.viewandinspect.config.TierSupportUiConstants;
+import org.slf4j.MDC;
+
+import org.openecomp.restclient.client.RestClient;
+import org.openecomp.restclient.enums.RestAuthenticationMode;
+import org.openecomp.restclient.client.Headers;
+import org.openecomp.cl.mdc.MdcContext;
+
+import org.openecomp.cl.mdc.MdcContext;
+
+/**
+ * The Class SearchAdapter.
+ */
+public class SearchAdapter {
+
+ private static final Logger LOG = LoggerFactory.getInstance().getLogger(SearchAdapter.class);
+
+ private RestClient client;
+
+ private Map<String, List<String>> commonHeaders;
+ private SearchServiceConfig sasConfig;
+
+ /**
+ * Instantiates a new search adapter.
+ * @throws Exception
+ */
+ public SearchAdapter() throws Exception {
+ sasConfig = SearchServiceConfig.getConfig();
+ Encryptor encryptor = new Encryptor();
+ client = new RestClient().authenticationMode(RestAuthenticationMode.SSL_CERT)
+ .validateServerHostname(false).validateServerCertChain(false)
+ .clientCertFile(TierSupportUiConstants.CONFIG_AUTH_LOCATION + sasConfig.getCertName())
+ .clientCertPassword(encryptor.decryptValue(sasConfig.getKeystorePassword()))
+ .trustStore(TierSupportUiConstants.CONFIG_AUTH_LOCATION + sasConfig.getKeystore());
+
+ commonHeaders = new HashMap<String, List<String>>();
+ commonHeaders.put("Accept", Arrays.asList("application/json"));
+ commonHeaders.put(Headers.FROM_APP_ID, Arrays.asList("AAI-UI"));
+ }
+
+ public SearchServiceConfig getSasConfig() {
+ return sasConfig;
+ }
+
+ public void setSasConfig(SearchServiceConfig sasConfig) {
+ this.sasConfig = sasConfig;
+ }
+
+ public OperationResult doPost(String url, String jsonPayload, String acceptContentType) {
+ org.openecomp.restclient.client.OperationResult or = client.post(url, jsonPayload, getTxnHeader(),
+ MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
+ return new OperationResult(or.getResultCode(), or.getResult());
+ }
+
+ public OperationResult doGet(String url, String acceptContentType) {
+ org.openecomp.restclient.client.OperationResult or =
+ client.get(url, getTxnHeader(), MediaType.APPLICATION_JSON_TYPE);
+ return new OperationResult(or.getResultCode(), or.getResult());
+ }
+
+ public OperationResult doPut(String url, String payload, String acceptContentType) {
+ org.openecomp.restclient.client.OperationResult or = client.put(url, payload, getTxnHeader(),
+ MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
+ return new OperationResult(or.getResultCode(), or.getResult());
+ }
+
+ public OperationResult doDelete(String url, String acceptContentType) {
+
+ org.openecomp.restclient.client.OperationResult or =
+ client.delete(url, getTxnHeader(), MediaType.APPLICATION_JSON_TYPE);
+ return new OperationResult(or.getResultCode(), or.getResult());
+ }
+
+ public Map<String, List<String>> getTxnHeader() {
+ Map headers = new HashMap<String, List<String>>();
+ headers.putAll(this.commonHeaders);
+ headers.put("X-TransactionId", Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));
+ headers.put("X-FromAppId", Arrays.asList(MDC.get(MdcContext.MDC_PARTNER_NAME)));
+ return headers;
+ }
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/elasticsearch/config/ElasticSearchConfig.java b/src/main/java/org/openecomp/sparky/dal/elasticsearch/config/ElasticSearchConfig.java
new file mode 100644
index 0000000..3f2cf7a
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/elasticsearch/config/ElasticSearchConfig.java
@@ -0,0 +1,543 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.elasticsearch.config;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.openecomp.sparky.dal.exception.ElasticSearchOperationException;
+import org.openecomp.sparky.synchronizer.config.TaskProcessorConfig;
+import org.openecomp.sparky.util.ConfigHelper;
+import org.openecomp.sparky.viewandinspect.config.TierSupportUiConstants;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+
+/**
+ * The Class ElasticSearchConfig.
+ */
+public class ElasticSearchConfig {
+
+ public static final String CONFIG_FILE =
+ TierSupportUiConstants.DYNAMIC_CONFIG_APP_LOCATION + "elasticsearch.properties";
+
+ private static ElasticSearchConfig instance;
+
+ private String ipAddress;
+
+ private String httpPort;
+
+ private String javaApiPort;
+
+ private String indexName;
+
+ private String type;
+
+ private String clusterName;
+
+ private String mappingsFileName;
+
+ private String settingsFileName;
+
+ private int syncAdapterMaxConcurrentWorkers;
+
+ private String auditIndexName;
+
+ private String topographicalSearchIndex;
+
+ private String entityCountHistoryIndex;
+
+ private String autosuggestIndexname;
+
+ private String entityCountHistoryMappingsFileName;
+
+ private String autoSuggestSettingsFileName;
+
+ private String autoSuggestMappingsFileName;
+
+ private String dynamicMappingsFileName;
+
+ private static final String IP_ADDRESS_DEFAULT = "localhost";
+
+ private static final String HTTP_PORT_DEFAULT = "9200";
+
+ private static final String JAVA_API_PORT_DEFAULT = "9300";
+
+ private static final String TYPE_DEFAULT = "aaiEntities";
+
+ private static final String CLUSTER_NAME_DEFAULT = "elasticsearch";
+
+ private static final String INDEX_NAME_DEFAULT = "entitySearchIndex";
+
+ private static final String AUDIT_INDEX_NAME_DEFAULT = "auditdataindex";
+
+ private static final String TOPOGRAPHICAL_INDEX_NAME_DEFAULT = "topographicalSearchIndex";
+
+ private static final String ENTITY_COUNT_HISTORY_INDEX_NAME_DEFAULT = "entityCountHistory";
+
+ private static final String ENTITY_AUTO_SUGGEST_INDEX_NAME_DEFAULT =
+ TierSupportUiConstants.ENTITY_AUTO_SUGGEST_INDEX_NAME_DEFAULT;
+
+ private static final String ENTITY_AUTO_SUGGEST_SETTINGS_FILE_DEFAULT =
+ TierSupportUiConstants.ENTITY_AUTO_SUGGEST_SETTINGS_FILE_DEFAULT;
+
+ private static final String ENTITY_AUTO_SUGGEST_MAPPINGS_FILE_DEFAULT =
+ TierSupportUiConstants.ENTITY_AUTO_SUGGEST_SETTINGS_FILE_DEFAULT;
+
+ private static final String ENTITY_DYNAMIC_MAPPINGS_FILE_DEFAULT =
+ TierSupportUiConstants.ENTITY_DYNAMIC_MAPPINGS_FILE_DEFAULT;
+
+ private static final String BULK_API = "_bulk";
+
+ private TaskProcessorConfig processorConfig;
+
+ public TaskProcessorConfig getProcessorConfig() {
+ return processorConfig;
+ }
+
+ public void setProcessorConfig(TaskProcessorConfig processorConfig) {
+ this.processorConfig = processorConfig;
+ }
+
+ public static ElasticSearchConfig getConfig() throws Exception {
+
+ if (instance == null) {
+ instance = new ElasticSearchConfig();
+ instance.initializeProperties();
+ }
+
+ return instance;
+ }
+
+ public static void setConfig(ElasticSearchConfig config) {
+ /*
+ * Explicitly allow setting the configuration singleton. This will be useful for automation.
+ */
+
+ ElasticSearchConfig.instance = config;
+ }
+
+ /**
+ * Instantiates a new elastic search config.
+ */
+ public ElasticSearchConfig() {
+ // test method
+ }
+
+ public String getElasticFullUrl(String resourceUrl, String indexName, String indexType)
+ throws Exception {
+ final String host = getIpAddress();
+ final String port = getHttpPort();
+ return String.format("http://%s:%s/%s/%s%s", host, port, indexName, indexType, resourceUrl);
+ }
+
+ public String getElasticFullUrl(String resourceUrl, String indexName) throws Exception {
+ final String host = getIpAddress();
+ final String port = getHttpPort();
+ return String.format("http://%s:%s/%s/%s%s", host, port, indexName,
+ ElasticSearchConfig.getConfig().getType(), resourceUrl);
+ }
+
+ public String getElasticFullUrl(String resourceUrl) throws Exception {
+ final String host = getIpAddress();
+ final String port = getHttpPort();
+ final String indexName = getIndexName();
+ return String.format("http://%s:%s/%s/%s%s", host, port, indexName, getType(), resourceUrl);
+ }
+
+ /**
+ * Initialize properties.
+ */
+ private void initializeProperties() {
+ Properties props = ConfigHelper.loadConfigFromExplicitPath(CONFIG_FILE);
+
+ ipAddress = props.getProperty("elasticsearch.ipAddress", IP_ADDRESS_DEFAULT);
+ httpPort = props.getProperty("elasticsearch.httpPort", "" + HTTP_PORT_DEFAULT);
+ javaApiPort = props.getProperty("elasticsearch.javaApiPort", "" + JAVA_API_PORT_DEFAULT);
+ type = props.getProperty("elasticsearch.type", TYPE_DEFAULT);
+ clusterName = props.getProperty("elasticsearch.clusterName", CLUSTER_NAME_DEFAULT);
+ indexName = props.getProperty("elasticsearch.indexName", INDEX_NAME_DEFAULT);
+ mappingsFileName = props.getProperty("elasticsearch.mappingsFileName");
+ settingsFileName = props.getProperty("elasticsearch.settingsFileName");
+ auditIndexName = props.getProperty("elasticsearch.auditIndexName", AUDIT_INDEX_NAME_DEFAULT);
+ topographicalSearchIndex =
+ props.getProperty("elasticsearch.topographicalIndexName", TOPOGRAPHICAL_INDEX_NAME_DEFAULT);
+ entityCountHistoryIndex = props.getProperty("elasticsearch.entityCountHistoryIndexName",
+ ENTITY_COUNT_HISTORY_INDEX_NAME_DEFAULT);
+ entityCountHistoryMappingsFileName =
+ props.getProperty("elasticsearch.entityCountHistoryMappingsFileName");
+
+ autosuggestIndexname = props.getProperty("elasticsearch.autosuggestIndexname",
+ ENTITY_AUTO_SUGGEST_INDEX_NAME_DEFAULT);
+ autoSuggestSettingsFileName = props.getProperty("elasticsearch.autosuggestSettingsFileName",
+ ENTITY_AUTO_SUGGEST_SETTINGS_FILE_DEFAULT);
+ autoSuggestMappingsFileName = props.getProperty("elasticsearch.autosuggestMappingsFileName",
+ ENTITY_AUTO_SUGGEST_MAPPINGS_FILE_DEFAULT);
+ dynamicMappingsFileName = props.getProperty("elasticsearch.dynamicMappingsFileName",
+ ENTITY_DYNAMIC_MAPPINGS_FILE_DEFAULT);
+
+ syncAdapterMaxConcurrentWorkers =
+ Integer.parseInt(props.getProperty("elasticsearch.syncAdapter.maxConcurrentWorkers", "5"));
+
+ processorConfig = new TaskProcessorConfig();
+ processorConfig.initializeFromProperties(
+ ConfigHelper.getConfigWithPrefix("elasticsearch.taskProcessor", props));
+
+ }
+
+ public String getIpAddress() {
+ return ipAddress;
+ }
+
+ public void setIpAddress(String ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+
+ public String getHttpPort() {
+ return httpPort;
+ }
+
+ public void setHttpPort(String httpPort) {
+ this.httpPort = httpPort;
+ }
+
+ public String getJavaApiPort() {
+ return javaApiPort;
+ }
+
+ public void setJavaApiPort(String javaApiPort) {
+ this.javaApiPort = javaApiPort;
+ }
+
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public void setIndexName(String indexName) {
+ this.indexName = indexName;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getMappingsFileName() {
+ return mappingsFileName;
+ }
+
+ public void setMappingsFileName(String mappingsFileName) {
+ this.mappingsFileName = mappingsFileName;
+ }
+
+ public String getSettingsFileName() {
+ return settingsFileName;
+ }
+
+ public int getSyncAdapterMaxConcurrentWorkers() {
+ return syncAdapterMaxConcurrentWorkers;
+ }
+
+ public void setSyncAdapterMaxConcurrentWorkers(int syncAdapterMaxConcurrentWorkers) {
+ this.syncAdapterMaxConcurrentWorkers = syncAdapterMaxConcurrentWorkers;
+ }
+
+ public void setSettingsFileName(String settingsFileName) {
+ this.settingsFileName = settingsFileName;
+ }
+
+ public String getAuditIndexName() {
+ return auditIndexName;
+ }
+
+ public void setAuditIndexName(String auditIndexName) {
+ this.auditIndexName = auditIndexName;
+ }
+
+ public String getTopographicalSearchIndex() {
+ return topographicalSearchIndex;
+ }
+
+ public void setTopographicalSearchIndex(String topographicalSearchIndex) {
+ this.topographicalSearchIndex = topographicalSearchIndex;
+ }
+
+ public String getEntityCountHistoryIndex() {
+ return entityCountHistoryIndex;
+ }
+
+ public void setEntityCountHistoryIndex(String entityCountHistoryIndex) {
+ this.entityCountHistoryIndex = entityCountHistoryIndex;
+ }
+
+
+ public String getEntityCountHistoryMappingsFileName() {
+ return entityCountHistoryMappingsFileName;
+ }
+
+ public void setEntityCountHistoryMappingsFileName(String entityCountHistoryMappingsFileName) {
+ this.entityCountHistoryMappingsFileName = entityCountHistoryMappingsFileName;
+ }
+
+ public String getBulkUrl() {
+ String url = this.getIpAddress();
+ String port = this.getHttpPort();
+ return String.format("http://%s:%s/%s", url, port, BULK_API);
+ }
+
+ public String getConfigAsString(String configItem, String configFileName)
+ throws ElasticSearchOperationException {
+ String indexConfig = null;
+
+ try {
+ indexConfig = ConfigHelper.getFileContents(configFileName);
+ } catch (IOException exc) {
+ throw new ElasticSearchOperationException(
+ "Failed to read index " + configItem + " from file = " + configFileName + ".", exc);
+ }
+
+ if (indexConfig == null) {
+ throw new ElasticSearchOperationException(
+ "Failed to load index " + configItem + " with filename = " + configFileName + ".");
+ }
+ return indexConfig;
+ }
+
+ public String getElasticSearchSettings() throws ElasticSearchOperationException {
+ return getConfigAsString("settings",
+ TierSupportUiConstants.getConfigPath(this.getSettingsFileName()));
+ }
+
+ public String getDynamicMappings() throws ElasticSearchOperationException{
+ return getConfigAsString("mapping",
+ TierSupportUiConstants.getConfigPath(this.getDynamicMappingsFileName()));
+ }
+ public String getElasticSearchMappings() throws ElasticSearchOperationException {
+ return getConfigAsString("mapping",
+ TierSupportUiConstants.getConfigPath(this.getMappingsFileName()));
+ }
+
+ public String getElasticSearchEntityCountHistoryMappings()
+ throws ElasticSearchOperationException {
+ return getConfigAsString("mapping",
+ TierSupportUiConstants.getConfigPath(this.getEntityCountHistoryMappingsFileName()));
+ }
+
+ public String getAutosuggestIndexSettings() throws ElasticSearchOperationException {
+ return getConfigAsString("setting",
+ TierSupportUiConstants.getConfigPath(this.getAutoSuggestSettingsFileName()));
+ }
+
+ public String getAutosuggestIndexMappings() throws ElasticSearchOperationException {
+ return getConfigAsString("mapping",
+ TierSupportUiConstants.getConfigPath(this.getAutoSuggestMappingsFileName()));
+ }
+
+ public String getAutosuggestIndexname() {
+ return autosuggestIndexname;
+ }
+
+ public void setAutosuggestIndexname(String autosuggestIndexname) {
+ this.autosuggestIndexname = autosuggestIndexname;
+ }
+
+ public String getAutoSuggestSettingsFileName() {
+ return autoSuggestSettingsFileName;
+ }
+
+ public void setAutoSuggestSettingsFileName(String autoSuggestSettingsFileName) {
+ this.autoSuggestSettingsFileName = autoSuggestSettingsFileName;
+ }
+
+ public String getAutoSuggestMappingsFileName() {
+ return autoSuggestMappingsFileName;
+ }
+
+ public void setAutoSuggestMappingsFileName(String autoSuggestMappingsFileName) {
+ this.autoSuggestMappingsFileName = autoSuggestMappingsFileName;
+ }
+
+ public String getDynamicMappingsFileName() {
+ return dynamicMappingsFileName;
+ }
+
+ public void setDynamicMappingsFileName(String dynamicMappingsFileName) {
+ this.dynamicMappingsFileName = dynamicMappingsFileName;
+ }
+
+ /**
+ * Builds the elastic search table config.
+ *
+ * @return the string
+ * @throws ElasticSearchOperationException the elastic search operation exception
+ */
+ public String buildElasticSearchTableConfig() throws ElasticSearchOperationException {
+
+ JsonNode esSettingsNode;
+ JsonNode esMappingsNodes;
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ esSettingsNode = mapper.readTree(getElasticSearchSettings());
+ esMappingsNodes = mapper.readTree(getElasticSearchMappings());
+ } catch (IOException e1) {
+ throw new ElasticSearchOperationException("Caught an exception building initial ES index");
+ }
+
+ ObjectNode esConfig = (ObjectNode) mapper.createObjectNode().set("settings", esSettingsNode);
+ ObjectNode mappings = (ObjectNode) mapper.createObjectNode().set(getType(), esMappingsNodes);
+
+ esConfig.set("mappings", mappings);
+
+ try {
+ return mapper.writeValueAsString(esConfig);
+ } catch (JsonProcessingException exc) {
+ throw new ElasticSearchOperationException("Error getting object node as string", exc);
+ }
+
+ }
+
+ /**
+ * Builds the elastic search entity count history table config.
+ *
+ * @return the string
+ * @throws ElasticSearchOperationException the elastic search operation exception
+ */
+ public String buildElasticSearchEntityCountHistoryTableConfig()
+ throws ElasticSearchOperationException {
+
+ JsonNode esSettingsNode;
+ JsonNode esMappingsNodes;
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ esSettingsNode = mapper.readTree(getElasticSearchSettings());
+ esMappingsNodes = mapper.readTree(getElasticSearchEntityCountHistoryMappings());
+ } catch (IOException e1) {
+ throw new ElasticSearchOperationException("Caught an exception building initial ES index");
+ }
+
+ ObjectNode esConfig = (ObjectNode) mapper.createObjectNode().set("settings", esSettingsNode);
+ ObjectNode mappings = (ObjectNode) mapper.createObjectNode().set(getType(), esMappingsNodes);
+
+ esConfig.set("mappings", mappings);
+
+ try {
+ return mapper.writeValueAsString(esConfig);
+ } catch (JsonProcessingException exc) {
+ throw new ElasticSearchOperationException("Error getting object node as string", exc);
+ }
+
+ }
+
+ public String buildAggregationTableConfig() throws ElasticSearchOperationException {
+
+ JsonNode esMappingsNodes;
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ esMappingsNodes = mapper.readTree(this.getDynamicMappings());
+ } catch (IOException e1) {
+ throw new ElasticSearchOperationException(
+ "Caught an exception building Aggreagation ES index");
+ }
+
+ ObjectNode mappings = (ObjectNode) mapper.createObjectNode().set(getType(), esMappingsNodes);
+
+ ObjectNode indexConfig = (ObjectNode) mapper.createObjectNode().set("mappings", mappings);
+
+ try {
+ return mapper.writeValueAsString(indexConfig);
+ } catch (JsonProcessingException exc) {
+ throw new ElasticSearchOperationException("Error getting object node as string", exc);
+ }
+
+ }
+
+ public String buildAutosuggestionTableConfig() throws ElasticSearchOperationException {
+
+ JsonNode esSettingsNode;
+ JsonNode esMappingsNodes;
+ ObjectMapper mapper = new ObjectMapper();
+
+ try {
+ esSettingsNode = mapper.readTree(this.getAutosuggestIndexSettings());
+ esMappingsNodes = mapper.readTree(this.getAutosuggestIndexMappings());
+ } catch (IOException e1) {
+ throw new ElasticSearchOperationException(
+ "Caught an exception building Autosuggestion ES index");
+ }
+
+ ObjectNode indexConfig = (ObjectNode) mapper.createObjectNode().set("settings", esSettingsNode);
+ ObjectNode mappings = (ObjectNode) mapper.createObjectNode().set(getType(), esMappingsNodes);
+
+ indexConfig.set("mappings", mappings);
+
+ try {
+ return mapper.writeValueAsString(indexConfig);
+ } catch (JsonProcessingException exc) {
+ throw new ElasticSearchOperationException("Error getting object node as string", exc);
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "ElasticSearchConfig [ipAddress=" + ipAddress + ", httpPort=" + httpPort
+ + ", javaApiPort=" + javaApiPort + ", indexName=" + indexName + ", type=" + type
+ + ", clusterName=" + clusterName + ", mappingsFileName=" + mappingsFileName
+ + ", settingsFileName=" + settingsFileName + ", syncAdapterMaxConcurrentWorkers="
+ + syncAdapterMaxConcurrentWorkers + ", auditIndexName=" + auditIndexName
+ + ", topographicalSearchIndex=" + topographicalSearchIndex + ", entityCountHistoryIndex="
+ + entityCountHistoryIndex + ", autosuggestIndexname=" + autosuggestIndexname
+ + ", entityCountHistoryMappingsFileName=" + entityCountHistoryMappingsFileName
+ + ", autoSuggestSettingsFileName=" + autoSuggestSettingsFileName
+ + ", autoSuggestMappingsFileName=" + autoSuggestMappingsFileName
+ + ", dynamicMappingsFileName=" + dynamicMappingsFileName + ", processorConfig="
+ + processorConfig + "]";
+ }
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/exception/ElasticSearchOperationException.java b/src/main/java/org/openecomp/sparky/dal/exception/ElasticSearchOperationException.java
new file mode 100644
index 0000000..cb477d0
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/exception/ElasticSearchOperationException.java
@@ -0,0 +1,54 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.exception;
+
+/**
+ * The Class ElasticSearchOperationException.
+ */
+public class ElasticSearchOperationException extends Exception {
+
+ private static final long serialVersionUID = -7689309913743200670L;
+
+ /**
+ * Instantiates a new elastic search operation exception.
+ *
+ * @param message the message
+ * @param exc the exc
+ */
+ public ElasticSearchOperationException(String message, Exception exc) {
+ super(message, exc);
+ }
+
+ /**
+ * Instantiates a new elastic search operation exception.
+ *
+ * @param message the message
+ */
+ public ElasticSearchOperationException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/rest/HttpMethod.java b/src/main/java/org/openecomp/sparky/dal/rest/HttpMethod.java
new file mode 100644
index 0000000..6a7c3db
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/rest/HttpMethod.java
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.rest;
+
+
+/**
+ * The Enum HttpMethod.
+ */
+public enum HttpMethod {
+ GET, PUT, POST, DELETE, PATCH, HEAD
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/rest/OperationResult.java b/src/main/java/org/openecomp/sparky/dal/rest/OperationResult.java
new file mode 100644
index 0000000..fcceb2b
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/rest/OperationResult.java
@@ -0,0 +1,198 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.rest;
+
+/**
+ * The Class OperationResult.
+ */
+public class OperationResult {
+
+ private String result;
+
+ private String objectId;
+ private String requestLink;
+ private String requestPayload;
+
+ private int resultCode;
+
+ private boolean resolvedLinkFromCache;
+
+ private boolean resolvedLinkFromServer;
+
+ private boolean resolvedLinkFailure;
+
+ private int numRequestRetries;
+
+ private long responseTimeInMs;
+
+ /**
+ * Reset.
+ */
+ public void reset() {
+ this.objectId = null;
+ this.result = null;
+ this.requestLink = null;
+ this.requestPayload = null;
+ this.resultCode = -1;
+ this.resolvedLinkFailure = false;
+ this.resolvedLinkFromServer = false;
+ this.resolvedLinkFromCache = false;
+ this.responseTimeInMs = 0;
+ this.numRequestRetries = 0;
+ }
+
+ public String getObjectId() {
+ return objectId;
+ }
+
+ public void setObjectId(String objectId) {
+ this.objectId = objectId;
+ }
+
+ public boolean isResolvedLinkFromCache() {
+ return resolvedLinkFromCache;
+ }
+
+ /**
+ * Was successful.
+ *
+ * @return true, if successful
+ */
+ public boolean wasSuccessful() {
+ return (resultCode > 199 && resultCode < 300);
+ }
+
+ public String getRequestLink() {
+ return requestLink;
+ }
+
+ public void setRequestLink(String requestLink) {
+ this.requestLink = requestLink;
+ }
+
+ public String getRequestPayload() {
+ return requestPayload;
+ }
+
+ public void setRequestPayload(String requestPayload) {
+ this.requestPayload = requestPayload;
+ }
+
+ public void setResolvedLinkFromCache(boolean resolvedLinkFromCache) {
+ this.resolvedLinkFromCache = resolvedLinkFromCache;
+ }
+
+ public boolean isResolvedLinkFromServer() {
+ return resolvedLinkFromServer;
+ }
+
+ public void setResolvedLinkFromServer(boolean resolvedLinkFromServer) {
+ this.resolvedLinkFromServer = resolvedLinkFromServer;
+ }
+
+ public boolean isResolvedLinkFailure() {
+ return resolvedLinkFailure;
+ }
+
+ public void setResolvedLinkFailure(boolean resolvedLinkFailure) {
+ this.resolvedLinkFailure = resolvedLinkFailure;
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public int getResultCode() {
+ return resultCode;
+ }
+
+ public void setResultCode(int resultCode) {
+ this.resultCode = resultCode;
+ }
+
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+ /**
+ * Sets the result.
+ *
+ * @param resultCode the result code
+ * @param result the result
+ */
+ public void setResult(int resultCode, String result) {
+ this.resultCode = resultCode;
+ this.result = result;
+ }
+
+ /**
+ * Instantiates a new operation result.
+ */
+ public OperationResult() {
+ super();
+ }
+
+ /**
+ * Instantiates a new operation result.
+ *
+ * @param resultCode the result code
+ * @param result the result
+ */
+ public OperationResult(int resultCode, String result) {
+ super();
+ this.resultCode = resultCode;
+ this.result = result;
+ }
+
+ public long getResponseTimeInMs() {
+ return responseTimeInMs;
+ }
+
+ public void setResponseTimeInMs(long responseTimeInMs) {
+ this.responseTimeInMs = responseTimeInMs;
+ }
+
+ public int getNumRequestRetries() {
+ return numRequestRetries;
+ }
+
+ public void setNumRequestRetries(int numRequestRetries) {
+ this.numRequestRetries = numRequestRetries;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "OperationResult [result=" + result + ", resultCode=" + resultCode
+ + ", resolvedLinkFromCache=" + resolvedLinkFromCache + ", resolvedLinkFromServer="
+ + resolvedLinkFromServer + ", resolvedLinkFailure=" + resolvedLinkFailure
+ + ", numRequestRetries=" + numRequestRetries + ", responseTimeInMs=" + responseTimeInMs
+ + "]";
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/rest/RestClientBuilder.java b/src/main/java/org/openecomp/sparky/dal/rest/RestClientBuilder.java
new file mode 100644
index 0000000..267061a
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/rest/RestClientBuilder.java
@@ -0,0 +1,148 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.rest;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+
+import org.openecomp.sparky.security.SecurityContextFactory;
+import org.openecomp.sparky.security.SecurityContextFactoryImpl;
+
+/**
+ * This is a generic REST Client builder with flexible security validation. Sometimes it's nice to
+ * be able to disable server chain cert validation and hostname validation to work-around lab
+ * issues, but at the same time be able to provide complete validation with client cert + hostname +
+ * server cert chain validation.
+ * I used the ModelLoader REST client as a base and merged in the TSUI client I wrote which also
+ * validates the server hostname and server certificate chain.
+ *
+ * @author DAVEA
+ *
+ */
+public class RestClientBuilder {
+
+ /*
+ * TODO: implement fluent interface?
+ */
+
+ private boolean useHttps;
+ private boolean validateServerHostname;
+ private int connectTimeoutInMs;
+ private int readTimeoutInMs;
+ protected SecurityContextFactory sslContextFactory;
+
+ /**
+ * Instantiates a new rest client builder.
+ */
+ public RestClientBuilder() {
+ validateServerHostname = false;
+ connectTimeoutInMs = 60000;
+ readTimeoutInMs = 60000;
+ useHttps = true;
+ sslContextFactory = new SecurityContextFactoryImpl();
+ }
+
+ public SecurityContextFactory getSslContextFactory() {
+ return sslContextFactory;
+ }
+
+ public void setSslContextFactory(SecurityContextFactory sslContextFactory) {
+ this.sslContextFactory = sslContextFactory;
+ }
+
+ public boolean isUseHttps() {
+ return useHttps;
+ }
+
+ public void setUseHttps(boolean useHttps) {
+ this.useHttps = useHttps;
+ }
+
+ public int getConnectTimeoutInMs() {
+ return connectTimeoutInMs;
+ }
+
+ public void setConnectTimeoutInMs(int connectTimeoutInMs) {
+ this.connectTimeoutInMs = connectTimeoutInMs;
+ }
+
+ public int getReadTimeoutInMs() {
+ return readTimeoutInMs;
+ }
+
+ public void setReadTimeoutInMs(int readTimeoutInMs) {
+ this.readTimeoutInMs = readTimeoutInMs;
+ }
+
+ public boolean isValidateServerHostname() {
+ return validateServerHostname;
+ }
+
+ public void setValidateServerHostname(boolean validateServerHostname) {
+ this.validateServerHostname = validateServerHostname;
+ }
+
+ public Client getClient() throws Exception {
+
+ Client client = null;
+ ClientConfig clientConfig = new DefaultClientConfig();
+
+ if (useHttps) {
+ SSLContext sslContext = sslContextFactory.getSecureContext();
+
+ if (validateServerHostname) {
+
+ clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+ new HTTPSProperties(null, sslContext));
+
+ } else {
+ clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+ new HTTPSProperties(new HostnameVerifier() {
+ @Override
+ public boolean verify(String string, SSLSession sslSession) {
+ return true;
+ }
+ }, sslContext));
+
+ }
+ }
+
+ client = Client.create(clientConfig);
+
+ client.setConnectTimeout(connectTimeoutInMs);
+ client.setReadTimeout(readTimeoutInMs);
+
+ return client;
+
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/rest/RestDataProvider.java b/src/main/java/org/openecomp/sparky/dal/rest/RestDataProvider.java
new file mode 100644
index 0000000..15dad28
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/rest/RestDataProvider.java
@@ -0,0 +1,112 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.rest;
+
+/**
+ * The Interface RestDataProvider.
+ */
+public interface RestDataProvider {
+
+ /**
+ * Do get.
+ *
+ * @param url the url
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doGet(String url, String acceptContentType);
+
+ /**
+ * Do delete.
+ *
+ * @param url the url
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doDelete(String url, String acceptContentType);
+
+ /**
+ * Do post.
+ *
+ * @param url the url
+ * @param jsonPayload the json payload
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doPost(String url, String jsonPayload, String acceptContentType);
+
+ /**
+ * Do put.
+ *
+ * @param url the url
+ * @param jsonPayload the json payload
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doPut(String url, String jsonPayload, String acceptContentType);
+
+ /**
+ * Do patch.
+ *
+ * @param url the url
+ * @param jsonPayload the json payload
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doPatch(String url, String jsonPayload, String acceptContentType);
+
+ /**
+ * Do head.
+ *
+ * @param url the url
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doHead(String url, String acceptContentType);
+
+ /**
+ * Do restful operation.
+ *
+ * @param method the method
+ * @param url the url
+ * @param payload the payload
+ * @param payloadType the payload type
+ * @param acceptContentType the accept content type
+ * @return the operation result
+ */
+ OperationResult doRestfulOperation(HttpMethod method, String url, String payload,
+ String payloadType, String acceptContentType);
+
+ /**
+ * Shutdown.
+ */
+ void shutdown();
+
+ /**
+ * Clear cache.
+ */
+ void clearCache();
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/rest/RestOperationalStatistics.java b/src/main/java/org/openecomp/sparky/dal/rest/RestOperationalStatistics.java
new file mode 100644
index 0000000..7b0ca48
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/rest/RestOperationalStatistics.java
@@ -0,0 +1,256 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.rest;
+
+import org.openecomp.sparky.analytics.AbstractStatistics;
+import org.openecomp.sparky.dal.NetworkTransaction;
+
+/**
+ * The Class RestOperationalStatistics.
+ */
+public class RestOperationalStatistics extends AbstractStatistics {
+
+ private static final String GET_1XX = "GET_1XX";
+ private static final String GET_2XX = "GET_2XX";
+ private static final String GET_3XX = "GET_3XX";
+ private static final String GET_4XX = "GET_4XX";
+ private static final String GET_5XX = "GET_5XX";
+ private static final String GET_6XX = "GET_6XX";
+
+ private static final String PUT_1XX = "PUT_1XX";
+ private static final String PUT_2XX = "PUT_2XX";
+ private static final String PUT_3XX = "PUT_3XX";
+ private static final String PUT_4XX = "PUT_4XX";
+ private static final String PUT_5XX = "PUT_5XX";
+ private static final String PUT_6XX = "PUT_6XX";
+
+ private static final String POST_1XX = "POST_1XX";
+ private static final String POST_2XX = "POST_2XX";
+ private static final String POST_3XX = "POST_3XX";
+ private static final String POST_4XX = "POST_4XX";
+ private static final String POST_5XX = "POST_5XX";
+ private static final String POST_6XX = "POST_6XX";
+
+ private static final String DELETE_1XX = "DELETE_1XX";
+ private static final String DELETE_2XX = "DELETE_2XX";
+ private static final String DELETE_3XX = "DELETE_3XX";
+ private static final String DELETE_4XX = "DELETE_4XX";
+ private static final String DELETE_5XX = "DELETE_5XX";
+ private static final String DELETE_6XX = "DELETE_6XX";
+
+ /**
+ * Creates the counters.
+ */
+ private void createCounters() {
+
+ addCounter(GET_1XX);
+ addCounter(GET_2XX);
+ addCounter(GET_3XX);
+ addCounter(GET_4XX);
+ addCounter(GET_5XX);
+ addCounter(GET_6XX);
+
+ addCounter(PUT_1XX);
+ addCounter(PUT_2XX);
+ addCounter(PUT_3XX);
+ addCounter(PUT_4XX);
+ addCounter(PUT_5XX);
+ addCounter(PUT_6XX);
+
+ addCounter(POST_1XX);
+ addCounter(POST_2XX);
+ addCounter(POST_3XX);
+ addCounter(POST_4XX);
+ addCounter(POST_5XX);
+ addCounter(POST_6XX);
+
+ addCounter(DELETE_1XX);
+ addCounter(DELETE_2XX);
+ addCounter(DELETE_3XX);
+ addCounter(DELETE_4XX);
+ addCounter(DELETE_5XX);
+ addCounter(DELETE_6XX);
+
+
+ }
+
+ /**
+ * Gets the result code.
+ *
+ * @param txn the txn
+ * @return the result code
+ */
+ private int getResultCode(NetworkTransaction txn) {
+
+ if (txn == null) {
+ return -1;
+ }
+
+ if (txn.getOperationResult() == null) {
+ return -1;
+ }
+
+ return txn.getOperationResult().getResultCode();
+
+ }
+
+ /**
+ * Update counters.
+ *
+ * @param txn the txn
+ */
+ public void updateCounters(NetworkTransaction txn) {
+
+ if (txn == null) {
+ return;
+ }
+
+ int rc = getResultCode(txn);
+
+ switch (txn.getOperationType()) {
+
+ case GET: {
+
+ if (100 <= rc && rc <= 199) {
+ pegCounter(GET_1XX);
+ } else if (200 <= rc && rc <= 299) {
+ pegCounter(GET_2XX);
+ } else if (300 <= rc && rc <= 399) {
+ pegCounter(GET_3XX);
+ } else if (400 <= rc && rc <= 499) {
+ pegCounter(GET_4XX);
+ } else if (500 <= rc && rc <= 599) {
+ pegCounter(GET_5XX);
+ } else if (600 <= rc && rc <= 699) {
+ pegCounter(GET_6XX);
+ }
+
+ break;
+ }
+
+ case PUT: {
+
+ if (100 <= rc && rc <= 199) {
+ pegCounter(PUT_1XX);
+ } else if (200 <= rc && rc <= 299) {
+ pegCounter(PUT_2XX);
+ } else if (300 <= rc && rc <= 399) {
+ pegCounter(PUT_3XX);
+ } else if (400 <= rc && rc <= 499) {
+ pegCounter(PUT_4XX);
+ } else if (500 <= rc && rc <= 599) {
+ pegCounter(PUT_5XX);
+ } else if (600 <= rc && rc <= 699) {
+ pegCounter(PUT_6XX);
+ }
+
+ break;
+ }
+
+ case POST: {
+
+ if (100 <= rc && rc <= 199) {
+ pegCounter(POST_1XX);
+ } else if (200 <= rc && rc <= 299) {
+ pegCounter(POST_2XX);
+ } else if (300 <= rc && rc <= 399) {
+ pegCounter(POST_3XX);
+ } else if (400 <= rc && rc <= 499) {
+ pegCounter(POST_4XX);
+ } else if (500 <= rc && rc <= 599) {
+ pegCounter(POST_5XX);
+ } else if (600 <= rc && rc <= 699) {
+ pegCounter(POST_6XX);
+ }
+
+ break;
+ }
+
+ case DELETE: {
+
+ if (100 <= rc && rc <= 199) {
+ pegCounter(DELETE_1XX);
+ } else if (200 <= rc && rc <= 299) {
+ pegCounter(DELETE_2XX);
+ } else if (300 <= rc && rc <= 399) {
+ pegCounter(DELETE_3XX);
+ } else if (400 <= rc && rc <= 499) {
+ pegCounter(DELETE_4XX);
+ } else if (500 <= rc && rc <= 599) {
+ pegCounter(DELETE_5XX);
+ } else if (600 <= rc && rc <= 699) {
+ pegCounter(DELETE_6XX);
+ }
+
+ break;
+ }
+
+ default: {
+ // not expecting anything else yet
+ }
+
+ }
+
+ }
+
+ /**
+ * Instantiates a new rest operational statistics.
+ */
+ public RestOperationalStatistics() {
+ createCounters();
+ }
+
+ public String getStatisticsReport() {
+
+ StringBuilder sb = new StringBuilder(128);
+
+ sb.append("\n ")
+ .append(String.format(
+ "%-12s 1XX: %-12d 2XX: %-12d 3XX: %-12d 4XX: %-12d 5XX: %-12d 6XX: %-12d ",
+ HttpMethod.DELETE, getCounterValue(DELETE_1XX), getCounterValue(DELETE_2XX),
+ getCounterValue(DELETE_3XX), getCounterValue(DELETE_4XX), getCounterValue(DELETE_5XX),
+ getCounterValue(DELETE_6XX)));
+
+ sb.append("\n ").append(String.format(
+ "%-12s 1XX: %-12d 2XX: %-12d 3XX: %-12d 4XX: %-12d 5XX: %-12d 6XX: %-12d ", HttpMethod.PUT,
+ getCounterValue(PUT_1XX), getCounterValue(PUT_2XX), getCounterValue(PUT_3XX),
+ getCounterValue(PUT_4XX), getCounterValue(PUT_5XX), getCounterValue(PUT_6XX)));
+
+ sb.append("\n ").append(String.format(
+ "%-12s 1XX: %-12d 2XX: %-12d 3XX: %-12d 4XX: %-12d 5XX: %-12d 6XX: %-12d ", HttpMethod.POST,
+ getCounterValue(POST_1XX), getCounterValue(POST_2XX), getCounterValue(POST_3XX),
+ getCounterValue(POST_4XX), getCounterValue(POST_5XX), getCounterValue(POST_6XX)));
+
+ sb.append("\n ").append(String.format(
+ "%-12s 1XX: %-12d 2XX: %-12d 3XX: %-12d 4XX: %-12d 5XX: %-12d 6XX: %-12d ", HttpMethod.GET,
+ getCounterValue(GET_1XX), getCounterValue(GET_2XX), getCounterValue(GET_3XX),
+ getCounterValue(GET_4XX), getCounterValue(GET_5XX), getCounterValue(GET_6XX)));
+
+ return sb.toString();
+ }
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/rest/RestfulDataAccessor.java b/src/main/java/org/openecomp/sparky/dal/rest/RestfulDataAccessor.java
new file mode 100644
index 0000000..1c2fb07
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/rest/RestfulDataAccessor.java
@@ -0,0 +1,357 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.rest;
+
+import java.security.SecureRandom;
+
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.sparky.dal.cache.EntityCache;
+import org.openecomp.sparky.logging.AaiUiMsgs;
+import org.openecomp.sparky.util.NodeUtils;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.WebResource.Builder;
+
+/**
+ * The Class RestfulDataAccessor.
+ */
+public class RestfulDataAccessor implements RestDataProvider {
+
+ protected SecureRandom txnIdGenerator;
+
+ protected RestClientBuilder clientBuilder;
+
+ protected EntityCache entityCache;
+ private boolean cacheEnabled;
+ private static final Logger LOG =
+ LoggerFactory.getInstance().getLogger(RestfulDataAccessor.class);
+
+ private boolean resourceNotFoundErrorsSurpressed;
+
+ public static final String APPLICATION_JSON = "application/json";
+ public static final String APPLICATION_MERGE_PATCH_JSON = "application/merge-patch+json";
+ public static final String APPLICATION_X_WWW_FORM_URL_ENCODED =
+ "application/x-www-form-urlencoded";
+
+
+ /**
+ * Instantiates a new restful data accessor.
+ *
+ * @param clientBuilder the client builder
+ */
+ public RestfulDataAccessor(RestClientBuilder clientBuilder) {
+ this.clientBuilder = clientBuilder;
+ txnIdGenerator = new SecureRandom();
+ resourceNotFoundErrorsSurpressed = false;
+ cacheEnabled = false;
+ entityCache = null;
+ }
+
+ protected boolean isCacheEnabled() {
+ return cacheEnabled;
+ }
+
+ public void setCacheEnabled(boolean cacheEnabled) {
+ this.cacheEnabled = cacheEnabled;
+ }
+
+ protected EntityCache getEntityCache() {
+ return entityCache;
+ }
+
+ public void setEntityCache(EntityCache entityCache) {
+ this.entityCache = entityCache;
+ }
+
+ /**
+ * Cache result.
+ *
+ * @param result the result
+ */
+ private void cacheResult(OperationResult result) {
+ if (cacheEnabled && entityCache != null) {
+ final String id =
+ NodeUtils.generateUniqueShaDigest(result.getRequestLink(), result.getRequestPayload());
+ entityCache.put(id, result);
+ }
+ }
+
+ /**
+ * Populate operation result.
+ *
+ * @param response the response
+ * @param opResult the op result
+ */
+ protected void populateOperationResult(ClientResponse response, OperationResult opResult) {
+
+ if (response == null) {
+ opResult.setResult(500, "Client response was null");
+ return;
+ }
+
+ int statusCode = response.getStatus();
+ String payload = response.getEntity(String.class);
+
+ opResult.setResult(statusCode, payload);
+
+ }
+
+ /**
+ * Gets the cached data.
+ *
+ * @param link the link
+ * @param payload the payload
+ * @return the cached data
+ */
+ private OperationResult getCachedData(String link, String payload) {
+ if (cacheEnabled && entityCache != null) {
+ final String id = NodeUtils.generateUniqueShaDigest(link, payload);
+ return entityCache.get(id, link);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doRestfulOperation(org.openecomp.sparky.dal.rest.HttpMethod, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doRestfulOperation(HttpMethod method, String url, String payload,
+ String payloadType, String acceptContentType) {
+
+ ClientResponse clientResponse = null;
+
+ long startTimeInMs = System.currentTimeMillis();
+ Client client = null;
+ Builder builder = null;
+
+ OperationResult operationResult = null;
+
+ /*
+ * Attempt to get cached data for the requested URL. We don't currently cache the other
+ * operations.
+ */
+
+ operationResult = getCachedData(url, payload);
+
+ if (operationResult != null) {
+
+ /*
+ * cache-hit, return what we found
+ */
+
+ // System.out.println("operationResult = " + operationResult.getResultCode());
+ // System.out.println("opresult = " + operationResult.getResult());
+ return operationResult;
+ }
+
+ /*
+ * else cache miss / cache disabled (default operation)
+ */
+
+ operationResult = new OperationResult();
+ operationResult.setRequestLink(url);
+
+ try {
+
+ client = clientBuilder.getClient();
+
+ switch (method) {
+ case GET: {
+ builder = setClientDefaults(client, url, null, acceptContentType);
+ clientResponse = builder.get(ClientResponse.class);
+ break;
+ }
+
+ case PUT: {
+ builder = setClientDefaults(client, url, payloadType, acceptContentType);
+ clientResponse = builder.put(ClientResponse.class, payload);
+ break;
+ }
+
+ case POST: {
+ builder = setClientDefaults(client, url, payloadType, acceptContentType);
+ clientResponse = builder.post(ClientResponse.class, payload);
+ break;
+ }
+
+ case DELETE: {
+ builder = setClientDefaults(client, url, null, acceptContentType);
+ clientResponse = builder.delete(ClientResponse.class);
+ break;
+ }
+
+ case PATCH: {
+ builder = setClientDefaults(client, url, payloadType, acceptContentType);
+ builder = builder.header("X-HTTP-Method-Override", "PATCH");
+ clientResponse = builder.post(ClientResponse.class, payload);
+ break;
+ }
+
+ case HEAD: {
+ builder = setClientDefaults(client, url, null, acceptContentType);
+ clientResponse = builder.head();
+ break;
+ }
+
+
+ default: {
+ operationResult.setResult(500, "Unhandled HTTP Method operation = " + method);
+ return operationResult;
+ }
+
+ }
+
+ } catch (Exception ex) {
+ LOG.error(AaiUiMsgs.RESTFULL_OP_ERROR_VERBOSE, url, ex.getLocalizedMessage());
+ operationResult.setResult(500,
+ String.format("Error retrieving link = '%s' from restful endpoint due to error = '%s'",
+ url, ex.getLocalizedMessage()));
+ return operationResult;
+ }
+
+ populateOperationResult(clientResponse, operationResult);
+
+ if (operationResult.getResultCode() != 404
+ || (operationResult.getResultCode() == 404 && !isResourceNotFoundErrorsSurpressed())) {
+ LOG.info(AaiUiMsgs.RESTFULL_OP_COMPLETE, method.toString(),
+ String.valueOf(System.currentTimeMillis() - startTimeInMs), url,
+ String.valueOf(operationResult.getResultCode()));
+ }
+
+ cacheResult(operationResult);
+
+ return operationResult;
+
+ }
+
+ public boolean isResourceNotFoundErrorsSurpressed() {
+ return resourceNotFoundErrorsSurpressed;
+ }
+
+ public void setResourceNotFoundErrorsSurpressed(boolean resourceNotFoundErrorsSurpressed) {
+ this.resourceNotFoundErrorsSurpressed = resourceNotFoundErrorsSurpressed;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doGet(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doGet(String url, String acceptContentType) {
+ return doRestfulOperation(HttpMethod.GET, url, null, null, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doDelete(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doDelete(String url, String acceptContentType) {
+ return doRestfulOperation(HttpMethod.DELETE, url, null, null, acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPost(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doPost(String url, String jsonPayload, String acceptContentType) {
+ return doRestfulOperation(HttpMethod.POST, url, jsonPayload, APPLICATION_JSON,
+ acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPut(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doPut(String url, String jsonPayload, String acceptContentType) {
+ return doRestfulOperation(HttpMethod.PUT, url, jsonPayload, APPLICATION_JSON,
+ acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPatch(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doPatch(String url, String jsonPayload, String acceptContentType) {
+ return doRestfulOperation(HttpMethod.PATCH, url, jsonPayload, APPLICATION_MERGE_PATCH_JSON,
+ acceptContentType);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#doHead(java.lang.String, java.lang.String)
+ */
+ @Override
+ public OperationResult doHead(String url, String acceptContentType) {
+ return doRestfulOperation(HttpMethod.HEAD, url, null, null, acceptContentType);
+ }
+
+ /**
+ * Sets the client defaults.
+ *
+ * @param client the client
+ * @param url the url
+ * @param payloadContentType the payload content type
+ * @param acceptContentType the accept content type
+ * @return the builder
+ */
+ protected Builder setClientDefaults(Client client, String url, String payloadContentType,
+ String acceptContentType) {
+ WebResource resource = client.resource(url);
+ Builder builder = null;
+ builder = resource.accept(acceptContentType);
+
+ if (payloadContentType != null) {
+ builder = builder.header("Content-Type", payloadContentType);
+ }
+
+ return builder;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#shutdown()
+ */
+ @Override
+ public void shutdown() {
+
+ if (entityCache != null) {
+ entityCache.shutdown();
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sparky.dal.rest.RestDataProvider#clearCache()
+ */
+ @Override
+ public void clearCache() {
+ if (cacheEnabled) {
+ entityCache.clear();
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/sas/config/SearchServiceConfig.java b/src/main/java/org/openecomp/sparky/dal/sas/config/SearchServiceConfig.java
new file mode 100644
index 0000000..1ff2001
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/sas/config/SearchServiceConfig.java
@@ -0,0 +1,224 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.sas.config;
+
+import java.util.Properties;
+
+import org.openecomp.sparky.util.ConfigHelper;
+import org.openecomp.sparky.viewandinspect.config.TierSupportUiConstants;
+
+/**
+ * The Class ElasticSearchConfig.
+ */
+public class SearchServiceConfig {
+
+ public static final String CONFIG_FILE =
+ TierSupportUiConstants.DYNAMIC_CONFIG_APP_LOCATION + "search-service.properties";
+
+ private static SearchServiceConfig instance;
+
+ private String ipAddress;
+
+ private String httpPort;
+
+ private String indexName;
+
+ private String auditIndexName;
+
+ private String topographicalSearchIndex;
+
+ private String entityCountHistoryIndex;
+
+ private String version;
+
+ private String type;
+
+ private String certName;
+
+ private String keystorePassword;
+
+ private String keystore;
+
+ private static final String IP_ADDRESS_DEFAULT = "localhost";
+
+ private static final String HTTP_PORT_DEFAULT = "9509";
+
+ private static final String INDEX_NAME_DEFAULT = "entitySearchIndex-localhost";
+
+ private static final String AUDIT_INDEX_NAME_DEFAULT = "di-violations";
+
+ private static final String TOPOGRAPHICAL_INDEX_NAME_DEFAULT =
+ "topographicalsearchindex-localhost";
+
+ private static final String ENTITY_COUNT_HISTORY_INDEX_NAME_DEFAULT =
+ "entitycounthistoryindex-localhost";
+
+ private static final String VERSION_DEFAULT = "v1";
+
+ public static SearchServiceConfig getConfig() throws Exception {
+
+ if (instance == null) {
+ instance = new SearchServiceConfig();
+ instance.initializeProperties();
+ }
+
+ return instance;
+ }
+
+ public static void setConfig(SearchServiceConfig config) {
+ SearchServiceConfig.instance = config;
+ }
+
+ /**
+ * Instantiates a new search service config.
+ */
+ public SearchServiceConfig() {
+ // test method
+ }
+
+ /**
+ * Initialize properties.
+ */
+ private void initializeProperties() {
+ Properties props = ConfigHelper.loadConfigFromExplicitPath(CONFIG_FILE);
+
+ Properties sasProps = ConfigHelper.getConfigWithPrefix("search-service", props);
+
+ ipAddress = sasProps.getProperty("ipAddress", IP_ADDRESS_DEFAULT);
+ httpPort = sasProps.getProperty("httpPort", "" + HTTP_PORT_DEFAULT);
+ version = sasProps.getProperty("version", "" + VERSION_DEFAULT);
+ indexName = sasProps.getProperty("indexName", INDEX_NAME_DEFAULT);
+ auditIndexName = sasProps.getProperty("auditIndexName", AUDIT_INDEX_NAME_DEFAULT);
+ topographicalSearchIndex = sasProps.getProperty("topographicalIndexName",
+ TOPOGRAPHICAL_INDEX_NAME_DEFAULT);
+ entityCountHistoryIndex = sasProps.getProperty("entityCountHistoryIndexName",
+ ENTITY_COUNT_HISTORY_INDEX_NAME_DEFAULT);
+ certName =
+ sasProps.getProperty("ssl.cert-name", "aai-client-cert.p12");
+ keystorePassword = sasProps.getProperty("ssl.keystore-password",
+ "OBF:1i9a1u2a1unz1lr61wn51wn11lss1unz1u301i6o");
+ keystore = sasProps.getProperty("ssl.keystore", "tomcat_keystore");
+ }
+
+ public String getIpAddress() {
+ return ipAddress;
+ }
+
+ public void setIpAddress(String ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+
+ public String getHttpPort() {
+ return httpPort;
+ }
+
+ public void setHttpPort(String httpPort) {
+ this.httpPort = httpPort;
+ }
+
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public void setIndexName(String indexName) {
+ this.indexName = indexName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getAuditIndexName() {
+ return auditIndexName;
+ }
+
+ public void setAuditIndexName(String auditIndexName) {
+ this.auditIndexName = auditIndexName;
+ }
+
+ public String getTopographicalSearchIndex() {
+ return topographicalSearchIndex;
+ }
+
+ public void setTopographicalSearchIndex(String topographicalSearchIndex) {
+ this.topographicalSearchIndex = topographicalSearchIndex;
+ }
+
+ public String getEntityCountHistoryIndex() {
+ return entityCountHistoryIndex;
+ }
+
+ public void setEntityCountHistoryIndex(String entityCountHistoryIndex) {
+ this.entityCountHistoryIndex = entityCountHistoryIndex;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+
+ public String getCertName() {
+ return certName;
+ }
+
+ public void setCertName(String certName) {
+ this.certName = certName;
+ }
+
+ public String getKeystorePassword() {
+ return keystorePassword;
+ }
+
+ public void setKeystorePassword(String keystorePassword) {
+ this.keystorePassword = keystorePassword;
+ }
+
+ public String getKeystore() {
+ return keystore;
+ }
+
+ public void setKeystore(String keystore) {
+ this.keystore = keystore;
+ }
+
+ @Override
+ public String toString() {
+ return "SearchServiceConfig [ipAddress=" + ipAddress + ", httpPort=" + httpPort + ", indexName="
+ + indexName + ", auditIndexName=" + auditIndexName + ", topographicalSearchIndex="
+ + topographicalSearchIndex + ", entityCountHistoryIndex=" + entityCountHistoryIndex
+ + ", version=" + version + ", type=" + type + "]";
+ }
+
+
+}
diff --git a/src/main/java/org/openecomp/sparky/dal/servlet/ResettableStreamHttpServletRequest.java b/src/main/java/org/openecomp/sparky/dal/servlet/ResettableStreamHttpServletRequest.java
new file mode 100644
index 0000000..d7b1e6b
--- /dev/null
+++ b/src/main/java/org/openecomp/sparky/dal/servlet/ResettableStreamHttpServletRequest.java
@@ -0,0 +1,129 @@
+/**
+ * ============LICENSE_START===================================================
+ * SPARKY (AAI UI service)
+ * ============================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ============================================================================
+ * 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=====================================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ */
+
+package org.openecomp.sparky.dal.servlet;
+
+import com.google.common.primitives.Bytes;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+/**
+ * The Class ResettableStreamHttpServletRequest.
+ */
+public class ResettableStreamHttpServletRequest extends HttpServletRequestWrapper {
+
+ private byte[] requestBody = new byte[0];
+ private boolean bufferFilled = false;
+
+ /**
+ * Constructs a request object wrapping the given request.
+ *
+ * @param request The request to wrap
+ * @throws IllegalArgumentException if the request is null
+ */
+ public ResettableStreamHttpServletRequest(HttpServletRequest request) {
+ super(request);
+ }
+
+ /**
+ * Get request body.
+ *
+ * @return Bytes with the request body contents.
+ * @throws IOException In case stream reqding fails.
+ */
+ public byte[] getRequestBody() throws IOException {
+ if (bufferFilled) {
+ return Arrays.copyOf(requestBody, requestBody.length);
+ }
+
+ InputStream inputStream = super.getInputStream();
+
+ byte[] buffer = new byte[102400];
+
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ requestBody = Bytes.concat(this.requestBody, Arrays.copyOfRange(buffer, 0, bytesRead));
+ }
+
+ bufferFilled = true;
+
+ return requestBody;
+ }
+
+ @Override
+ public ServletInputStream getInputStream() throws IOException {
+ return new CustomServletInputStream(getRequestBody());
+ }
+
+ /**
+ * The Class CustomServletInputStream.
+ */
+ private static class CustomServletInputStream extends ServletInputStream {
+
+ private ByteArrayInputStream buffer;
+
+ /**
+ * Instantiates a new custom servlet input stream.
+ *
+ * @param contents the contents
+ */
+ public CustomServletInputStream(byte[] contents) {
+ this.buffer = new ByteArrayInputStream(contents);
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.InputStream#read()
+ */
+ @Override
+ public int read() throws IOException {
+ return buffer.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return buffer.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener arg0) {
+ throw new RuntimeException("Not implemented");
+ }
+
+ }
+
+}