From b4922d319d293894fddd512d29b5f0d1411915d9 Mon Sep 17 00:00:00 2001 From: ARULNA Date: Mon, 12 Jun 2017 16:41:12 -0400 Subject: Initial commit for AAI-UI(sparky-backend) Change-Id: I785397ed4197663cdf0c1351041d2f708ed08763 Signed-off-by: ARULNA --- .../openecomp/sparky/dal/NetworkTransaction.java | 135 +++++ .../sparky/dal/aai/ActiveInventoryAdapter.java | 418 ++++++++++++++++ .../dal/aai/ActiveInventoryDataProvider.java | 91 ++++ .../dal/aai/ActiveInventoryEntityStatistics.java | 307 ++++++++++++ ...tiveInventoryProcessingExceptionStatistics.java | 139 ++++++ .../dal/aai/config/ActiveInventoryConfig.java | 159 ++++++ .../dal/aai/config/ActiveInventoryRestConfig.java | 283 +++++++++++ .../dal/aai/config/ActiveInventorySslConfig.java | 217 ++++++++ .../dal/aai/enums/RestAuthenticationMode.java | 69 +++ .../openecomp/sparky/dal/cache/EntityCache.java | 63 +++ .../sparky/dal/cache/InMemoryEntityCache.java | 101 ++++ .../sparky/dal/cache/PersistentEntityCache.java | 305 ++++++++++++ .../dal/elasticsearch/ElasticSearchAdapter.java | 165 +++++++ .../elasticsearch/ElasticSearchDataProvider.java | 66 +++ .../ElasticSearchEntityStatistics.java | 274 +++++++++++ .../dal/elasticsearch/HashQueryResponse.java | 59 +++ .../sparky/dal/elasticsearch/SearchAdapter.java | 122 +++++ .../elasticsearch/config/ElasticSearchConfig.java | 543 +++++++++++++++++++++ .../exception/ElasticSearchOperationException.java | 54 ++ .../org/openecomp/sparky/dal/rest/HttpMethod.java | 34 ++ .../openecomp/sparky/dal/rest/OperationResult.java | 198 ++++++++ .../sparky/dal/rest/RestClientBuilder.java | 148 ++++++ .../sparky/dal/rest/RestDataProvider.java | 112 +++++ .../sparky/dal/rest/RestOperationalStatistics.java | 256 ++++++++++ .../sparky/dal/rest/RestfulDataAccessor.java | 357 ++++++++++++++ .../sparky/dal/sas/config/SearchServiceConfig.java | 224 +++++++++ .../ResettableStreamHttpServletRequest.java | 129 +++++ 27 files changed, 5028 insertions(+) create mode 100644 src/main/java/org/openecomp/sparky/dal/NetworkTransaction.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryAdapter.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryDataProvider.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryEntityStatistics.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryConfig.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventoryRestConfig.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/config/ActiveInventorySslConfig.java create mode 100644 src/main/java/org/openecomp/sparky/dal/aai/enums/RestAuthenticationMode.java create mode 100644 src/main/java/org/openecomp/sparky/dal/cache/EntityCache.java create mode 100644 src/main/java/org/openecomp/sparky/dal/cache/InMemoryEntityCache.java create mode 100644 src/main/java/org/openecomp/sparky/dal/cache/PersistentEntityCache.java create mode 100644 src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchAdapter.java create mode 100644 src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchDataProvider.java create mode 100644 src/main/java/org/openecomp/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java create mode 100644 src/main/java/org/openecomp/sparky/dal/elasticsearch/HashQueryResponse.java create mode 100644 src/main/java/org/openecomp/sparky/dal/elasticsearch/SearchAdapter.java create mode 100644 src/main/java/org/openecomp/sparky/dal/elasticsearch/config/ElasticSearchConfig.java create mode 100644 src/main/java/org/openecomp/sparky/dal/exception/ElasticSearchOperationException.java create mode 100644 src/main/java/org/openecomp/sparky/dal/rest/HttpMethod.java create mode 100644 src/main/java/org/openecomp/sparky/dal/rest/OperationResult.java create mode 100644 src/main/java/org/openecomp/sparky/dal/rest/RestClientBuilder.java create mode 100644 src/main/java/org/openecomp/sparky/dal/rest/RestDataProvider.java create mode 100644 src/main/java/org/openecomp/sparky/dal/rest/RestOperationalStatistics.java create mode 100644 src/main/java/org/openecomp/sparky/dal/rest/RestfulDataAccessor.java create mode 100644 src/main/java/org/openecomp/sparky/dal/sas/config/SearchServiceConfig.java create mode 100644 src/main/java/org/openecomp/sparky/dal/servlet/ResettableStreamHttpServletRequest.java (limited to 'src/main/java/org/openecomp/sparky/dal') 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 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 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> activeInventoryEntityStatistics; + + /** + * Creates the entity op stats. + * + * @return the hash map + */ + private HashMap createEntityOpStats() { + + HashMap opStats = new HashMap(); + + 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 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 descriptors = loader.getCrossReferenceEntityDescriptors(); + * + * + * } + */ + + + /** + * Initializecreate active inventory entity statistics. + */ + private void initializecreateActiveInventoryEntityStatistics() { + Set keys = activeInventoryEntityStatistics.keySet(); + + Set opStatKeySet = null; + Map 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>(); + // createSearchableActiveInventoryEntityStatistics(); + // createCrossEntityReferenceActiveInventoryEntityStatistics(); + reset(); + } + + /** + * Initialize counters from oxm entity descriptors. + * + * @param descriptors the descriptors + */ + public void initializeCountersFromOxmEntityDescriptors( + Map 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 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> activeInventoryEntitySortedTreeMap = + new TreeMap>(new Comparator() { + + @Override + public int compare(String o1, String o2) { + return o1.toLowerCase().compareTo(o2.toLowerCase()); + } + }); + + activeInventoryEntitySortedTreeMap.putAll(activeInventoryEntityStatistics); + + for (String counterEntityKey : activeInventoryEntitySortedTreeMap.keySet()) { + + HashMap 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 shallowEntities; + + private RestAuthenticationMode authenticationMode; + + public List 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: + *
  • HTTP_NOAUTH - intended to represent basic HTTP no authentication + *
  • SSL_BASIC - HTTP/S with username/password + *
  • 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 cachedEntityData; + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(InMemoryEntityCache.class); + + /** + * Instantiates a new in memory entity cache. + */ + public InMemoryEntityCache() { + cachedEntityData = new ConcurrentHashMap(); + } + + /* (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:
  • implement time-to-live on the cache, maybe pull in one of Guava's eviction caches? + *
  • 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 resourcePathAndDomain = new ArrayList(); + + 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 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 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> entityStatistics; + private OxmModelLoader loader; + + /** + * Creates the entity op stats. + * + * @return the hash map + */ + private HashMap createEntityOpStats() { + + HashMap opStats = new HashMap(); + + 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 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 keys = entityStatistics.keySet(); + + Set opStatKeySet = null; + Map 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>(); + // createActiveInventoryEntityStatistics(); + reset(); + } + + /** + * Initialize counters from oxm entity descriptors. + * + * @param descriptors the descriptors + */ + public void initializeCountersFromOxmEntityDescriptors( + Map 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 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> elasticEntitySortedTreeMap = + new TreeMap>(new Comparator() { + + @Override + public int compare(String o1, String o2) { + return o1.toLowerCase().compareTo(o2.toLowerCase()); + } + }); + + elasticEntitySortedTreeMap.putAll(entityStatistics); + + for (String counterEntityKey : elasticEntitySortedTreeMap.keySet()) { + + HashMap 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> 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>(); + 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> getTxnHeader() { + Map headers = new HashMap>(); + 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"); + } + + } + +} -- cgit 1.2.3-korg