diff options
author | Shawn Severin <shawn.severin@amdocs.com> | 2017-12-11 15:42:52 -0500 |
---|---|---|
committer | Shawn Severin <shawn.severin@amdocs.com> | 2017-12-11 15:43:42 -0500 |
commit | 7b42006c51d4f014f72ae39170544a85d2f09fb5 (patch) | |
tree | 9dc8c0f56d7b85e843f7f29bae7c9207b118bd18 /src/main/java/org | |
parent | 1249ee87c69c9c4566f2c52c5cbb56e4089044c4 (diff) |
Adding UI extensibility
Adding the ability for Sparky developers to create their own custom
front-end views
Issue-ID: AAI-542
Change-Id: I83f9608639799e3bf85b654f44a0a7a5a85ad264
Signed-off-by: Shawn Severin <shawn.severin@amdocs.com>
Diffstat (limited to 'src/main/java/org')
176 files changed, 10844 insertions, 10233 deletions
diff --git a/src/main/java/org/onap/aai/sparky/JaxrsEchoService.java b/src/main/java/org/onap/aai/sparky/JaxrsEchoService.java index 8e7e0a2..f7ea619 100644 --- a/src/main/java/org/onap/aai/sparky/JaxrsEchoService.java +++ b/src/main/java/org/onap/aai/sparky/JaxrsEchoService.java @@ -22,14 +22,14 @@ */ package org.onap.aai.sparky; -import com.att.ajsc.beans.PropertiesMapBean; -import com.att.ajsc.filemonitor.AJSCPropertiesMap; - import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import com.att.ajsc.beans.PropertiesMapBean; +import com.att.ajsc.filemonitor.AJSCPropertiesMap; + /** * The Class JaxrsEchoService. diff --git a/src/main/java/org/onap/aai/sparky/JaxrsUserService.java b/src/main/java/org/onap/aai/sparky/JaxrsUserService.java new file mode 100644 index 0000000..dc7f5a4 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/JaxrsUserService.java @@ -0,0 +1,61 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky; + +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; + +/** + * The Class JaxrsUserService. + */ +@Path("/user") +public class JaxrsUserService { + + private static final Map<String, String> userIdToNameMap; + + static { + userIdToNameMap = new HashMap<String, String>(); + userIdToNameMap.put("dw113c", "Doug Wait"); + userIdToNameMap.put("so401q", "Stuart O'Day"); + } + + /** + * Lookup user. + * + * @param userId the user id + * @return the string + */ + @GET + @Path("/{userId}") + @Produces("text/plain") + public String lookupUser(@PathParam("userId") String userId) { + String name = userIdToNameMap.get(userId); + return name != null ? name : "unknown id"; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/config/exception/ConfigurationException.java b/src/main/java/org/onap/aai/sparky/Test.java index f796c38..6efca77 100644 --- a/src/main/java/org/onap/aai/sparky/config/exception/ConfigurationException.java +++ b/src/main/java/org/onap/aai/sparky/Test.java @@ -20,12 +20,8 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.config.exception; +package org.onap.aai.sparky; - -/** - * The Class ConfigurationException. - */ -public class ConfigurationException extends Exception { +public class Test { } diff --git a/src/main/java/org/onap/aai/sparky/aggregatevnf/search/AggregateSummaryProcessor.java b/src/main/java/org/onap/aai/sparky/aggregatevnf/search/AggregateSummaryProcessor.java new file mode 100644 index 0000000..6d2ec6e --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/aggregatevnf/search/AggregateSummaryProcessor.java @@ -0,0 +1,238 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.aggregatevnf.search; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.json.JsonObject; + +import org.apache.camel.Exchange; +import org.apache.camel.component.restlet.RestletConstants; +import org.json.JSONArray; +import org.json.JSONObject; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; +import org.onap.aai.sparky.dataintegrity.config.DiUiConstants; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.search.filters.FilterQueryBuilder; +import org.onap.aai.sparky.search.filters.entity.SearchFilter; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.MediaType; +import org.restlet.data.Status; + +public class AggregateSummaryProcessor { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(AggregateSummaryProcessor.class); + + private static final String KEY_FILTERS = "filters"; + + private SearchAdapter search = null; + + private String vnfAggregationIndexName; + private String elasticSearchIp; + private String elatsticSearchPort; + + public AggregateSummaryProcessor() { + try { + if (search == null) { + search = new SearchAdapter(); + } + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "Failed to get elastic search configuration with error = " + exc.getMessage()); + } + } + + public void setVnfAggregationIndexName(String vnfAggregationIndexName) { + this.vnfAggregationIndexName = vnfAggregationIndexName; + } + + public void setElasticSearchIp(String elasticSearchIp) { + this.elasticSearchIp = elasticSearchIp; + } + + public void setElatsticSearchPort(String elatsticSearchPort) { + this.elatsticSearchPort = elatsticSearchPort; + } + + public void getFilteredAggregation(Exchange exchange) { + + Response response = + exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); + + Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); + + /* + * Disables automatic Apache Camel Restlet component logging which prints out an undesirable log + * entry which includes client (e.g. browser) information + */ + request.setLoggable(false); + + try { + String payload = exchange.getIn().getBody(String.class); + + if (payload == null || payload.isEmpty()) { + + LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, "Request Payload is empty"); + + /* + * Don't throw back an error, just return an empty set + */ + + } else { + + JSONObject parameters = new JSONObject(payload); + + JSONArray requestFilters = null; + if (parameters.has(KEY_FILTERS)) { + requestFilters = parameters.getJSONArray(KEY_FILTERS); + } else { + + JSONObject zeroResponsePayload = new JSONObject(); + zeroResponsePayload.put("count", 0); + response.setStatus(Status.SUCCESS_OK); + response.setEntity(zeroResponsePayload.toString(), MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + + LOG.error(AaiUiMsgs.ERROR_FILTERS_NOT_FOUND); + return; + } + + if (requestFilters != null && requestFilters.length() > 0) { + List<JSONObject> filtersToQuery = new ArrayList<JSONObject>(); + for (int i = 0; i < requestFilters.length(); i++) { + JSONObject filterEntry = requestFilters.getJSONObject(i); + filtersToQuery.add(filterEntry); + } + + String jsonResponsePayload = getVnfFilterAggregations(filtersToQuery); + response.setStatus(Status.SUCCESS_OK); + response.setEntity(jsonResponsePayload, MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + + } else { + String emptyResponse = getEmptyAggResponse(); + response.setStatus(Status.SUCCESS_OK); + response.setEntity(emptyResponse, MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + LOG.error(AaiUiMsgs.ERROR_FILTERS_NOT_FOUND); + } + } + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "FilterProcessor failed to get filter list due to error = " + exc.getMessage()); + } + } + + private String getEmptyAggResponse() { + JSONObject aggPayload = new JSONObject(); + aggPayload.put("totalChartHits", 0); + aggPayload.put("buckets", new JSONArray()); + JSONObject payload = new JSONObject(); + payload.append("groupby_aggregation", aggPayload); + + return payload.toString(); + } + + private static final String FILTER_ID_KEY = "filterId"; + private static final String FILTER_VALUE_KEY = "filterValue"; + private static final int DEFAULT_SHOULD_MATCH_SCORE = 1; + private static final String VNF_FILTER_AGGREGATION = "vnfFilterAggregation"; + + + private String getVnfFilterAggregations(List<JSONObject> filtersToQuery) throws IOException { + + List<SearchFilter> searchFilters = new ArrayList<SearchFilter>(); + for (JSONObject filterEntry : filtersToQuery) { + + String filterId = filterEntry.getString(FILTER_ID_KEY); + if (filterId != null) { + SearchFilter filter = new SearchFilter(); + filter.setFilterId(filterId); + + if (filterEntry.has(FILTER_VALUE_KEY)) { + String filterValue = filterEntry.getString(FILTER_VALUE_KEY); + filter.addValue(filterValue); + } + + searchFilters.add(filter); + } + } + + // Create query for summary by entity type + JsonObject vnfSearch = + FilterQueryBuilder.createCombinedBoolAndAggQuery(searchFilters, DEFAULT_SHOULD_MATCH_SCORE); + + // Parse response for summary by entity type query + OperationResult opResult = + search.doPost(getFullUrl(vnfAggregationIndexName, TierSupportUiConstants.ES_SEARCH_API), + vnfSearch.toString(), DiUiConstants.APP_JSON); + + return buildAggregateVnfResponseJson(opResult.getResult()); + + } + + /** + * Get Full URL for search using elastic search configuration. + * + * @param api the api + * @return the full url + */ + private String getFullUrl(String indexName, String api) { + final String host = elasticSearchIp; + final String port = elatsticSearchPort; + return String.format("http://%s:%s/%s/%s", host, port, indexName, api); + } + + private String buildAggregateVnfResponseJson(String responseJsonStr) { + + JSONObject finalOutputToFe = new JSONObject(); + JSONObject responseJson = new JSONObject(responseJsonStr); + + + JSONObject hits = responseJson.getJSONObject("hits"); + int totalHits = hits.getInt("total"); + finalOutputToFe.put("total", totalHits); + + JSONObject aggregations = responseJson.getJSONObject("aggregations"); + String[] aggKeys = JSONObject.getNames(aggregations); + JSONObject aggregationsList = new JSONObject(); + + for (String aggName : aggKeys) { + JSONObject aggregation = aggregations.getJSONObject(aggName); + JSONArray buckets = aggregation.getJSONArray("buckets"); + aggregationsList.put(aggName, buckets); + } + + finalOutputToFe.put("aggregations", aggregationsList); + + return finalOutputToFe.toString(); + } +} diff --git a/src/main/java/org/onap/aai/sparky/aggregatevnf/search/AggregateVnfSearchProvider.java b/src/main/java/org/onap/aai/sparky/aggregatevnf/search/AggregateVnfSearchProvider.java new file mode 100644 index 0000000..ec3dfaa --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/aggregatevnf/search/AggregateVnfSearchProvider.java @@ -0,0 +1,160 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.aggregatevnf.search; + +import java.util.ArrayList; +import java.util.List; + +import javax.json.JsonObject; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.common.search.CommonSearchSuggestion; +import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; +import org.onap.aai.sparky.dataintegrity.config.DiUiConstants; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.search.api.SearchProvider; +import org.onap.aai.sparky.search.entity.QuerySearchEntity; +import org.onap.aai.sparky.search.entity.SearchSuggestion; +import org.onap.aai.sparky.search.filters.entity.UiFilterValueEntity; +import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class AggregateVnfSearchProvider implements SearchProvider { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(AggregateVnfSearchProvider.class); + + private ObjectMapper mapper; + private static SearchAdapter search = null; + + private String autoSuggestIndexName; + private String elasticSearchIp; + private String elatsticSearchPort; + + public AggregateVnfSearchProvider() { + + mapper = new ObjectMapper(); + + try { + if (search == null) { + search = new SearchAdapter(); + } + } catch (Exception exc) { + LOG.error(AaiUiMsgs.CONFIGURATION_ERROR, + "Search Configuration Error. Error = " + exc.getMessage()); + } + } + + public void setAutoSuggestIndexName(String autoSuggestIndexName) { + this.autoSuggestIndexName = autoSuggestIndexName; + } + + public void setElasticSearchIp(String elasticSearchIp) { + this.elasticSearchIp = elasticSearchIp; + } + + public void setElatsticSearchPort(String elatsticSearchPort) { + this.elatsticSearchPort = elatsticSearchPort; + } + + /** + * Get Full URL for search using elastic search configuration. + * + * @param api the api + * @return the full url + */ + private String getFullUrl(String indexName, String api) { + final String host = elasticSearchIp; + final String port = elatsticSearchPort; + return String.format("http://%s:%s/%s/%s", host, port, indexName, api); + } + + @Override + public List<SearchSuggestion> search(QuerySearchEntity queryRequest) { + + List<SearchSuggestion> returnList = new ArrayList<SearchSuggestion>(); + + try { + + /* Create suggestions query */ + JsonObject vnfSearch = VnfSearchQueryBuilder.createSuggestionsQuery( + String.valueOf(queryRequest.getMaxResults()), queryRequest.getQueryStr()); + + /* Parse suggestions response */ + OperationResult opResult = + search.doPost(getFullUrl(autoSuggestIndexName, TierSupportUiConstants.ES_SUGGEST_API), + vnfSearch.toString(), DiUiConstants.APP_JSON); + + String result = opResult.getResult(); + + if (!opResult.wasSuccessful()) { + LOG.error(AaiUiMsgs.ERROR_PARSING_JSON_PAYLOAD_VERBOSE, result); + return returnList; + } + + JSONObject responseJson = new JSONObject(result); + String suggestionsKey = "vnfs"; + JSONArray suggestionsArray = new JSONArray(); + JSONArray suggestions = responseJson.getJSONArray(suggestionsKey); + if (suggestions.length() > 0) { + suggestionsArray = suggestions.getJSONObject(0).getJSONArray("options"); + for (int i = 0; i < suggestionsArray.length(); i++) { + JSONObject querySuggestion = suggestionsArray.getJSONObject(i); + if (querySuggestion != null) { + CommonSearchSuggestion responseSuggestion = new CommonSearchSuggestion(); + responseSuggestion.setText(querySuggestion.getString("text")); + responseSuggestion.setRoute("vnfSearch"); // TODO -> Read route from + // suggestive-search.properties instead of + // hard coding + responseSuggestion + .setHashId(NodeUtils.generateUniqueShaDigest(querySuggestion.getString("text"))); + + // Extract filter list from JSON and add to response suggestion + JSONObject payload = querySuggestion.getJSONObject("payload"); + if (payload.length() > 0) { + JSONArray filterList = payload.getJSONArray("filterList"); + for (int filter = 0; filter < filterList.length(); filter++) { + String filterValueString = filterList.getJSONObject(filter).toString(); + UiFilterValueEntity filterValue = + mapper.readValue(filterValueString, UiFilterValueEntity.class); + responseSuggestion.getFilterValues().add(filterValue); + } + } + returnList.add(responseSuggestion); + } + } + } + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, "Search failed due to error = " + exc.getMessage()); + } + + return returnList; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/search/VnfSearchQueryBuilder.java b/src/main/java/org/onap/aai/sparky/aggregatevnf/search/VnfSearchQueryBuilder.java index 9e206b3..96fea3f 100644 --- a/src/main/java/org/onap/aai/sparky/search/VnfSearchQueryBuilder.java +++ b/src/main/java/org/onap/aai/sparky/aggregatevnf/search/VnfSearchQueryBuilder.java @@ -20,9 +20,8 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.search; +package org.onap.aai.sparky.aggregatevnf.search; -import java.util.Date; import java.util.Map; import javax.json.Json; @@ -31,11 +30,23 @@ import javax.json.JsonArrayBuilder; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; +import org.onap.aai.sparky.dataintegrity.config.DiUiConstants; + /** * Build a JSON payload to send to elastic search to get vnf search data. */ public class VnfSearchQueryBuilder { + static final String SEVERITY = DiUiConstants.SEVERITY; + static final String TIMESTAMP = DiUiConstants.KEY_TIMESTAMP; + static final String VIOLATIONS = DiUiConstants.VIOLATIONS; + static final String CATEGORY = DiUiConstants.CATEGORY; + static final String ENTITY_TYPE = DiUiConstants.ENTITY_TYPE; + + static final String ITEM = DiUiConstants.KEY_ITEM; + static final String ITEM_AGG = DiUiConstants.KEY_ITEM_AGG; + static final String BY_ITEM = DiUiConstants.KEY_BY_ITEM; + static final String BUCKETS = DiUiConstants.KEY_BUCKETS; /** * Creates the suggestions query. @@ -170,5 +181,4 @@ public class VnfSearchQueryBuilder { return jsonBuilder.build(); } - } diff --git a/src/main/java/org/onap/aai/sparky/aggregation/sync/AggregationSyncControllerFactory.java b/src/main/java/org/onap/aai/sparky/aggregation/sync/AggregationSyncControllerFactory.java new file mode 100644 index 0000000..6d8decf --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/aggregation/sync/AggregationSyncControllerFactory.java @@ -0,0 +1,232 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.aggregation.sync; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.config.oxm.SuggestionEntityDescriptor; +import org.onap.aai.sparky.config.oxm.SuggestionEntityLookup; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.ElasticSearchIndexCleaner; +import org.onap.aai.sparky.sync.ElasticSearchSchemaFactory; +import org.onap.aai.sparky.sync.IndexCleaner; +import org.onap.aai.sparky.sync.IndexIntegrityValidator; +import org.onap.aai.sparky.sync.SyncController; +import org.onap.aai.sparky.sync.SyncControllerImpl; +import org.onap.aai.sparky.sync.SyncControllerRegistrar; +import org.onap.aai.sparky.sync.SyncControllerRegistry; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; + +public class AggregationSyncControllerFactory implements SyncControllerRegistrar { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(AggregationSyncControllerFactory.class); + + private ActiveInventoryAdapter aaiAdapter; + private ElasticSearchAdapter esAdapter; + private SuggestionEntityLookup suggestionEntityLookup; + + private Map<String, String> aggregationEntityToIndexMap; + private Map<String, ElasticSearchSchemaConfig> indexNameToSchemaConfigMap; + + private ElasticSearchEndpointConfig elasticSearchEndpointConfig; + private SyncControllerConfig syncControllerConfig; + private SyncControllerRegistry syncControllerRegistry; + private NetworkStatisticsConfig aaiStatConfig; + private NetworkStatisticsConfig esStatConfig; + + private List<SyncController> syncControllers; + + public AggregationSyncControllerFactory(ElasticSearchEndpointConfig esEndpointConfig, + SyncControllerConfig syncControllerConfig, SyncControllerRegistry syncControllerRegistry, + SuggestionEntityLookup suggestionEntityLookup) { + this.syncControllers = new ArrayList<SyncController>(); + this.elasticSearchEndpointConfig = esEndpointConfig; + this.syncControllerConfig = syncControllerConfig; + this.syncControllerRegistry = syncControllerRegistry; + this.suggestionEntityLookup = suggestionEntityLookup; + } + + public NetworkStatisticsConfig getAaiStatConfig() { + return aaiStatConfig; + } + + public void setAaiStatConfig(NetworkStatisticsConfig aaiStatConfig) { + this.aaiStatConfig = aaiStatConfig; + } + + public NetworkStatisticsConfig getEsStatConfig() { + return esStatConfig; + } + + public void setEsStatConfig(NetworkStatisticsConfig esStatConfig) { + this.esStatConfig = esStatConfig; + } + + public Map<String, ElasticSearchSchemaConfig> getIndexNameToSchemaConfigMap() { + return indexNameToSchemaConfigMap; + } + + public void setIndexNameToSchemaConfigMap( + Map<String, ElasticSearchSchemaConfig> indexNameToSchemaConfigMap) { + this.indexNameToSchemaConfigMap = indexNameToSchemaConfigMap; + } + + public ElasticSearchEndpointConfig getElasticSearchEndpointConfig() { + return elasticSearchEndpointConfig; + } + + public void setElasticSearchEndpointConfig( + ElasticSearchEndpointConfig elasticSearchEndpointConfig) { + this.elasticSearchEndpointConfig = elasticSearchEndpointConfig; + } + + public SyncControllerConfig getSyncControllerConfig() { + return syncControllerConfig; + } + + public void setSyncControllerConfig(SyncControllerConfig syncControllerConfig) { + this.syncControllerConfig = syncControllerConfig; + } + + public ActiveInventoryAdapter getAaiAdapter() { + return aaiAdapter; + } + + public void setAaiAdapter(ActiveInventoryAdapter aaiAdapter) { + this.aaiAdapter = aaiAdapter; + } + + public ElasticSearchAdapter getEsAdapter() { + return esAdapter; + } + + public void setEsAdapter(ElasticSearchAdapter esAdapter) { + this.esAdapter = esAdapter; + } + + public SuggestionEntityLookup getSuggestionEntityLookup() { + return suggestionEntityLookup; + } + + public void setSuggestionEntityLookup(SuggestionEntityLookup suggestionEntityLookup) { + this.suggestionEntityLookup = suggestionEntityLookup; + } + + public Map<String, String> getAggregationEntityToIndexMap() { + return aggregationEntityToIndexMap; + } + + public void setAggregationEntityToIndexMap(Map<String, String> aggregationEntityToIndexMap) { + this.aggregationEntityToIndexMap = aggregationEntityToIndexMap; + } + + public void buildControllers() { + + if (syncControllerConfig.isEnabled()) { + + Map<String, SuggestionEntityDescriptor> suggestionEntitites = + suggestionEntityLookup.getSuggestionSearchEntityDescriptors(); + SyncControllerImpl aggregationSyncController = null; + + for (String entityType : suggestionEntitites.keySet()) { + + String indexName = aggregationEntityToIndexMap.get(entityType); + + if (indexName == null) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "Could not determine aggregation index name" + " for entity type: " + entityType); + continue; + } + + try { + + aggregationSyncController = new SyncControllerImpl(syncControllerConfig, entityType); + + ElasticSearchSchemaConfig schemaConfig = indexNameToSchemaConfigMap.get(indexName); + + if (schemaConfig == null) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "Could not determine elastic search schema config for index name: " + indexName); + continue; + } + + IndexIntegrityValidator aggregationIndexValidator = + new IndexIntegrityValidator(esAdapter, schemaConfig, elasticSearchEndpointConfig, + ElasticSearchSchemaFactory.getIndexSchema(schemaConfig)); + + aggregationSyncController.registerIndexValidator(aggregationIndexValidator); + + AggregationSynchronizer aggSynchronizer = new AggregationSynchronizer(entityType, + schemaConfig, syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + + aggSynchronizer.setAaiAdapter(aaiAdapter); + aggSynchronizer.setElasticSearchAdapter(esAdapter); + + aggregationSyncController.registerEntitySynchronizer(aggSynchronizer); + + IndexCleaner entityDataIndexCleaner = + new ElasticSearchIndexCleaner(esAdapter, elasticSearchEndpointConfig, schemaConfig); + + aggregationSyncController.registerIndexCleaner(entityDataIndexCleaner); + + syncControllers.add(aggregationSyncController); + } catch (Exception exc) { + + exc.printStackTrace(); + + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "Failed to build aggregation sync controller. Error : " + exc.getMessage()); + } + + } + } else { + LOG.info(AaiUiMsgs.INFO_GENERIC, "Sync controller with name = " + + syncControllerConfig.getControllerName() + " is disabled"); + } + } + + @Override + public void registerController() { + + buildControllers(); + + if (syncControllerRegistry != null) { + for (SyncController controller : syncControllers) { + syncControllerRegistry.registerSyncController(controller); + } + } + + } +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/AggregationSynchronizer.java b/src/main/java/org/onap/aai/sparky/aggregation/sync/AggregationSynchronizer.java index 817e633..2a115db 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/AggregationSynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/aggregation/sync/AggregationSynchronizer.java @@ -20,56 +20,50 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.aggregation.sync; import static java.util.concurrent.CompletableFuture.supplyAsync; import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collection; import java.util.Deque; import java.util.EnumSet; -import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -import javax.json.Json; - +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; import org.onap.aai.sparky.dal.NetworkTransaction; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.config.SynchronizerConfiguration; -import org.onap.aai.sparky.synchronizer.entity.AggregationEntity; -import org.onap.aai.sparky.synchronizer.entity.MergableEntity; -import org.onap.aai.sparky.synchronizer.entity.SelfLinkDescriptor; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.synchronizer.task.PerformActiveInventoryRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchPut; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchUpdate; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.SynchronizerConstants; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.entity.AggregationEntity; +import org.onap.aai.sparky.sync.entity.MergableEntity; +import org.onap.aai.sparky.sync.entity.SelfLinkDescriptor; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.task.PerformActiveInventoryRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchPut; +import org.onap.aai.sparky.sync.task.PerformElasticSearchRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchUpdate; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.slf4j.MDC; -import org.onap.aai.cl.mdc.MdcContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectReader; @@ -121,6 +115,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer private boolean syncInProgress; private Map<String, String> contextMap; private String entityType; + private ElasticSearchSchemaConfig schemaConfig; /** * Instantiates a new entity aggregation synchronizer. @@ -128,11 +123,19 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer * @param indexName the index name * @throws Exception the exception */ - public AggregationSynchronizer(String entityType, String indexName) throws Exception { - super(LOG, "AGGES-" + indexName.toUpperCase(), 2, 5, 5, indexName); // multiple Autosuggestion - // Entity Synchronizer will - // run for different indices - + public AggregationSynchronizer(String entityType, ElasticSearchSchemaConfig schemaConfig, + int numSyncWorkers, int numActiveInventoryWorkers, int numElasticWorkers, + NetworkStatisticsConfig aaiStatConfig, NetworkStatisticsConfig esStatConfig) + throws Exception { + + super(LOG, "AGGES-" + schemaConfig.getIndexName().toUpperCase(), numSyncWorkers, + numActiveInventoryWorkers, numElasticWorkers, schemaConfig.getIndexName(), aaiStatConfig, + esStatConfig); // multiple + // Autosuggestion + // Entity Synchronizer will + // run for different indices + + this.schemaConfig = schemaConfig; this.entityType = entityType; this.allWorkEnumerated = false; this.entityCounters = new ConcurrentHashMap<String, AtomicInteger>(); @@ -145,10 +148,10 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer this.retryLimitTracker = new ConcurrentHashMap<String, Integer>(); this.esPutExecutor = NodeUtils.createNamedExecutor("AGGES-ES-PUT", 1, LOG); - Map<String, OxmEntityDescriptor> descriptor = new HashMap<String, OxmEntityDescriptor>(); - descriptor.put(entityType, oxmModelLoader.getEntityDescriptors().get(entityType)); - this.aaiEntityStats.initializeCountersFromOxmEntityDescriptors(descriptor); - this.esEntityStats.initializeCountersFromOxmEntityDescriptors(descriptor); + + this.aaiEntityStats.intializeEntityCounters(entityType); + this.esEntityStats.intializeEntityCounters(entityType); + this.contextMap = MDC.getCopyOfContextMap(); } @@ -171,11 +174,13 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer MDC.setContextMap(contextMap); OperationResult typeLinksResult = null; try { - typeLinksResult = aaiDataProvider.getSelfLinksByEntityType(entity); + typeLinksResult = aaiAdapter.getSelfLinksByEntityType(entity); aaiWorkOnHand.decrementAndGet(); processEntityTypeSelfLinks(typeLinksResult); } catch (Exception exc) { // TODO -> LOG, what should be logged here? + + exc.printStackTrace(); } return null; @@ -255,7 +260,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer * called incrementAndGet when queuing the failed PUT! */ - supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, esDataProvider), + supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, elasticSearchAdapter), esExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -341,7 +346,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer String responseSource = NodeUtils.convertObjectToJson(sourceObject.get(0), false); MergableEntity me = mapper.readValue(responseSource, MergableEntity.class); ObjectReader updater = mapper.readerForUpdating(me); - MergableEntity merged = updater.readValue(ae.getIndexDocumentJson()); + MergableEntity merged = updater.readValue(ae.getAsJson()); jsonPayload = mapper.writeValueAsString(merged); } } catch (IOException exc) { @@ -352,14 +357,15 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer return; } } else { - jsonPayload = ae.getIndexDocumentJson(); + jsonPayload = ae.getAsJson(); } if (wasEntryDiscovered) { if (versionNumber != null && jsonPayload != null) { - String requestPayload = esDataProvider.buildBulkImportOperationRequest(getIndexName(), - ElasticSearchConfig.getConfig().getType(), ae.getId(), versionNumber, jsonPayload); + String requestPayload = + elasticSearchAdapter.buildBulkImportOperationRequest(schemaConfig.getIndexName(), + schemaConfig.getIndexDocType(), ae.getId(), versionNumber, jsonPayload); NetworkTransaction transactionTracker = new NetworkTransaction(); transactionTracker.setEntityType(esGetTxn.getEntityType()); @@ -368,7 +374,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer esWorkOnHand.incrementAndGet(); supplyAsync(new PerformElasticSearchUpdate(ElasticSearchConfig.getConfig().getBulkUrl(), - requestPayload, esDataProvider, transactionTracker), esPutExecutor) + requestPayload, elasticSearchAdapter, transactionTracker), esPutExecutor) .whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -394,7 +400,8 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer updateElasticTxn.setOperationType(HttpMethod.PUT); esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchPut(jsonPayload, updateElasticTxn, esDataProvider), + supplyAsync( + new PerformElasticSearchPut(jsonPayload, updateElasticTxn, elasticSearchAdapter), esPutExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -493,7 +500,8 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer if (linkDescriptor.getSelfLink() != null && linkDescriptor.getEntityType() != null) { - descriptor = oxmModelLoader.getEntityDescriptor(linkDescriptor.getEntityType()); + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors() + .get(linkDescriptor.getEntityType()); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, linkDescriptor.getEntityType()); @@ -509,7 +517,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer aaiWorkOnHand.incrementAndGet(); - supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiDataProvider), aaiExecutor) + supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiAdapter), aaiExecutor) .whenComplete((result, error) -> { aaiWorkOnHand.decrementAndGet(); @@ -549,7 +557,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer final String jsonResult = txn.getOperationResult().getResult(); if (jsonResult != null && jsonResult.length() > 0) { - AggregationEntity ae = new AggregationEntity(oxmModelLoader); + AggregationEntity ae = new AggregationEntity(); ae.setLink(ActiveInventoryConfig.extractResourcePath(txn.getLink())); populateAggregationEntityDocument(ae, jsonResult, txn.getDescriptor()); ae.deriveFields(); @@ -570,7 +578,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchRetrieval(n2, esDataProvider), esExecutor) + supplyAsync(new PerformElasticSearchRetrieval(n2, elasticSearchAdapter), esExecutor) .whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -629,7 +637,6 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer String message = "Could not deserialize JSON (representing operation result) as node tree. " + "Operation result = " + jsonResult + ". " + exc.getLocalizedMessage(); LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, message); - return; } JsonNode resultData = rootNode.get("result-data"); @@ -651,7 +658,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer if (resourceType != null && resourceLink != null) { - descriptor = oxmModelLoader.getEntityDescriptor(resourceType); + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors().get(resourceType); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, resourceType); @@ -660,7 +667,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer } selflinks.add(new SelfLinkDescriptor(resourceLink, - SynchronizerConfiguration.NODES_ONLY_MODIFIER, resourceType)); + SynchronizerConstants.NODES_ONLY_MODIFIER, resourceType)); } @@ -673,7 +680,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#doSync() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#doSync() */ @Override public OperationState doSync() { @@ -699,7 +706,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) */ @Override public String getStatReport(boolean showFinalReport) { @@ -718,7 +725,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#shutdown() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#shutdown() */ @Override public void shutdown() { @@ -747,7 +754,7 @@ public class AggregationSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.AbstractEntitySynchronizer#clearCache() + * @see org.openecomp.sparky.synchronizer.AbstractEntitySynchronizer#clearCache() */ @Override public void clearCache() { diff --git a/src/main/java/org/onap/aai/sparky/aggregation/sync/HistoricalEntitySummarizer.java b/src/main/java/org/onap/aai/sparky/aggregation/sync/HistoricalEntitySummarizer.java new file mode 100644 index 0000000..5ee11be --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/aggregation/sync/HistoricalEntitySummarizer.java @@ -0,0 +1,391 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.aggregation.sync; + +import static java.util.concurrent.CompletableFuture.supplyAsync; + +import java.io.IOException; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +import javax.json.Json; +import javax.ws.rs.core.MediaType; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.config.oxm.SearchableEntityLookup; +import org.onap.aai.sparky.config.oxm.SearchableOxmEntityDescriptor; +import org.onap.aai.sparky.dal.rest.HttpMethod; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.util.NodeUtils; +import org.slf4j.MDC; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +/** + * The Class HistoricalEntitySummarizer. + */ +public class HistoricalEntitySummarizer extends AbstractEntitySynchronizer + implements IndexSynchronizer { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(HistoricalEntitySummarizer.class); + private static final String INSERTION_DATE_TIME_FORMAT = "yyyyMMdd'T'HHmmssZ"; + + private boolean allWorkEnumerated; + private ConcurrentHashMap<String, AtomicInteger> entityCounters; + private boolean syncInProgress; + private Map<String, String> contextMap; + private ElasticSearchSchemaConfig schemaConfig; + + /** + * Instantiates a new historical entity summarizer. + * + * @param indexName the index name + * @throws Exception the exception + */ + public HistoricalEntitySummarizer(ElasticSearchSchemaConfig schemaConfig, int internalSyncWorkers, + int aaiWorkers, int esWorkers, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(LOG, "HES", internalSyncWorkers, aaiWorkers, esWorkers, schemaConfig.getIndexName(), + aaiStatConfig, esStatConfig); + + this.schemaConfig = schemaConfig; + this.allWorkEnumerated = false; + this.entityCounters = new ConcurrentHashMap<String, AtomicInteger>(); + this.synchronizerName = "Historical Entity Summarizer"; + this.enabledStatFlags = EnumSet.of(StatFlag.AAI_REST_STATS, StatFlag.ES_REST_STATS); + this.syncInProgress = false; + this.contextMap = MDC.getCopyOfContextMap(); + this.syncDurationInMs = -1; + } + + /** + * Collect all the work. + * + * @return the operation state + */ + private OperationState collectAllTheWork() { + + Map<String, SearchableOxmEntityDescriptor> descriptorMap = + SearchableEntityLookup.getInstance().getSearchableEntityDescriptors(); + + if (descriptorMap.isEmpty()) { + LOG.error(AaiUiMsgs.OXM_FAILED_RETRIEVAL, "historical entities"); + + return OperationState.ERROR; + } + + Collection<String> entityTypes = descriptorMap.keySet(); + + AtomicInteger asyncWoH = new AtomicInteger(0); + + asyncWoH.set(entityTypes.size()); + + try { + for (String entityType : entityTypes) { + + supplyAsync(new Supplier<Void>() { + + @Override + public Void get() { + MDC.setContextMap(contextMap); + try { + OperationResult typeLinksResult = aaiAdapter.getSelfLinksByEntityType(entityType); + updateActiveInventoryCounters(HttpMethod.GET, entityType, typeLinksResult); + processEntityTypeSelfLinks(entityType, typeLinksResult); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GETTING_DATA_FROM_AAI, exc.getMessage()); + + } + + return null; + } + + }, aaiExecutor).whenComplete((result, error) -> { + + asyncWoH.decrementAndGet(); + + if (error != null) { + LOG.error(AaiUiMsgs.HISTORICAL_COLLECT_ERROR, error.getMessage()); + } + + }); + + } + + + while (asyncWoH.get() > 0) { + + if (LOG.isDebugEnabled()) { + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, + indexName + " summarizer waiting for all the links to be processed."); + } + + Thread.sleep(250); + } + + esWorkOnHand.set(entityCounters.size()); + + // start doing the real work + allWorkEnumerated = true; + + insertEntityTypeCounters(); + + if (LOG.isDebugEnabled()) { + + StringBuilder sb = new StringBuilder(128); + + sb.append("\n\nHistorical Entity Counters:"); + + for (Entry<String, AtomicInteger> entry : entityCounters.entrySet()) { + sb.append("\n").append(entry.getKey()).append(" = ").append(entry.getValue().get()); + } + + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, sb.toString()); + + } + + } catch (Exception exc) { + LOG.error(AaiUiMsgs.HISTORICAL_COLLECT_ERROR, exc.getMessage()); + + + esWorkOnHand.set(0); + allWorkEnumerated = true; + + return OperationState.ERROR; + } + + return OperationState.OK; + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#doSync() + */ + @Override + public OperationState doSync() { + this.syncDurationInMs = -1; + String txnID = NodeUtils.getRandomTxnId(); + MdcContext.initialize(txnID, "HistoricalEntitySynchronizer", "", "Sync", ""); + + if (syncInProgress) { + LOG.info(AaiUiMsgs.HISTORICAL_SYNC_PENDING); + return OperationState.PENDING; + } + + clearCache(); + + syncInProgress = true; + this.syncStartedTimeStampInMs = System.currentTimeMillis(); + allWorkEnumerated = false; + + return collectAllTheWork(); + } + + /** + * Process entity type self links. + * + * @param entityType the entity type + * @param operationResult the operation result + */ + private void processEntityTypeSelfLinks(String entityType, OperationResult operationResult) { + + JsonNode rootNode = null; + + final String jsonResult = operationResult.getResult(); + + if (jsonResult != null && jsonResult.length() > 0 && operationResult.wasSuccessful()) { + + try { + rootNode = mapper.readTree(jsonResult); + } catch (IOException exc) { + LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, exc.getMessage()); + return; + } + + JsonNode resultData = rootNode.get("result-data"); + ArrayNode resultDataArrayNode = null; + + if (resultData != null && resultData.isArray()) { + resultDataArrayNode = (ArrayNode) resultData; + entityCounters.put(entityType, new AtomicInteger(resultDataArrayNode.size())); + } + } + + } + + /** + * Insert entity type counters. + */ + private void insertEntityTypeCounters() { + + if (esWorkOnHand.get() <= 0) { + return; + } + + SimpleDateFormat dateFormat = new SimpleDateFormat(INSERTION_DATE_TIME_FORMAT); + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + String currentFormattedTimeStamp = dateFormat.format(timestamp); + + Set<Entry<String, AtomicInteger>> entityCounterEntries = entityCounters.entrySet(); + + for (Entry<String, AtomicInteger> entityCounterEntry : entityCounterEntries) { + + supplyAsync(new Supplier<Void>() { + + @Override + public Void get() { + MDC.setContextMap(contextMap); + String jsonString = + Json.createObjectBuilder().add("count", entityCounterEntry.getValue().get()) + .add("entityType", entityCounterEntry.getKey()) + .add("timestamp", currentFormattedTimeStamp).build().toString(); + + String link = null; + try { + link = getElasticFullUrl("", indexName); + OperationResult or = + elasticSearchAdapter.doPost(link, jsonString, MediaType.APPLICATION_JSON_TYPE); + updateElasticSearchCounters(HttpMethod.POST, entityCounterEntry.getKey(), or); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ES_STORE_FAILURE, exc.getMessage()); + } + + return null; + } + + }, esExecutor).whenComplete((result, error) -> { + + esWorkOnHand.decrementAndGet(); + + }); + + } + + while (esWorkOnHand.get() > 0) { + + try { + Thread.sleep(500); + } catch (InterruptedException exc) { + LOG.error(AaiUiMsgs.INTERRUPTED, "historical Entities", exc.getMessage()); + } + } + + } + + @Override + public SynchronizerState getState() { + + if (!isSyncDone()) { + return SynchronizerState.PERFORMING_SYNCHRONIZATION; + } + + return SynchronizerState.IDLE; + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) + */ + @Override + public String getStatReport(boolean showFinalReport) { + syncDurationInMs = System.currentTimeMillis() - syncStartedTimeStampInMs; + return this.getStatReport(syncDurationInMs, showFinalReport); + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#shutdown() + */ + @Override + public void shutdown() { + this.shutdownExecutors(); + } + + @Override + protected boolean isSyncDone() { + + int totalWorkOnHand = aaiWorkOnHand.get() + esWorkOnHand.get(); + + if (LOG.isDebugEnabled()) { + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, indexName + ", isSyncDone(), totalWorkOnHand = " + + totalWorkOnHand + " all work enumerated = " + allWorkEnumerated); + } + + if (totalWorkOnHand > 0 || !allWorkEnumerated) { + return false; + } + + this.syncInProgress = false; + + return true; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.AbstractEntitySynchronizer#clearCache() + */ + @Override + public void clearCache() { + + if (syncInProgress) { + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, + "Historical Entity Summarizer in progress, request to clear cache ignored"); + return; + } + + super.clearCache(); + this.resetCounters(); + if (entityCounters != null) { + entityCounters.clear(); + } + + allWorkEnumerated = false; + + } + +} diff --git a/src/main/java/org/onap/aai/sparky/aggregation/sync/HistoricalEntitySyncController.java b/src/main/java/org/onap/aai/sparky/aggregation/sync/HistoricalEntitySyncController.java new file mode 100644 index 0000000..1f7db2e --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/aggregation/sync/HistoricalEntitySyncController.java @@ -0,0 +1,90 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.aggregation.sync; + +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.sync.ElasticSearchSchemaFactory; +import org.onap.aai.sparky.sync.IndexIntegrityValidator; +import org.onap.aai.sparky.sync.SyncControllerImpl; +import org.onap.aai.sparky.sync.SyncControllerRegistrar; +import org.onap.aai.sparky.sync.SyncControllerRegistry; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; + +public class HistoricalEntitySyncController extends SyncControllerImpl + implements SyncControllerRegistrar { + + private SyncControllerRegistry syncControllerRegistry; + + public HistoricalEntitySyncController(SyncControllerConfig syncControllerConfig, + ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, + ElasticSearchSchemaConfig schemaConfig, ElasticSearchEndpointConfig endpointConfig, + int syncFrequencyInMinutes, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(syncControllerConfig); + + // final String controllerName = "Historical Entity Count Synchronizer"; + + long taskFrequencyInMs = syncFrequencyInMinutes * 60 * 1000; + + setDelayInMs(taskFrequencyInMs); + setSyncFrequencyInMs(taskFrequencyInMs); + + IndexIntegrityValidator entityCounterHistoryValidator = new IndexIntegrityValidator(esAdapter, + schemaConfig, endpointConfig, ElasticSearchSchemaFactory.getIndexSchema(schemaConfig)); + + registerIndexValidator(entityCounterHistoryValidator); + + HistoricalEntitySummarizer historicalSummarizer = new HistoricalEntitySummarizer(schemaConfig, + syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + + historicalSummarizer.setAaiAdapter(aaiAdapter); + historicalSummarizer.setElasticSearchAdapter(esAdapter); + + registerEntitySynchronizer(historicalSummarizer); + + } + + public SyncControllerRegistry getSyncControllerRegistry() { + return syncControllerRegistry; + } + + public void setSyncControllerRegistry(SyncControllerRegistry syncControllerRegistry) { + this.syncControllerRegistry = syncControllerRegistry; + } + + @Override + public void registerController() { + if (syncControllerRegistry != null) { + if (syncControllerConfig.isEnabled()) { + syncControllerRegistry.registerSyncController(this); + } + } + + } +} diff --git a/src/main/java/org/onap/aai/sparky/analytics/AbstractStatistics.java b/src/main/java/org/onap/aai/sparky/analytics/AbstractStatistics.java index 9d2fec6..6e7d854 100644 --- a/src/main/java/org/onap/aai/sparky/analytics/AbstractStatistics.java +++ b/src/main/java/org/onap/aai/sparky/analytics/AbstractStatistics.java @@ -20,6 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ + package org.onap.aai.sparky.analytics; import java.util.HashMap; @@ -31,35 +32,6 @@ import java.util.concurrent.atomic.AtomicInteger; public class AbstractStatistics implements ComponentStatistics { private HashMap<String, AtomicInteger> namedCounters; - - /** - * @return the namedCounters - */ - public HashMap<String, AtomicInteger> getNamedCounters() { - return namedCounters; - } - - /** - * @param namedCounters the namedCounters to set - */ - public void setNamedCounters(HashMap<String, AtomicInteger> namedCounters) { - this.namedCounters = namedCounters; - } - - /** - * @return the namedHistograms - */ - public HashMap<String, HistogramSampler> getNamedHistograms() { - return namedHistograms; - } - - /** - * @param namedHistograms the namedHistograms to set - */ - public void setNamedHistograms(HashMap<String, HistogramSampler> namedHistograms) { - this.namedHistograms = namedHistograms; - } - private HashMap<String, HistogramSampler> namedHistograms; /** @@ -73,7 +45,7 @@ public class AbstractStatistics implements ComponentStatistics { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.analytics.ComponentStatistics#addCounter(java.lang.String) + * @see org.openecomp.sparky.analytics.ComponentStatistics#addCounter(java.lang.String) */ /* * sync-lock the creation of counters during initialization, but run time should not use lock @@ -96,7 +68,7 @@ public class AbstractStatistics implements ComponentStatistics { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.analytics.ComponentStatistics#pegCounter(java.lang.String) + * @see org.openecomp.sparky.analytics.ComponentStatistics#pegCounter(java.lang.String) */ @Override public void pegCounter(String key) { @@ -112,7 +84,7 @@ public class AbstractStatistics implements ComponentStatistics { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.analytics.ComponentStatistics#incrementCounter(java.lang.String, int) + * @see org.openecomp.sparky.analytics.ComponentStatistics#incrementCounter(java.lang.String, int) */ @Override public void incrementCounter(String key, int value) { @@ -129,7 +101,7 @@ public class AbstractStatistics implements ComponentStatistics { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.analytics.ComponentStatistics#addHistogram(java.lang.String, + * @see org.openecomp.sparky.analytics.ComponentStatistics#addHistogram(java.lang.String, * java.lang.String, long, int, int) */ @Override @@ -147,7 +119,7 @@ public class AbstractStatistics implements ComponentStatistics { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.analytics.ComponentStatistics#updateHistogram(java.lang.String, long) + * @see org.openecomp.sparky.analytics.ComponentStatistics#updateHistogram(java.lang.String, long) */ @Override public void updateHistogram(String key, long value) { @@ -161,7 +133,7 @@ public class AbstractStatistics implements ComponentStatistics { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.analytics.ComponentStatistics#reset() + * @see org.openecomp.sparky.analytics.ComponentStatistics#reset() */ @Override public void reset() { diff --git a/src/main/java/org/onap/aai/sparky/analytics/HistoricalCounter.java b/src/main/java/org/onap/aai/sparky/analytics/HistoricalCounter.java index 622693c..50941cc 100644 --- a/src/main/java/org/onap/aai/sparky/analytics/HistoricalCounter.java +++ b/src/main/java/org/onap/aai/sparky/analytics/HistoricalCounter.java @@ -20,7 +20,6 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ - package org.onap.aai.sparky.analytics; /** @@ -33,62 +32,6 @@ public class HistoricalCounter { private double min; - /** - * @return the totalOfSamples - */ - public double getTotalOfSamples() { - return totalOfSamples; - } - - /** - * @param totalOfSamples the totalOfSamples to set - */ - public void setTotalOfSamples(double totalOfSamples) { - this.totalOfSamples = totalOfSamples; - } - - /** - * @return the maintainSingleValue - */ - public boolean isMaintainSingleValue() { - return maintainSingleValue; - } - - /** - * @param maintainSingleValue the maintainSingleValue to set - */ - public void setMaintainSingleValue(boolean maintainSingleValue) { - this.maintainSingleValue = maintainSingleValue; - } - - /** - * @param min the min to set - */ - public void setMin(double min) { - this.min = min; - } - - /** - * @param max the max to set - */ - public void setMax(double max) { - this.max = max; - } - - /** - * @param numSamples the numSamples to set - */ - public void setNumSamples(long numSamples) { - this.numSamples = numSamples; - } - - /** - * @param value the value to set - */ - public void setValue(double value) { - this.value = value; - } - private double max; private double totalOfSamples; @@ -175,6 +118,31 @@ public class HistoricalCounter { return (totalOfSamples / numSamples); } + public void setMin(double min) { + this.min = min; + } + + public void setMax(double max) { + this.max = max; + } + + public double getTotalOfSamples() { + return totalOfSamples; + } + + public void setTotalOfSamples(double totalOfSamples) { + this.totalOfSamples = totalOfSamples; + } + + public void setNumSamples(long numSamples) { + this.numSamples = numSamples; + } + + public void setMaintainSingleValue(boolean maintainSingleValue) { + this.maintainSingleValue = maintainSingleValue; + } + + /** * Reset. */ diff --git a/src/main/java/org/onap/aai/sparky/autosuggestion/sync/AutoSuggestionSyncController.java b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/AutoSuggestionSyncController.java new file mode 100644 index 0000000..950eb45 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/AutoSuggestionSyncController.java @@ -0,0 +1,97 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.autosuggestion.sync; + +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.sync.ElasticSearchIndexCleaner; +import org.onap.aai.sparky.sync.ElasticSearchSchemaFactory; +import org.onap.aai.sparky.sync.IndexCleaner; +import org.onap.aai.sparky.sync.IndexIntegrityValidator; +import org.onap.aai.sparky.sync.SyncControllerImpl; +import org.onap.aai.sparky.sync.SyncControllerRegistrar; +import org.onap.aai.sparky.sync.SyncControllerRegistry; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; + +public class AutoSuggestionSyncController extends SyncControllerImpl + implements SyncControllerRegistrar { + + private SyncControllerRegistry syncControllerRegistry; + + public AutoSuggestionSyncController(SyncControllerConfig syncControllerConfig, + ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, + ElasticSearchSchemaConfig schemaConfig, ElasticSearchEndpointConfig endpointConfig, + NetworkStatisticsConfig aaiStatConfig, NetworkStatisticsConfig esStatConfig) + throws Exception { + super(syncControllerConfig); + + // final String controllerName = "Auto Suggestion Synchronizer"; + + IndexIntegrityValidator autoSuggestionIndexValidator = new IndexIntegrityValidator(esAdapter, + schemaConfig, endpointConfig, ElasticSearchSchemaFactory.getIndexSchema(schemaConfig)); + + registerIndexValidator(autoSuggestionIndexValidator); + + AutosuggestionSynchronizer suggestionSynchronizer = new AutosuggestionSynchronizer(schemaConfig, + syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + + suggestionSynchronizer.setAaiAdapter(aaiAdapter); + suggestionSynchronizer.setElasticSearchAdapter(esAdapter); + + registerEntitySynchronizer(suggestionSynchronizer); + + IndexCleaner autosuggestIndexCleaner = + new ElasticSearchIndexCleaner(esAdapter, endpointConfig, schemaConfig); + + registerIndexCleaner(autosuggestIndexCleaner); + + } + + public SyncControllerRegistry getSyncControllerRegistry() { + return syncControllerRegistry; + } + + + + public void setSyncControllerRegistry(SyncControllerRegistry syncControllerRegistry) { + this.syncControllerRegistry = syncControllerRegistry; + } + + + + @Override + public void registerController() { + + if (syncControllerRegistry != null) { + if (syncControllerConfig.isEnabled()) { + syncControllerRegistry.registerSyncController(this); + } + } + + } +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/AutosuggestionSynchronizer.java b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/AutosuggestionSynchronizer.java index 328fb97..4ce7ce3 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/AutosuggestionSynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/AutosuggestionSynchronizer.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.autosuggestion.sync; import static java.util.concurrent.CompletableFuture.supplyAsync; @@ -40,25 +40,32 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.config.oxm.SuggestionEntityDescriptor; +import org.onap.aai.sparky.config.oxm.SuggestionEntityLookup; import org.onap.aai.sparky.dal.NetworkTransaction; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.config.SynchronizerConfiguration; -import org.onap.aai.sparky.synchronizer.entity.SelfLinkDescriptor; -import org.onap.aai.sparky.synchronizer.entity.SuggestionSearchEntity; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.synchronizer.task.PerformActiveInventoryRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchPut; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchRetrieval; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.SynchronizerConstants; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.entity.SelfLinkDescriptor; +import org.onap.aai.sparky.sync.entity.SuggestionSearchEntity; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.task.PerformActiveInventoryRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchPut; +import org.onap.aai.sparky.sync.task.PerformElasticSearchRetrieval; import org.onap.aai.sparky.util.NodeUtils; import org.onap.aai.sparky.util.SuggestionsPermutation; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.cl.mdc.MdcContext; import org.slf4j.MDC; import com.fasterxml.jackson.core.JsonProcessingException; @@ -114,10 +121,11 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer * @param indexName the index name * @throws Exception the exception */ - public AutosuggestionSynchronizer(String indexName) throws Exception { - super(LOG, "ASES-" + indexName.toUpperCase(), 2, 5, 5, indexName); // multiple Autosuggestion - // Entity Synchronizer will - // run for different indices + public AutosuggestionSynchronizer(ElasticSearchSchemaConfig schemaConfig, int internalSyncWorkers, + int aaiWorkers, int esWorkers, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(LOG, "ASES-" + schemaConfig.getIndexName().toUpperCase(), internalSyncWorkers, aaiWorkers, + esWorkers, schemaConfig.getIndexName(), aaiStatConfig, esStatConfig); this.allWorkEnumerated = false; this.selflinks = new ConcurrentLinkedDeque<SelfLinkDescriptor>(); @@ -137,8 +145,8 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer */ private OperationState collectAllTheWork() { final Map<String, String> contextMap = MDC.getCopyOfContextMap(); - Map<String, OxmEntityDescriptor> descriptorMap = - oxmModelLoader.getSuggestionSearchEntityDescriptors(); + Map<String, SuggestionEntityDescriptor> descriptorMap = + SuggestionEntityLookup.getInstance().getSuggestionSearchEntityDescriptors(); if (descriptorMap.isEmpty()) { LOG.error(AaiUiMsgs.ERROR_LOADING_OXM_SUGGESTIBLE_ENTITIES); @@ -166,7 +174,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer MDC.setContextMap(contextMap); OperationResult typeLinksResult = null; try { - typeLinksResult = aaiDataProvider.getSelfLinksByEntityType(key); + typeLinksResult = aaiAdapter.getSelfLinksByEntityType(key); aaiWorkOnHand.decrementAndGet(); processEntityTypeSelfLinks(typeLinksResult); } catch (Exception exc) { @@ -221,7 +229,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#doSync() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#doSync() */ @Override public OperationState doSync() { @@ -252,7 +260,6 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer String message = "Could not deserialize JSON (representing operation result) as node tree. " + "Operation result = " + jsonResult + ". " + exc.getLocalizedMessage(); LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, message); - return; } JsonNode resultData = rootNode.get("result-data"); @@ -274,7 +281,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer if (resourceType != null && resourceLink != null) { - descriptor = oxmModelLoader.getEntityDescriptor(resourceType); + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors().get(resourceType); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, resourceType); @@ -282,7 +289,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer continue; } selflinks.add(new SelfLinkDescriptor(resourceLink, - SynchronizerConfiguration.NODES_ONLY_MODIFIER, resourceType)); + SynchronizerConstants.NODES_ONLY_MODIFIER, resourceType)); } @@ -305,7 +312,8 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer if (linkDescriptor.getSelfLink() != null && linkDescriptor.getEntityType() != null) { - descriptor = oxmModelLoader.getEntityDescriptor(linkDescriptor.getEntityType()); + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors() + .get(linkDescriptor.getEntityType()); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, linkDescriptor.getEntityType()); @@ -321,7 +329,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer aaiWorkOnHand.incrementAndGet(); - supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiDataProvider), aaiExecutor) + supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiAdapter), aaiExecutor) .whenComplete((result, error) -> { aaiWorkOnHand.decrementAndGet(); @@ -354,9 +362,10 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer * * @return List of all valid suggestion attributes(key's) */ - public List<String> getSuggestionFromReponse(JsonNode node, String entityName) { + public List<String> getSuggestableAttrNamesFromReponse(JsonNode node, String entityName) { List<String> suggestableAttr = new ArrayList<String>(); - HashMap<String, String> desc = oxmModelLoader.getOxmModel().get(entityName); + HashMap<String, String> desc = + SuggestionEntityLookup.getInstance().getSuggestionSearchEntityOxmModel().get(entityName); String attr = desc.get("suggestibleAttributes"); suggestableAttr = Arrays.asList(attr.split(",")); List<String> suggestableValue = new ArrayList<>(); @@ -389,17 +398,19 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer String entityName = txn.getDescriptor().getEntityName(); JsonNode entityNode = mapper.readTree(jsonResult); - SuggestionsPermutation suggPermutation = new SuggestionsPermutation(); - ArrayList<ArrayList<String>> uniqueLists = suggPermutation - .getSuggestionsPermutation(getSuggestionFromReponse(entityNode, entityName)); + List<String> availableSuggestableAttrName = + getSuggestableAttrNamesFromReponse(entityNode, entityName); + ArrayList<ArrayList<String>> uniqueLists = + SuggestionsPermutation.getNonEmptyUniqueLists(availableSuggestableAttrName); // Now we have a list of all possible permutations for the status that are // defined for this entity type. Try inserting a document for every combination. for (ArrayList<String> uniqueList : uniqueLists) { - SuggestionSearchEntity sse = new SuggestionSearchEntity(oxmModelLoader); + + SuggestionSearchEntity sse = + new SuggestionSearchEntity(SuggestionEntityLookup.getInstance()); sse.setSuggestableAttr(uniqueList); - sse.setPayloadFromResponse(entityNode); - sse.setLink(txn.getLink()); + sse.setFilterBasedPayloadFromResponse(entityNode, entityName, uniqueList); sse.setLink(ActiveInventoryConfig.extractResourcePath(txn.getLink())); populateSuggestionSearchEntityDocument(sse, jsonResult, txn); // The unique id for the document will be created at derive fields @@ -422,7 +433,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchRetrieval(n2, esDataProvider), esExecutor) + supplyAsync(new PerformElasticSearchRetrieval(n2, elasticSearchAdapter), esExecutor) .whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -457,7 +468,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer List<String> primaryKeyValues = new ArrayList<String>(); String pkeyValue = null; - for (String keyName : resultDescriptor.getPrimaryKeyAttributeName()) { + for (String keyName : resultDescriptor.getPrimaryKeyAttributeNames()) { pkeyValue = NodeUtils.getNodeFieldAsText(entityNode, keyName); if (pkeyValue != null) { primaryKeyValues.add(pkeyValue); @@ -516,7 +527,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer try { String jsonPayload = null; - jsonPayload = sse.getIndexDocumentJson(); + jsonPayload = sse.getAsJson(); if (link != null && jsonPayload != null) { NetworkTransaction updateElasticTxn = new NetworkTransaction(); @@ -526,7 +537,8 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer updateElasticTxn.setOperationType(HttpMethod.PUT); esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchPut(jsonPayload, updateElasticTxn, esDataProvider), + supplyAsync( + new PerformElasticSearchPut(jsonPayload, updateElasticTxn, elasticSearchAdapter), esPutExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -612,7 +624,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer * called incrementAndGet when queuing the failed PUT! */ - supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, esDataProvider), + supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, elasticSearchAdapter), esExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -673,7 +685,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) */ @Override public String getStatReport(boolean showFinalReport) { @@ -684,7 +696,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#shutdown() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#shutdown() */ @Override public void shutdown() { @@ -713,7 +725,7 @@ public class AutosuggestionSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.AbstractEntitySynchronizer#clearCache() + * @see org.openecomp.sparky.synchronizer.AbstractEntitySynchronizer#clearCache() */ @Override public void clearCache() { diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/AggregationSuggestionSynchronizer.java b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/VnfAliasSuggestionSynchronizer.java index cd5877a..c6fa69b 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/AggregationSuggestionSynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/VnfAliasSuggestionSynchronizer.java @@ -20,44 +20,52 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.autosuggestion.sync; import static java.util.concurrent.CompletableFuture.supplyAsync; import java.util.Map; import java.util.concurrent.ExecutorService; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.dal.NetworkTransaction; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.entity.AggregationSuggestionEntity; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchPut; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.entity.AggregationSuggestionEntity; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.task.PerformElasticSearchPut; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.cl.mdc.MdcContext; import org.slf4j.MDC; -public class AggregationSuggestionSynchronizer extends AbstractEntitySynchronizer + +public class VnfAliasSuggestionSynchronizer extends AbstractEntitySynchronizer implements IndexSynchronizer { private static final Logger LOG = - LoggerFactory.getInstance().getLogger(AggregationSuggestionSynchronizer.class); + LoggerFactory.getInstance().getLogger(VnfAliasSuggestionSynchronizer.class); private boolean isSyncInProgress; private boolean shouldPerformRetry; private Map<String, String> contextMap; protected ExecutorService esPutExecutor; - public AggregationSuggestionSynchronizer(String indexName) throws Exception { - super(LOG, "ASS-" + indexName.toUpperCase(), 2, 5, 5, indexName); + public VnfAliasSuggestionSynchronizer(ElasticSearchSchemaConfig schemaConfig, + int internalSyncWorkers, int aaiWorkers, int esWorkers, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(LOG, "VASS-" + schemaConfig.getIndexName().toUpperCase(), internalSyncWorkers, aaiWorkers, + esWorkers, schemaConfig.getIndexName(), aaiStatConfig, esStatConfig); this.isSyncInProgress = false; this.shouldPerformRetry = false; - this.synchronizerName = "Aggregation Suggestion Synchronizer"; + this.synchronizerName = "VNFs Alias Suggestion Synchronizer"; this.contextMap = MDC.getCopyOfContextMap(); this.esPutExecutor = NodeUtils.createNamedExecutor("ASS-ES-PUT", 2, LOG); } @@ -83,6 +91,7 @@ public class AggregationSuggestionSynchronizer extends AbstractEntitySynchronize isSyncInProgress = true; this.syncDurationInMs = -1; syncStartedTimeStampInMs = System.currentTimeMillis(); + syncEntity(); while (!isSyncDone()) { @@ -101,10 +110,11 @@ public class AggregationSuggestionSynchronizer extends AbstractEntitySynchronize private void syncEntity() { String txnId = NodeUtils.getRandomTxnId(); - MdcContext.initialize(txnId, "AggregationSuggestionSynchronizer", "", "Sync", ""); + MdcContext.initialize(txnId, synchronizerName, "", "Sync", ""); AggregationSuggestionEntity syncEntity = new AggregationSuggestionEntity(); syncEntity.deriveFields(); + syncEntity.initializeFilters(); String link = null; try { @@ -115,7 +125,7 @@ public class AggregationSuggestionSynchronizer extends AbstractEntitySynchronize try { String jsonPayload = null; - jsonPayload = syncEntity.getIndexDocumentJson(); + jsonPayload = syncEntity.getAsJson(); if (link != null && jsonPayload != null) { NetworkTransaction elasticPutTxn = new NetworkTransaction(); @@ -124,9 +134,8 @@ public class AggregationSuggestionSynchronizer extends AbstractEntitySynchronize esWorkOnHand.incrementAndGet(); final Map<String, String> contextMap = MDC.getCopyOfContextMap(); - supplyAsync( - new PerformElasticSearchPut(jsonPayload, elasticPutTxn, esDataProvider, contextMap), - esPutExecutor).whenComplete((result, error) -> { + supplyAsync(new PerformElasticSearchPut(jsonPayload, elasticPutTxn, elasticSearchAdapter, + contextMap), esPutExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); diff --git a/src/main/java/org/onap/aai/sparky/autosuggestion/sync/VnfAliasSyncController.java b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/VnfAliasSyncController.java new file mode 100644 index 0000000..3376eed --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/autosuggestion/sync/VnfAliasSyncController.java @@ -0,0 +1,95 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.autosuggestion.sync; + +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.sync.ElasticSearchIndexCleaner; +import org.onap.aai.sparky.sync.ElasticSearchSchemaFactory; +import org.onap.aai.sparky.sync.IndexCleaner; +import org.onap.aai.sparky.sync.IndexIntegrityValidator; +import org.onap.aai.sparky.sync.SyncControllerImpl; +import org.onap.aai.sparky.sync.SyncControllerRegistrar; +import org.onap.aai.sparky.sync.SyncControllerRegistry; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; + +public class VnfAliasSyncController extends SyncControllerImpl implements SyncControllerRegistrar { + + private SyncControllerRegistry syncControllerRegistry; + + public VnfAliasSyncController(SyncControllerConfig syncControllerConfig, + ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, + ElasticSearchSchemaConfig schemaConfig, ElasticSearchEndpointConfig endpointConfig, + NetworkStatisticsConfig aaiStatConfig, NetworkStatisticsConfig esStatConfig) + throws Exception { + super(syncControllerConfig); + + // final String controllerName = "VNFs Alias Suggestion Synchronizer"; + + IndexIntegrityValidator indexValidator = new IndexIntegrityValidator(esAdapter, schemaConfig, + endpointConfig, ElasticSearchSchemaFactory.getIndexSchema(schemaConfig)); + + registerIndexValidator(indexValidator); + + VnfAliasSuggestionSynchronizer synchronizer = new VnfAliasSuggestionSynchronizer(schemaConfig, + syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + + synchronizer.setAaiAdapter(aaiAdapter); + synchronizer.setElasticSearchAdapter(esAdapter); + + registerEntitySynchronizer(synchronizer); + + + IndexCleaner indexCleaner = + new ElasticSearchIndexCleaner(esAdapter, endpointConfig, schemaConfig); + + registerIndexCleaner(indexCleaner); + + } + + public SyncControllerRegistry getSyncControllerRegistry() { + return syncControllerRegistry; + } + + public void setSyncControllerRegistry(SyncControllerRegistry syncControllerRegistry) { + this.syncControllerRegistry = syncControllerRegistry; + } + + @Override + public void registerController() { + + if (syncControllerRegistry != null) { + if (syncControllerConfig.isEnabled()) { + syncControllerRegistry.registerSyncController(this); + } + } + + } + + +} diff --git a/src/main/java/org/onap/aai/sparky/common/search/CommonSearchSuggestion.java b/src/main/java/org/onap/aai/sparky/common/search/CommonSearchSuggestion.java new file mode 100644 index 0000000..8a3f119 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/common/search/CommonSearchSuggestion.java @@ -0,0 +1,88 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.common.search; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.aai.sparky.search.entity.SearchSuggestion; +import org.onap.aai.sparky.search.filters.entity.UiFilterValueEntity; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +@JsonInclude(Include.NON_NULL) +public class CommonSearchSuggestion implements SearchSuggestion { + protected String hashId; + protected String route; + protected String text; + protected List<UiFilterValueEntity> filterValues = new ArrayList<>(); + + public CommonSearchSuggestion() {} + + public CommonSearchSuggestion(String hashId, String route, String text, String perspective, + List<UiFilterValueEntity> filterValues) { + this.hashId = hashId; + this.route = route; + this.text = text; + this.filterValues = filterValues; + } + + public List<UiFilterValueEntity> getFilterValues() { + return filterValues; + } + + public String getHashId() { + return hashId; + } + + public String getRoute() { + return route; + } + + public String getText() { + return text; + } + + public void setHashId(String hashId) { + this.hashId = hashId; + } + + public void setRoute(String route) { + this.route = route; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return "CommonSearchSuggestion [" + (hashId != null ? "hashId=" + hashId + ", " : "") + + (route != null ? "route=" + route + ", " : "") + + (text != null ? "text=" + text + ", " : "") + + (filterValues != null ? "filterValues=" + filterValues : "") + "]"; + } + + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReference.java b/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReference.java index e4a9f90..1df9296 100644 --- a/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReference.java +++ b/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReference.java @@ -20,7 +20,6 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ - package org.onap.aai.sparky.config.oxm; import java.util.ArrayList; diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReferenceDescriptor.java b/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReferenceDescriptor.java new file mode 100644 index 0000000..f0e6d4e --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReferenceDescriptor.java @@ -0,0 +1,65 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +public class CrossEntityReferenceDescriptor extends OxmEntityDescriptor { + protected CrossEntityReference crossEntityReference; + + public CrossEntityReference getCrossEntityReference() { + return crossEntityReference; + } + + public void setCrossEntityReference(CrossEntityReference crossEntityReference) { + this.crossEntityReference = crossEntityReference; + } + + /** + * Checks for cross entity references. + * + * @return true, if successful + */ + public boolean hasCrossEntityReferences() { + if (this.crossEntityReference == null) { + return false; + } + if (!this.crossEntityReference.getReferenceAttributes().isEmpty()) { + return true; + } + return false; + } + + + @Override + public String toString() { + return "CrossEntityReferenceDescriptor [" + + (crossEntityReference != null ? "crossEntityReference=" + crossEntityReference + ", " + : "") + + (entityName != null ? "entityName=" + entityName + ", " : "") + + (primaryKeyAttributeNames != null ? "primaryKeyAttributeNames=" + primaryKeyAttributeNames + : "") + + "]"; + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReferenceLookup.java b/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReferenceLookup.java new file mode 100644 index 0000000..81fe943 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/CrossEntityReferenceLookup.java @@ -0,0 +1,154 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.oxm.mappings.Descriptor; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; + +public class CrossEntityReferenceLookup implements OxmModelProcessor { + + // TODO: kill singleton collaborator pattern + private static CrossEntityReferenceLookup instance; + + private Map<String, HashMap<String, String>> crossReferenceEntityOxmModel; + private Map<String, CrossEntityReferenceDescriptor> crossReferenceEntityDescriptors; + + + private CrossEntityReferenceLookup() { + crossReferenceEntityOxmModel = new LinkedHashMap<String, HashMap<String, String>>(); + crossReferenceEntityDescriptors = new HashMap<String, CrossEntityReferenceDescriptor>(); + } + + public synchronized static CrossEntityReferenceLookup getInstance() { + + /* + * I hate this method and I want it to go away. The singleton pattern is transitory, I want this + * class to be wired via a bean reference instead. But from the starting point, it would require + * fixing all the classes across the code base up front and I don't want this task to expand + * beyond just refactoring the OxmModelLoader. For now I'll keep the singleton pattern, but I + * really want to get rid of it once we are properly spring wired. + */ + + if (instance == null) { + instance = new CrossEntityReferenceLookup(); + } + + return instance; + } + + + @Override + public void processOxmModel(DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + + DynamicType entity = jaxbContext.getDynamicType(desc.getAlias()); + + LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>(); + + // Not all fields have key attributes + if (desc.getPrimaryKeyFields() != null) { + oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString() + .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "")); + } + + String entityName = desc.getDefaultRootElement(); + + // add entityName + oxmProperties.put("entityName", entityName); + + Map<String, String> properties = entity.getDescriptor().getProperties(); + if (properties != null) { + for (Map.Entry<String, String> entry : properties.entrySet()) { + + if (entry.getKey().equalsIgnoreCase("crossEntityReference")) { + oxmProperties.put("crossEntityReference", entry.getValue()); + } + } + } + + if (oxmProperties.containsKey("crossEntityReference")) { + crossReferenceEntityOxmModel.put(entityName, oxmProperties); + } + + } + + for (Entry<String, HashMap<String, String>> crossRefModel : crossReferenceEntityOxmModel + .entrySet()) { + HashMap<String, String> attribute = crossRefModel.getValue(); + CrossEntityReferenceDescriptor entity = new CrossEntityReferenceDescriptor(); + entity.setEntityName(attribute.get("entityName")); + entity.setPrimaryKeyAttributeNames( + Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); + + List<String> crossEntityRefTokens = + Arrays.asList(attribute.get("crossEntityReference").split(",")); + + if (crossEntityRefTokens.size() >= 2) { + CrossEntityReference entityRef = new CrossEntityReference(); + entityRef.setTargetEntityType(crossEntityRefTokens.get(0)); + + for (int i = 1; i < crossEntityRefTokens.size(); i++) { + entityRef.addReferenceAttribute(crossEntityRefTokens.get(i)); + } + + entity.setCrossEntityReference(entityRef); + } + crossReferenceEntityDescriptors.put(attribute.get("entityName"), entity); + } + + } + + public Map<String, HashMap<String, String>> getCrossReferenceEntityOxmModel() { + return crossReferenceEntityOxmModel; + } + + public void setCrossReferenceEntityOxmModel( + Map<String, HashMap<String, String>> crossReferenceEntityOxmModel) { + this.crossReferenceEntityOxmModel = crossReferenceEntityOxmModel; + } + + public Map<String, CrossEntityReferenceDescriptor> getCrossReferenceEntityDescriptors() { + return crossReferenceEntityDescriptors; + } + + public void setCrossReferenceEntityDescriptors( + Map<String, CrossEntityReferenceDescriptor> crossReferenceEntityDescriptors) { + this.crossReferenceEntityDescriptors = crossReferenceEntityDescriptors; + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/GeoEntityDescriptor.java b/src/main/java/org/onap/aai/sparky/config/oxm/GeoEntityDescriptor.java new file mode 100644 index 0000000..5a45842 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/GeoEntityDescriptor.java @@ -0,0 +1,59 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +public class GeoEntityDescriptor extends OxmEntityDescriptor { + + protected String geoLatName; + + protected String geoLongName; + + public String getGeoLatName() { + return geoLatName; + } + + public void setGeoLatName(String geoLatName) { + this.geoLatName = geoLatName; + } + + public String getGeoLongName() { + return geoLongName; + } + + public void setGeoLongName(String geoLongName) { + this.geoLongName = geoLongName; + } + + @Override + public String toString() { + return "GeoEntityDescriptor [" + (geoLatName != null ? "geoLatName=" + geoLatName + ", " : "") + + (geoLongName != null ? "geoLongName=" + geoLongName + ", " : "") + + (entityName != null ? "entityName=" + entityName + ", " : "") + + (primaryKeyAttributeNames != null ? "primaryKeyAttributeNames=" + primaryKeyAttributeNames + : "") + + "]"; + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/GeoEntityLookup.java b/src/main/java/org/onap/aai/sparky/config/oxm/GeoEntityLookup.java new file mode 100644 index 0000000..f8b1ceb --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/GeoEntityLookup.java @@ -0,0 +1,155 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.oxm.mappings.Descriptor; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; + +public class GeoEntityLookup implements OxmModelProcessor { + + // TODO: kill singleton collaborator pattern + private static GeoEntityLookup instance; + + private Map<String, HashMap<String, String>> geoEntityOxmModel; + + private Map<String, GeoOxmEntityDescriptor> geoEntityDescriptors; + + private GeoEntityLookup() { + geoEntityOxmModel = new LinkedHashMap<String, HashMap<String, String>>(); + geoEntityDescriptors = new HashMap<String, GeoOxmEntityDescriptor>(); + } + + public synchronized static GeoEntityLookup getInstance() { + + /* + * I hate this method and I want it to go away. The singleton pattern is transitory, I want this + * class to be wired via a bean reference instead. But from the starting point, it would require + * fixing all the classes across the code base up front and I don't want this task to expand + * beyond just refactoring the OxmModelLoader. For now I'll keep the singleton pattern, but I + * really want to get rid of it once we are properly spring wired. + */ + + if (instance == null) { + instance = new GeoEntityLookup(); + } + + return instance; + } + + public Map<String, HashMap<String, String>> getGeoEntityOxmModel() { + return geoEntityOxmModel; + } + + public void setGeoEntityOxmModel(Map<String, HashMap<String, String>> geoEntityOxmModel) { + this.geoEntityOxmModel = geoEntityOxmModel; + } + + public Map<String, GeoOxmEntityDescriptor> getGeoEntityDescriptors() { + return geoEntityDescriptors; + } + + public void setGeoEntityDescriptors(Map<String, GeoOxmEntityDescriptor> geoEntityDescriptors) { + this.geoEntityDescriptors = geoEntityDescriptors; + } + + @Override + public void processOxmModel(DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + + DynamicType entity = jaxbContext.getDynamicType(desc.getAlias()); + + LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>(); + + // Not all fields have key attributes + if (desc.getPrimaryKeyFields() != null) { + oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString() + .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "")); + } + + String entityName = desc.getDefaultRootElement(); + + // add entityName + oxmProperties.put("entityName", entityName); + + Map<String, String> properties = entity.getDescriptor().getProperties(); + + if (properties != null) { + for (Map.Entry<String, String> entry : properties.entrySet()) { + + if (entry.getKey().equalsIgnoreCase("geoLat")) { + if (entry.getValue().length() > 0) { + oxmProperties.put("geoLat", entry.getValue()); + } + } else if (entry.getKey().equalsIgnoreCase("geoLong")) { + if (entry.getValue().length() > 0) { + oxmProperties.put("geoLong", entry.getValue()); + } + } + } + } + + if (oxmProperties.containsKey("geoLat") && oxmProperties.containsKey("geoLong")) { + geoEntityOxmModel.put(entityName, oxmProperties); + } + + } + + for (Entry<String, HashMap<String, String>> entityModel : geoEntityOxmModel.entrySet()) { + + HashMap<String, String> attribute = entityModel.getValue(); + + GeoOxmEntityDescriptor entity = new GeoOxmEntityDescriptor(); + + entity.setEntityName(attribute.get("entityName")); + + if (attribute.containsKey("primaryKeyAttributeNames")) { + + entity.setPrimaryKeyAttributeNames( + Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); + + if (attribute.containsKey("geoLat") || attribute.containsKey("geoLong")) { + entity.setGeoLatName(attribute.get("geoLat")); + entity.setGeoLongName(attribute.get("geoLong")); + } + + geoEntityDescriptors.put(attribute.get("entityName"), entity); + } + } + + } + + +} diff --git a/src/main/java/org/onap/aai/sparky/search/SuggestionList.java b/src/main/java/org/onap/aai/sparky/config/oxm/GeoOxmEntityDescriptor.java index 5548ffb..595c81a 100644 --- a/src/main/java/org/onap/aai/sparky/search/SuggestionList.java +++ b/src/main/java/org/onap/aai/sparky/config/oxm/GeoOxmEntityDescriptor.java @@ -20,51 +20,50 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.search; +package org.onap.aai.sparky.config.oxm; -import java.util.LinkedList; -import java.util.List; +public class GeoOxmEntityDescriptor extends OxmEntityDescriptor { -public class SuggestionList { - // TODO: verify which data type these fields should be - private Long processingTimeInMs; - private Long totalFound; - private Long numReturned; - private List<Suggestion> suggestions = new LinkedList<>(); + private String geoLatName; - public void addSuggestion(Suggestion suggestion) { - suggestions.add(suggestion); - } + private String geoLongName; - public List<Suggestion> getSuggestions() { - return suggestions; + public String getGeoLatName() { + return geoLatName; } - public void setSuggestions(List<Suggestion> suggestions) { - this.suggestions = suggestions; + public void setGeoLatName(String geoLatName) { + this.geoLatName = geoLatName; } - public Long getProcessingTimeInMs() { - return processingTimeInMs; + public String getGeoLongName() { + return geoLongName; } - public Long getTotalFound() { - return totalFound; + public void setGeoLongName(String geoLongName) { + this.geoLongName = geoLongName; } - public Long getNumReturned() { - return numReturned; + /** + * Checks for geo entity. + * + * @return true, if successful + */ + public boolean hasGeoEntity() { + return (this.geoLongName != null && this.geoLatName != null); } - public void setProcessingTimeInMs(Long processingTimeInMs) { - this.processingTimeInMs = processingTimeInMs; + @Override + public String toString() { + return "GeoOxmEntityDescriptor [" + + (geoLatName != null ? "geoLatName=" + geoLatName + ", " : "") + + (geoLongName != null ? "geoLongName=" + geoLongName + ", " : "") + + (entityName != null ? "entityName=" + entityName + ", " : "") + + (primaryKeyAttributeNames != null ? "primaryKeyAttributeNames=" + primaryKeyAttributeNames + : "") + + "]"; } - public void setTotalFound(Long totalFound) { - this.totalFound = totalFound; - } - public void setNumReturned(Long numReturned) { - this.numReturned = numReturned; - } + } diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityDescriptor.java b/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityDescriptor.java index 379cca2..3b3fabd 100644 --- a/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityDescriptor.java +++ b/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityDescriptor.java @@ -22,28 +22,18 @@ */ package org.onap.aai.sparky.config.oxm; +import java.util.ArrayList; import java.util.List; -import org.onap.aai.sparky.synchronizer.entity.SuggestionSearchEntity; - -/** - * The Class OxmEntityDescriptor. - */ public class OxmEntityDescriptor { - private String entityName; - - private List<String> primaryKeyAttributeName; - - private List<String> searchableAttributes; - - private CrossEntityReference crossEntityReference; + protected String entityName; - private String geoLatName; + protected List<String> primaryKeyAttributeNames; - private String geoLongName; - - private SuggestionSearchEntity suggestionSearchEntity; + public OxmEntityDescriptor() { + primaryKeyAttributeNames = new ArrayList<String>(); + } public String getEntityName() { return entityName; @@ -53,124 +43,24 @@ public class OxmEntityDescriptor { this.entityName = entityName; } - public List<String> getPrimaryKeyAttributeName() { - return primaryKeyAttributeName; - } - - public void setPrimaryKeyAttributeName(List<String> primaryKeyAttributeName) { - this.primaryKeyAttributeName = primaryKeyAttributeName; - } - - public List<String> getSearchableAttributes() { - return searchableAttributes; - } - - public void setSearchableAttributes(List<String> searchableAttributes) { - this.searchableAttributes = searchableAttributes; - } - - /** - * Checks for searchable attributes. - * - * @return true, if successful - */ - public boolean hasSearchableAttributes() { - - if (this.searchableAttributes == null) { - return false; - } - - if (this.searchableAttributes.size() > 0) { - return true; - } - - return false; - - } - - public CrossEntityReference getCrossEntityReference() { - return crossEntityReference; - } - - public void setCrossEntityReference(CrossEntityReference crossEntityReference) { - this.crossEntityReference = crossEntityReference; + public List<String> getPrimaryKeyAttributeNames() { + return primaryKeyAttributeNames; } - /** - * Checks for cross entity references. - * - * @return true, if successful - */ - public boolean hasCrossEntityReferences() { - if (this.crossEntityReference == null) { - return false; - } - if (!this.crossEntityReference.getReferenceAttributes().isEmpty()) { - return true; - } - return false; + public void setPrimaryKeyAttributeNames(List<String> primaryKeyAttributeNames) { + this.primaryKeyAttributeNames = primaryKeyAttributeNames; } - public String getGeoLatName() { - return geoLatName; - } - - public void setGeoLatName(String geoLatName) { - this.geoLatName = geoLatName; - } - - public String getGeoLongName() { - return geoLongName; - } - - public void setGeoLongName(String geoLongName) { - this.geoLongName = geoLongName; - } - - /** - * Checks for geo entity. - * - * @return true, if successful - */ - public boolean hasGeoEntity() { - - if (this.geoLongName != null && this.geoLatName != null) { - return true; - } - - return false; - - } - - public SuggestionSearchEntity getSuggestionSearchEntity() { - return this.suggestionSearchEntity; - } - - public void setSuggestionSearchEntity(SuggestionSearchEntity suggestionSearchEntity) { - this.suggestionSearchEntity = suggestionSearchEntity; - } - - /** - * Checks for non-null, populated SuggestionSearchEntity. - * - * @return true, if successful - */ - public boolean hasSuggestionSearchEntity() { - if (this.suggestionSearchEntity == null) { - return false; - } - if (!this.suggestionSearchEntity.getSuggestionConnectorWords().isEmpty()) { - return true; - } - return false; + public void addPrimaryKeyName(String name) { + primaryKeyAttributeNames.add(name); } @Override public String toString() { - return "OxmEntityDescriptor [entityName=" + entityName + ", primaryKeyAttributeName=" - + primaryKeyAttributeName + ", searchableAttributes=" + searchableAttributes - + ", crossEntityReference=" + crossEntityReference + ", geoLatName=" + geoLatName - + ", geoLongName=" + geoLongName + ", suggestionSearchEntity=" + suggestionSearchEntity + return "OxmEntityDescriptor [" + (entityName != null ? "entityName=" + entityName + ", " : "") + + (primaryKeyAttributeNames != null ? "primaryKeyAttributeNames=" + primaryKeyAttributeNames + : "") + "]"; } + } diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityLookup.java b/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityLookup.java new file mode 100644 index 0000000..168a4b1 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/OxmEntityLookup.java @@ -0,0 +1,151 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.oxm.mappings.Descriptor; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; + +public class OxmEntityLookup implements OxmModelProcessor { + + // TODO: kill singleton collaborator pattern + private static OxmEntityLookup instance; + + private Map<String, HashMap<String, String>> oxmModel; + + private Map<String, DynamicType> entityTypeLookup; + + private Map<String, OxmEntityDescriptor> entityDescriptors; + + + private OxmEntityLookup() { + oxmModel = new LinkedHashMap<String, HashMap<String, String>>(); + entityTypeLookup = new LinkedHashMap<String, DynamicType>(); + entityDescriptors = new HashMap<String, OxmEntityDescriptor>(); + } + + public synchronized static OxmEntityLookup getInstance() { + + /* + * I hate this method and I want it to go away. The singleton pattern is transitory, I want this + * class to be wired via a bean reference instead. But from the starting point, it would require + * fixing all the classes across the code base up front and I don't want this task to expand + * beyond just refactoring the OxmModelLoader. For now I'll keep the singleton pattern, but I + * really want to get rid of it once we are properly spring wired. + */ + + if (instance == null) { + instance = new OxmEntityLookup(); + } + + return instance; + } + + + @Override + public void processOxmModel(DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + + DynamicType entity = jaxbContext.getDynamicType(desc.getAlias()); + + LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>(); + + // Not all fields have key attributes + if (desc.getPrimaryKeyFields() != null) { + oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString() + .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "")); + } + + String entityName = desc.getDefaultRootElement(); + + entityTypeLookup.put(entityName, entity); + + // add entityName + oxmProperties.put("entityName", entityName); + + Map<String, String> properties = entity.getDescriptor().getProperties(); + + oxmModel.put(entityName, oxmProperties); + + } + + for (Entry<String, HashMap<String, String>> entityModel : oxmModel.entrySet()) { + HashMap<String, String> attribute = entityModel.getValue(); + OxmEntityDescriptor entity = new OxmEntityDescriptor(); + + entity.setEntityName(attribute.get("entityName")); + + if (attribute.containsKey("primaryKeyAttributeNames")) { + + entity.setPrimaryKeyAttributeNames( + Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); + + entityDescriptors.put(attribute.get("entityName"), entity); + } + } + + } + + public Map<String, HashMap<String, String>> getOxmModel() { + return oxmModel; + } + + public void setOxmModel(Map<String, HashMap<String, String>> oxmModel) { + this.oxmModel = oxmModel; + } + + public Map<String, DynamicType> getEntityTypeLookup() { + return entityTypeLookup; + } + + public void setEntityTypeLookup(Map<String, DynamicType> entityTypeLookup) { + this.entityTypeLookup = entityTypeLookup; + } + + public Map<String, OxmEntityDescriptor> getEntityDescriptors() { + return entityDescriptors; + } + + public void setEntityDescriptors(Map<String, OxmEntityDescriptor> entityDescriptors) { + this.entityDescriptors = entityDescriptors; + } + + public void addEntityDescriptor(String type, OxmEntityDescriptor descriptor) { + if (this.entityDescriptors != null) { + this.entityDescriptors.put(type, descriptor); + } + } + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoader.java b/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoader.java index 853a537..b953917 100644 --- a/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoader.java +++ b/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoader.java @@ -22,485 +22,163 @@ */ package org.onap.aai.sparky.config.oxm; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; +import java.util.HashSet; import java.util.Map; -import java.util.Map.Entry; -import java.util.Vector; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.eclipse.persistence.dynamic.DynamicType; -import org.eclipse.persistence.internal.oxm.mappings.Descriptor; import org.eclipse.persistence.jaxb.JAXBContextProperties; import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory; -import org.eclipse.persistence.mappings.DatabaseMapping; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.entity.SuggestionSearchEntity; -import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; -/** - * The Class OxmModelLoader. - */ public class OxmModelLoader { - private static OxmModelLoader instance; - private static final Logger LOG = LoggerFactory.getInstance().getLogger(OxmModelLoader.class); - private Map<String, HashMap<String, String>> oxmModel = - new LinkedHashMap<String, HashMap<String, String>>(); - - private Map<String, DynamicType> entityTypeLookup = new LinkedHashMap<String, DynamicType>(); - - private Map<String, HashMap<String, String>> searchableOxmModel = - new LinkedHashMap<String, HashMap<String, String>>(); - - private Map<String, HashMap<String, String>> crossReferenceEntityOxmModel = - new LinkedHashMap<String, HashMap<String, String>>(); - - private Map<String, HashMap<String, String>> geoEntityOxmModel = - new LinkedHashMap<String, HashMap<String, String>>(); - - private Map<String, HashMap<String, String>> suggestionSearchEntityOxmModel = - new LinkedHashMap<String, HashMap<String, String>>(); - - private Map<String, OxmEntityDescriptor> entityDescriptors = - new HashMap<String, OxmEntityDescriptor>(); - - private Map<String, OxmEntityDescriptor> searchableEntityDescriptors = - new HashMap<String, OxmEntityDescriptor>(); - - private Map<String, OxmEntityDescriptor> crossReferenceEntityDescriptors = - new HashMap<String, OxmEntityDescriptor>(); - - private Map<String, OxmEntityDescriptor> geoEntityDescriptors = - new HashMap<String, OxmEntityDescriptor>(); - - private Map<String, OxmEntityDescriptor> suggestionSearchEntityDescriptors = - new HashMap<String, OxmEntityDescriptor>(); - - public static OxmModelLoader getInstance() { - if (instance == null) { - instance = new OxmModelLoader(); - LOG.info(AaiUiMsgs.INITIALIZE_OXM_MODEL_LOADER); - instance.loadModels(); - } + /* + * The intent of this parameter is to be able to programmatically over-ride the latest AAI schema + * version discovered from the aai-schema jar file. This property is optional, but if set on the + * bean or by another class in the system, then it will override the spec version that is loaded. + * + * If the latestVersionOverride is greater than 0 then it will set the latest version to the + * specified version, and that stream will be returned if available. + */ - return instance; + protected int oxmApiVersionOverride; + protected Set<OxmModelProcessor> processors; + private int latestVersionNum = 0; - } + private final static Pattern p = Pattern.compile("aai_oxm_(v)(.*).xml"); - /** - * Instantiates a new oxm model loader. - */ public OxmModelLoader() { + this(-1, new HashSet<OxmModelProcessor>()); + } + public OxmModelLoader(int apiVersionOverride, Set<OxmModelProcessor> oxmModelProcessors) { + this.oxmApiVersionOverride = apiVersionOverride; + this.processors = oxmModelProcessors; } - /** - * Load models. - */ - private void loadModels() { - // find latest version of OXM file in folder - String version = findLatestOxmVersion(); - if (version == null) { - LOG.error(AaiUiMsgs.OXM_FILE_NOT_FOUND, TierSupportUiConstants.CONFIG_OXM_LOCATION); - return; + protected synchronized Map<Integer, InputStream> getStreamHandlesForOxmFromResource() { + Map<Integer, InputStream> listOfOxmFiles = new HashMap<Integer, InputStream>(); + ClassLoader oxmClassLoader = OxmModelLoader.class.getClassLoader(); + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(oxmClassLoader); + Resource[] resources = null; + try { + resources = resolver.getResources("classpath*:/oxm/aai_oxm*.xml"); + } catch (IOException ex) { + LOG.error(AaiUiMsgs.OXM_LOADING_ERROR, ex.getMessage()); } - // load the latest version based on file name - loadModel(version); + if (resources == null) { + LOG.error(AaiUiMsgs.OXM_LOADING_ERROR, "No OXM schema files found on classpath"); + } + + for (Resource resource : resources) { + Matcher m = p.matcher(resource.getFilename()); + if (m.matches()) { + try { + listOfOxmFiles.put(new Integer(m.group(2)), resource.getInputStream()); + } catch (Exception e) { + LOG.error(AaiUiMsgs.OXM_LOADING_ERROR, resource.getFilename(), e.getMessage()); + } + } + } + return listOfOxmFiles; } /** - * Load model. - * - * @param version the version + * Load an oxm model. + * + * @param inputStream file handle for oxm */ - public void loadModel(String version) { - String fileName = loadOxmFileName(version); - - try (FileInputStream inputStream = new FileInputStream(new File(fileName))) { - Map<String, Object> properties = new HashMap<String, Object>(); - properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, inputStream); - + protected void loadModel(InputStream inputStream) { + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, inputStream); + try { final DynamicJAXBContext oxmContext = DynamicJAXBContextFactory .createContextFromOXM(Thread.currentThread().getContextClassLoader(), properties); + parseOxmContext(oxmContext); // populateSearchableOxmModel(); - LOG.info(AaiUiMsgs.OXM_LOAD_SUCCESS); - - } catch (FileNotFoundException fnf) { - LOG.info(AaiUiMsgs.OXM_READ_ERROR_NONVERBOSE); - LOG.error(AaiUiMsgs.OXM_READ_ERROR_VERBOSE, fileName); + LOG.info(AaiUiMsgs.OXM_LOAD_SUCCESS, String.valueOf(latestVersionNum)); } catch (Exception exc) { LOG.info(AaiUiMsgs.OXM_PARSE_ERROR_NONVERBOSE); - LOG.error(AaiUiMsgs.OXM_PARSE_ERROR_VERBOSE, fileName, exc.getMessage()); + LOG.error(AaiUiMsgs.OXM_PARSE_ERROR_VERBOSE, "OXM v" + latestVersionNum, exc.getMessage()); } } /** - * Parses the oxm context. - * - * @param oxmContext the oxm context + * Load the latest oxm model. */ - private void parseOxmContext(DynamicJAXBContext oxmContext) { - @SuppressWarnings("rawtypes") - List<Descriptor> descriptorsList = oxmContext.getXMLContext().getDescriptors(); - - for (@SuppressWarnings("rawtypes") - Descriptor desc : descriptorsList) { - - DynamicType entity = oxmContext.getDynamicType(desc.getAlias()); - - LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>(); - - // Not all fields have key attributes - if (desc.getPrimaryKeyFields() != null) { - oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString() - .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "")); - } - - String entityName = desc.getDefaultRootElement(); - - entityTypeLookup.put(entityName, entity); - - // add entityName - oxmProperties.put("entityName", entityName); - - Map<String, String> properties = entity.getDescriptor().getProperties(); - if (properties != null) { - for (Map.Entry<String, String> entry : properties.entrySet()) { - - if (entry.getKey().equalsIgnoreCase("searchable")) { - oxmProperties.put("searchableAttributes", entry.getValue()); - } else if (entry.getKey().equalsIgnoreCase("crossEntityReference")) { - oxmProperties.put("crossEntityReference", entry.getValue()); - } else if (entry.getKey().equalsIgnoreCase("geoLat")) { - if (entry.getValue().length() > 0) { - oxmProperties.put("geoLat", entry.getValue()); - } - } else if (entry.getKey().equalsIgnoreCase("geoLong")) { - if (entry.getValue().length() > 0) { - oxmProperties.put("geoLong", entry.getValue()); - } - } else if (entry.getKey().equalsIgnoreCase("containsSuggestibleProps")) { - - oxmProperties.put("containsSuggestibleProps", "true"); - - Vector<DatabaseMapping> descriptorMaps = entity.getDescriptor().getMappings(); - List<String> listOfSuggestableAttributes = new ArrayList<String>(); - - for (DatabaseMapping descMap : descriptorMaps) { - if (descMap.isAbstractDirectMapping()) { - - if (descMap.getProperties().get("suggestibleOnSearch") != null) { - String suggestableOnSearchString = - String.valueOf(descMap.getProperties().get("suggestibleOnSearch")); - - boolean isSuggestibleOnSearch = Boolean.valueOf(suggestableOnSearchString); - - if (isSuggestibleOnSearch) { - /* Grab attribute types for suggestion */ - String attributeName = - descMap.getField().getName().replaceAll("/text\\(\\)", ""); - listOfSuggestableAttributes.add(attributeName); - - if (descMap.getProperties().get("suggestionVerbs") != null) { - String suggestionVerbsString = - String.valueOf(descMap.getProperties().get("suggestionVerbs")); - - oxmProperties.put("suggestionVerbs", suggestionVerbsString); - } - } - } - } - } - if (!listOfSuggestableAttributes.isEmpty()) { - oxmProperties.put("suggestibleAttributes", - String.join(",", listOfSuggestableAttributes)); - } - } else if (entry.getKey().equalsIgnoreCase("suggestionAliases")) { - oxmProperties.put("suggestionAliases", entry.getValue()); - } - } - } - - oxmModel.put(entityName, oxmProperties); - - // Add all searchable entity types for reserve lookup - if (oxmProperties.containsKey("searchableAttributes")) { - searchableOxmModel.put(entityName, oxmProperties); - } + public synchronized void loadLatestOxmModel() { - if (oxmProperties.containsKey("crossEntityReference")) { - crossReferenceEntityOxmModel.put(entityName, oxmProperties); - } - - if (oxmProperties.containsKey("geoLat") && oxmProperties.containsKey("geoLong")) { - geoEntityOxmModel.put(entityName, oxmProperties); - } - - if (oxmProperties.containsKey("containsSuggestibleProps")) { - suggestionSearchEntityOxmModel.put(entityName, oxmProperties); - } - } - - for (Entry<String, HashMap<String, String>> entityModel : oxmModel.entrySet()) { - HashMap<String, String> attribute = entityModel.getValue(); - OxmEntityDescriptor entity = new OxmEntityDescriptor(); - entity.setEntityName(attribute.get("entityName")); - if (attribute.containsKey("primaryKeyAttributeNames")) { - - entity.setPrimaryKeyAttributeName( - Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); - if (attribute.containsKey("searchableAttributes")) { - entity.setSearchableAttributes( - Arrays.asList(attribute.get("searchableAttributes").split(","))); - } else if (attribute.containsKey("crossEntityReference")) { - List<String> crossEntityRefTokens = - Arrays.asList(attribute.get("crossEntityReference").split(",")); - - if (crossEntityRefTokens.size() >= 2) { - CrossEntityReference entityRef = new CrossEntityReference(); - entityRef.setTargetEntityType(crossEntityRefTokens.get(0)); - - for (int i = 1; i < crossEntityRefTokens.size(); i++) { - entityRef.addReferenceAttribute(crossEntityRefTokens.get(i)); - } - - entity.setCrossEntityReference(entityRef); - } else { - LOG.error(AaiUiMsgs.OXM_PROP_DEF_ERR_CROSS_ENTITY_REF, attribute.get("entityName"), - attribute.get("crossEntityReference")); - } - } - - if (attribute.containsKey("geoLat") || attribute.containsKey("geoLong")) { - entity.setGeoLatName(attribute.get("geoLat")); - entity.setGeoLongName(attribute.get("geoLong")); - } - - if (attribute.containsKey("suggestionVerbs")) { - String entityName = attribute.get("entityName"); - SuggestionSearchEntity suggestionSearchEntity = new SuggestionSearchEntity(this); - suggestionSearchEntity.setEntityType(entityName); - - entity.setSuggestionSearchEntity(suggestionSearchEntity); - } - - entityDescriptors.put(attribute.get("entityName"), entity); - } - } + LOG.info(AaiUiMsgs.INITIALIZE_OXM_MODEL_LOADER); - - for (Entry<String, HashMap<String, String>> searchableModel : searchableOxmModel.entrySet()) { - HashMap<String, String> attribute = searchableModel.getValue(); - OxmEntityDescriptor entity = new OxmEntityDescriptor(); - entity.setEntityName(attribute.get("entityName")); - entity.setPrimaryKeyAttributeName( - Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); - entity - .setSearchableAttributes(Arrays.asList(attribute.get("searchableAttributes").split(","))); - searchableEntityDescriptors.put(attribute.get("entityName"), entity); - } - - for (Entry<String, HashMap<String, String>> geoEntityModel : geoEntityOxmModel.entrySet()) { - HashMap<String, String> attribute = geoEntityModel.getValue(); - OxmEntityDescriptor entity = new OxmEntityDescriptor(); - entity.setEntityName(attribute.get("entityName")); - entity.setPrimaryKeyAttributeName( - Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); - entity.setGeoLatName(attribute.get("geoLat")); - entity.setGeoLongName(attribute.get("geoLong")); - geoEntityDescriptors.put(attribute.get("entityName"), entity); + // find handles for available oxm models + final Map<Integer, InputStream> listOfOxmStreams = getStreamHandlesForOxmFromResource(); + if (listOfOxmStreams.isEmpty()) { + LOG.error(AaiUiMsgs.OXM_FILE_NOT_FOUND); + return; } - for (Entry<String, HashMap<String, String>> crossRefModel : crossReferenceEntityOxmModel - .entrySet()) { - HashMap<String, String> attribute = crossRefModel.getValue(); - OxmEntityDescriptor entity = new OxmEntityDescriptor(); - entity.setEntityName(attribute.get("entityName")); - entity.setPrimaryKeyAttributeName( - Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); - + InputStream stream = null; - List<String> crossEntityRefTokens = - Arrays.asList(attribute.get("crossEntityReference").split(",")); - - if (crossEntityRefTokens.size() >= 2) { - CrossEntityReference entityRef = new CrossEntityReference(); - entityRef.setTargetEntityType(crossEntityRefTokens.get(0)); + if (oxmApiVersionOverride > 0) { + latestVersionNum = oxmApiVersionOverride; + LOG.warn(AaiUiMsgs.WARN_GENERIC, "Overriding AAI Schema with version = " + latestVersionNum); + stream = listOfOxmStreams.get(latestVersionNum); + } else { - for (int i = 1; i < crossEntityRefTokens.size(); i++) { - entityRef.addReferenceAttribute(crossEntityRefTokens.get(i)); + for (Integer key : listOfOxmStreams.keySet()) { + if (key.intValue() > latestVersionNum) { + latestVersionNum = key.intValue(); + stream = listOfOxmStreams.get(key); } - - entity.setCrossEntityReference(entityRef); } - crossReferenceEntityDescriptors.put(attribute.get("entityName"), entity); } - for (Entry<String, HashMap<String, String>> suggestionEntityModel : suggestionSearchEntityOxmModel - .entrySet()) { - HashMap<String, String> attribute = suggestionEntityModel.getValue(); - - String entityName = attribute.get("entityName"); - SuggestionSearchEntity suggestionSearchEntity = new SuggestionSearchEntity(this); - suggestionSearchEntity.setEntityType(entityName); + // load the latest oxm file + loadModel(stream); - if (attribute.get("suggestionVerbs") != null) { - suggestionSearchEntity.setSuggestionConnectorWords( - Arrays.asList(attribute.get("suggestionVerbs").split(","))); - } - - if (attribute.get("suggestionAliases") != null) { - suggestionSearchEntity - .setSuggestionAliases(Arrays.asList(attribute.get("suggestionAliases").split(","))); - } - - if (attribute.get("suggestibleAttributes") != null) { - suggestionSearchEntity.setSuggestionPropertyTypes( - Arrays.asList(attribute.get("suggestibleAttributes").split(","))); - } - - OxmEntityDescriptor entity = new OxmEntityDescriptor(); - entity.setSuggestionSearchEntity(suggestionSearchEntity); - entity.setEntityName(entityName); - - if (attribute.get("primaryKeyAttributeNames") != null) { - entity.setPrimaryKeyAttributeName( - Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); - } - - suggestionSearchEntityDescriptors.put(entityName, entity); - } } - /** - * Find latest oxm version. - * - * @return the string - */ - public String findLatestOxmVersion() { - File[] listOxmFiles = loadOxmFolder().listFiles(); - - if (listOxmFiles == null) { - return null; - } - - Integer latestVersion = -1; - - Pattern oxmFileNamePattern = Pattern.compile("^aai_oxm_v([0-9]*).xml"); - - for (File file : listOxmFiles) { - if (file.isFile()) { - String fileName = file.getName(); - Matcher matcher = oxmFileNamePattern.matcher(fileName); - if (matcher.matches()) { - if (latestVersion <= Integer.parseInt(matcher.group(1))) { - latestVersion = Integer.parseInt(matcher.group(1)); - } - } - } - - } - if (latestVersion != -1) { - return "v" + latestVersion.toString(); - } else { - return null; - } - + public int getLatestVersionNum() { + return latestVersionNum; } - /** - * Load oxm folder. - * - * @return the file - */ - public File loadOxmFolder() { - return new File(TierSupportUiConstants.CONFIG_OXM_LOCATION); + public void setLatestVersionNum(int latestVersionNum) { + this.latestVersionNum = latestVersionNum; } /** - * Load oxm file name. + * Parses the oxm context. * - * @param version the version - * @return the string - */ - public String loadOxmFileName(String version) { - return new String(TierSupportUiConstants.CONFIG_OXM_LOCATION + "aai_oxm_" + version + ".xml"); - } - - /* - * Get the original representation of the OXM Model - */ - public Map<String, HashMap<String, String>> getOxmModel() { - return oxmModel; - } - - /* - * Get the searchable raw map entity types + * @param oxmContext the oxm context */ - public Map<String, HashMap<String, String>> getSearchableOxmModel() { - return searchableOxmModel; - } - - public Map<String, HashMap<String, String>> getCrossReferenceEntityOxmModel() { - return crossReferenceEntityOxmModel; - } - - public Map<String, OxmEntityDescriptor> getEntityDescriptors() { - return entityDescriptors; - } + private void parseOxmContext(DynamicJAXBContext oxmContext) { - /** - * Gets the entity descriptor. - * - * @param type the type - * @return the entity descriptor - */ - public OxmEntityDescriptor getEntityDescriptor(String type) { - return entityDescriptors.get(type); - } + if (processors != null && processors.size() > 0) { - public Map<String, OxmEntityDescriptor> getSearchableEntityDescriptors() { - return searchableEntityDescriptors; - } + for (OxmModelProcessor processor : processors) { - /** - * Gets the searchable entity descriptor. - * - * @param entityType the entity type - * @return the searchable entity descriptor - */ - public OxmEntityDescriptor getSearchableEntityDescriptor(String entityType) { - return searchableEntityDescriptors.get(entityType); - } + processor.processOxmModel(oxmContext); - public Map<String, OxmEntityDescriptor> getCrossReferenceEntityDescriptors() { - return crossReferenceEntityDescriptors; - } + } - public Map<String, OxmEntityDescriptor> getGeoEntityDescriptors() { - return geoEntityDescriptors; - } + } - public Map<String, OxmEntityDescriptor> getSuggestionSearchEntityDescriptors() { - return suggestionSearchEntityDescriptors; } } diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoaderFilter.java b/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoaderFilter.java deleted file mode 100644 index 0ddf80a..0000000 --- a/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelLoaderFilter.java +++ /dev/null @@ -1,90 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.config.oxm; - -import java.io.IOException; -import java.net.UnknownHostException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.mdc.MdcContext; - -/** - * The Class OxmModelLoaderFilter. - */ -public class OxmModelLoaderFilter implements Filter { - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, - * javax.servlet.FilterChain) - */ - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - - /* - * However, we will setup the filtermap with a url that should never get it, so we shouldn't - * ever be in here. - */ - - chain.doFilter(request, response); - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) - */ - @Override - public void init(FilterConfig filterConfig) throws ServletException { - String txnID = NodeUtils.getRandomTxnId(); - MdcContext.initialize(txnID, "OxmModelLoaderFilter", "", "Init", ""); - - try { - OxmModelLoader.getInstance(); - } catch (Exception exc) { - throw new ServletException("Caught an exception while initializing OXM model loader filter", - exc); - } - - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#destroy() - */ - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - -} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelProcessor.java b/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelProcessor.java new file mode 100644 index 0000000..b8e7c6f --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/OxmModelProcessor.java @@ -0,0 +1,31 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; + +public interface OxmModelProcessor { + + public void processOxmModel(DynamicJAXBContext jaxbContext); + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/SearchableEntityLookup.java b/src/main/java/org/onap/aai/sparky/config/oxm/SearchableEntityLookup.java new file mode 100644 index 0000000..d8a27ac --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/SearchableEntityLookup.java @@ -0,0 +1,138 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.oxm.mappings.Descriptor; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; + +public class SearchableEntityLookup implements OxmModelProcessor { + + // TODO: kill singleton collaborator pattern + private static SearchableEntityLookup instance; + + private Map<String, HashMap<String, String>> searchableOxmModel; + private Map<String, SearchableOxmEntityDescriptor> searchableEntityDescriptors; + + private SearchableEntityLookup() { + searchableOxmModel = new LinkedHashMap<String, HashMap<String, String>>(); + searchableEntityDescriptors = new HashMap<String, SearchableOxmEntityDescriptor>(); + } + + public synchronized static SearchableEntityLookup getInstance() { + + /* + * I hate this method and I want it to go away. The singleton pattern is transitory, I want this + * class to be wired via a bean reference instead. But from the starting point, it would require + * fixing all the classes across the code base up front and I don't want this task to expand + * beyond just refactoring the OxmModelLoader. For now I'll keep the singleton pattern, but I + * really want to get rid of it once we are properly spring wired. + */ + + if (instance == null) { + instance = new SearchableEntityLookup(); + } + + return instance; + } + + + @Override + public void processOxmModel(DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + + DynamicType entity = jaxbContext.getDynamicType(desc.getAlias()); + + LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>(); + + // Not all fields have key attributes + if (desc.getPrimaryKeyFields() != null) { + oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString() + .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "")); + } + + String entityName = desc.getDefaultRootElement(); + + // add entityName + oxmProperties.put("entityName", entityName); + + Map<String, String> properties = entity.getDescriptor().getProperties(); + if (properties != null) { + for (Map.Entry<String, String> entry : properties.entrySet()) { + + if (entry.getKey().equalsIgnoreCase("searchable")) { + oxmProperties.put("searchableAttributes", entry.getValue()); + } + } + } + + // Add all searchable entity types for reserve lookup + if (oxmProperties.containsKey("searchableAttributes")) { + searchableOxmModel.put(entityName, oxmProperties); + } + + } + + for (Entry<String, HashMap<String, String>> searchableModel : searchableOxmModel.entrySet()) { + HashMap<String, String> attribute = searchableModel.getValue(); + SearchableOxmEntityDescriptor entity = new SearchableOxmEntityDescriptor(); + entity.setEntityName(attribute.get("entityName")); + entity.setPrimaryKeyAttributeNames( + Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); + entity + .setSearchableAttributes(Arrays.asList(attribute.get("searchableAttributes").split(","))); + searchableEntityDescriptors.put(attribute.get("entityName"), entity); + } + + } + + public Map<String, HashMap<String, String>> getSearchableOxmModel() { + return searchableOxmModel; + } + + public void setSearchableOxmModel(Map<String, HashMap<String, String>> searchableOxmModel) { + this.searchableOxmModel = searchableOxmModel; + } + + public Map<String, SearchableOxmEntityDescriptor> getSearchableEntityDescriptors() { + return searchableEntityDescriptors; + } + + public void setSearchableEntityDescriptors( + Map<String, SearchableOxmEntityDescriptor> searchableEntityDescriptors) { + this.searchableEntityDescriptors = searchableEntityDescriptors; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/SearchableOxmEntityDescriptor.java b/src/main/java/org/onap/aai/sparky/config/oxm/SearchableOxmEntityDescriptor.java new file mode 100644 index 0000000..cdd5ad0 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/SearchableOxmEntityDescriptor.java @@ -0,0 +1,73 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import java.util.List; + +public class SearchableOxmEntityDescriptor extends OxmEntityDescriptor { + + protected List<String> searchableAttributes; + + public List<String> getSearchableAttributes() { + return searchableAttributes; + } + + public void setSearchableAttributes(List<String> searchableAttributes) { + this.searchableAttributes = searchableAttributes; + } + + public void addSearchableAttribute(String attributeName) { + searchableAttributes.add(attributeName); + } + + /** + * Checks for searchable attributes. + * + * @return true, if successful + */ + public boolean hasSearchableAttributes() { + + if (this.searchableAttributes == null) { + return false; + } + + if (this.searchableAttributes.size() > 0) { + return true; + } + + return false; + + } + + @Override + public String toString() { + return "SearchableOxmEntityDescriptor [" + + (searchableAttributes != null ? "searchableAttributes=" + searchableAttributes + ", " + : "") + + (entityName != null ? "entityName=" + entityName + ", " : "") + + (primaryKeyAttributeNames != null ? "primaryKeyAttributeNames=" + primaryKeyAttributeNames + : "") + + "]"; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/SuggestionEntityDescriptor.java b/src/main/java/org/onap/aai/sparky/config/oxm/SuggestionEntityDescriptor.java new file mode 100644 index 0000000..c72068a --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/SuggestionEntityDescriptor.java @@ -0,0 +1,52 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import org.onap.aai.sparky.sync.entity.SuggestionSearchEntity; + +public class SuggestionEntityDescriptor extends OxmEntityDescriptor { + + protected SuggestionSearchEntity suggestionSearchEntity; + + public SuggestionSearchEntity getSuggestionSearchEntity() { + return suggestionSearchEntity; + } + + public void setSuggestionSearchEntity(SuggestionSearchEntity suggestionSearchEntity) { + this.suggestionSearchEntity = suggestionSearchEntity; + } + + @Override + public String toString() { + return "SuggestionEntityDescriptor [" + + (suggestionSearchEntity != null + ? "suggestionSearchEntity=" + suggestionSearchEntity + ", " : "") + + (entityName != null ? "entityName=" + entityName + ", " : "") + + (primaryKeyAttributeNames != null ? "primaryKeyAttributeNames=" + primaryKeyAttributeNames + : "") + + "]"; + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/config/oxm/SuggestionEntityLookup.java b/src/main/java/org/onap/aai/sparky/config/oxm/SuggestionEntityLookup.java new file mode 100644 index 0000000..758ae60 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/config/oxm/SuggestionEntityLookup.java @@ -0,0 +1,197 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.config.oxm; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Vector; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.oxm.mappings.Descriptor; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; +import org.eclipse.persistence.mappings.DatabaseMapping; +import org.onap.aai.sparky.sync.entity.SuggestionSearchEntity; + +public class SuggestionEntityLookup implements OxmModelProcessor { + + // TODO: kill singleton collaborator pattern + private static SuggestionEntityLookup instance; + + private Map<String, HashMap<String, String>> suggestionSearchEntityOxmModel; + private Map<String, SuggestionEntityDescriptor> suggestionSearchEntityDescriptors; + + private SuggestionEntityLookup() { + suggestionSearchEntityOxmModel = new LinkedHashMap<String, HashMap<String, String>>(); + suggestionSearchEntityDescriptors = new HashMap<String, SuggestionEntityDescriptor>(); + } + + public synchronized static SuggestionEntityLookup getInstance() { + + /* + * I hate this method and I want it to go away. The singleton pattern is transitory, I want this + * class to be wired via a bean reference instead. But from the starting point, it would require + * fixing all the classes across the code base up front and I don't want this task to expand + * beyond just refactoring the OxmModelLoader. For now I'll keep the singleton pattern, but I + * really want to get rid of it once we are properly spring wired. + */ + + if (instance == null) { + instance = new SuggestionEntityLookup(); + } + + return instance; + } + + + @Override + public void processOxmModel(DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + + DynamicType entity = jaxbContext.getDynamicType(desc.getAlias()); + + LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>(); + + // Not all fields have key attributes + if (desc.getPrimaryKeyFields() != null) { + oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString() + .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", "")); + } + + String entityName = desc.getDefaultRootElement(); + + // add entityName + oxmProperties.put("entityName", entityName); + + Map<String, String> properties = entity.getDescriptor().getProperties(); + if (properties != null) { + for (Map.Entry<String, String> entry : properties.entrySet()) { + + + if (entry.getKey().equalsIgnoreCase("containsSuggestibleProps")) { + + oxmProperties.put("containsSuggestibleProps", "true"); + + Vector<DatabaseMapping> descriptorMaps = entity.getDescriptor().getMappings(); + List<String> listOfSuggestableAttributes = new ArrayList<String>(); + + for (DatabaseMapping descMap : descriptorMaps) { + if (descMap.isAbstractDirectMapping()) { + + if (descMap.getProperties().get("suggestibleOnSearch") != null) { + String suggestableOnSearchString = + String.valueOf(descMap.getProperties().get("suggestibleOnSearch")); + + boolean isSuggestibleOnSearch = Boolean.valueOf(suggestableOnSearchString); + + if (isSuggestibleOnSearch) { + /* Grab attribute types for suggestion */ + String attributeName = + descMap.getField().getName().replaceAll("/text\\(\\)", ""); + listOfSuggestableAttributes.add(attributeName); + + if (descMap.getProperties().get("suggestionVerbs") != null) { + String suggestionVerbsString = + String.valueOf(descMap.getProperties().get("suggestionVerbs")); + + oxmProperties.put("suggestionVerbs", suggestionVerbsString); + } + } + } + } + } + + if (!listOfSuggestableAttributes.isEmpty()) { + oxmProperties.put("suggestibleAttributes", + String.join(",", listOfSuggestableAttributes)); + } + } else if (entry.getKey().equalsIgnoreCase("suggestionAliases")) { + oxmProperties.put("suggestionAliases", entry.getValue()); + } + } + } + + if (oxmProperties.containsKey("containsSuggestibleProps")) { + suggestionSearchEntityOxmModel.put(entityName, oxmProperties); + } + } + + for (Entry<String, HashMap<String, String>> suggestionEntityModel : suggestionSearchEntityOxmModel + .entrySet()) { + HashMap<String, String> attribute = suggestionEntityModel.getValue(); + + String entityName = attribute.get("entityName"); + SuggestionSearchEntity suggestionSearchEntity = new SuggestionSearchEntity(this); + suggestionSearchEntity.setEntityType(entityName); + + if (attribute.get("suggestionAliases") != null) { + suggestionSearchEntity + .setSuggestionAliases(Arrays.asList(attribute.get("suggestionAliases").split(","))); + } + + if (attribute.get("suggestibleAttributes") != null) { + suggestionSearchEntity.setSuggestionPropertyTypes( + Arrays.asList(attribute.get("suggestibleAttributes").split(","))); + } + + SuggestionEntityDescriptor entity = new SuggestionEntityDescriptor(); + entity.setSuggestionSearchEntity(suggestionSearchEntity); + entity.setEntityName(entityName); + + if (attribute.get("primaryKeyAttributeNames") != null) { + entity.setPrimaryKeyAttributeNames( + Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(","))); + } + + suggestionSearchEntityDescriptors.put(entityName, entity); + } + } + + public Map<String, HashMap<String, String>> getSuggestionSearchEntityOxmModel() { + return suggestionSearchEntityOxmModel; + } + + public void setSuggestionSearchEntityOxmModel( + Map<String, HashMap<String, String>> suggestionSearchEntityOxmModel) { + this.suggestionSearchEntityOxmModel = suggestionSearchEntityOxmModel; + } + + public Map<String, SuggestionEntityDescriptor> getSuggestionSearchEntityDescriptors() { + return suggestionSearchEntityDescriptors; + } + + public void setSuggestionSearchEntityDescriptors( + Map<String, SuggestionEntityDescriptor> suggestionSearchEntityDescriptors) { + this.suggestionSearchEntityDescriptors = suggestionSearchEntityDescriptors; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/CrossEntityReferenceSynchronizer.java b/src/main/java/org/onap/aai/sparky/crossentityreference/sync/CrossEntityReferenceSynchronizer.java index 8328627..39ee8c5 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/CrossEntityReferenceSynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/crossentityreference/sync/CrossEntityReferenceSynchronizer.java @@ -20,13 +20,11 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.crossentityreference.sync; import static java.util.concurrent.CompletableFuture.supplyAsync; import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Deque; @@ -38,30 +36,39 @@ import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ExecutorService; import java.util.function.Supplier; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.CrossEntityReference; +import org.onap.aai.sparky.config.oxm.CrossEntityReferenceDescriptor; +import org.onap.aai.sparky.config.oxm.CrossEntityReferenceLookup; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.config.oxm.SearchableEntityLookup; +import org.onap.aai.sparky.config.oxm.SearchableOxmEntityDescriptor; import org.onap.aai.sparky.dal.NetworkTransaction; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.config.SynchronizerConfiguration; -import org.onap.aai.sparky.synchronizer.entity.IndexableCrossEntityReference; -import org.onap.aai.sparky.synchronizer.entity.MergableEntity; -import org.onap.aai.sparky.synchronizer.entity.SelfLinkDescriptor; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.synchronizer.task.PerformActiveInventoryRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchPut; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchUpdate; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.SynchronizerConstants; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.entity.IndexableCrossEntityReference; +import org.onap.aai.sparky.sync.entity.MergableEntity; +import org.onap.aai.sparky.sync.entity.SelfLinkDescriptor; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.task.PerformActiveInventoryRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchPut; +import org.onap.aai.sparky.sync.task.PerformElasticSearchRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchUpdate; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.slf4j.MDC; -import org.onap.aai.cl.mdc.MdcContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectReader; @@ -105,12 +112,13 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer LoggerFactory.getInstance().getLogger(CrossEntityReferenceSynchronizer.class); private static final String SERVICE_INSTANCE = "service-instance"; + private Deque<SelfLinkDescriptor> selflinks; private Deque<RetryCrossEntitySyncContainer> retryQueue; private Map<String, Integer> retryLimitTracker; private boolean isAllWorkEnumerated; protected ExecutorService esPutExecutor; - protected ActiveInventoryConfig aaiConfig; + /** * Instantiates a new cross entity reference synchronizer. @@ -118,27 +126,29 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer * @param indexName the index name * @throws Exception the exception */ - public CrossEntityReferenceSynchronizer(String indexName, ActiveInventoryConfig aaiConfig) - throws Exception { - super(LOG, "CERS", 2, 5, 5, indexName); + public CrossEntityReferenceSynchronizer(ElasticSearchSchemaConfig schemaConfig, + int internalSyncWorkers, int aaiWorkers, int esWorkers, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(LOG, "CERS", internalSyncWorkers, aaiWorkers, esWorkers, schemaConfig.getIndexName(), + aaiStatConfig, esStatConfig); this.selflinks = new ConcurrentLinkedDeque<SelfLinkDescriptor>(); this.retryQueue = new ConcurrentLinkedDeque<RetryCrossEntitySyncContainer>(); this.retryLimitTracker = new ConcurrentHashMap<String, Integer>(); this.synchronizerName = "Cross Reference Entity Synchronizer"; this.isAllWorkEnumerated = false; this.esPutExecutor = NodeUtils.createNamedExecutor("CERS-ES-PUT", 5, LOG); - this.aaiEntityStats.initializeCountersFromOxmEntityDescriptors( - oxmModelLoader.getCrossReferenceEntityDescriptors()); - this.esEntityStats.initializeCountersFromOxmEntityDescriptors( - oxmModelLoader.getCrossReferenceEntityDescriptors()); - this.aaiConfig = aaiConfig; + this.aaiEntityStats.intializeEntityCounters( + CrossEntityReferenceLookup.getInstance().getCrossReferenceEntityDescriptors().keySet()); + + this.esEntityStats.intializeEntityCounters( + CrossEntityReferenceLookup.getInstance().getCrossReferenceEntityDescriptors().keySet()); this.syncDurationInMs = -1; } /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#doSync() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#doSync() */ @Override public OperationState doSync() { @@ -164,7 +174,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) */ @Override public String getStatReport(boolean showFinalReport) { @@ -175,7 +185,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#shutdown() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#shutdown() */ @Override public void shutdown() { @@ -200,8 +210,8 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer */ private OperationState launchSyncFlow() { final Map<String, String> contextMap = MDC.getCopyOfContextMap(); - Map<String, OxmEntityDescriptor> descriptorMap = - oxmModelLoader.getCrossReferenceEntityDescriptors(); + Map<String, CrossEntityReferenceDescriptor> descriptorMap = + CrossEntityReferenceLookup.getInstance().getCrossReferenceEntityDescriptors(); if (descriptorMap.isEmpty()) { LOG.error(AaiUiMsgs.ERROR_LOADING_OXM); @@ -229,7 +239,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer MDC.setContextMap(contextMap); OperationResult typeLinksResult = null; try { - typeLinksResult = aaiDataProvider.getSelfLinksByEntityType(key); + typeLinksResult = aaiAdapter.getSelfLinksByEntityType(key); aaiWorkOnHand.decrementAndGet(); processEntityTypeSelfLinks(typeLinksResult); } catch (Exception exc) { @@ -286,11 +296,12 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer SelfLinkDescriptor linkDescriptor = selflinks.poll(); aaiWorkOnHand.decrementAndGet(); - OxmEntityDescriptor descriptor = null; + CrossEntityReferenceDescriptor descriptor = null; if (linkDescriptor.getSelfLink() != null && linkDescriptor.getEntityType() != null) { - descriptor = oxmModelLoader.getEntityDescriptor(linkDescriptor.getEntityType()); + descriptor = CrossEntityReferenceLookup.getInstance().getCrossReferenceEntityDescriptors() + .get(linkDescriptor.getEntityType()); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, linkDescriptor.getEntityType()); @@ -302,13 +313,14 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer NetworkTransaction txn = new NetworkTransaction(); txn.setDescriptor(descriptor); - txn.setLink(linkDescriptor.getSelfLink() + linkDescriptor.getDepthModifier()); + txn.setLink(linkDescriptor.getSelfLink()); + txn.setQueryParameters(linkDescriptor.getDepthModifier()); txn.setOperationType(HttpMethod.GET); txn.setEntityType(linkDescriptor.getEntityType()); aaiWorkOnHand.incrementAndGet(); - supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiDataProvider), aaiExecutor) + supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiAdapter), aaiExecutor) .whenComplete((result, error) -> { aaiWorkOnHand.decrementAndGet(); @@ -345,15 +357,14 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer try { rootNode = mapper.readTree(jsonResult); } catch (IOException exc) { - String message = "Could not deserialize JSON (representing operation result) as node tree. " - + "Operation result = " + jsonResult + ". " + exc.getLocalizedMessage(); - LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, message); - return; + // TODO // TODO -> LOG, waht should be logged here? } JsonNode resultData = rootNode.get("result-data"); ArrayNode resultDataArrayNode = null; + CrossEntityReferenceLookup cerLookup = CrossEntityReferenceLookup.getInstance(); + if (resultData.isArray()) { resultDataArrayNode = (ArrayNode) resultData; @@ -366,10 +377,10 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer final String resourceType = NodeUtils.getNodeFieldAsText(element, "resource-type"); final String resourceLink = NodeUtils.getNodeFieldAsText(element, "resource-link"); - OxmEntityDescriptor descriptor = null; + CrossEntityReferenceDescriptor descriptor = null; if (resourceType != null && resourceLink != null) { - descriptor = oxmModelLoader.getEntityDescriptor(resourceType); + descriptor = cerLookup.getCrossReferenceEntityDescriptors().get(resourceType); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, resourceType); @@ -378,7 +389,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer } if (descriptor.hasCrossEntityReferences()) { selflinks.add(new SelfLinkDescriptor(resourceLink, - SynchronizerConfiguration.DEPTH_ALL_MODIFIER, resourceType)); + SynchronizerConstants.DEPTH_ALL_MODIFIER, resourceType)); } } } @@ -398,13 +409,14 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer */ private String determineEntityQueryString(String entityType, JsonNode entityJsonNode) { - OxmEntityDescriptor entityDescriptor = oxmModelLoader.getEntityDescriptor(entityType); + OxmEntityDescriptor entityDescriptor = + OxmEntityLookup.getInstance().getEntityDescriptors().get(entityType); String queryString = null; if (entityDescriptor != null) { - final List<String> primaryKeyNames = entityDescriptor.getPrimaryKeyAttributeName(); + final List<String> primaryKeyNames = entityDescriptor.getPrimaryKeyAttributeNames(); final List<String> keyValues = new ArrayList<String>(); NodeUtils.extractFieldValuesFromObject(entityJsonNode, primaryKeyNames, keyValues); @@ -430,7 +442,10 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer return; } - if (txn.getDescriptor().hasCrossEntityReferences()) { + CrossEntityReferenceDescriptor cerDescriptor = CrossEntityReferenceLookup.getInstance() + .getCrossReferenceEntityDescriptors().get(txn.getDescriptor().getEntityName()); + + if (cerDescriptor != null && cerDescriptor.hasCrossEntityReferences()) { final String jsonResult = txn.getOperationResult().getResult(); @@ -448,182 +463,207 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer * <li>Rinse and repeat. */ - OxmEntityDescriptor parentEntityDescriptor = - oxmModelLoader.getEntityDescriptor(txn.getEntityType()); + CrossEntityReference cerDefinition = cerDescriptor.getCrossEntityReference(); + + if (cerDefinition != null) { + JsonNode convertedNode = null; + try { + convertedNode = + NodeUtils.convertJsonStrToJsonNode(txn.getOperationResult().getResult()); + + final String parentEntityQueryString = + determineEntityQueryString(txn.getEntityType(), convertedNode); + + List<String> extractedParentEntityAttributeValues = new ArrayList<String>(); + + NodeUtils.extractFieldValuesFromObject(convertedNode, + cerDefinition.getReferenceAttributes(), extractedParentEntityAttributeValues); + + List<JsonNode> nestedTargetEntityInstances = new ArrayList<JsonNode>(); + NodeUtils.extractObjectsByKey(convertedNode, cerDefinition.getTargetEntityType(), + nestedTargetEntityInstances); + + for (JsonNode targetEntityInstance : nestedTargetEntityInstances) { + + if (cerDescriptor != null) { + + String childEntityType = cerDefinition.getTargetEntityType(); + + List<String> childPrimaryKeyNames = cerDescriptor.getPrimaryKeyAttributeNames(); + + List<String> childKeyValues = new ArrayList<String>(); + NodeUtils.extractFieldValuesFromObject(targetEntityInstance, childPrimaryKeyNames, + childKeyValues); + + String childEntityQueryKeyString = + childEntityType + "." + NodeUtils.concatArray(childPrimaryKeyNames, "/") + ":" + + NodeUtils.concatArray(childKeyValues); + + /** + * Build generic-query to query child instance self-link from AAI + */ + List<String> orderedQueryKeyParams = new ArrayList<String>(); + + /** + * At present, there is an issue with resolving the self-link using the + * generic-query with nothing more than the service-instance identifier and the + * service-subscription. There is another level of detail we don't have access to + * unless we parse it out of the service-subscription self-link, which is a coupling + * I would like to avoid. Fortunately, there is a workaround, but only for + * service-instances, which is presently our only use-case for the + * cross-entity-reference in R1707. Going forwards hopefully there will be other + * ways to resolve a child self-link using parental embedded meta data that we don't + * currently have. + * + * The work-around with the service-instance entity-type is that it's possible to + * request the self-link using only the service-instance-id because of a historical + * AAI functional query requirement that it be possible to query a service-instance + * only by it's service-instance-id. This entity type is the only one in the system + * that can be queried this way which makes it a very limited workaround, but good + * enough for the current release. + */ + + if (SERVICE_INSTANCE.equals(childEntityType)) { + orderedQueryKeyParams.clear(); + orderedQueryKeyParams.add(childEntityQueryKeyString); + } else { + orderedQueryKeyParams.add(parentEntityQueryString); + orderedQueryKeyParams.add(childEntityQueryKeyString); + } - if (parentEntityDescriptor != null) { + String genericQueryStr = null; + try { + genericQueryStr = + aaiAdapter.getGenericQueryForSelfLink(childEntityType, orderedQueryKeyParams); - CrossEntityReference cerDefinition = parentEntityDescriptor.getCrossEntityReference(); + if (genericQueryStr != null) { + aaiWorkOnHand.incrementAndGet(); - if (cerDefinition != null) { - JsonNode convertedNode = null; - try { - convertedNode = - NodeUtils.convertJsonStrToJsonNode(txn.getOperationResult().getResult()); + OperationResult aaiQueryResult = aaiAdapter.queryActiveInventoryWithRetries( + genericQueryStr, "application/json", aaiAdapter.getNumRequestRetries()); - final String parentEntityQueryString = - determineEntityQueryString(txn.getEntityType(), convertedNode); + aaiWorkOnHand.decrementAndGet(); - List<String> extractedParentEntityAttributeValues = new ArrayList<String>(); + if (aaiQueryResult != null && aaiQueryResult.wasSuccessful()) { - NodeUtils.extractFieldValuesFromObject(convertedNode, - cerDefinition.getReferenceAttributes(), extractedParentEntityAttributeValues); + Collection<JsonNode> entityLinks = new ArrayList<JsonNode>(); + JsonNode genericQueryResult = null; + try { + genericQueryResult = + NodeUtils.convertJsonStrToJsonNode(aaiQueryResult.getResult()); - List<JsonNode> nestedTargetEntityInstances = new ArrayList<JsonNode>(); - NodeUtils.extractObjectsByKey(convertedNode, cerDefinition.getTargetEntityType(), - nestedTargetEntityInstances); + if (genericQueryResult != null) { - for (JsonNode targetEntityInstance : nestedTargetEntityInstances) { + NodeUtils.extractObjectsByKey(genericQueryResult, "resource-link", + entityLinks); - OxmEntityDescriptor cerDescriptor = oxmModelLoader - .getSearchableEntityDescriptor(cerDefinition.getTargetEntityType()); + String selfLink = null; - if (cerDescriptor != null) { + if (entityLinks.size() != 1) { + /** + * an ambiguity exists where we can't reliably determine the self link, + * this should be a permanent error + */ + LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_SELFLINK_AMBIGUITY, + String.valueOf(entityLinks.size())); + } else { + selfLink = ((JsonNode) entityLinks.toArray()[0]).asText(); - String childEntityType = cerDefinition.getTargetEntityType(); + SearchableEntityLookup searchableEntityLookup = + SearchableEntityLookup.getInstance(); - List<String> childPrimaryKeyNames = cerDescriptor.getPrimaryKeyAttributeName(); + SearchableOxmEntityDescriptor searchableDescriptor = + searchableEntityLookup.getSearchableEntityDescriptors() + .get(txn.getEntityType()); - List<String> childKeyValues = new ArrayList<String>(); - NodeUtils.extractFieldValuesFromObject(targetEntityInstance, childPrimaryKeyNames, - childKeyValues); + if (searchableDescriptor != null + && searchableDescriptor.getSearchableAttributes().size() > 0) { - String childEntityQueryKeyString = - childEntityType + "." + NodeUtils.concatArray(childPrimaryKeyNames, "/") + ":" - + NodeUtils.concatArray(childKeyValues); + IndexableCrossEntityReference icer = + getPopulatedDocument(targetEntityInstance, cerDescriptor); - /** - * Build generic-query to query child instance self-link from AAI - */ - List<String> orderedQueryKeyParams = new ArrayList<String>(); - if (SERVICE_INSTANCE.equals(childEntityType)) { - orderedQueryKeyParams.clear(); - orderedQueryKeyParams.add(childEntityQueryKeyString); - } else { - orderedQueryKeyParams.add(parentEntityQueryString); - orderedQueryKeyParams.add(childEntityQueryKeyString); - } - String genericQueryStr = null; - try { - genericQueryStr = aaiDataProvider.getGenericQueryForSelfLink(childEntityType, - orderedQueryKeyParams); - - if (genericQueryStr != null) { - aaiWorkOnHand.incrementAndGet(); - OperationResult aaiQueryResult = aaiDataProvider - .queryActiveInventoryWithRetries(genericQueryStr, "application/json", - aaiConfig.getAaiRestConfig().getNumRequestRetries()); - aaiWorkOnHand.decrementAndGet(); - if (aaiQueryResult != null && aaiQueryResult.wasSuccessful()) { - - Collection<JsonNode> entityLinks = new ArrayList<JsonNode>(); - JsonNode genericQueryResult = null; - try { - genericQueryResult = - NodeUtils.convertJsonStrToJsonNode(aaiQueryResult.getResult()); - - if (genericQueryResult != null) { - - NodeUtils.extractObjectsByKey(genericQueryResult, "resource-link", - entityLinks); - - String selfLink = null; - - if (entityLinks.size() != 1) { - /** - * an ambiguity exists where we can't reliably determine the self - * link, this should be a permanent error - */ - LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_SELFLINK_AMBIGUITY, - String.valueOf(entityLinks.size())); - } else { - selfLink = ((JsonNode) entityLinks.toArray()[0]).asText(); - - if (!cerDescriptor.getSearchableAttributes().isEmpty()) { - - IndexableCrossEntityReference icer = - getPopulatedDocument(targetEntityInstance, cerDescriptor); - - for (String parentCrossEntityReferenceAttributeValue : extractedParentEntityAttributeValues) { - icer.addCrossEntityReferenceValue( - parentCrossEntityReferenceAttributeValue); - } - - icer.setLink(ActiveInventoryConfig.extractResourcePath(selfLink)); - - icer.deriveFields(); - - String link = null; - try { - link = getElasticFullUrl("/" + icer.getId(), getIndexName()); - } catch (Exception exc) { - LOG.error(AaiUiMsgs.ES_FAILED_TO_CONSTRUCT_QUERY, - exc.getLocalizedMessage()); - } - - if (link != null) { - NetworkTransaction n2 = new NetworkTransaction(); - n2.setLink(link); - n2.setEntityType(txn.getEntityType()); - n2.setDescriptor(txn.getDescriptor()); - n2.setOperationType(HttpMethod.GET); - - esWorkOnHand.incrementAndGet(); - - supplyAsync(new PerformElasticSearchRetrieval(n2, esDataProvider), - esExecutor).whenComplete((result, error) -> { - - esWorkOnHand.decrementAndGet(); - - if (error != null) { - LOG.error(AaiUiMsgs.ES_RETRIEVAL_FAILED, - error.getLocalizedMessage()); - } else { - updateElasticSearchCounters(result); - performDocumentUpsert(result, icer); - } - }); - } + for (String parentCrossEntityReferenceAttributeValue : extractedParentEntityAttributeValues) { + icer.addCrossEntityReferenceValue( + parentCrossEntityReferenceAttributeValue); + } + + icer.setLink(ActiveInventoryConfig.extractResourcePath(selfLink)); + + icer.deriveFields(); + + String link = null; + try { + link = getElasticFullUrl("/" + icer.getId(), getIndexName()); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ES_FAILED_TO_CONSTRUCT_QUERY, + exc.getLocalizedMessage()); + } + + if (link != null) { + NetworkTransaction n2 = new NetworkTransaction(); + n2.setLink(link); + n2.setEntityType(txn.getEntityType()); + n2.setDescriptor(txn.getDescriptor()); + n2.setOperationType(HttpMethod.GET); + + esWorkOnHand.incrementAndGet(); + + supplyAsync( + new PerformElasticSearchRetrieval(n2, elasticSearchAdapter), + esExecutor).whenComplete((result, error) -> { + + esWorkOnHand.decrementAndGet(); + + if (error != null) { + LOG.error(AaiUiMsgs.ES_RETRIEVAL_FAILED, + error.getLocalizedMessage()); + } else { + updateElasticSearchCounters(result); + performDocumentUpsert(result, icer); + } + }); } } - } else { - LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_DURING_AAI_RESPONSE_CONVERSION); } - - } catch (Exception exc) { - LOG.error(AaiUiMsgs.JSON_CONVERSION_ERROR, JsonNode.class.toString(), - exc.getLocalizedMessage()); + } else { + LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_DURING_AAI_RESPONSE_CONVERSION); } - } else { - String message = "Entity sync failed because AAI query failed with error "; - LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_QUERY_ERROR, message); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.JSON_CONVERSION_ERROR, JsonNode.class.toString(), + exc.getLocalizedMessage()); } } else { - String message = - "Entity Sync failed because generic query str could not be determined."; + String message = "Entity sync failed because AAI query failed with error " + + aaiQueryResult.getResult(); LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_QUERY_ERROR, message); } - } catch (Exception exc) { + + } else { String message = - "Failed to sync entity because generation of generic query failed with error = " - + exc.getMessage(); + "Entity Sync failed because generic query str could not be determined."; LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_QUERY_ERROR, message); } - + } catch (Exception exc) { + String message = + "Failed to sync entity because generation of generic query failed with error = " + + exc.getMessage(); + LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_QUERY_ERROR, message); } - } - } catch (IOException ioe) { - LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, ioe.getMessage()); + } } - } - } else { - LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_DESCRIPTOR_NOT_FOUND, txn.getEntityType()); + } catch (IOException ioe) { + LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, ioe.getMessage()); + } } + } + + } else { + LOG.error(AaiUiMsgs.ENTITY_SYNC_FAILED_DESCRIPTOR_NOT_FOUND, txn.getEntityType()); } } @@ -694,7 +734,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer String responseSource = NodeUtils.convertObjectToJson(sourceObject.get(0), false); MergableEntity me = mapper.readValue(responseSource, MergableEntity.class); ObjectReader updater = mapper.readerForUpdating(me); - MergableEntity merged = updater.readValue(icer.getIndexDocumentJson()); + MergableEntity merged = updater.readValue(icer.getAsJson()); jsonPayload = mapper.writeValueAsString(merged); } } catch (IOException exc) { @@ -703,14 +743,15 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer return; } } else { - jsonPayload = icer.getIndexDocumentJson(); + jsonPayload = icer.getAsJson(); } if (wasEntryDiscovered) { if (versionNumber != null && jsonPayload != null) { - String requestPayload = esDataProvider.buildBulkImportOperationRequest(getIndexName(), - ElasticSearchConfig.getConfig().getType(), icer.getId(), versionNumber, jsonPayload); + String requestPayload = elasticSearchAdapter.buildBulkImportOperationRequest( + getIndexName(), ElasticSearchConfig.getConfig().getType(), icer.getId(), + versionNumber, jsonPayload); NetworkTransaction transactionTracker = new NetworkTransaction(); transactionTracker.setEntityType(esGetResult.getEntityType()); @@ -719,7 +760,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer esWorkOnHand.incrementAndGet(); supplyAsync(new PerformElasticSearchUpdate(ElasticSearchConfig.getConfig().getBulkUrl(), - requestPayload, esDataProvider, transactionTracker), esPutExecutor) + requestPayload, elasticSearchAdapter, transactionTracker), esPutExecutor) .whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -743,7 +784,8 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer updateElasticTxn.setOperationType(HttpMethod.PUT); esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchPut(jsonPayload, updateElasticTxn, esDataProvider), + supplyAsync( + new PerformElasticSearchPut(jsonPayload, updateElasticTxn, elasticSearchAdapter), esPutExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -826,7 +868,7 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer * that for this request already when queuing the failed PUT! */ - supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, esDataProvider), + supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, elasticSearchAdapter), esExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -882,14 +924,14 @@ public class CrossEntityReferenceSynchronizer extends AbstractEntitySynchronizer protected IndexableCrossEntityReference getPopulatedDocument(JsonNode entityNode, OxmEntityDescriptor resultDescriptor) throws JsonProcessingException, IOException { - IndexableCrossEntityReference icer = new IndexableCrossEntityReference(oxmModelLoader); + IndexableCrossEntityReference icer = new IndexableCrossEntityReference(); icer.setEntityType(resultDescriptor.getEntityName()); List<String> primaryKeyValues = new ArrayList<String>(); String pkeyValue = null; - for (String keyName : resultDescriptor.getPrimaryKeyAttributeName()) { + for (String keyName : resultDescriptor.getPrimaryKeyAttributeNames()) { pkeyValue = NodeUtils.getNodeFieldAsText(entityNode, keyName); if (pkeyValue != null) { primaryKeyValues.add(pkeyValue); diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryAdapter.java b/src/main/java/org/onap/aai/sparky/dal/ActiveInventoryAdapter.java index 08a6584..40bb98c 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryAdapter.java +++ b/src/main/java/org/onap/aai/sparky/dal/ActiveInventoryAdapter.java @@ -20,44 +20,43 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.dal.aai; +package org.onap.aai.sparky.dal; import java.io.IOException; +import java.net.URISyntaxException; import java.net.URLEncoder; -import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriBuilder; + +import org.apache.http.NameValuePair; import org.apache.http.client.utils.URIBuilder; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.aai.restclient.enums.RestAuthenticationMode; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryRestConfig; -import org.onap.aai.sparky.dal.aai.enums.RestAuthenticationMode; import org.onap.aai.sparky.dal.exception.ElasticSearchOperationException; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestClientBuilder; -import org.onap.aai.sparky.dal.rest.RestfulDataAccessor; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.security.SecurityContextFactory; +import org.onap.aai.sparky.util.Encryptor; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -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 { +public class ActiveInventoryAdapter { private static final Logger LOG = LoggerFactory.getInstance().getLogger(ActiveInventoryAdapter.class); @@ -66,74 +65,153 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor private static final String HEADER_FROM_APP_ID = "X-FromAppId"; private static final String HEADER_AUTHORIZATION = "Authorization"; + private static final String HTTP_SCHEME = "http"; + private static final String HTTPS_SCHEME = "https"; + private static final String TRANSACTION_ID_PREFIX = "txnId-"; private static final String UI_APP_NAME = "AAI-UI"; + private OxmModelLoader oxmModelLoader; + private OxmEntityLookup oxmEntityLookup; - private ActiveInventoryConfig config; + private RestClient restClient; + + private String activeInventoryIpAddress; + private String activeInventoryServerPort; + private int numRequestRetries; + private String basicAuthUserName; + private String basicAuthPassword; + private RestAuthenticationMode restAuthenticationMode; + private int connectTimeoutInMs; + private int readTimeoutInMs; /** * 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) + + public ActiveInventoryAdapter(OxmModelLoader oxmModelLoader, + RestAuthenticationMode authenticationMode, boolean validateServerHostname, + boolean validateServerCertChain, String certFileName, String certPassword, + String truststoreFileName, int connectTimeoutInMs, int readTimeoutInMs) throws ElasticSearchOperationException, IOException { - super(restClientBuilder); - try { - this.config = ActiveInventoryConfig.getConfig(); - } catch (Exception exc) { - throw new ElasticSearchOperationException("Error getting active inventory configuration", - exc); - } + this.oxmModelLoader = oxmModelLoader; + this.restAuthenticationMode = authenticationMode; + this.connectTimeoutInMs = connectTimeoutInMs; + this.readTimeoutInMs = readTimeoutInMs; + + + Encryptor enc = new Encryptor(); + String certFileNameFullPath = TierSupportUiConstants.CONFIG_AUTH_LOCATION + certFileName; + String decryptedCertPassword = enc.decryptValue(certPassword); + String truststoreFileNameFullPath = + TierSupportUiConstants.CONFIG_AUTH_LOCATION + truststoreFileName; - clientBuilder.setUseHttps(true); + this.restClient = new RestClient().authenticationMode(authenticationMode) + .validateServerCertChain(validateServerCertChain) + .validateServerHostname(validateServerHostname).clientCertFile(certFileNameFullPath) + .clientCertPassword(decryptedCertPassword).trustStore(truststoreFileNameFullPath) + .connectTimeoutMs(connectTimeoutInMs).readTimeoutMs(readTimeoutInMs); - clientBuilder.setValidateServerHostname(config.getAaiSslConfig().isValidateServerHostName()); + } + + public ActiveInventoryAdapter(OxmModelLoader oxmModelLoader, + RestAuthenticationMode authenticationMode, boolean validateServerHostname, + boolean validateServerCertChain, String basicAuthUserName, String basicAuthPassword, + int connectTimeoutInMs, int readTimeoutInMs) + throws ElasticSearchOperationException, IOException { + + this.oxmModelLoader = oxmModelLoader; + this.restAuthenticationMode = authenticationMode; + + this.restClient = new RestClient().authenticationMode(authenticationMode) + .validateServerCertChain(validateServerCertChain) + .validateServerHostname(validateServerHostname).connectTimeoutMs(connectTimeoutInMs) + .readTimeoutMs(readTimeoutInMs); + + this.basicAuthUserName = basicAuthUserName; + this.basicAuthPassword = basicAuthPassword; + + } - SecurityContextFactory sslContextFactory = clientBuilder.getSslContextFactory(); - sslContextFactory.setServerCertificationChainValidationEnabled( - config.getAaiSslConfig().isValidateServerCertificateChain()); + protected Map<String, List<String>> getMessageHeaders() { + + Map<String, List<String>> headers = new HashMap<String, List<String>>(); + + headers.putIfAbsent(HEADER_FROM_APP_ID, new ArrayList<String>()); + headers.get(HEADER_FROM_APP_ID).add(UI_APP_NAME); + + headers.putIfAbsent(HEADER_TRANS_ID, new ArrayList<String>()); + headers.get(HEADER_TRANS_ID).add(TRANSACTION_ID_PREFIX + NodeUtils.getRandomTxnId()); + + if (restAuthenticationMode == RestAuthenticationMode.SSL_BASIC) { + + headers.putIfAbsent(HEADER_AUTHORIZATION, new ArrayList<String>()); + headers.get(HEADER_AUTHORIZATION).add(getBasicAuthenticationCredentials()); - 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()); + return headers; + } + protected String getBasicAuthenticationCredentials() { + String usernameAndPassword = String.join(":", basicAuthUserName, basicAuthPassword); + return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes()); } - /* - * (non-Javadoc) - * - * @see - * org.onap.aai.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()); + public int getNumRequestRetries() { + return numRequestRetries; + } + + + + public void setNumRequestRetries(int numRequestRetries) { + this.numRequestRetries = numRequestRetries; + } + + public OxmEntityLookup getOxmEntityLookup() { + return oxmEntityLookup; + } + + public void setOxmEntityLookup(OxmEntityLookup oxmEntityLookup) { + this.oxmEntityLookup = oxmEntityLookup; + } + + public String getActiveInventoryIpAddress() { + return activeInventoryIpAddress; + } + + public void setActiveInventoryIpAddress(String activeInventoryIpAddress) { + this.activeInventoryIpAddress = activeInventoryIpAddress; + } + + public String getActiveInventoryServerPort() { + return activeInventoryServerPort; + } + + public void setActiveInventoryServerPort(String activeInventoryServerPort) { + this.activeInventoryServerPort = activeInventoryServerPort; + } + + protected String getResourceBasePath() { + + String versionStr = null; + if (oxmModelLoader != null) { + versionStr = String.valueOf(oxmModelLoader.getLatestVersionNum()); } - return builder; + return "/aai/v" + versionStr; + + } + + public int getConnectTimeoutInMs() { + return this.connectTimeoutInMs; + } + + public int getReadTimeoutInMs() { + return this.readTimeoutInMs; } /** @@ -144,11 +222,9 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor * @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); + final String basePath = getResourceBasePath(); + return String.format("https://%s:%s%s%s", activeInventoryIpAddress, activeInventoryServerPort, + basePath, resourceUrl); } public String getGenericQueryForSelfLink(String startNodeType, List<String> queryParams) @@ -165,21 +241,11 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor final String constructedLink = urlBuilder.toString(); - // TODO: debug log for constructed link - return constructedLink; } - /* - * (non-Javadoc) - * - * @see - * org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider#getSelfLinksByEntityType(java.lang. - * String) - */ - @Override public OperationResult getSelfLinksByEntityType(String entityType) throws Exception { /* @@ -192,8 +258,7 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor "Failed to getSelfLinksByEntityType() because entityType is null"); } - OxmEntityDescriptor entityDescriptor = - OxmModelLoader.getInstance().getEntityDescriptor(entityType); + OxmEntityDescriptor entityDescriptor = oxmEntityLookup.getEntityDescriptors().get(entityType); if (entityDescriptor == null) { throw new NoSuchElementException("Failed to getSelfLinksByEntityType() because could" @@ -202,25 +267,16 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor String link = null; final String primaryKeyStr = - NodeUtils.concatArray(entityDescriptor.getPrimaryKeyAttributeName(), "/"); + NodeUtils.concatArray(entityDescriptor.getPrimaryKeyAttributeNames(), "/"); link = getFullUrl("/search/nodes-query?search-node-type=" + entityType + "&filter=" + primaryKeyStr + ":EXISTS"); - - return doGet(link, "application/json"); + return restClient.get(link, getMessageHeaders(), MediaType.APPLICATION_JSON_TYPE); } - /* - * (non-Javadoc) - * - * @see - * org.onap.aai.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 { @@ -238,7 +294,6 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor "Failed to getSelfLinkForEntity() because primaryKeyValue is null"); } - /* * 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. @@ -264,8 +319,7 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor } - return queryActiveInventoryWithRetries(link, "application/json", - this.config.getAaiRestConfig().getNumRequestRetries()); + return queryActiveInventoryWithRetries(link, "application/json", numRequestRetries); } @@ -305,25 +359,19 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor */ // package protected for test classes instead of private OperationResult queryActiveInventory(String url, String acceptContentType) { - return doGet(url, acceptContentType); + + return restClient.get(url, getMessageHeaders(), MediaType.APPLICATION_JSON_TYPE); + } - /* - * (non-Javadoc) - * - * @see - * org.onap.aai.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++) { + for (int retryCount = 0; retryCount < numRetries; retryCount++) { - LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_SEQ, url, String.valueOf(x + 1)); + LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_SEQ, url, String.valueOf(retryCount + 1)); result = queryActiveInventory(url, responseType); @@ -337,33 +385,12 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor * parallelized threads per task processor. */ - result.setNumRequestRetries(x); + result.setNumRetries(retryCount); 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)); + result.setFromCache(false); + LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_DONE_SEQ, url, String.valueOf(retryCount + 1)); return result; } @@ -377,31 +404,57 @@ public class ActiveInventoryAdapter extends RestfulDataAccessor LOG.error(AaiUiMsgs.QUERY_AAI_WAIT_INTERRUPTION, exc.getLocalizedMessage()); break; } - LOG.error(AaiUiMsgs.QUERY_AAI_RETRY_FAILURE_WITH_SEQ, url, String.valueOf(x + 1)); - } + LOG.error(AaiUiMsgs.QUERY_AAI_RETRY_FAILURE_WITH_SEQ, url, String.valueOf(retryCount + 1)); + } - result.setResolvedLinkFailure(true); LOG.info(AaiUiMsgs.QUERY_AAI_RETRY_MAXED_OUT, url); return result; } - /* - * (non-Javadoc) + public String repairSelfLink(String selfLink) { + return repairSelfLink(selfLink, null); + } + + /** + * This method adds a scheme, host and port (if missing) to the passed-in URI. If these parts of + * the URI are already present, they will not be duplicated. * - * @see org.onap.aai.sparky.dal.rest.RestfulDataAccessor#shutdown() + * @param selflink The URI to repair + * @param queryParams The query parameters as a single string + * @return The corrected URI (i.e. includes a scheme/host/port) */ - @Override - public void shutdown() { - // TODO Auto-generated method stub + public String repairSelfLink(String selflink, String queryParams) { + if (selflink == null) { + return selflink; + } - if (entityCache != null) { - entityCache.shutdown(); + UriBuilder builder = UriBuilder.fromPath(selflink).host(activeInventoryIpAddress) + .port(Integer.parseInt(activeInventoryServerPort)); + + switch (restAuthenticationMode) { + + case SSL_BASIC: + case SSL_CERT: { + builder.scheme(HTTPS_SCHEME); + break; + } + + default: { + builder.scheme(HTTP_SCHEME); + } } - } + boolean includeQueryParams = ((null != queryParams) && (!"".equals(queryParams))); + /* + * builder.build().toString() will encode special characters to hexadecimal pairs prefixed with + * a '%' so we're adding the query parameters separately, in their UTF-8 representations, so + * that characters such as '?', '&', etc. remain intact as needed by the synchronizer + */ + return (builder.build().toString() + (includeQueryParams ? queryParams : "")); + } } diff --git a/src/main/java/org/onap/aai/sparky/dal/ElasticSearchAdapter.java b/src/main/java/org/onap/aai/sparky/dal/ElasticSearchAdapter.java new file mode 100644 index 0000000..1e2bb8d --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/dal/ElasticSearchAdapter.java @@ -0,0 +1,120 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.dal; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; + +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.aai.restclient.enums.RestAuthenticationMode; + +/** + * The Class ElasticSearchAdapter. + * + */ +public class ElasticSearchAdapter { + + private static final String BULK_IMPORT_INDEX_TEMPLATE = + "{\"index\":{\"_index\":\"%s\",\"_type\":\"%s\",\"_id\":\"%s\", \"_version\":\"%s\"}}\n"; + + private RestClient restClient; + + /** + * Instantiates a new elastic search adapter. + */ + public ElasticSearchAdapter(RestAuthenticationMode restAuthenticationMode, int connectTimeoutInMs, + int readTimeoutInMs) { + + this.restClient = new RestClient().authenticationMode(restAuthenticationMode) + .connectTimeoutMs(connectTimeoutInMs).readTimeoutMs(readTimeoutInMs); + + } + + protected Map<String, List<String>> getMessageHeaders() { + Map<String, List<String>> headers = new HashMap<String, List<String>>(); + // insert mandatory headers if there are any + return headers; + } + + public OperationResult doGet(String url, MediaType acceptContentType) { + return restClient.get(url, getMessageHeaders(), acceptContentType); + } + + public OperationResult doDelete(String url, MediaType acceptContentType) { + return restClient.delete(url, getMessageHeaders(), acceptContentType); + } + + public OperationResult doPost(String url, String jsonPayload, MediaType acceptContentType) { + return restClient.post(url, jsonPayload, getMessageHeaders(), MediaType.APPLICATION_JSON_TYPE, + acceptContentType); + } + + public OperationResult doPut(String url, String jsonPayload, MediaType acceptContentType) { + return restClient.put(url, jsonPayload, getMessageHeaders(), MediaType.APPLICATION_JSON_TYPE, + acceptContentType); + } + + public OperationResult doPatch(String url, String jsonPayload, MediaType acceptContentType) { + + Map<String, List<String>> headers = getMessageHeaders(); + headers.putIfAbsent("X-HTTP-Method-Override", new ArrayList<String>()); + headers.get("X-HTTP-Method-Override").add("PATCH"); + + return restClient.post(url, jsonPayload, headers, MediaType.APPLICATION_JSON_TYPE, + acceptContentType); + } + + public OperationResult doHead(String url, MediaType acceptContentType) { + return restClient.head(url, getMessageHeaders(), acceptContentType); + } + + public OperationResult doBulkOperation(String url, String payload) { + return restClient.put(url, payload, getMessageHeaders(), + MediaType.APPLICATION_FORM_URLENCODED_TYPE, MediaType.APPLICATION_JSON_TYPE); + } + + 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(); + + } + + public OperationResult retrieveEntityById(String host, String port, String indexName, + String docType, String resourceUrl) { + String esUrl = + String.format("http://%s:%s/%s/%s/%s", host, port, indexName, docType, resourceUrl); + return doGet(esUrl, MediaType.APPLICATION_JSON_TYPE); + } + +} diff --git a/src/main/java/org/onap/aai/sparky/dal/NetworkTransaction.java b/src/main/java/org/onap/aai/sparky/dal/NetworkTransaction.java index da24c80..fbc89c3 100644 --- a/src/main/java/org/onap/aai/sparky/dal/NetworkTransaction.java +++ b/src/main/java/org/onap/aai/sparky/dal/NetworkTransaction.java @@ -22,9 +22,10 @@ */ package org.onap.aai.sparky.dal; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; + /** * The Class NetworkTransaction. @@ -37,12 +38,16 @@ public class NetworkTransaction { private String link; + private String queryParameters; + private HttpMethod operationType; private OxmEntityDescriptor descriptor; private long createdTimeStampInMs; + private long opTimeInMs; + private long taskAgeInMs; /** @@ -50,6 +55,7 @@ public class NetworkTransaction { */ public NetworkTransaction() { this.createdTimeStampInMs = System.currentTimeMillis(); + this.opTimeInMs = 0L; } /** @@ -64,6 +70,7 @@ public class NetworkTransaction { this.operationType = method; this.entityType = entityType; this.operationResult = or; + this.opTimeInMs = 0L; } public HttpMethod getOperationType() { @@ -109,6 +116,22 @@ public class NetworkTransaction { this.link = link; } + public String getQueryParameters() { + return queryParameters; + } + + public void setQueryParameters(String queryParameters) { + this.queryParameters = queryParameters; + } + + public long getOpTimeInMs() { + return opTimeInMs; + } + + public void setOpTimeInMs(long opTimeInMs) { + this.opTimeInMs = opTimeInMs; + } + public OxmEntityDescriptor getDescriptor() { return descriptor; } diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryDataProvider.java b/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryDataProvider.java index 21fb4e6..75e7a54 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryDataProvider.java +++ b/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryDataProvider.java @@ -30,6 +30,11 @@ import org.onap.aai.sparky.dal.rest.RestDataProvider; /** * The Interface ActiveInventoryDataProvider. */ + +/* + * TODO: DELETE ME + */ + public interface ActiveInventoryDataProvider extends RestDataProvider { /** @@ -81,7 +86,7 @@ public interface ActiveInventoryDataProvider extends RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#shutdown() + * @see org.openecomp.sparky.dal.rest.RestDataProvider#shutdown() */ @Override void shutdown(); diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryEntityStatistics.java b/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryEntityStatistics.java index c1ed906..6ffebef 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryEntityStatistics.java +++ b/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryEntityStatistics.java @@ -29,10 +29,9 @@ import java.util.Set; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicInteger; -import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.rest.OperationResult; + /** * The Class ActiveInventoryEntityStatistics. @@ -51,9 +50,6 @@ public class ActiveInventoryEntityStatistics { private static final String ERROR = "Error"; - private OxmModelLoader loader; - - private Map<String, HashMap<String, AtomicInteger>> activeInventoryEntityStatistics; /** @@ -76,30 +72,6 @@ public class ActiveInventoryEntityStatistics { } - /* - * private void createSearchableActiveInventoryEntityStatistics() { - * - * Map<String,OxmEntityDescriptor> descriptors = loader.getSearchableEntityDescriptors(); - * - * if(descriptors == null) { return; } - * - * OxmEntityDescriptor d = null; for ( String key : descriptors.keySet() ) { d = - * descriptors.get(key); activeInventoryEntityStatistics.put(d.getEntityName(), - * createEntityOpStats()); } - * - * } - */ - - /* - * private void createCrossEntityReferenceActiveInventoryEntityStatistics() { - * - * Map<String,OxmEntityDescriptor> descriptors = loader.getCrossReferenceEntityDescriptors(); - * - * - * } - */ - - /** * Initializecreate active inventory entity statistics. */ @@ -126,11 +98,8 @@ public class ActiveInventoryEntityStatistics { * * @param loader the loader */ - public ActiveInventoryEntityStatistics(OxmModelLoader loader) { - this.loader = loader; + public ActiveInventoryEntityStatistics() { activeInventoryEntityStatistics = new HashMap<String, HashMap<String, AtomicInteger>>(); - // createSearchableActiveInventoryEntityStatistics(); - // createCrossEntityReferenceActiveInventoryEntityStatistics(); reset(); } @@ -139,21 +108,29 @@ public class ActiveInventoryEntityStatistics { * * @param descriptors the descriptors */ - public void initializeCountersFromOxmEntityDescriptors( - Map<String, OxmEntityDescriptor> descriptors) { + public void intializeEntityCounters(String... entityTypes) { + + if (entityTypes != null && entityTypes.length > 0) { + for (String entityType : entityTypes) { + activeInventoryEntityStatistics.put(entityType, createEntityOpStats()); + } - if (descriptors == null) { - return; } - OxmEntityDescriptor descriptor = null; - for (String key : descriptors.keySet()) { - descriptor = descriptors.get(key); - activeInventoryEntityStatistics.put(descriptor.getEntityName(), createEntityOpStats()); + } + + public void intializeEntityCounters(Set<String> entityTypes) { + + if (entityTypes != null && entityTypes.size() > 0) { + for (String entityType : entityTypes) { + activeInventoryEntityStatistics.put(entityType, createEntityOpStats()); + } } + } + /** * Reset. */ @@ -230,8 +207,8 @@ public class ActiveInventoryEntityStatistics { opStats.get(NO_PAYLOAD).incrementAndGet(); } - if (or.getNumRequestRetries() > 0) { - opStats.get(NUM_RETRIES).addAndGet(or.getNumRequestRetries()); + if (or.getNumRetries() > 0) { + opStats.get(NUM_RETRIES).addAndGet(or.getNumRetries()); } } diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java b/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java index eb4eb6c..329d0f0 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java +++ b/src/main/java/org/onap/aai/sparky/dal/aai/ActiveInventoryProcessingExceptionStatistics.java @@ -22,12 +22,13 @@ */ package org.onap.aai.sparky.dal.aai; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.analytics.AbstractStatistics; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; /** * The Class ActiveInventoryProcessingExceptionStatistics. diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryConfig.java b/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryConfig.java index e88ca51..d311993 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryConfig.java +++ b/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryConfig.java @@ -26,30 +26,25 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Properties; -import javax.ws.rs.core.UriBuilder; - +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.config.TaskProcessorConfig; import org.onap.aai.sparky.util.ConfigHelper; import org.onap.aai.sparky.util.Encryptor; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; /** * 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 Logger LOG = LoggerFactory.getInstance().getLogger(ActiveInventoryConfig.class); - private static final String HTTP_SCHEME = "http"; - private static final String HTTPS_SCHEME = "https"; + public static ActiveInventoryConfig getConfig() throws Exception { if (instance == null) { @@ -61,7 +56,6 @@ public class ActiveInventoryConfig { private ActiveInventoryRestConfig aaiRestConfig; private ActiveInventorySslConfig aaiSslConfig; - private TaskProcessorConfig taskProcessorConfig; /** * Instantiates a new active inventory config. @@ -71,37 +65,18 @@ public class ActiveInventoryConfig { 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)); - - + initialize(props); } - protected ActiveInventoryConfig(Properties props) throws Exception { + public ActiveInventoryConfig(Properties props) throws Exception { + initialize(props); + } + private void initialize(Properties props) { 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; } @@ -118,35 +93,11 @@ public class ActiveInventoryConfig { 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(); - - } public static String extractResourcePath(String selflink) { try { - return new URI(selflink).getPath(); + return new URI(selflink).getRawPath(); } catch (URISyntaxException uriSyntaxException) { LOG.error(AaiUiMsgs.ERROR_EXTRACTING_RESOURCE_PATH_FROM_LINK, uriSyntaxException.getMessage()); @@ -165,9 +116,6 @@ public class ActiveInventoryConfig { + aaiSslConfig + "]"; } - public URI getBaseUri() { - return UriBuilder.fromUri("https://" + aaiRestConfig.getHost() + ":" + aaiRestConfig.getPort() - + aaiRestConfig.getResourceBasePath()).build(); - } + } diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryRestConfig.java b/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryRestConfig.java index 5ed537b..617a74c 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryRestConfig.java +++ b/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventoryRestConfig.java @@ -36,27 +36,6 @@ public class ActiveInventoryRestConfig { private String host; - /** - * @return the cacheFailures - */ - public boolean isCacheFailures() { - return cacheFailures; - } - - /** - * @param cacheFailures the cacheFailures to set - */ - public void setCacheFailures(boolean cacheFailures) { - this.cacheFailures = cacheFailures; - } - - /** - * @param shallowEntities the shallowEntities to set - */ - public void setShallowEntities(List<String> shallowEntities) { - this.shallowEntities = shallowEntities; - } - private String port; private int connectTimeoutInMs; @@ -67,20 +46,6 @@ public class ActiveInventoryRestConfig { private int numResolverWorkers; - private boolean useCacheOnly; - - private boolean cacheEnabled; - - private boolean cacheFailures; - - private String storageFolderOverride; - - int numCacheWorkers; - - private long maxTimeToLiveInMs; - - private String resourceBasePath; - private List<String> shallowEntities; private RestAuthenticationMode authenticationMode; @@ -96,13 +61,12 @@ public class ActiveInventoryRestConfig { */ public ActiveInventoryRestConfig(Properties props) { - if (props == null) { + if (props == null || props.isEmpty()) { 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")); @@ -114,23 +78,6 @@ public class ActiveInventoryRestConfig { 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())); @@ -154,26 +101,6 @@ public class ActiveInventoryRestConfig { 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. @@ -195,14 +122,6 @@ public class ActiveInventoryRestConfig { return false; } - public boolean isUseCacheOnly() { - return useCacheOnly; - } - - public void setUseCacheOnly(boolean useCacheOnly) { - this.useCacheOnly = useCacheOnly; - } - public int getNumResolverWorkers() { return numResolverWorkers; } @@ -211,30 +130,6 @@ public class ActiveInventoryRestConfig { 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; } @@ -243,10 +138,6 @@ public class ActiveInventoryRestConfig { return port; } - public String getResourceBasePath() { - return resourceBasePath; - } - public void setHost(String host) { this.host = host; } @@ -255,29 +146,6 @@ public class ActiveInventoryRestConfig { 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; } diff --git a/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventorySslConfig.java b/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventorySslConfig.java index 080a787..75ce36a 100644 --- a/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventorySslConfig.java +++ b/src/main/java/org/onap/aai/sparky/dal/aai/config/ActiveInventorySslConfig.java @@ -56,7 +56,7 @@ public class ActiveInventorySslConfig { */ public ActiveInventorySslConfig(Properties props, Encryptor encryptor) { - if (props == null) { + if (props == null || props.isEmpty()) { return; } @@ -197,20 +197,6 @@ public class ActiveInventorySslConfig { return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes()); } - /** - * @return the enableSslDebug - */ - public boolean isEnableSslDebug() { - return enableSslDebug; - } - - /** - * @param enableSslDebug the enableSslDebug to set - */ - public void setEnableSslDebug(boolean enableSslDebug) { - this.enableSslDebug = enableSslDebug; - } - /* * (non-Javadoc) * diff --git a/src/main/java/org/onap/aai/sparky/dal/cache/InMemoryEntityCache.java b/src/main/java/org/onap/aai/sparky/dal/cache/InMemoryEntityCache.java deleted file mode 100644 index 5245e29..0000000 --- a/src/main/java/org/onap/aai/sparky/dal/cache/InMemoryEntityCache.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.dal.cache; - -import java.util.concurrent.ConcurrentHashMap; - -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; - -/** - * The Class InMemoryEntityCache. - * - * @author davea. - */ -public class InMemoryEntityCache implements EntityCache { - - private ConcurrentHashMap<String, OperationResult> cachedEntityData; - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(InMemoryEntityCache.class); - - /** - * Instantiates a new in memory entity cache. - */ - public InMemoryEntityCache() { - cachedEntityData = new ConcurrentHashMap<String, OperationResult>(); - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.dal.cache.EntityCache#put(java.lang.String, - * org.onap.aai.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.onap.aai.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.onap.aai.sparky.dal.cache.EntityCache#shutdown() - */ - @Override - public void shutdown() { - // TODO Auto-generated method stub - // nothing to do - - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.dal.cache.EntityCache#clear() - */ - @Override - public void clear() { - cachedEntityData.clear(); - } - -} diff --git a/src/main/java/org/onap/aai/sparky/dal/cache/PersistentEntityCache.java b/src/main/java/org/onap/aai/sparky/dal/cache/PersistentEntityCache.java deleted file mode 100644 index f64b3c7..0000000 --- a/src/main/java/org/onap/aai/sparky/dal/cache/PersistentEntityCache.java +++ /dev/null @@ -1,256 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.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.onap.aai.sparky.dal.aai.ActiveInventoryAdapter; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.task.PersistOperationResultToDisk; -import org.onap.aai.sparky.synchronizer.task.RetrieveOperationResultFromDisk; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * The Class PersistentEntityCache. - */ -public class PersistentEntityCache implements EntityCache { - - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(ActiveInventoryAdapter.class); - - /* - * TODO: <li>implement time-to-live on the cache, maybe pull in one of Guava's eviction caches? - * <li>implement abstract-base-cache to hold common cach-y things (like ttl) - */ - - private static final String DEFAULT_OUTPUT_PATH = "offlineEntityCache"; - private ExecutorService persistentExecutor; - private ObjectMapper mapper; - private String storagePath; - - /** - * Instantiates a new persistent entity cache. - */ - public PersistentEntityCache() { - this(null, 10); - } - - /** - * Instantiates a new persistent entity cache. - * - * @param numWorkers the num workers - */ - public PersistentEntityCache(int numWorkers) { - this(null, numWorkers); - } - - /** - * Instantiates a new persistent entity cache. - * - * @param storageFolderOverride the storage folder override - * @param numWorkers the num workers - */ - public PersistentEntityCache(String storageFolderOverride, int numWorkers) { - persistentExecutor = NodeUtils.createNamedExecutor("PEC", numWorkers, LOG); - mapper = new ObjectMapper(); - - if (storageFolderOverride != null && storageFolderOverride.length() > 0) { - this.storagePath = storageFolderOverride; - } else { - this.storagePath = DEFAULT_OUTPUT_PATH; - } - } - - /** - * Generate offline storage path from uri. - * - * @param link the link - * @return the string - */ - private String generateOfflineStoragePathFromUri(String link) { - - try { - URI uri = new URI(link); - - String modHost = uri.getHost().replace(".", "_"); - - String[] tokens = uri.getPath().split("\\/"); - List<String> resourcePathAndDomain = new ArrayList<String>(); - - if (tokens.length >= 4) { - - int numElements = 0; - for (String w : tokens) { - - if (numElements > 3) { - break; - } - - if (w.length() > 0) { - resourcePathAndDomain.add(w); - numElements++; - } - - } - } else { - return this.storagePath + "\\"; - } - - return this.storagePath + "\\" + modHost + "\\" - + NodeUtils.concatArray(resourcePathAndDomain, "_") + "\\"; - - } catch (Exception exc) { - LOG.error(AaiUiMsgs.OFFLINE_STORAGE_PATH_ERROR, link, exc.getMessage()); - } - - return this.storagePath + "\\"; - - } - - /** - * Creates the dirs. - * - * @param directoryPath the directory path - */ - private void createDirs(String directoryPath) { - if (directoryPath == null) { - return; - } - - Path path = Paths.get(directoryPath); - // if directory exists? - if (!Files.exists(path)) { - try { - Files.createDirectories(path); - } catch (IOException exc) { - LOG.error(AaiUiMsgs.DISK_CREATE_DIR_IO_ERROR, exc.getMessage()); - } - } - - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.dal.cache.EntityCache#get(java.lang.String, java.lang.String) - */ - @Override - public OperationResult get(String key, String link) { - - final String storagePath = generateOfflineStoragePathFromUri(link); - createDirs(storagePath); - final String persistentFileName = storagePath + "\\" + key + ".json"; - - CompletableFuture<OperationResult> task = supplyAsync( - new RetrieveOperationResultFromDisk(persistentFileName, mapper, LOG), persistentExecutor); - - try { - /* - * this will do a blocking get, but it will be blocking only on the thread that executed this - * method which should be one of the persistentWorker threads from the executor. - */ - return task.get(); - } catch (InterruptedException | ExecutionException exc) { - // TODO Auto-generated catch block - LOG.error(AaiUiMsgs.DISK_NAMED_DATA_READ_IO_ERROR, "txn", exc.getMessage()); - } - - return null; - - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.dal.cache.EntityCache#put(java.lang.String, - * org.onap.aai.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()); - } - - }); - } - - } - - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.dal.cache.EntityCache#shutdown() - */ - @Override - public void shutdown() { - if (persistentExecutor != null) { - persistentExecutor.shutdown(); - } - - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.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/onap/aai/sparky/dal/elasticsearch/ElasticSearchAdapter.java b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchAdapter.java deleted file mode 100644 index 9962bcb..0000000 --- a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchAdapter.java +++ /dev/null @@ -1,213 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.dal.elasticsearch; - -import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; -import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestDataProvider; -import org.onap.aai.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.onap.aai.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.onap.aai.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.onap.aai.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.onap.aai.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.onap.aai.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.onap.aai.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.onap.aai.sparky.dal.rest.RestDataProvider#clearCache() - */ - @Override - public void clearCache() { - restDataProvider.clearCache(); - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.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.onap.aai.sparky.dal.elasticsearch.ElasticSearchDataProvider#shutdown() - */ - @Override - public void shutdown() { - restDataProvider.shutdown(); - } - - /* - * (non-Javadoc) - * - * @see - * org.onap.aai.sparky.dal.rest.RestDataProvider#doRestfulOperation(org.onap.aai.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.onap.aai.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"); - } - - /** - * @return the bulkImportIndexTemplate - */ - public static String getBulkImportIndexTemplate() { - return BULK_IMPORT_INDEX_TEMPLATE; - } - - /** - * @return the restDataProvider - */ - public RestDataProvider getRestDataProvider() { - return restDataProvider; - } - - /** - * @return the esConfig - */ - public ElasticSearchConfig getEsConfig() { - return esConfig; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchDataProvider.java b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchDataProvider.java index 416e251..90075fe 100644 --- a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchDataProvider.java +++ b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchDataProvider.java @@ -25,6 +25,10 @@ package org.onap.aai.sparky.dal.elasticsearch; import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.dal.rest.RestDataProvider; +/* + * TODO: DELETE ME + */ + /** * The Interface ElasticSearchDataProvider. */ @@ -57,7 +61,7 @@ public interface ElasticSearchDataProvider extends RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#shutdown() + * @see org.openecomp.sparky.dal.rest.RestDataProvider#shutdown() */ @Override void shutdown(); diff --git a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java index 50d318b..ba012bd 100644 --- a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java +++ b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/ElasticSearchEntityStatistics.java @@ -29,11 +29,10 @@ import java.util.Set; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicInteger; -import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.dal.NetworkTransaction; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; + /** * The Class ElasticSearchEntityStatistics. @@ -48,7 +47,6 @@ public class ElasticSearchEntityStatistics { private static final String ERROR = "ERROR"; private Map<String, HashMap<String, AtomicInteger>> entityStatistics; - private OxmModelLoader loader; /** * Creates the entity op stats. @@ -70,19 +68,6 @@ public class ElasticSearchEntityStatistics { } - /* - * private void createActiveInventoryEntityStatistics() { - * - * Map<String,OxmEntityDescriptor> descriptors = loader.getSearchableEntityDescriptors(); - * - * if(descriptors == null) { return; } - * - * OxmEntityDescriptor d = null; for ( String key : descriptors.keySet() ) { d = - * descriptors.get(key); entityStatistics.put(d.getEntityName(), createEntityOpStats()); } - * - * } - */ - /** * Initializecreate active inventory entity statistics. */ @@ -109,10 +94,8 @@ public class ElasticSearchEntityStatistics { * * @param loader the loader */ - public ElasticSearchEntityStatistics(OxmModelLoader loader) { - this.loader = loader; + public ElasticSearchEntityStatistics() { entityStatistics = new HashMap<String, HashMap<String, AtomicInteger>>(); - // createActiveInventoryEntityStatistics(); reset(); } @@ -121,18 +104,25 @@ public class ElasticSearchEntityStatistics { * * @param descriptors the descriptors */ - public void initializeCountersFromOxmEntityDescriptors( - Map<String, OxmEntityDescriptor> descriptors) { + public void intializeEntityCounters(String... entityTypes) { + + if (entityTypes != null && entityTypes.length > 0) { + for (String entityType : entityTypes) { + entityStatistics.put(entityType, createEntityOpStats()); + } - if (descriptors == null) { - return; } - OxmEntityDescriptor descriptor = null; - for (String key : descriptors.keySet()) { - descriptor = descriptors.get(key); - entityStatistics.put(descriptor.getEntityName(), createEntityOpStats()); + } + + public void intializeEntityCounters(Set<String> entityTypes) { + + if (entityTypes != null && entityTypes.size() > 0) { + for (String entityType : entityTypes) { + entityStatistics.put(entityType, createEntityOpStats()); + } } + } /** diff --git a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/HashQueryResponse.java b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/HashQueryResponse.java index 646916b..8abf20f 100644 --- a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/HashQueryResponse.java +++ b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/HashQueryResponse.java @@ -22,8 +22,7 @@ */ package org.onap.aai.sparky.dal.elasticsearch; -import org.json.JSONObject; -import org.onap.aai.sparky.dal.rest.OperationResult; +import org.onap.aai.restclient.client.OperationResult; public class HashQueryResponse { private String jsonPayload = null; diff --git a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/SearchAdapter.java b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/SearchAdapter.java index 200f405..c4e81b7 100644 --- a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/SearchAdapter.java +++ b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/SearchAdapter.java @@ -29,20 +29,17 @@ import java.util.Map; import javax.ws.rs.core.MediaType; -import org.onap.aai.sparky.dal.rest.OperationResult; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.Headers; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; import org.onap.aai.sparky.dal.sas.config.SearchServiceConfig; import org.onap.aai.sparky.util.Encryptor; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.slf4j.MDC; -import org.onap.aai.restclient.client.RestClient; -import org.onap.aai.restclient.enums.RestAuthenticationMode; -import org.onap.aai.restclient.client.Headers; -import org.onap.aai.cl.mdc.MdcContext; - -import org.onap.aai.cl.mdc.MdcContext; /** * The Class SearchAdapter. @@ -53,41 +50,6 @@ public class SearchAdapter { private RestClient client; - /** - * @return the client - */ - public RestClient getClient() { - return client; - } - - /** - * @param client the client to set - */ - public void setClient(RestClient client) { - this.client = client; - } - - /** - * @return the commonHeaders - */ - public Map<String, List<String>> getCommonHeaders() { - return commonHeaders; - } - - /** - * @param commonHeaders the commonHeaders to set - */ - public void setCommonHeaders(Map<String, List<String>> commonHeaders) { - this.commonHeaders = commonHeaders; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - private Map<String, List<String>> commonHeaders; private SearchServiceConfig sasConfig; @@ -99,8 +61,8 @@ public class SearchAdapter { public SearchAdapter() throws Exception { sasConfig = SearchServiceConfig.getConfig(); Encryptor encryptor = new Encryptor(); - client = new RestClient().authenticationMode(RestAuthenticationMode.SSL_CERT) - .validateServerHostname(false).validateServerCertChain(false) + + client = new RestClient().validateServerHostname(false).validateServerCertChain(false) .clientCertFile(TierSupportUiConstants.CONFIG_AUTH_LOCATION + sasConfig.getCertName()) .clientCertPassword(encryptor.decryptValue(sasConfig.getKeystorePassword())) .trustStore(TierSupportUiConstants.CONFIG_AUTH_LOCATION + sasConfig.getKeystore()); @@ -119,27 +81,25 @@ public class SearchAdapter { } public OperationResult doPost(String url, String jsonPayload, String acceptContentType) { - org.onap.aai.restclient.client.OperationResult or = client.post(url, jsonPayload, - getTxnHeader(), MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE); + 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.onap.aai.restclient.client.OperationResult or = - client.get(url, getTxnHeader(), MediaType.APPLICATION_JSON_TYPE); + 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.onap.aai.restclient.client.OperationResult or = client.put(url, payload, getTxnHeader(), - MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE); + 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.onap.aai.restclient.client.OperationResult or = - client.delete(url, getTxnHeader(), MediaType.APPLICATION_JSON_TYPE); + OperationResult or = client.delete(url, getTxnHeader(), MediaType.APPLICATION_JSON_TYPE); return new OperationResult(or.getResultCode(), or.getResult()); } diff --git a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/config/ElasticSearchConfig.java b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/config/ElasticSearchConfig.java index 68e4151..c3c27f8 100644 --- a/src/main/java/org/onap/aai/sparky/dal/elasticsearch/config/ElasticSearchConfig.java +++ b/src/main/java/org/onap/aai/sparky/dal/elasticsearch/config/ElasticSearchConfig.java @@ -22,21 +22,11 @@ */ package org.onap.aai.sparky.dal.elasticsearch.config; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; import java.util.Properties; -import org.onap.aai.sparky.dal.exception.ElasticSearchOperationException; -import org.onap.aai.sparky.synchronizer.config.TaskProcessorConfig; import org.onap.aai.sparky.util.ConfigHelper; import org.onap.aai.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. @@ -64,9 +54,7 @@ public class ElasticSearchConfig { private String settingsFileName; - private int syncAdapterMaxConcurrentWorkers; - - private String auditIndexName; + private String topographicalSearchIndex; private String entityCountHistoryIndex; @@ -112,16 +100,6 @@ public class ElasticSearchConfig { 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) { @@ -174,6 +152,10 @@ public class ElasticSearchConfig { private void initializeProperties() { Properties props = ConfigHelper.loadConfigFromExplicitPath(CONFIG_FILE); + if (props == null || props.isEmpty()) { + return; + } + 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); @@ -182,9 +164,11 @@ public class ElasticSearchConfig { 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"); @@ -197,13 +181,6 @@ public class ElasticSearchConfig { 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() { @@ -266,24 +243,16 @@ public class ElasticSearchConfig { 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 String getTopographicalSearchIndex() { + return topographicalSearchIndex; } - public void setAuditIndexName(String auditIndexName) { - this.auditIndexName = auditIndexName; + public void setTopographicalSearchIndex(String topographicalSearchIndex) { + this.topographicalSearchIndex = topographicalSearchIndex; } public String getEntityCountHistoryIndex() { @@ -309,55 +278,6 @@ public class ElasticSearchConfig { 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; } @@ -382,266 +302,4 @@ public class ElasticSearchConfig { 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); - } - - } - - /** - * @return the instance - */ - public static ElasticSearchConfig getInstance() { - return instance; - } - - /** - * @param instance the instance to set - */ - public static void setInstance(ElasticSearchConfig instance) { - ElasticSearchConfig.instance = instance; - } - - /** - * @return the configFile - */ - public static String getConfigFile() { - return CONFIG_FILE; - } - - /** - * @return the ipAddressDefault - */ - public static String getIpAddressDefault() { - return IP_ADDRESS_DEFAULT; - } - - /** - * @return the httpPortDefault - */ - public static String getHttpPortDefault() { - return HTTP_PORT_DEFAULT; - } - - /** - * @return the javaApiPortDefault - */ - public static String getJavaApiPortDefault() { - return JAVA_API_PORT_DEFAULT; - } - - /** - * @return the typeDefault - */ - public static String getTypeDefault() { - return TYPE_DEFAULT; - } - - /** - * @return the clusterNameDefault - */ - public static String getClusterNameDefault() { - return CLUSTER_NAME_DEFAULT; - } - - /** - * @return the indexNameDefault - */ - public static String getIndexNameDefault() { - return INDEX_NAME_DEFAULT; - } - - /** - * @return the auditIndexNameDefault - */ - public static String getAuditIndexNameDefault() { - return AUDIT_INDEX_NAME_DEFAULT; - } - - /** - * @return the topographicalIndexNameDefault - */ - public static String getTopographicalIndexNameDefault() { - return TOPOGRAPHICAL_INDEX_NAME_DEFAULT; - } - - /** - * @return the entityCountHistoryIndexNameDefault - */ - public static String getEntityCountHistoryIndexNameDefault() { - return ENTITY_COUNT_HISTORY_INDEX_NAME_DEFAULT; - } - - /** - * @return the entityAutoSuggestIndexNameDefault - */ - public static String getEntityAutoSuggestIndexNameDefault() { - return ENTITY_AUTO_SUGGEST_INDEX_NAME_DEFAULT; - } - - /** - * @return the entityAutoSuggestSettingsFileDefault - */ - public static String getEntityAutoSuggestSettingsFileDefault() { - return ENTITY_AUTO_SUGGEST_SETTINGS_FILE_DEFAULT; - } - - /** - * @return the entityAutoSuggestMappingsFileDefault - */ - public static String getEntityAutoSuggestMappingsFileDefault() { - return ENTITY_AUTO_SUGGEST_MAPPINGS_FILE_DEFAULT; - } - - /** - * @return the entityDynamicMappingsFileDefault - */ - public static String getEntityDynamicMappingsFileDefault() { - return ENTITY_DYNAMIC_MAPPINGS_FILE_DEFAULT; - } - - /** - * @return the bulkApi - */ - public static String getBulkApi() { - return BULK_API; - } - - /* - * (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 - + ", entityCountHistoryIndex=" + entityCountHistoryIndex + ", autosuggestIndexname=" - + autosuggestIndexname + ", entityCountHistoryMappingsFileName=" - + entityCountHistoryMappingsFileName + ", autoSuggestSettingsFileName=" - + autoSuggestSettingsFileName + ", autoSuggestMappingsFileName=" - + autoSuggestMappingsFileName + ", dynamicMappingsFileName=" + dynamicMappingsFileName - + ", processorConfig=" + processorConfig + "]"; - } } diff --git a/src/main/java/org/onap/aai/sparky/dal/proxy/config/DataRouterConfig.java b/src/main/java/org/onap/aai/sparky/dal/proxy/config/DataRouterConfig.java new file mode 100644 index 0000000..df2ae13 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/dal/proxy/config/DataRouterConfig.java @@ -0,0 +1,132 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.dal.proxy.config; + +import java.util.Properties; + +import org.onap.aai.sparky.util.ConfigHelper; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; + +public class DataRouterConfig { + private String host; + private String port; + private String drUriSuffix; + private String certName; + private String keystorePassword; + private String keystore; + private int connectTimeout; + private int readTimeout; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + 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; + } + + public int getConnectTimeout() { + return connectTimeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public int getReadTimeout() { + return readTimeout; + } + + public void setReadTimeout(int readTimeout) { + this.readTimeout = readTimeout; + } + + public String getDrUriSuffix() { + return drUriSuffix; + } + + public void setDrUriSuffix(String drUriSuffix) { + this.drUriSuffix = drUriSuffix; + } + + public DataRouterConfig(Properties props) { + + if (props == null) { + return; + } + + Properties restProps = ConfigHelper.getConfigWithPrefix("data-router.rest", props); + host = restProps.getProperty(TierSupportUiConstants.IP_ADDRESS, "localhost"); + port = restProps.getProperty(TierSupportUiConstants.PORT, "9502"); + drUriSuffix = restProps.getProperty(TierSupportUiConstants.DR_URI_SUFFIX, "ui-request"); + connectTimeout = + Integer.parseInt(restProps.getProperty(TierSupportUiConstants.DR_CONNECT_TIMEOUT, "5000")); + readTimeout = + Integer.parseInt(restProps.getProperty(TierSupportUiConstants.DR_READ_TIMEOUT, "1000")); + + Properties sslProps = ConfigHelper.getConfigWithPrefix("data-router.ssl", props); + certName = sslProps.getProperty(TierSupportUiConstants.DR_CERT_NAME, "aai-client-cert.p12"); + keystorePassword = sslProps.getProperty(TierSupportUiConstants.DR_KEYSTORE_PASSWORD, ""); + keystore = sslProps.getProperty(TierSupportUiConstants.DR_KEYSTORE, "tomcat_keystore"); + } + + @Override + public String toString() { + return "DataRouterConfig [host=" + host + ", port=" + port + ", drUriSuffix=" + drUriSuffix + + ", certName=" + certName + ", keystorePassword=" + keystorePassword + ", keystore=" + + keystore + ", connectTimeout=" + connectTimeout + ", readTimeout=" + readTimeout + "]"; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/dal/proxy/processor/AaiUiProxyProcessor.java b/src/main/java/org/onap/aai/sparky/dal/proxy/processor/AaiUiProxyProcessor.java new file mode 100644 index 0000000..444a34b --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/dal/proxy/processor/AaiUiProxyProcessor.java @@ -0,0 +1,227 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.dal.proxy.processor; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.json.Json; +import javax.json.JsonObjectBuilder; +import javax.servlet.http.HttpServletRequest; + +import org.apache.camel.Exchange; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.aai.restclient.rest.HttpUtil; +import org.onap.aai.sparky.dal.proxy.config.DataRouterConfig; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.util.ConfigHelper; +import org.onap.aai.sparky.util.Encryptor; +import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; +import org.slf4j.MDC; + +/** + * The Class AaiUiProxyProcessor. + */ +public class AaiUiProxyProcessor { + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(AaiUiProxyProcessor.class); + private static Logger auditLogger = + LoggerFactory.getInstance().getAuditLogger(AaiUiProxyProcessor.class.getName()); + public String configFile = + TierSupportUiConstants.DYNAMIC_CONFIG_APP_LOCATION + "data-router.properties"; + + private RestClient client; + private DataRouterConfig config; + private String drBaseUrl; + private OperationResult operationResult = null; + + private String xTransactionId; + private String xFromAppId; + + private static final String ROUTER_SERVICE = "routerService"; + + public String getDrBaseUrl() { + return drBaseUrl; + } + + public void setDrBaseUrl(String drBaseUrl) { + this.drBaseUrl = drBaseUrl; + } + + /** + * Instantiates a new AaiUiProxyProcessor. + */ + + public AaiUiProxyProcessor() { + Properties props = ConfigHelper.loadConfigFromExplicitPath(configFile); + config = new DataRouterConfig(props); + initializeProxyProcessor(config); + } + + public AaiUiProxyProcessor(DataRouterConfig config) { + initializeProxyProcessor(config); + } + + private void initializeProxyProcessor(DataRouterConfig config) { + Encryptor encryptor = new Encryptor(); + client = new RestClient().validateServerHostname(false).validateServerCertChain(false) + .clientCertFile(TierSupportUiConstants.CONFIG_AUTH_LOCATION + config.getCertName()) + .clientCertPassword(encryptor.decryptValue(config.getKeystorePassword())) + .trustStore(TierSupportUiConstants.CONFIG_AUTH_LOCATION + config.getKeystore()) + .connectTimeoutMs(config.getConnectTimeout()).readTimeoutMs(config.getReadTimeout()); + + drBaseUrl = + "https://" + config.getHost() + ":" + config.getPort() + "/" + config.getDrUriSuffix(); + } + + void setUpMdcContext(final Exchange exchange, final HttpServletRequest request) { + + Object xTransactionId = exchange.getIn().getHeader("X-TransactionId"); + if (xTransactionId == null) { + this.xTransactionId = NodeUtils.getRandomTxnId(); + } else { + this.xTransactionId = (String) xTransactionId; + } + + Object partnerName = exchange.getIn().getHeader("X-FromAppId"); + if (partnerName == null) { + xFromAppId = "Browser"; + } else { + xFromAppId = (String) partnerName; + } + + MdcContext.initialize((String) xTransactionId, "AAI-UI", "", xFromAppId, + request.getRequestURI() + ":" + request.getLocalPort()); + } + + private Map<String, List<String>> getHeaders() { + Map<String, List<String>> headers = new HashMap<>(); + headers.put("X-FromAppId", Arrays.asList(TierSupportUiConstants.APP_NAME)); + 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; + } + + private String getProxyPayloadAsString(final Exchange exchange) { + JsonObjectBuilder jsonBuilder = Json.createObjectBuilder(); + String srcUri = ""; + try { + srcUri = (String) exchange.getIn().getHeader(Exchange.HTTP_URI); + jsonBuilder.add("origin-uri", srcUri); + + String body = exchange.getIn().getBody(String.class); + + if (body != null && body.length() != 0) { + jsonBuilder.add("origin-payload", body); + } + + } catch (Exception e) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "Failed to extract payload for proxying.\n" + "Requestor URL: " + srcUri); + } + + return jsonBuilder.build().toString(); + } + + private String getDrUrl(String requestUri) { + String url = ""; + int pos = requestUri.indexOf(ROUTER_SERVICE); + if (pos != -1) { + url = drBaseUrl + requestUri.substring(pos + ROUTER_SERVICE.length()); + } else { + LOG.error(AaiUiMsgs.DR_REQUEST_URI_FOR_PROXY_UNKNOWN, requestUri); + } + return url; + } + + public void proxyMessage(Exchange exchange) { + HttpServletRequest request = exchange.getIn().getBody(HttpServletRequest.class); + + setUpMdcContext(exchange, request); + + try { + Map<String, List<String>> headers = getHeaders(); + String proxyPayload = getProxyPayloadAsString(exchange); + String fromUrl = (String) exchange.getIn().getHeader(Exchange.HTTP_URI); + String toUrl = getDrUrl(fromUrl); + auditLogger.info(AaiUiMsgs.DR_PROXY_FROM_TO, fromUrl, toUrl); + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, + "Proxying request:\n" + proxyPayload + "\n" + "Target URL:\n" + toUrl); + + long startTimeInMs = System.currentTimeMillis(); + + operationResult = client.post(toUrl, proxyPayload, headers, + javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE, + javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE); + + long drOpTime = (System.currentTimeMillis() - startTimeInMs); + int rc = operationResult.getResultCode(); + String result = ""; + + if (HttpUtil.isHttpResponseClassSuccess(rc)) { + result = operationResult.getResult(); + } else { + result = operationResult.getFailureCause(); + LOG.info(AaiUiMsgs.DR_PROCESSING_FAILURE, String.valueOf(rc), proxyPayload); + } + + auditLogger.info(AaiUiMsgs.DR_PROCESSING_TIME, String.valueOf(drOpTime)); + + exchange.getOut().setHeader("X-TransactionId", xTransactionId); + exchange.getOut().setHeader("X-FromAppId", xFromAppId); + exchange.getOut().setHeader("RequestUrl", request.getRequestURI()); + exchange.getOut().setHeader("RequestPort", request.getLocalPort()); + exchange.getOut().setBody(result); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_PROCESSING_REQUEST, exc); + } + } + + public RestClient getClient() { + return client; + } + + public void setClient(RestClient client) { + this.client = client; + } + + public DataRouterConfig getConfig() { + return config; + } + + public void setConfig(DataRouterConfig config) { + this.config = config; + } + + protected OperationResult getOperationResult() { + return operationResult; + } +} diff --git a/src/main/java/org/onap/aai/sparky/dal/rest/RestClientBuilder.java b/src/main/java/org/onap/aai/sparky/dal/rest/RestClientBuilder.java index 77f04e0..5977a03 100644 --- a/src/main/java/org/onap/aai/sparky/dal/rest/RestClientBuilder.java +++ b/src/main/java/org/onap/aai/sparky/dal/rest/RestClientBuilder.java @@ -22,11 +22,6 @@ */ package org.onap.aai.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; @@ -34,6 +29,11 @@ import javax.net.ssl.SSLSession; import org.onap.aai.sparky.security.SecurityContextFactory; import org.onap.aai.sparky.security.SecurityContextFactoryImpl; +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; + /** * 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 diff --git a/src/main/java/org/onap/aai/sparky/dal/rest/RestfulDataAccessor.java b/src/main/java/org/onap/aai/sparky/dal/rest/RestfulDataAccessor.java index c229de1..9f07aff 100644 --- a/src/main/java/org/onap/aai/sparky/dal/rest/RestfulDataAccessor.java +++ b/src/main/java/org/onap/aai/sparky/dal/rest/RestfulDataAccessor.java @@ -24,11 +24,9 @@ package org.onap.aai.sparky.dal.rest; import java.security.SecureRandom; -import org.onap.aai.sparky.dal.cache.EntityCache; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.util.NodeUtils; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; @@ -37,6 +35,9 @@ import com.sun.jersey.api.client.WebResource.Builder; /** * The Class RestfulDataAccessor. + * + * TODO: DELETE ME + * */ public class RestfulDataAccessor implements RestDataProvider { @@ -44,8 +45,6 @@ public class RestfulDataAccessor implements RestDataProvider { protected RestClientBuilder clientBuilder; - protected EntityCache entityCache; - private boolean cacheEnabled; private static final Logger LOG = LoggerFactory.getInstance().getLogger(RestfulDataAccessor.class); @@ -66,37 +65,6 @@ public class RestfulDataAccessor implements RestDataProvider { 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); - } } /** @@ -119,27 +87,12 @@ public class RestfulDataAccessor implements RestDataProvider { } - /** - * 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.onap.aai.sparky.dal.rest.RestDataProvider#doRestfulOperation(org.onap.aai.sparky.dal.rest. - * HttpMethod, java.lang.String, java.lang.String, java.lang.String, java.lang.String) + * 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, @@ -151,31 +104,11 @@ public class RestfulDataAccessor implements RestDataProvider { 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 operationResult = new OperationResult(); operationResult.setRequestLink(url); try { @@ -245,8 +178,6 @@ public class RestfulDataAccessor implements RestDataProvider { String.valueOf(operationResult.getResultCode())); } - cacheResult(operationResult); - return operationResult; } @@ -262,7 +193,7 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#doGet(java.lang.String, java.lang.String) + * @see org.openecomp.sparky.dal.rest.RestDataProvider#doGet(java.lang.String, java.lang.String) */ @Override public OperationResult doGet(String url, String acceptContentType) { @@ -272,7 +203,8 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#doDelete(java.lang.String, java.lang.String) + * @see org.openecomp.sparky.dal.rest.RestDataProvider#doDelete(java.lang.String, + * java.lang.String) */ @Override public OperationResult doDelete(String url, String acceptContentType) { @@ -282,7 +214,7 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#doPost(java.lang.String, java.lang.String, + * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPost(java.lang.String, java.lang.String, * java.lang.String) */ @Override @@ -294,7 +226,7 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#doPut(java.lang.String, java.lang.String, + * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPut(java.lang.String, java.lang.String, * java.lang.String) */ @Override @@ -306,7 +238,7 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#doPatch(java.lang.String, java.lang.String, + * @see org.openecomp.sparky.dal.rest.RestDataProvider#doPatch(java.lang.String, java.lang.String, * java.lang.String) */ @Override @@ -318,7 +250,7 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#doHead(java.lang.String, java.lang.String) + * @see org.openecomp.sparky.dal.rest.RestDataProvider#doHead(java.lang.String, java.lang.String) */ @Override public OperationResult doHead(String url, String acceptContentType) { @@ -350,27 +282,20 @@ public class RestfulDataAccessor implements RestDataProvider { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#shutdown() + * @see org.openecomp.sparky.dal.rest.RestDataProvider#shutdown() */ @Override public void shutdown() { - if (entityCache != null) { - entityCache.shutdown(); - } - } /* * (non-Javadoc) * - * @see org.onap.aai.sparky.dal.rest.RestDataProvider#clearCache() + * @see org.openecomp.sparky.dal.rest.RestDataProvider#clearCache() */ @Override public void clearCache() { - if (cacheEnabled) { - entityCache.clear(); - } } diff --git a/src/main/java/org/onap/aai/sparky/dal/sas/config/SearchServiceConfig.java b/src/main/java/org/onap/aai/sparky/dal/sas/config/SearchServiceConfig.java index 0925d71..cb6f933 100644 --- a/src/main/java/org/onap/aai/sparky/dal/sas/config/SearchServiceConfig.java +++ b/src/main/java/org/onap/aai/sparky/dal/sas/config/SearchServiceConfig.java @@ -70,6 +70,9 @@ public class SearchServiceConfig { 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 { @@ -108,6 +111,8 @@ public class SearchServiceConfig { 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"); diff --git a/src/main/java/org/onap/aai/sparky/dal/servlet/ResettableStreamHttpServletRequest.java b/src/main/java/org/onap/aai/sparky/dal/servlet/ResettableStreamHttpServletRequest.java deleted file mode 100644 index 4713222..0000000 --- a/src/main/java/org/onap/aai/sparky/dal/servlet/ResettableStreamHttpServletRequest.java +++ /dev/null @@ -1,128 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.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"); - } - - } - -} diff --git a/src/main/java/org/onap/aai/sparky/dataintegrity/config/DiUiConstants.java b/src/main/java/org/onap/aai/sparky/dataintegrity/config/DiUiConstants.java new file mode 100644 index 0000000..c449931 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/dataintegrity/config/DiUiConstants.java @@ -0,0 +1,77 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.dataintegrity.config; + +/** + * The Class DiUiConstants. + */ +public class DiUiConstants { + + public static final String APP_JSON = "application/json"; + public static final String CATEGORY = "category"; + + public static final String ENTITY_TYPE = "entityType"; + public static final String KEY_AGG = "aggregations"; + public static final String KEY_AGG_RESULT = "aggregationResult"; + public static final String KEY_AGG_RESULT_COUNT = "count"; + public static final String KEY_AGG_RESULT_ID = "key_as_string"; + public static final String KEY_BUCKETS = "buckets"; + public static final String KEY_ROUTE = "route"; + public static final String KEY_FILTERS = "filters"; + public static final String KEY_FILTER_VALUE = "filterValue"; + public static final String KEY_FILTER_ID = "filterId"; + public static final String KEY_START_DATE = "startDate"; + public static final String KEY_END_DATE = "endDate"; + public static final String KEY_TIME_ZONE = "time_zone"; + public static final String DEFAULT_TIME_ZONE = "+00:00"; + + public static final String WIDGET_TYPE_SEVERITY = "severity"; + public static final String WIDGET_TYPE_CATEGORY = "category"; + public static final String WIDGET_TYPE_ENTITY_TYPE = "entityType"; + public static final String WIDGET_TYPE_PAGINATED_TABLE = "pagination"; + public static final String WIDGET_TYPE_DATE_HISTOGRAM = "dateHistogram"; + + + public static final String KEY_BY_ITEM = "by_item"; + public static final String KEY_ENTITY_ID = "entityId"; + public static final String KEY_HITS = "hits"; + public static final String KEY_SEARCH_RESULT = "searchResult"; + public static final String KEY_INNER_HITS = "inner_hits"; + public static final String KEY_ITEM = "item"; + public static final String KEY_ITEM_AGG = "item_aggregation"; + public static final String KEY_TIMESTAMP = "violationTimestamp"; + public static final String KEY_TOTAL_HITS = "totalHits"; + public static final String KEY_VIOLATION_DETAILS = "violationDetails"; + public static final String SEARCH_API = "query"; + + public static final String SEVERITY = "severity"; + public static final String UI_KEY_BY_CATEGORY = "group_by_status"; + public static final String UI_KEY_BY_DATE = "group_by_date"; + public static final String UI_KEY_BY_ENTITY_TYPE = "group_by_entityType"; + public static final String UI_KEY_BY_SEVERITY = "group_by_severity"; + + public static final String UI_KEY_ORDER_BY_DATE = "order_by_date"; + public static final String VIOLATIONS = "violations"; + public static final String KEY_VIEW_NAME = "Data Integrity"; + +} diff --git a/src/main/java/org/onap/aai/sparky/editattributes/AttributeEditProcessor.java b/src/main/java/org/onap/aai/sparky/editattributes/AttributeEditProcessor.java new file mode 100644 index 0000000..42b439e --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/editattributes/AttributeEditProcessor.java @@ -0,0 +1,182 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.editattributes; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.component.restlet.RestletConstants; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.editattributes.entity.EditRequest; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.util.NodeUtils; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.ClientInfo; +import org.restlet.data.Cookie; +import org.restlet.data.MediaType; +import org.restlet.data.Status; +import org.restlet.util.Series; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * The Class AttributeEditProcessor. + */ +public class AttributeEditProcessor { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(AttributeEditProcessor.class); + + private ObjectMapper mapper; + private AttributeUpdater attrUpdater; + + public AttributeEditProcessor(AttributeUpdater attributeUpdater) { + this.attrUpdater = attributeUpdater; + + this.mapper = new ObjectMapper(); + mapper.setSerializationInclusion(Include.NON_EMPTY); + } + + public void editAttribute(Exchange exchange) { + + Object xTransactionId = exchange.getIn().getHeader("X-TransactionId"); + + if (xTransactionId == null) { + xTransactionId = NodeUtils.getRandomTxnId(); + } + + Object partnerName = exchange.getIn().getHeader("X-FromAppId"); + if (partnerName == null) { + partnerName = "Browser"; + } + + Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); + + /* + * Disables automatic Apache Camel Restlet component logging which prints out an undesirable log + * entry which includes client (e.g. browser) information + */ + request.setLoggable(false); + + ClientInfo clientInfo = request.getClientInfo(); + MdcContext.initialize((String) xTransactionId, "AAI-UI", "", (String) partnerName, + clientInfo.getAddress() + ":" + clientInfo.getPort()); + + String payload = exchange.getIn().getBody(String.class); + EditRequest editRequest = null; + OperationResult operationResult = new OperationResult(); + + Response response = + exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); + response.setStatus(Status.SUCCESS_OK); // 200 is assumed unless an actual exception occurs (a + // failure is still a valid response) + + boolean wasErrorDuringProcessing = false; + String errorMessage = null; + + + try { + + if (payload != null && !payload.isEmpty()) { + editRequest = mapper.readValue(payload, EditRequest.class); + + if (editRequest != null) { + + String attUid = getAttUid(request.getCookies()); + String objectUri = editRequest.getEntityUri(); + Map<String, Object> attributeValues = editRequest.getAttributes(); + + if (attUid != null && !attUid.isEmpty() && objectUri != null && !objectUri.isEmpty() + && attributeValues != null && !attributeValues.isEmpty()) { + + LOG.info(AaiUiMsgs.ATTRIBUTES_HANDLING_EDIT, objectUri, editRequest.toString()); + + operationResult = attrUpdater.updateObjectAttribute(objectUri, attributeValues, attUid); + + boolean wasSuccess = (operationResult.getResultCode() == 200); + String message = String.format("Edit Attributes completed with Result Code : %s (%s).", + operationResult.getResultCode(), wasSuccess ? "success" : "failed"); + + LOG.info(AaiUiMsgs.INFO_GENERIC, message); + } + } + } else { + wasErrorDuringProcessing = true; + errorMessage = "Empty payload provided, need details to complete request"; + } + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage()); + operationResult.setResult(500, "Error encountered while trying to update attributes."); + response.setStatus(Status.SERVER_ERROR_INTERNAL); + } + + if (wasErrorDuringProcessing) { + LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_MESSAGE, errorMessage); + } + + response.setEntity(operationResult.getResult(), MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + } + + /** + * Gets the att uid. + * + * @param request the request + * @return the att uid + * @throws UnsupportedEncodingException the unsupported encoding exception + */ + public String getAttUid(Series<Cookie> cookies) throws UnsupportedEncodingException { + String attId = ""; + if (cookies == null) { + LOG.error(AaiUiMsgs.COOKIE_NOT_FOUND); + return attId; + } + for (Cookie cookie : cookies) { + if (cookie.getName().equals("attESHr")) { + // This cookie is of the form : + // "FIRSTNAME|LASTNAME|emailname@domain.com|||ab1234||fl6789,RBFMSKQ," + // + "Z9V2298,9762186|YNNNNNNNNNNNNNYNNYYNNNNN|FIRSTNAME|EY6SC9000|" + // we are to extract fl6789 from this which would be the attuid for the user. + String value = cookie.getValue(); + value = java.net.URLDecoder.decode(value, "UTF-8"); + LOG.info(AaiUiMsgs.COOKIE_FOUND, value); + String[] values = value.split("\\|"); + if (values.length > 7) { + attId = (values[7].split(","))[0]; + + String initials = (values[0].substring(0, 1) + values[1].substring(0, 1)).toLowerCase(); + if (attId.startsWith(initials)) { + return attId; + } + } + } + } + return attId; + } +} diff --git a/src/main/java/org/onap/aai/sparky/editattributes/AttributeUpdater.java b/src/main/java/org/onap/aai/sparky/editattributes/AttributeUpdater.java new file mode 100644 index 0000000..5e6d652 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/editattributes/AttributeUpdater.java @@ -0,0 +1,366 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.editattributes; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.ws.rs.core.UriBuilder; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; +import org.onap.aai.sparky.editattributes.exception.AttributeUpdateException; +import org.onap.aai.sparky.logging.AaiUiMsgs; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; + +/** + * Class to process attribute updates on AAI objects. + * + * + */ +public class AttributeUpdater { + + /** + * The Class AaiEditObject. + */ + public class AaiEditObject { + String objectType; + String rootElement; + String keyName; + String keyValue; + String schemaVersion; + + /** + * Instantiates a new aai edit object. + */ + public AaiEditObject() { + + } + + /** + * Instantiates a new aai edit object. + * + * @param objectType the object type + * @param idName the id name + * @param schemaVersion the schema version + */ + public AaiEditObject(String objectType, String idName, String schemaVersion) { + super(); + this.objectType = objectType; + this.keyName = idName; + this.schemaVersion = schemaVersion; + } + + public String getObjectType() { + return objectType; + } + + public void setObjectType(String objectType) { + this.objectType = objectType; + } + + public String getKeyName() { + return keyName; + } + + public void setKeyName(String idName) { + this.keyName = idName; + } + + public String getSchemaVersion() { + return schemaVersion; + } + + public void setSchemaVersion(String schemaVersion) { + this.schemaVersion = schemaVersion; + } + + public void setKeyValue(String keyValue) { + this.keyValue = keyValue; + } + + public String getKeyValue() { + return keyValue; + } + + public String getRootElement() { + return rootElement; + } + + public void setRootElement(String rootElement) { + this.rootElement = rootElement; + } + + } + + private static final Logger LOG = LoggerFactory.getInstance().getLogger(AttributeUpdater.class); + private static final String MESSAGE_VERSION_EXTRACTION_REGEX = "\\/(v[0-9]+)"; + private static final String ATTRIBUTES_UPDATED_SUCCESSFULLY = "Attributes updated successfully"; + private static final String ATTRIBUTES_NOT_UPDATED = "Attributes not updated. "; + private ActiveInventoryConfig aaiConfig; + private ActiveInventoryAdapter aaiAdapter; + private UserValidator validator; + private OxmModelLoader oxmModelLoader; + private OxmEntityLookup oxmEntityLookup; + + /** + * Instantiates a new attribute updater. + * + * @throws AttributeUpdateException + */ + public AttributeUpdater(OxmModelLoader oxmModelLoader, OxmEntityLookup oxmEntityLookup, + ActiveInventoryAdapter activeInventoryAdapter) throws AttributeUpdateException { + super(); + this.oxmModelLoader = oxmModelLoader; + this.oxmEntityLookup = oxmEntityLookup; + this.aaiAdapter = activeInventoryAdapter; + + try { + this.aaiConfig = ActiveInventoryConfig.getConfig(); // TODO -> Config to become a bean + this.validator = new UserValidator(); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ATTRIBUTES_ERROR_GETTING_AAI_CONFIG_OR_ADAPTER, + exc.getLocalizedMessage()); + throw new AttributeUpdateException(exc); + } + } + + protected String getResourceBasePath() { + + String versionStr = null; + if (oxmModelLoader != null) { + versionStr = String.valueOf(oxmModelLoader.getLatestVersionNum()); + } + + return "/aai/v" + versionStr; + + } + + protected URI getBaseUri() { + return UriBuilder.fromUri("https://" + aaiConfig.getAaiRestConfig().getHost() + ":" + + aaiConfig.getAaiRestConfig().getPort() + getResourceBasePath()).build(); + } + + /** + * Update object attribute. + * + * @param objectUri - Valid URI of the object as per OXM model. + * @param attributeValues - Map of (attribute-name & attribute-value) for any attributes to be + * updated to the value. + * @param attUid - ATTUID of the user requesting the update. + * @return - OperationResult with success or failure reason. + */ + public OperationResult updateObjectAttribute(String objectUri, + Map<String, Object> attributeValues, String attUid) { + OperationResult result = new OperationResult(); + LOG.info(AaiUiMsgs.ATTRIBUTES_UPDATE_METHOD_CALLED, objectUri, attUid, + String.valueOf(attributeValues)); + if (!validator.isAuthorizedUser(attUid)) { + result.setResultCode(403); + result.setResult(String.format("User %s is not authorized for Attributes update ", attUid)); + LOG.error(AaiUiMsgs.ATTRIBUTES_USER_NOT_AUTHORIZED_TO_UPDATE, attUid); + return result; + } + + AaiEditObject object = null; + + try { + object = getEditObjectFromUri(objectUri); + } catch (AttributeUpdateException exc) { + result.setResultCode(400); + result.setResult(ATTRIBUTES_NOT_UPDATED); + LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage()); + return result; + } + try { + String jsonPayload = convertEditRequestToJson(object, attributeValues); + String patchUri = getBaseUri().toString() + getRelativeUri(objectUri); + + + /* + * FIX ME: Dave Adams, 8-Nov-2017 + */ + + // result = aaiAdapter.doPatch(patchUri, jsonPayload, MediaType.APPLICATION_JSON); + + result = new OperationResult(); + result.setResultCode(404); + + if (result.getResultCode() == 200) { + result.setResult(ATTRIBUTES_UPDATED_SUCCESSFULLY); + String message = result.getResult() + " for " + objectUri; + LOG.info(AaiUiMsgs.INFO_GENERIC, message); + } else { + String message = + ATTRIBUTES_NOT_UPDATED + " For: " + objectUri + ". AAI PATCH Status Code : " + + result.getResultCode() + ". Error : " + result.getResult(); + LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_MESSAGE, message); + } + } catch (AttributeUpdateException exc) { + result.setResultCode(500); + result.setResult(ATTRIBUTES_NOT_UPDATED + exc.getLocalizedMessage()); + LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage()); + } + return result; + + } + + /** + * Gets the relative uri. + * + * @param objectUri the object uri + * @return the relative uri + */ + public String getRelativeUri(String objectUri) { + String tempUri = objectUri; + final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL); + Matcher matcher = pattern.matcher(objectUri); + while (matcher.find()) { + tempUri = objectUri.substring(matcher.end()); + } + if (!tempUri.startsWith("/")) { + tempUri = "/" + tempUri; + } + return tempUri; + } + + /** + * Gets the edits the object from uri. + * + * @param objectUri the object uri + * @return the edits the object from uri + * @throws AttributeUpdateException the attribute update exception + */ + public AaiEditObject getEditObjectFromUri(String objectUri) throws AttributeUpdateException { + + AaiEditObject object = new AaiEditObject(); + String version = getVersionFromUri(objectUri); + + if (null == version) { + version = "v" + String.valueOf(oxmModelLoader.getLatestVersionNum()); + } + object.setSchemaVersion(version); + + String[] values = objectUri.split("/"); + if (values.length < 2) { + throw new AttributeUpdateException("Invalid or malformed object URI : " + objectUri); + } + String keyValue = values[values.length - 1]; + String rootElement = values[values.length - 2]; + + object.setKeyValue(keyValue); + object.setRootElement(rootElement); + + String objectJavaType = null; + Map<String, DynamicType> entityTypeLookup = oxmEntityLookup.getEntityTypeLookup(); + DynamicType entity = entityTypeLookup.get(rootElement); + if (null != entity) { + objectJavaType = entity.getName(); + String message = + "Descriptor: Alias: " + objectJavaType + " : DefaultRootElement: " + rootElement; + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, message); + } + + + if (objectJavaType == null) { + throw new AttributeUpdateException( + "Object type could not be determined from the URI : " + objectUri); + } + object.setObjectType(objectJavaType); + + // Set key attribute name + final List<String> primaryKeys = entity.getDescriptor().getPrimaryKeyFieldNames(); + + if (primaryKeys.isEmpty()) { + throw new AttributeUpdateException("Object primary key not found in OXM version " + version); + } + + for (int i = 0; i < primaryKeys.size(); i++) { + final String primaryKey = primaryKeys.get(i); + if (primaryKey.indexOf("/text()") != -1) { + primaryKeys.set(i, primaryKey.replace("/text()", "")); + } + } + object.setKeyName(primaryKeys.iterator().next()); + + return object; + } + + /** + * Gets the version from uri. + * + * @param objectUri the object uri + * @return the version from uri + * @throws AttributeUpdateException the attribute update exception + */ + private String getVersionFromUri(String objectUri) throws AttributeUpdateException { + final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL); + Matcher matcher = pattern.matcher(objectUri); + String messageSchemaVersion = null; + while (matcher.find()) { + messageSchemaVersion = matcher.group(1); + break; + } + return messageSchemaVersion; + } + + /** + * Convert edit request to json. + * + * @param object the object + * @param attributeValues the attribute values + * @return the string + * @throws AttributeUpdateException the attribute update exception + */ + private static String convertEditRequestToJson(AaiEditObject object, + Map<String, Object> attributeValues) throws AttributeUpdateException { + + ObjectMapper mapper = new ObjectMapper(); + mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.KebabCaseStrategy()); + ObjectWriter ow = mapper.writer(); + + Map<String, Object> patchAttributes = new HashMap<>(); + patchAttributes.put(object.getKeyName(), object.getKeyValue()); + patchAttributes.putAll(attributeValues); + + try { + return ow.writeValueAsString(patchAttributes); + } catch (JsonProcessingException exc) { + throw new AttributeUpdateException("Caught a JPE while creating PATCH request body = ", exc); + } + } +} diff --git a/src/main/java/org/onap/aai/sparky/editattributes/UserAuthorizationReader.java b/src/main/java/org/onap/aai/sparky/editattributes/UserAuthorizationReader.java new file mode 100644 index 0000000..65467a2 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/editattributes/UserAuthorizationReader.java @@ -0,0 +1,77 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.editattributes; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Reads user IDs from a file. Each line in the user authorization file should contain a single user + * ID. For example, + * + * <pre> + * user1 + * user2 + * </pre> + */ +public class UserAuthorizationReader { + + private File userAuthorizationFile; + + /** + * Set the user authorization file. + * + * @param file a user authorization file + */ + public UserAuthorizationReader(File file) { + this.userAuthorizationFile = file; + } + + /** + * Gets user IDs from a file. + * + * @return a list of user IDs + * @throws IOException if there is a problem reading the user configuration file + */ + public List<String> getUsers() throws IOException { + List<String> userList = new ArrayList<>(); + try (Stream<String> stream = Files.lines(getUserAuthorizationFile().toPath())) { + userList.addAll(stream.map(String::trim).collect(Collectors.toList())); + } + return userList; + } + + // Getters and setters + public File getUserAuthorizationFile() { + return userAuthorizationFile; + } + + public void setUserAuthorizationFile(File file) { + this.userAuthorizationFile = file; + } +} diff --git a/src/main/java/org/onap/aai/sparky/editattributes/UserValidator.java b/src/main/java/org/onap/aai/sparky/editattributes/UserValidator.java new file mode 100644 index 0000000..cccd815 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/editattributes/UserValidator.java @@ -0,0 +1,65 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.editattributes; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; + +/** + * Validates users against a user authorization file. + */ +public class UserValidator { + + private static final Logger LOG = LoggerFactory.getInstance().getLogger(UserValidator.class); + private static final String USER_AUTH_FILE = + TierSupportUiConstants.AUTHORIZED_USERS_FILE_LOCATION; + + private UserAuthorizationReader userAuthorizationReader = + new UserAuthorizationReader(new File(USER_AUTH_FILE)); + + /** + * Returns true if the user is authorized. + * + * @param userId a user identifier + * @return true if the user ID is present in the user authorization file + */ + public boolean isAuthorizedUser(String userId) { + if (userId != null && !userId.isEmpty()) { + try { + List<String> users = userAuthorizationReader.getUsers(); + return users.contains(userId); + } catch (IOException exc) { + LOG.error(AaiUiMsgs.USER_AUTHORIZATION_FILE_UNAVAILABLE, userId); + return false; + } + } else { + return false; + } + } +} diff --git a/src/main/java/org/onap/aai/sparky/search/Suggestion.java b/src/main/java/org/onap/aai/sparky/editattributes/entity/EditRequest.java index 72530ef..df4c685 100644 --- a/src/main/java/org/onap/aai/sparky/search/Suggestion.java +++ b/src/main/java/org/onap/aai/sparky/editattributes/entity/EditRequest.java @@ -20,38 +20,48 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.search; +package org.onap.aai.sparky.editattributes.entity; -public class Suggestion { +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The Class EditRequest. + */ +public class EditRequest { + + @JsonProperty("entity-uri") + private String entityUri; + + @JsonProperty("entity-type") private String entityType; - private String searchTags; - private SearchEntityProperties properties; - public Suggestion(SearchEntityProperties properties) { - this.properties = properties; - } + @JsonProperty("attributes") + private Map<String, Object> attributes = new HashMap<>(); - public String getEntityType() { - return entityType; + public String getEntityUri() { + return entityUri; } - public String getSearchTags() { - return searchTags; + public void setEntityUri(String entityUri) { + this.entityUri = entityUri; } - public SearchEntityProperties getProperties() { - return properties; + public String getEntityType() { + return entityType; } public void setEntityType(String entityType) { this.entityType = entityType; } - public void setSearchTags(String searchTags) { - this.searchTags = searchTags; + public Map<String, Object> getAttributes() { + return attributes; } - public void setProperties(SearchEntityProperties properties) { - this.properties = properties; + public void setAttributes(Map<String, Object> attributes) { + this.attributes = attributes; } } diff --git a/src/main/java/org/onap/aai/sparky/editattributes/exception/AttributeUpdateException.java b/src/main/java/org/onap/aai/sparky/editattributes/exception/AttributeUpdateException.java new file mode 100644 index 0000000..4612785 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/editattributes/exception/AttributeUpdateException.java @@ -0,0 +1,60 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.editattributes.exception; + +/** + * The Class AttributeUpdateException. + */ +public class AttributeUpdateException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Attribute Edit specific Exception Class. + * + * @param exc the exc + */ + + public AttributeUpdateException(Exception exc) { + super(exc); + } + + /** + * Instantiates a new attribute update exception. + * + * @param message the message + */ + public AttributeUpdateException(String message) { + super(message); + } + + /** + * Instantiates a new attribute update exception. + * + * @param message the message + * @param exc the exc + */ + public AttributeUpdateException(String message, Exception exc) { + super(message, exc); + } +} diff --git a/src/main/java/org/onap/aai/sparky/inventory/EntityHistoryQueryBuilder.java b/src/main/java/org/onap/aai/sparky/inventory/EntityHistoryQueryBuilder.java new file mode 100644 index 0000000..b765dc8 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/inventory/EntityHistoryQueryBuilder.java @@ -0,0 +1,143 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.inventory; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; + +/** + * The Class EntityHistoryQueryBuilder. + */ +public class EntityHistoryQueryBuilder { + + private static final String TABLE = "table"; + private static final String GRAPH = "graph"; + + /** + * Gets the query. + * + * @param type the type + * @return the query + */ + public static JsonObject getQuery(String type) { + if (type.equalsIgnoreCase(TABLE)) { + return createTableQuery(); + } else if (type.equalsIgnoreCase(GRAPH)) { + return createGraphQuery(); + } else { + return null; + } + } + + /** + * Creates the graph query. + * + * @return the json object + */ + public static JsonObject createGraphQuery() { + JsonObjectBuilder jsonBuilder = Json.createObjectBuilder(); + + jsonBuilder.add("aggs", + Json.createObjectBuilder().add("group_by_entityType", + Json.createObjectBuilder() + .add("terms", Json.createObjectBuilder().add("field", "entityType").add("size", 0)) + .add("aggs", Json.createObjectBuilder().add("group_by_date", + Json.createObjectBuilder().add("date_histogram", createDateHistogram()) + .add("aggs", Json.createObjectBuilder().add("sort_by_date", + Json.createObjectBuilder().add("top_hits", createTopHitsBlob()))))))); + jsonBuilder.add("size", 0); + + return jsonBuilder.build(); + } + + /** + * Creates the table query. + * + * @return the json object + */ + public static JsonObject createTableQuery() { + JsonObjectBuilder jsonBuilder = Json.createObjectBuilder(); + + jsonBuilder + .add("aggs", + Json.createObjectBuilder().add("group_by_entityType", + Json.createObjectBuilder() + .add("terms", + Json.createObjectBuilder().add("field", "entityType").add("size", 0)) + .add("aggs", Json.createObjectBuilder().add("sort_by_date", + Json.createObjectBuilder().add("top_hits", createTopHitsBlob()))))); + jsonBuilder.add("size", 0); + + return jsonBuilder.build(); + } + + /** + * Creates the date histogram. + * + * @return the json object + */ + private static JsonObject createDateHistogram() { + JsonObjectBuilder jsonBuilder = Json.createObjectBuilder(); + + jsonBuilder.add("field", "timestamp"); + jsonBuilder.add("min_doc_count", 1); + jsonBuilder.add("interval", "day"); + jsonBuilder.add("format", "epoch_millis"); + + return jsonBuilder.build(); + } + + /** + * Creates the top hits blob. + * + * @return the json object + */ + private static JsonObject createTopHitsBlob() { + JsonObjectBuilder builder = Json.createObjectBuilder(); + builder.add("size", 1); + builder.add("sort", getSortCriteria()); + return builder.build(); + } + + public static JsonArray getSortCriteria() { + JsonArrayBuilder jsonBuilder = Json.createArrayBuilder(); + jsonBuilder.add(Json.createObjectBuilder().add("timestamp", + Json.createObjectBuilder().add("order", "desc"))); + + return jsonBuilder.build(); + } + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(String[] args) { + System.out.println("TABLE-QUERY: " + createTableQuery().toString()); + System.out.println("GRAPH_QUERY: " + createGraphQuery().toString()); + } + +} diff --git a/src/main/java/org/onap/aai/sparky/inventory/GeoVisualizationProcessor.java b/src/main/java/org/onap/aai/sparky/inventory/GeoVisualizationProcessor.java new file mode 100644 index 0000000..c356191 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/inventory/GeoVisualizationProcessor.java @@ -0,0 +1,202 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.inventory; + +import java.io.IOException; + +import org.apache.camel.Exchange; +import org.apache.camel.component.restlet.RestletConstants; +import org.json.JSONArray; +import org.json.JSONObject; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; +import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.logging.util.ServletUtils; +import org.onap.aai.sparky.util.NodeUtils; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.ClientInfo; +import org.restlet.data.Form; +import org.restlet.data.MediaType; +import org.restlet.data.Parameter; +import org.restlet.data.Status; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * The Class GeoVisualizationServlet. + */ +public class GeoVisualizationProcessor { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(GeoVisualizationProcessor.class); + + private ObjectMapper mapper; + private SearchAdapter search = null; + private ElasticSearchConfig elasticConfig = null; + + private static final String SEARCH_STRING = "_search"; + private static final String SEARCH_PARAMETER = + "?filter_path=hits.hits._source&_source=location&size=5000&q=entityType:"; + private static final String PARAMETER_KEY = "entity"; + + /** + * Instantiates a new geo visualization processor + */ + public GeoVisualizationProcessor() { + this.mapper = new ObjectMapper(); + + try { + if (elasticConfig == null) { + elasticConfig = ElasticSearchConfig.getConfig(); + } + if (search == null) { + search = new SearchAdapter(); + } + this.mapper = new ObjectMapper(); + } catch (Exception exc) { + + } + } + + public void setSearch(SearchAdapter search) { + this.search = search; + } + + public void setElasticConfig(ElasticSearchConfig elasticConfig) { + this.elasticConfig = elasticConfig; + } + + /** + * Gets the geo visualization results. + * + * @param response the response + * @param entityType the entity type + * @return the geo visualization results + * @throws Exception the exception + */ + protected OperationResult getGeoVisualizationResults(Exchange exchange) throws Exception { + OperationResult operationResult = new OperationResult(); + + + Object xTransactionId = exchange.getIn().getHeader("X-TransactionId"); + if (xTransactionId == null) { + xTransactionId = NodeUtils.getRandomTxnId(); + } + + Object partnerName = exchange.getIn().getHeader("X-FromAppId"); + if (partnerName == null) { + partnerName = "Browser"; + } + + Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); + + /* + * Disables automatic Apache Camel Restlet component logging which prints out an undesirable log + * entry which includes client (e.g. browser) information + */ + request.setLoggable(false); + + ClientInfo clientInfo = request.getClientInfo(); + MdcContext.initialize((String) xTransactionId, "AAI-UI", "", (String) partnerName, + clientInfo.getAddress() + ":" + clientInfo.getPort()); + + String entityType = ""; + + Form form = request.getResourceRef().getQueryAsForm(); + for (Parameter parameter : form) { + if (PARAMETER_KEY.equals(parameter.getName())) { + entityType = parameter.getName(); + } + } + + String parameters = SEARCH_PARAMETER + entityType; + String requestString = String.format("/%s/%s/%s", elasticConfig.getTopographicalSearchIndex(), + SEARCH_STRING, parameters); + + try { + final String fullUrlStr = ServletUtils.getFullUrl(elasticConfig, requestString); + OperationResult opResult = search.doGet(fullUrlStr, "application/json"); + + JSONObject finalOutputJson = formatOutput(opResult.getResult()); + + Response response = + exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); + response.setStatus(Status.SUCCESS_OK); + response.setEntity(String.valueOf(finalOutputJson), MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, "Error processing Geo Visualization request"); + } + + return operationResult; + } + + /** + * Format output. + * + * @param results the results + * @return the JSON object + */ + private JSONObject formatOutput(String results) { + JsonNode resultNode = null; + JSONObject finalResult = new JSONObject(); + JSONArray entitiesArr = new JSONArray(); + + try { + resultNode = mapper.readTree(results); + + final JsonNode hitsNode = resultNode.get("hits").get("hits"); + if (hitsNode.isArray()) { + + for (final JsonNode arrayNode : hitsNode) { + JsonNode sourceNode = arrayNode.get("_source"); + if (sourceNode.get("location") != null) { + JsonNode locationNode = sourceNode.get("location"); + if (NodeUtils.isNumeric(locationNode.get("lon").asText()) + && NodeUtils.isNumeric(locationNode.get("lat").asText())) { + JSONObject location = new JSONObject(); + location.put("longitude", locationNode.get("lon").asText()); + location.put("latitude", locationNode.get("lat").asText()); + + entitiesArr.put(location); + } + + } + } + } + finalResult.put("plotPoints", entitiesArr); + + } catch (IOException exc) { + LOG.warn(AaiUiMsgs.ERROR_BUILDING_SEARCH_RESPONSE, exc.getLocalizedMessage()); + } + + return finalResult; + } +} diff --git a/src/main/java/org/onap/aai/sparky/inventory/entity/GeoIndexDocument.java b/src/main/java/org/onap/aai/sparky/inventory/entity/GeoIndexDocument.java new file mode 100644 index 0000000..3596c54 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/inventory/entity/GeoIndexDocument.java @@ -0,0 +1,292 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.inventory.entity; + +import java.io.Serializable; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.sync.entity.IndexDocument; +import org.onap.aai.sparky.util.NodeUtils; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * The Class GeoIndexDocument. + */ +public class GeoIndexDocument implements Serializable, IndexDocument { + + @JsonIgnore + private static final long serialVersionUID = -5188479658230319058L; + + protected String entityType; + protected String entityPrimaryKeyValue; + protected String entityPrimaryKeyName; + protected String latitude; + protected String longitude; + protected String selfLink; + + @JsonIgnore + protected OxmEntityLookup oxmEntityLookup; + + @JsonIgnore + protected ObjectMapper mapper = new ObjectMapper(); + // generated, SHA-256 digest + @JsonIgnore + protected String id; + + /** + * Convert bytes to hex string. + * + * @param bytesToConvert the bytes to convert + * @return the string + */ + private static String convertBytesToHexString(byte[] bytesToConvert) { + StringBuffer hexString = new StringBuffer(); + for (int i = 0; i < bytesToConvert.length; i++) { + hexString.append(Integer.toHexString(0xFF & bytesToConvert[i])); + } + return hexString.toString(); + } + + + @JsonIgnore + public boolean isValidGeoDocument() { + + boolean isValid = true; + + isValid &= (this.getEntityType() != null); + isValid &= (this.getLatitude() != null); + isValid &= (this.getLongitude() != null); + isValid &= (this.getId() != null); + isValid &= (this.getSelfLink() != null); + + isValid &= NodeUtils.isNumeric(this.getLatitude()); + isValid &= NodeUtils.isNumeric(this.getLongitude()); + + return isValid; + } + + /** + * Concat array. + * + * @param list the list + * @param delimiter the delimiter + * @return the string + */ + private static String concatArray(List<String> list, char delimiter) { + + if (list == null || list.size() == 0) { + return ""; + } + + StringBuilder result = new StringBuilder(64); + + int listSize = list.size(); + boolean firstValue = true; + + for (String item : list) { + + if (firstValue) { + result.append(item); + firstValue = false; + } else { + result.append(delimiter).append(item); + } + + } + + return result.toString(); + + } + + /* + * We'll try and create a unique identity key that we can use for differencing the previously + * imported record sets as we won't have granular control of what is created/removed and when. The + * best we can hope for is identification of resources by generated Id until the Identity-Service + * UUID is tagged against all resources, then we can use that instead. + */ + + /** + * Generate unique sha digest. + * + * @param entityType the entity type + * @param fieldName the field name + * @param fieldValue the field value + * @return the string + * @throws NoSuchAlgorithmException the no such algorithm exception + */ + public static String generateUniqueShaDigest(String entityType, String fieldName, + String fieldValue) throws NoSuchAlgorithmException { + + /* + * Basically SHA-256 will result in an identity with a guaranteed uniqueness compared to just a + * java hashcode value. + */ + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + digest.update(String.format("%s.%s.%s", entityType, fieldName, fieldValue).getBytes()); + return convertBytesToHexString(digest.digest()); + } + + /** + * Instantiates a new geo index document. + */ + public GeoIndexDocument() {} + + /* + * (non-Javadoc) + * + * @see com.att.queryrouter.dao.DocumentStoreDataEntity#getAsJson() + */ + + @Override + @JsonIgnore + public String getAsJson() throws JsonProcessingException { + + if (latitude != null && longitude != null) { + + /** + * A valid entry from this class is one that has both lat and long. If one or both is missing + * we shouldn't be indexing anything. + */ + + return NodeUtils.convertObjectToJson(this, true); + + } + + return null; + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.entity.IndexDocument#deriveFields() + */ + @Override + public void deriveFields() { + + /* + * We'll try and create a unique identity key that we can use for differencing the previously + * imported record sets as we won't have granular control of what is created/removed and when. + * The best we can hope for is identification of resources by generated Id until the + * Identity-Service UUID is tagged against all resources, then we can use that instead. + */ + + OxmEntityDescriptor descriptor = oxmEntityLookup.getEntityDescriptors().get(entityType); + String entityPrimaryKeyName = + NodeUtils.concatArray(descriptor.getPrimaryKeyAttributeNames(), "/"); + + this.id = + NodeUtils.generateUniqueShaDigest(entityType, entityPrimaryKeyName, entityPrimaryKeyValue); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "TopographicalEntity [" + ("entityType=" + entityType + ", ") + + ("entityPrimaryKeyValue=" + entityPrimaryKeyValue + ", ") + + ("latitude=" + latitude + ", ") + ("longitude=" + longitude + ", ") + ("ID=" + id + ", ") + + ("selfLink=" + selfLink) + "]"; + } + + @Override + @JsonIgnore + public String getId() { + return this.id; + } + + @JsonProperty("entityType") + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + @JsonProperty("entityPrimaryKeyValue") + public String getEntityPrimaryKeyValue() { + return entityPrimaryKeyValue; + } + + public void setEntityPrimaryKeyValue(String entityPrimaryKeyValue) { + this.entityPrimaryKeyValue = entityPrimaryKeyValue; + } + + @JsonProperty("entityPrimaryKeyName") + public String getEntityPrimaryKeyName() { + return entityPrimaryKeyName; + } + + public void setEntityPrimaryKeyName(String entityPrimaryKeyName) { + this.entityPrimaryKeyName = entityPrimaryKeyName; + } + + @JsonProperty("lat") + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + @JsonProperty("long") + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + @JsonProperty("link") + public String getSelfLink() { + return selfLink; + } + + public void setSelfLink(String selfLink) { + this.selfLink = selfLink; + } + + @JsonIgnore + public static long getSerialversionuid() { + return serialVersionUID; + } + + public void setId(String id) { + this.id = id; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/inventory/entity/TopographicalEntity.java b/src/main/java/org/onap/aai/sparky/inventory/entity/TopographicalEntity.java new file mode 100644 index 0000000..7736255 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/inventory/entity/TopographicalEntity.java @@ -0,0 +1,220 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.inventory.entity; + +import java.io.IOException; +import java.io.Serializable; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +import javax.json.Json; +import javax.json.JsonObject; + +/** + * The Class TopographicalEntity. + */ +public class TopographicalEntity implements Serializable { + + private static final long serialVersionUID = -5188479658230319058L; + + protected String entityType; + protected String entityPrimaryKeyValue; + protected String entityPrimaryKeyName; + protected String latitude; + protected String longitude; + protected String selfLink; + + // generated, SHA-256 digest + protected String id; + + /** + * Convert bytes to hex string. + * + * @param bytesToConvert the bytes to convert + * @return the string + */ + private static String convertBytesToHexString(byte[] bytesToConvert) { + StringBuffer hexString = new StringBuffer(); + for (int i = 0; i < bytesToConvert.length; i++) { + hexString.append(Integer.toHexString(0xFF & bytesToConvert[i])); + } + return hexString.toString(); + } + + /** + * Concat array. + * + * @param list the list + * @param delimiter the delimiter + * @return the string + */ + private static String concatArray(List<String> list, char delimiter) { + + if (list == null || list.size() == 0) { + return ""; + } + + StringBuilder result = new StringBuilder(64); + + int listSize = list.size(); + boolean firstValue = true; + + for (String item : list) { + + if (firstValue) { + result.append(item); + firstValue = false; + } else { + result.append(delimiter).append(item); + } + + } + + return result.toString(); + + } + + /* + * We'll try and create a unique identity key that we can use for differencing the previously + * imported record sets as we won't have granular control of what is created/removed and when. The + * best we can hope for is identification of resources by generated Id until the Identity-Service + * UUID is tagged against all resources, then we can use that instead. + */ + + /** + * Generate unique sha digest. + * + * @param entityType the entity type + * @param fieldName the field name + * @param fieldValue the field value + * @return the string + * @throws NoSuchAlgorithmException the no such algorithm exception + */ + public static String generateUniqueShaDigest(String entityType, String fieldName, + String fieldValue) throws NoSuchAlgorithmException { + + /* + * Basically SHA-256 will result in an identity with a guaranteed uniqueness compared to just a + * java hashcode value. + */ + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + digest.update(String.format("%s.%s.%s", entityType, fieldName, fieldValue).getBytes()); + return convertBytesToHexString(digest.digest()); + } + + /** + * Instantiates a new topographical entity. + */ + public TopographicalEntity() {} + + /* + * (non-Javadoc) + * + * @see com.att.queryrouter.dao.DocumentStoreDataEntity#getAsJson() + */ + public String getAsJson() throws IOException { + + JsonObject obj = + Json.createObjectBuilder().add("entityType", entityType).add("pkey", entityPrimaryKeyValue) + .add("location", Json.createObjectBuilder().add("lat", latitude).add("lon", longitude)) + .add("selfLink", selfLink).build(); + + return obj.toString(); + } + + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "TopographicalEntity [" + ("entityType=" + entityType + ", ") + + ("entityPrimaryKeyValue=" + entityPrimaryKeyValue + ", ") + + ("latitude=" + latitude + ", ") + ("longitude=" + longitude + ", ") + ("ID=" + id + ", ") + + ("selfLink=" + selfLink) + "]"; + } + + public String getId() { + return this.id; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public String getEntityPrimaryKeyValue() { + return entityPrimaryKeyValue; + } + + public void setEntityPrimaryKeyValue(String entityPrimaryKeyValue) { + this.entityPrimaryKeyValue = entityPrimaryKeyValue; + } + + public String getEntityPrimaryKeyName() { + return entityPrimaryKeyName; + } + + public void setEntityPrimaryKeyName(String entityPrimaryKeyName) { + this.entityPrimaryKeyName = entityPrimaryKeyName; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getSelfLink() { + return selfLink; + } + + public void setSelfLink(String selfLink) { + this.selfLink = selfLink; + } + + public static long getSerialversionuid() { + return serialVersionUID; + } + + public void setId(String id) { + this.id = id; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/logging/AaiUiMsgs.java b/src/main/java/org/onap/aai/sparky/logging/AaiUiMsgs.java index c89f83c..5854bc7 100644 --- a/src/main/java/org/onap/aai/sparky/logging/AaiUiMsgs.java +++ b/src/main/java/org/onap/aai/sparky/logging/AaiUiMsgs.java @@ -22,10 +22,10 @@ */ package org.onap.aai.sparky.logging; -import com.att.eelf.i18n.EELFResourceManager; - import org.onap.aai.cl.eelf.LogMessageEnum; +import com.att.eelf.i18n.EELFResourceManager; + /** * The Enum AaiUiMsgs. */ @@ -52,6 +52,14 @@ public enum AaiUiMsgs implements LogMessageEnum { UNEXPECTED_TOKEN_COUNT, /** Arguments: {0} = Error/exception message. */ ADD_SEARCH_TARGET_ATTRIBUTES_FAILED, + /** Arguments: {0} = Error/exception message. */ + NODE_INTEGRITY_OVERLAY_ERROR, + /** Arguments: {0} = Node ID. */ + NODE_INTEGRITY_ALREADY_PROCESSED, + /** Arguments: {0} = Node ID. */ + SKIPPING_PROCESS_NODE_INTEGRITY, + /** Arguments: {0} = Error/exception message. */ + FAILED_TO_PROCESS_NODE_INTEGRITY, /** No argument */ MAX_EVALUATION_ATTEMPTS_EXCEEDED, /** Arguments: {0} = Error/exception message. */ @@ -244,10 +252,10 @@ public enum AaiUiMsgs implements LogMessageEnum { INTERRUPTED, /** Arguments: {0} = Entity Type {1} Entity */ GEO_SYNC_IGNORING_ENTITY, + /** Arguments: {0} = reason */ + OXM_LOADING_ERROR, /** Arguments: {0} = type */ - OXM_FAILED_RETRIEVAL, - /** Arguments: {0} = Directory. */ - OXM_FILE_NOT_FOUND, + OXM_FAILED_RETRIEVAL, OXM_FILE_NOT_FOUND, /** No argument */ OXM_READ_ERROR_NONVERBOSE, /** Arguments: {0} = OXM File name */ @@ -256,7 +264,7 @@ public enum AaiUiMsgs implements LogMessageEnum { OXM_PARSE_ERROR_NONVERBOSE, /** Arguments: {0} = OXM File name {1} = Exception */ OXM_PARSE_ERROR_VERBOSE, - /** No argument */ + /** Arguments: {0} = Numerical value for loaded OXM version */ OXM_LOAD_SUCCESS, /** Arguments: {0} = Entity {1} = Found property-value */ OXM_PROP_DEF_ERR_CROSS_ENTITY_REF, @@ -302,6 +310,20 @@ public enum AaiUiMsgs implements LogMessageEnum { AAI_RETRIEVAL_FAILED_GENERIC, /** Arguments: {0} = Self Link */ AAI_RETRIEVAL_FAILED_FOR_SELF_LINK, + /** Arguments: {0} = Exception */ + ATTRIBUTES_NOT_UPDATED_EXCEPTION, + /** Arguments: {0} = Message */ + ATTRIBUTES_NOT_UPDATED_MESSAGE, + /** Arguments: {0} = Exception */ + ATTRIBUTES_ERROR_GETTING_AAI_CONFIG_OR_ADAPTER, + /** Arguments: {0} = Schema File URI */ + ATTRIBUTES_ERROR_LOADING_MODEL_VERSION, + /** Arguments: {0} = Request URI {1} = Edit Request Body */ + ATTRIBUTES_HANDLING_EDIT, + /** Arguments: {0} = Object URI {1} = Attribute ID {2} Attribute Values */ + ATTRIBUTES_UPDATE_METHOD_CALLED, + /** Arguments: {0} = Attribute ID */ + ATTRIBUTES_USER_NOT_AUTHORIZED_TO_UPDATE, /** Arguments: {0} = Cookie */ COOKIE_FOUND, /** No argument */ @@ -404,7 +426,7 @@ public enum AaiUiMsgs implements LogMessageEnum { /** Arguments: {0} = URL to extract parameter from */ ERROR_REMOVING_URL_PARAM, /** Arguments: {0} = Hash value */ - ERROR_INVALID_HASH, ERROR_HASH_NOT_FOUND, ERROR_READING_HTTP_REQ_PARAMS, + ERROR_INVALID_HASH, ERROR_HASH_NOT_FOUND, ERROR_FILTERS_NOT_FOUND, ERROR_READING_HTTP_REQ_PARAMS, /** Arguments: {0} = Exception */ ERROR_D3_GRAPH_VISUALIZATION, /** Arguments: {0} = Exception */ @@ -417,8 +439,25 @@ public enum AaiUiMsgs implements LogMessageEnum { VIEW_NAME_NOT_SUPPORTED, /** Arguments: {0} = response code, {1} = filter name */ ERROR_FETCHING_FILTER_VALUES, + /** Arguments: {0} = query type, {1} = view name */ + ERROR_PROCESSING_WIDGET_REQUEST, + /** Arguments: {0} = Time in ms */ + DR_PROCESSING_TIME, + /** Arguments: {0} = Response code {1} = payload */ + DR_PROCESSING_FAILURE, + /** Arguments: {0} = request uri */ + DR_REQUEST_URI_FOR_PROXY_UNKNOWN, + /** Arguments: {0} = origin-url {1} = dr-url */ + DR_PROXY_FROM_TO, + /** Arguments: {0} = Exception */ + URI_DECODING_EXCEPTION, + /** Arguments: {0} = Value {1} = Error */ + ENCRYPTION_ERROR, + /** Arguments: {0} = Encrypted value {1} = Error */ + DECRYPTION_ERROR, /** Arguments: {0} = URI */ RESOURCE_NOT_FOUND; + /** * Static initializer to ensure the resource bundles for this class are loaded... */ diff --git a/src/main/java/org/onap/aai/sparky/util/ServletUtils.java b/src/main/java/org/onap/aai/sparky/logging/util/ServletUtils.java index 2a8159e..dd040a2 100644 --- a/src/main/java/org/onap/aai/sparky/util/ServletUtils.java +++ b/src/main/java/org/onap/aai/sparky/logging/util/ServletUtils.java @@ -20,18 +20,18 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.util; +package org.onap.aai.sparky.logging.util; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.cl.api.Logger; /** * The Class ServletUtils. diff --git a/src/main/java/org/onap/aai/sparky/search/EntityCountHistoryProcessor.java b/src/main/java/org/onap/aai/sparky/search/EntityCountHistoryProcessor.java new file mode 100644 index 0000000..e2eef7a --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/search/EntityCountHistoryProcessor.java @@ -0,0 +1,417 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.search; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.restlet.RestletConstants; +import org.json.JSONArray; +import org.json.JSONObject; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; +import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; +import org.onap.aai.sparky.inventory.EntityHistoryQueryBuilder; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.logging.util.ServletUtils; +import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.util.RestletUtils; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.ClientInfo; +import org.restlet.data.MediaType; +import org.restlet.data.Status; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * Receives and processes Entity Count History requests + */ +public class EntityCountHistoryProcessor implements Processor { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(EntityCountHistoryProcessor.class); + + private static final long serialVersionUID = 1L; + + private SearchAdapter search = null; + private ElasticSearchConfig elasticConfig = null; + private VisualizationConfigs visualConfigs = null; + private ObjectMapper mapper; + + private static final String SEARCH_STRING = "_search"; + private static final String TYPE = "type"; + private static final String TABLE = "table"; + private static final String GRAPH = "graph"; + + private List<String> vnfEntityTypesToSummarize; + private boolean summarizevnf = false; + + private RestletUtils restletUtils = new RestletUtils(); + + /** + * Instantiates a new Entity Count History + */ + + public EntityCountHistoryProcessor(VisualizationConfigs visualizationConfigs) { + + this.visualConfigs = visualizationConfigs; + vnfEntityTypesToSummarize = + Arrays.asList(visualConfigs.getVnfEntityTypes().toLowerCase().split("[\\s,]+")); + summarizevnf = visualConfigs.getEntityTypesToSummarize().toLowerCase().contains("vnf"); + try { + if (elasticConfig == null) { + elasticConfig = ElasticSearchConfig.getConfig(); + } + + if (search == null) { + search = new SearchAdapter(); + } + this.mapper = new ObjectMapper(); + this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.CONFIGURATION_ERROR, exc.getLocalizedMessage()); + } + } + + /** + * Processes a entity count history search request + * + * @param exchange The Exchange object generated by Apache Camel for the incoming request + */ + + @Override + public void process(Exchange exchange) throws Exception { + + Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); + Response restletResponse = + exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); + + Object xTransactionId = exchange.getIn().getHeader("X-TransactionId"); + if (xTransactionId == null) { + xTransactionId = NodeUtils.getRandomTxnId(); + } + + Object partnerName = exchange.getIn().getHeader("X-FromAppId"); + if (partnerName == null) { + partnerName = "Browser"; + } + + /* + * Disables automatic Apache Camel Restlet component logging which prints out an undesirable log + * entry which includes client (e.g. browser) information + */ + request.setLoggable(false); + + ClientInfo clientInfo = request.getClientInfo(); + MdcContext.initialize((String) xTransactionId, "AAI-UI", "", (String) partnerName, + clientInfo.getAddress() + ":" + clientInfo.getPort()); + + String typeParameter = getTypeParameter(exchange); + + if (null != typeParameter && !typeParameter.isEmpty()) { + OperationResult operationResult = null; + + try { + operationResult = getResults(restletResponse, typeParameter); + restletResponse.setEntity(operationResult.getResult(), MediaType.APPLICATION_JSON); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.CONFIGURATION_ERROR, exc.getLocalizedMessage()); + } + } else { + LOG.error(AaiUiMsgs.RESOURCE_NOT_FOUND, request.getOriginalRef().toString()); + String errorMessage = + restletUtils.generateJsonErrorResponse("Unsupported request. Resource not found."); + restletResponse.setEntity(errorMessage, MediaType.APPLICATION_JSON); + restletResponse.setStatus(Status.CLIENT_ERROR_NOT_FOUND); + } + + exchange.getOut().setBody(restletResponse); + } + + + /** + * Format line graph output + * + * @param results The results + * @return The JSON object + * @throws JsonProcessingException The JSON processing exception + */ + public JSONObject formatLineGraphOutput(String results) throws JsonProcessingException { + Map<Long, Long> countByDateMap = new HashMap<Long, Long>(); + + JsonNode resultNode = null; + + JSONObject finalResult = new JSONObject(); + JSONArray finalResultArr = new JSONArray(); + + try { + resultNode = mapper.readTree(results); + + final JsonNode bucketsNode = getBucketsNode(resultNode); + + if (bucketsNode.isArray()) { + + for (final JsonNode entityNode : bucketsNode) { + final JsonNode dateBucketNode = entityNode.get("group_by_date").get("buckets"); + if (dateBucketNode.isArray()) { + for (final JsonNode dateBucket : dateBucketNode) { + Long date = dateBucket.get("key").asLong(); + final JsonNode countBucketNode = + dateBucket.get("sort_by_date").get("hits").get("hits"); + + if (countBucketNode.isArray()) { + final JsonNode latestEntityNode = countBucketNode.get(0); + + long currentCount = latestEntityNode.get("_source").get("count").asLong(); + if (countByDateMap.containsKey(date)) { + // add to the value if map already contains this date + currentCount += countByDateMap.get(date); + } + + countByDateMap.put(date, currentCount); + } + } + + } + } + } + + /* + * Sort the map by epoch timestamp + */ + Map<Long, Long> sortedMap = new TreeMap<Long, Long>(countByDateMap); + for (Entry<Long, Long> entry : sortedMap.entrySet()) { + JSONObject dateEntry = new JSONObject(); + dateEntry.put("date", entry.getKey()); + dateEntry.put("count", entry.getValue()); + finalResultArr.put(dateEntry); + } + + } catch (Exception exc) { + LOG.warn(AaiUiMsgs.ERROR_BUILDING_SEARCH_RESPONSE, exc.getLocalizedMessage()); + } + + return finalResult.put("result", finalResultArr); + } + + /** + * Format table output + * + * @param results The results + * @return The JSON object + * @throws JsonProcessingException The JSON processing exception + */ + public JSONObject formatTableOutput(String results) throws JsonProcessingException { + JsonNode resultNode = null; + + JSONObject finalResult = new JSONObject(); + JSONArray entitiesArr = new JSONArray(); + + Map<String, Long> entityCountInTable = initializeEntityMap(); + + long vnfCount = 0; + + try { + resultNode = mapper.readTree(results); + + final JsonNode bucketsNode = getBucketsNode(resultNode); + if (bucketsNode.isArray()) { + + for (final JsonNode entityNode : bucketsNode) { + String entityType = entityNode.get("key").asText(); + boolean isAVnf = vnfEntityTypesToSummarize.contains(entityType); + long countValue = 0; + + if (isAVnf || entityCountInTable.get(entityType) != null) { + final JsonNode hitsBucketNode = entityNode.get("sort_by_date").get("hits").get("hits"); + if (hitsBucketNode.isArray()) { + // the first bucket will be the latest + final JsonNode hitNode = hitsBucketNode.get(0); + + countValue = hitNode.get("_source").get("count").asLong(); + + /* + * Special case: Add all the VNF types together to get aggregate count + */ + if (summarizevnf && isAVnf) { + vnfCount += countValue; + countValue = vnfCount; + entityType = "vnf"; + } + + entityCountInTable.replace(entityType, countValue); + } + } + + } + } + for (Entry<String, Long> entry : entityCountInTable.entrySet()) { + JSONObject entityType = new JSONObject(); + entityType.put("key", entry.getKey()); + entityType.put("doc_count", entry.getValue()); + entitiesArr.put(entityType); + } + + finalResult.put("result", entitiesArr); + + } catch (Exception exc) { + LOG.warn(AaiUiMsgs.ERROR_BUILDING_RESPONSE_FOR_TABLE_QUERY, exc.getLocalizedMessage()); + } + + return finalResult; + } + + /** + * Gets the results + * + * @param response The response + * @param type The type + * @return The results + */ + public OperationResult getResults(Response response, String type) { + OperationResult operationResult = new OperationResult(); + + String requestString = + String.format("/%s/%s?pretty", elasticConfig.getEntityCountHistoryIndex(), SEARCH_STRING); + + String reqPayload = EntityHistoryQueryBuilder.getQuery(type).toString(); + + try { + final String fullUrlStr = ServletUtils.getFullUrl(elasticConfig, requestString); + OperationResult opResult = + restletUtils.executePostQuery(LOG, search, response, fullUrlStr, reqPayload); + + JSONObject finalOutput = null; + if (type.equalsIgnoreCase(TABLE)) { + finalOutput = formatTableOutput(opResult.getResult()); + } else if (type.equalsIgnoreCase(GRAPH)) { + finalOutput = formatLineGraphOutput(opResult.getResult()); + } + + if (finalOutput != null) { + response.setEntity(finalOutput.toString(), MediaType.APPLICATION_JSON); + operationResult.setResult(finalOutput.toString()); + } + } catch (JsonProcessingException exc) { + restletUtils.handleRestletErrors(LOG, "Unable to map JSONpayload", exc, response); + } + + return operationResult; + } + + /** + * Gets the buckets node + * + * @param node The node + * @return The buckets node + * @throws Exception The exception + */ + public JsonNode getBucketsNode(JsonNode node) throws Exception { + if (node.get("aggregations").get("group_by_entityType").get("buckets") != null) { + return node.get("aggregations").get("group_by_entityType").get("buckets"); + } else { + throw new Exception("Failed to map JSON response"); + } + } + + /** + * Initialize entity map + * + * @return the map + */ + private Map<String, Long> initializeEntityMap() { + Map<String, Long> entityMap = new HashMap<String, Long>(); + String[] entityTypes = visualConfigs.getEntityTypesToSummarize().split(","); + for (String entity : entityTypes) { + entityMap.put(entity, (long) 0); + } + + return entityMap; + } + + /** + * Extracts the "type" query parameter from the request URI + * + * @param exchange + * @return String containing the value of the "type" query parameter of the request. Returns null + * if no "type" parameter found + */ + public String getTypeParameter(Exchange exchange) { + String typeParameter = null; + + String requestUriParameterString = exchange.getIn().getHeader("CamelHttpQuery", String.class); + + if (null != requestUriParameterString) { + String[] requestParameterParts = requestUriParameterString.split("&"); + + String[] parameter = requestParameterParts[0].split("="); + String currentParameterKey = parameter[0]; + + if (null != currentParameterKey && !currentParameterKey.isEmpty()) { + // Check if we're looking at the "type" parameter key + if (currentParameterKey.equals(TYPE)) { + boolean uriIncludesTypeParameterValue = + (parameter.length >= 2) && !parameter[1].isEmpty(); + + if (uriIncludesTypeParameterValue) { + String typeParameterValue = parameter[1]; + + // Is the parameter value one that we return data for? + if (typeParameterValue.equalsIgnoreCase(TABLE) + || typeParameterValue.equalsIgnoreCase(GRAPH)) { + typeParameter = typeParameterValue; + } + } + } + } + } + + return typeParameter; + } + + public void setElasticConfig(ElasticSearchConfig elasticConfig) { + this.elasticConfig = elasticConfig; + } + + public void setRestletUtils(RestletUtils restletUtils) { + this.restletUtils = restletUtils; + } + + public void setSearch(SearchAdapter search) { + this.search = search; + } +} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SearchResponse.java b/src/main/java/org/onap/aai/sparky/search/SearchResponse.java index 7daf471..cddce49 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SearchResponse.java +++ b/src/main/java/org/onap/aai/sparky/search/SearchResponse.java @@ -20,12 +20,12 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.viewandinspect.entity; +package org.onap.aai.sparky.search; import java.util.ArrayList; import java.util.List; -import org.onap.aai.sparky.suggestivesearch.SuggestionEntity; +import org.onap.aai.sparky.search.entity.SearchSuggestion; /** * The Class SearchResponse. @@ -35,13 +35,13 @@ public class SearchResponse { private long processingTimeInMs; private int totalFound; - private List<SuggestionEntity> suggestions; + private List<SearchSuggestion> suggestions; /** * Instantiates a new search response. */ public SearchResponse() { - this.suggestions = new ArrayList<SuggestionEntity>(); + this.suggestions = new ArrayList<SearchSuggestion>(); this.processingTimeInMs = 0; this.totalFound = 0; } @@ -62,11 +62,11 @@ public class SearchResponse { this.totalFound = totalFound; } - public List<SuggestionEntity> getSuggestions() { + public List<SearchSuggestion> getSuggestions() { return suggestions; } - public void setSuggestions(List<SuggestionEntity> suggestions) { + public void setSuggestions(List<SearchSuggestion> suggestions) { this.suggestions = suggestions; } @@ -75,7 +75,7 @@ public class SearchResponse { * * @param suggestionEntry that will be converted to JSON */ - public void addSuggestion(SuggestionEntity suggestionEntity) { + public void addSuggestion(SearchSuggestion suggestionEntity) { suggestions.add(suggestionEntity); } @@ -87,4 +87,13 @@ public class SearchResponse { public void addToTotalFound(int additionalCount) { totalFound += additionalCount; } + + @Override + public String toString() { + return "SearchResponse [processingTimeInMs=" + processingTimeInMs + ", totalFound=" + totalFound + + ", " + (suggestions != null ? "suggestions=" + suggestions : "") + "]"; + } + + + } diff --git a/src/main/java/org/onap/aai/sparky/search/UnifiedSearchProcessor.java b/src/main/java/org/onap/aai/sparky/search/UnifiedSearchProcessor.java new file mode 100644 index 0000000..2983163 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/search/UnifiedSearchProcessor.java @@ -0,0 +1,212 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.search; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.apache.camel.Exchange; +import org.apache.camel.component.restlet.RestletConstants; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.search.api.SearchProvider; +import org.onap.aai.sparky.search.entity.QuerySearchEntity; +import org.onap.aai.sparky.search.entity.SearchSuggestion; +import org.onap.aai.sparky.search.registry.SearchProviderRegistry; +import org.onap.aai.sparky.util.NodeUtils; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.ClientInfo; +import org.restlet.data.MediaType; +import org.restlet.data.Status; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class UnifiedSearchProcessor { + + protected static final String HASH_ID_KEY = "hashId"; + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(UnifiedSearchProcessor.class); + + protected SearchProviderRegistry searchProviderRegistry; + protected ObjectMapper mapper; + protected boolean useOrderedSearchProviderKeys; + + public UnifiedSearchProcessor() { + mapper = new ObjectMapper(); + this.useOrderedSearchProviderKeys = false; + } + + public boolean isUseOrderedSearchProviderKeys() { + return useOrderedSearchProviderKeys; + } + + public void setUseOrderedSearchProviderKeys(boolean useOrderedSearchProviderKeys) { + this.useOrderedSearchProviderKeys = useOrderedSearchProviderKeys; + } + + public void search(Exchange exchange) { + + Object xTransactionId = exchange.getIn().getHeader("X-TransactionId"); + if (xTransactionId == null) { + xTransactionId = NodeUtils.getRandomTxnId(); + } + + Object partnerName = exchange.getIn().getHeader("X-FromAppId"); + if (partnerName == null) { + partnerName = "Browser"; + } + + Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); + + /* + * Disables automatic Apache Camel Restlet component logging which prints out an undesirable log + * entry which includes client (e.g. browser) information + */ + request.setLoggable(false); + + ClientInfo clientInfo = request.getClientInfo(); + MdcContext.initialize((String) xTransactionId, "AAI-UI", "", (String) partnerName, + clientInfo.getAddress() + ":" + clientInfo.getPort()); + + SearchResponse searchResponse = new SearchResponse(); + long processTime = System.currentTimeMillis(); + int totalAdded = 0; + + try { + String payload = exchange.getIn().getBody(String.class); + + if (payload == null || payload.isEmpty()) { + + LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, "Request Payload is empty"); + + /* + * Don't throw back an error, just return an empty set + */ + + } else { + + QuerySearchEntity searchRequest = mapper.readValue(payload, QuerySearchEntity.class); + int maxResultsPerSearch = Integer.valueOf(searchRequest.getMaxResults()); + + Map<String, List<SearchSuggestion>> searchProviderSuggestions = + new HashMap<String, List<SearchSuggestion>>(); + + int totalSuggestionsFromProviders = 0; + List<SearchSuggestion> suggestions = null; + for (SearchProvider searchProvider : searchProviderRegistry.getSearchProviders()) { + suggestions = searchProvider.search(searchRequest); + totalSuggestionsFromProviders += suggestions.size(); + searchProviderSuggestions.put(searchProvider.getClass().getCanonicalName(), suggestions); + } + + /* + * Using ordered search provider keys allows us to deterministically calculate how many + * results from each provider should be returned. At the moment, this behavior is primarily + * only beneficial to test classes. As there is a cost to sorted-collections in the call + * processing path, this behavior has been made optional. + */ + + if (useOrderedSearchProviderKeys) { + searchProviderSuggestions = + new TreeMap<String, List<SearchSuggestion>>(searchProviderSuggestions); + } + + if (totalSuggestionsFromProviders > 0) { + + int suggestionIndex = 0; + + Set<Entry<String, List<SearchSuggestion>>> searchProviderResults = + searchProviderSuggestions.entrySet(); + + while (totalAdded < maxResultsPerSearch && (totalAdded < totalSuggestionsFromProviders)) { + + for (Entry<String, List<SearchSuggestion>> searchProviderResultList : searchProviderResults) { + + if ((suggestionIndex <= (searchProviderResultList.getValue().size() - 1))) { + + if (totalAdded < maxResultsPerSearch) { + searchResponse + .addSuggestion(searchProviderResultList.getValue().get(suggestionIndex)); + totalAdded++; + } + } + + } + + suggestionIndex++; + + } + + } + + } + + searchResponse.addToTotalFound(totalAdded); + String searchResponseJson = NodeUtils.convertObjectToJson(searchResponse, true); + + processTime = System.currentTimeMillis() - processTime; + searchResponse.setProcessingTimeInMs(processTime); + + Response response = + exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); + response.setStatus(Status.SUCCESS_OK); + response.setEntity(searchResponseJson, MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + + } catch (Exception exc) { + LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, + "Query search failed with error = " + exc.getMessage()); + exchange.getOut().setBody( + generateJsonErrorResponse("Error while building response. Error = " + exc.getMessage()), + String.class); + } + } + + public SearchProviderRegistry getSearchProviderRegistry() { + return searchProviderRegistry; + } + + public void setSearchProviderRegistry(SearchProviderRegistry searchProviderRegistry) { + this.searchProviderRegistry = searchProviderRegistry; + } + + + /* + * This is the manual approach, however we could also create an object container for the error + * then use the Jackson ObjectWrite to dump the object to json instead. If it gets any more + * complicated we could do that approach so we don't have to manually trip over the JSON + * formatting. + */ + protected String generateJsonErrorResponse(String message) { + return String.format("{ \"errorMessage\" : %s }", message); + } + +} diff --git a/src/main/java/org/onap/aai/sparky/search/VnfSearchService.java b/src/main/java/org/onap/aai/sparky/search/VnfSearchService.java deleted file mode 100644 index 654aad0..0000000 --- a/src/main/java/org/onap/aai/sparky/search/VnfSearchService.java +++ /dev/null @@ -1,348 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.search; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.MediaType; - -import org.json.JSONArray; -import org.json.JSONObject; -import org.onap.aai.sparky.dal.elasticsearch.HashQueryResponse; -import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; -import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.suggestivesearch.SuggestionEntity; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.sparky.viewandinspect.entity.QuerySearchEntity; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; - - -/** - * From the given HTTP request, create vnf-search query for document store, and process document - * store response. - */ - -public class VnfSearchService { - - private static final String APP_JSON = MediaType.APPLICATION_JSON; - - private static ElasticSearchConfig esConfig = null; - - private static final Logger LOG = LoggerFactory.getInstance().getLogger(VnfSearchService.class); - - private static SearchAdapter search = null; - private static final String ES_SUGGEST_API = TierSupportUiConstants.ES_SUGGEST_API; - private static final String ES_COUNT_API = TierSupportUiConstants.ES_COUNT_API; - private static final String ES_SEARCH_API = TierSupportUiConstants.ES_SEARCH_API; - - private static final String ENTITY_TYPE = "generic-vnf"; - - /** - * Get Full URL for search using elastic search configuration. - * - * @param api the api - * @return the full url - */ - private static String getFullUrl(String indexName, String api) { - - final String host = esConfig.getIpAddress(); - final String port = esConfig.getHttpPort(); - return String.format("http://%s:%s/%s/%s", host, port, indexName, api); - } - - /** - * Process operation result. - * - * @param api the api - * @param response the response - * @param opResult the op result - * @throws IOException Signals that an I/O exception has occurred. - */ - private static void buildVnfQuerySearchResponse(String apiKey, HttpServletResponse response, - OperationResult opResult) throws IOException { - int resonseCode = opResult.getResultCode(); - String result = opResult.getResult(); - - if (resonseCode > 300) { - setServletResponse(true, resonseCode, response, result); - return; - } - - if (result != null) { - JSONObject finalOutputToFe = new JSONObject(); - JSONObject responseJson = new JSONObject(result); - - if (apiKey.equalsIgnoreCase(ES_SUGGEST_API)) { // process suggestion results - try { - String suggestionsKey = "vnfs"; - int total = 0; - JSONArray suggestionsArray = new JSONArray(); - JSONArray suggestions = responseJson.getJSONArray(suggestionsKey); - if (suggestions.length() > 0) { - suggestionsArray = suggestions.getJSONObject(0).getJSONArray("options"); - for (int i = 0; i < suggestionsArray.length(); i++) { - suggestionsArray.getJSONObject(i).remove("score"); // FE doesn't like this noise: - // 'score' - } - - total = suggestionsArray.length(); - } - finalOutputToFe.put("totalFound", total); - finalOutputToFe.put("suggestions", suggestionsArray); - } catch (Exception e) { - LOG.error(AaiUiMsgs.ERROR_GENERIC, - "Error parsing response from suggestions index. Response: " + result); - } - } else if (apiKey.equalsIgnoreCase(ES_COUNT_API)) { - try { - String shardsKey = "_shards"; - responseJson.remove(shardsKey); - finalOutputToFe = responseJson; - } catch (Exception e) { - LOG.error(AaiUiMsgs.ERROR_GENERIC, - "Error fetching total count response from aggregation index. Response: " + result); - } - } else if (apiKey.equalsIgnoreCase(ES_SEARCH_API)) { - try { - JSONArray bucketsArray = (responseJson.getJSONObject("aggregations") - .getJSONObject("default").getJSONArray("buckets")); - int count = 0; - for (int i = 0; i < bucketsArray.length(); i++) { - count += bucketsArray.getJSONObject(i).getInt("doc_count"); - } - JSONObject content = new JSONObject(); - content.put("totalChartHits", count); - content.put("buckets", bucketsArray); - finalOutputToFe.put("groupby_aggregation", content); - } catch (Exception e) { - LOG.error(AaiUiMsgs.ERROR_GENERIC, - "Error fetching group-by query response from aggregation index. Response: " + result); - } - } - - setServletResponse(false, resonseCode, response, finalOutputToFe.toString()); - } - } - - /** - * Sets the servlet response. - * - * @param isError the is error - * @param responseCode the response code - * @param response the response - * @param postPayload the post payload - * @throws IOException Signals that an I/O exception has occurred. - */ - public static void setServletResponse(boolean isError, int responseCode, - HttpServletResponse response, String postPayload) throws IOException { - - if (isError) { - LOG.error(AaiUiMsgs.ERROR_PARSING_JSON_PAYLOAD_VERBOSE, postPayload); - } - - response.setStatus(responseCode); - - if (postPayload != null) { - response.setContentType(APP_JSON); - PrintWriter out = response.getWriter(); - out.println(postPayload); - out.close(); - } - } - - /** - * Instantiates a new vnf search service. - */ - public VnfSearchService() { - try { - if (esConfig == null) { - esConfig = ElasticSearchConfig.getConfig(); - } - - if (search == null) { - search = new SearchAdapter(); - } - } catch (Exception exc) { - LOG.error(AaiUiMsgs.CONFIGURATION_ERROR, "Search"); - } - } - - - /** - * Gets the suggestions results. - * - * @param response the response - * @param maxResults maximum number of suggestions - * @param queryStr query string - * @return the suggestions results - * @throws IOException Signals that an I/O exception has occurred. - */ - public List<SuggestionEntity> getSuggestionsResults(QuerySearchEntity querySearchEntity, - int resultCountLimit) throws IOException { - List<SuggestionEntity> returnList = new ArrayList<SuggestionEntity>(); - - /* Create suggestions query */ - JsonObject vnfSearch = VnfSearchQueryBuilder - .createSuggestionsQuery(String.valueOf(resultCountLimit), querySearchEntity.getQueryStr()); - - /* Parse suggestions response */ - OperationResult opResult = - search.doPost(getFullUrl(esConfig.getAutosuggestIndexname(), ES_SUGGEST_API), - vnfSearch.toString(), APP_JSON); - - String result = opResult.getResult(); - - if (!opResult.wasSuccessful()) { - LOG.error(AaiUiMsgs.ERROR_PARSING_JSON_PAYLOAD_VERBOSE, result); - return returnList; - } - - JSONObject responseJson = new JSONObject(result); - String suggestionsKey = "vnfs"; - JSONArray suggestionsArray = new JSONArray(); - JSONArray suggestions = responseJson.getJSONArray(suggestionsKey); - if (suggestions.length() > 0) { - suggestionsArray = suggestions.getJSONObject(0).getJSONArray("options"); - for (int i = 0; i < suggestionsArray.length(); i++) { - JSONObject querySuggestion = suggestionsArray.getJSONObject(i); - if (querySuggestion != null) { - SuggestionEntity responseSuggestion = new SuggestionEntity(); - responseSuggestion.setText(querySuggestion.getString("text")); - responseSuggestion.setRoute("vnfSearch"); // TODO -> Read route from - // suggestive-search.properties instead of hard - // coding - responseSuggestion - .setHashId(NodeUtils.generateUniqueShaDigest(querySuggestion.getString("text"))); - returnList.add(responseSuggestion); - } - } - } - return returnList; - } - - - /** - * This method sets server response if lookup in ES has 0 count TODO: Change the response code to - * appropriate when FE-BE contract is finalized - * - * @param response - */ - public void setZeroCountResponse(HttpServletResponse response) throws IOException { - JSONObject payload = new JSONObject(); - payload.put("count", 0); - setServletResponse(false, 200, response, payload.toString()); - } - - /** - * This method sets server response if lookup in ES for an aggregation has 0 results TODO: Change - * the response code to appropriate when FE-BE contract is finalized - * - * @param response - */ - public void setEmptyAggResponse(HttpServletResponse response) throws IOException { - JSONObject aggPayload = new JSONObject(); - aggPayload.put("totalChartHits", 0); - aggPayload.put("buckets", new JSONArray()); - JSONObject payload = new JSONObject(); - payload.append("groupby_aggregation", aggPayload); - setServletResponse(false, 200, response, payload.toString()); - } - - public HashQueryResponse getJSONPayloadFromHash(String hashId) { - - HashQueryResponse hashQueryResponse = new HashQueryResponse(); - JsonObjectBuilder hashSearch = Json.createObjectBuilder(); - VnfSearchQueryBuilder.buildSingleTermCountQuery(hashSearch, "_id", hashId); - String hashSearchQuery = hashSearch.build().toString(); - OperationResult opResult = search.doPost( - getFullUrl(esConfig.getAutosuggestIndexname(), ES_SEARCH_API), hashSearchQuery, APP_JSON); - hashQueryResponse.setOpResult(opResult); - - if (opResult != null && opResult.wasSuccessful()) { - String result = opResult.getResult(); - if (result != null) { - JSONObject responseJson = new JSONObject(result); - JSONArray hits = responseJson.getJSONObject("hits").getJSONArray("hits"); - if (hits != null && hits.length() > 0) { - hashQueryResponse.setJsonPayload(hits.getJSONObject(0).getJSONObject("_source") - .getJSONObject("entity_suggest").toString()); - } - } - } - return hashQueryResponse; - } - - public void getEntityCountResults(HttpServletResponse response, Map<String, String> attributes) - throws IOException { - // Create entity counts query - JsonObject vnfSearch = VnfSearchQueryBuilder.createEntityCountsQuery(attributes); - - // Parse response for entity counts query - OperationResult opResult = search.doPost( - getFullUrl(TierSupportUiConstants.getAggregationIndexName(ENTITY_TYPE), ES_COUNT_API), - vnfSearch.toString(), APP_JSON); - buildVnfQuerySearchResponse(ES_COUNT_API, response, opResult); - } - - public void getSummaryByEntityType(HttpServletResponse response, Map<String, String> attributes, - String groupByKey) throws IOException { - // Create query for summary by entity type - JsonObject vnfSearch = - VnfSearchQueryBuilder.createSummaryByEntityTypeQuery(attributes, groupByKey); - - // Parse response for summary by entity type query - OperationResult opResult = search.doPost( - getFullUrl(TierSupportUiConstants.getAggregationIndexName(ENTITY_TYPE), ES_SEARCH_API), - vnfSearch.toString(), APP_JSON); - buildVnfQuerySearchResponse(ES_SEARCH_API, response, opResult); - } - - public SearchAdapter getSearch() { - return search; - } - - public void setSearch(SearchAdapter search) { - VnfSearchService.search = search; - } - - public static ElasticSearchConfig getEsConfig() { - return esConfig; - } - - public static void setEsConfig(ElasticSearchConfig esConfig) { - VnfSearchService.esConfig = esConfig; - } -} diff --git a/src/main/java/org/onap/aai/sparky/config/Configurable.java b/src/main/java/org/onap/aai/sparky/search/api/SearchProvider.java index d108bef..e593c3e 100644 --- a/src/main/java/org/onap/aai/sparky/config/Configurable.java +++ b/src/main/java/org/onap/aai/sparky/search/api/SearchProvider.java @@ -20,24 +20,15 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.config; +package org.onap.aai.sparky.search.api; -import org.onap.aai.sparky.config.exception.ConfigurationException; +import java.util.List; -/** - * The Interface Configurable. - */ -public interface Configurable { - - public boolean isValid(); +import org.onap.aai.sparky.search.entity.QuerySearchEntity; +import org.onap.aai.sparky.search.entity.SearchSuggestion; - public boolean isInitialized(); +public interface SearchProvider { - /** - * Load config. - * - * @throws ConfigurationException the configuration exception - */ - public void loadConfig() throws ConfigurationException; + List<SearchSuggestion> search(QuerySearchEntity queryRequest); } diff --git a/src/main/java/org/onap/aai/sparky/search/config/SuggestionConfig.java b/src/main/java/org/onap/aai/sparky/search/config/SuggestionConfig.java index 5ce4d3c..9208354 100644 --- a/src/main/java/org/onap/aai/sparky/search/config/SuggestionConfig.java +++ b/src/main/java/org/onap/aai/sparky/search/config/SuggestionConfig.java @@ -54,7 +54,7 @@ public class SuggestionConfig { private String defaultPairingValue; - private SuggestionConfig() {} + public SuggestionConfig() {} /** * Returns initialized instance as per singleton pattern. @@ -69,6 +69,10 @@ public class SuggestionConfig { return config; } + public static void setConfig(SuggestionConfig config) { + SuggestionConfig.config = config; + } + public void initializeConfigProperties() { Properties props = ConfigHelper.loadConfigFromExplicitPath(CONFIG_FILE); diff --git a/src/main/java/org/onap/aai/sparky/search/entity/ExternalSearchRequestEntity.java b/src/main/java/org/onap/aai/sparky/search/entity/ExternalSearchRequestEntity.java new file mode 100644 index 0000000..465eadc --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/search/entity/ExternalSearchRequestEntity.java @@ -0,0 +1,69 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.search.entity; + +public class ExternalSearchRequestEntity { + private String view; + private String entityId; + private String entityType; + + public ExternalSearchRequestEntity() { + this.view = ""; + this.entityId = ""; + this.entityType = ""; + } + + public String getView() { + return view; + } + + public void setView(String view) { + this.view = view; + } + + public String getEntityId() { + return entityId; + } + + public void setEntityId(String entityId) { + this.entityId = entityId; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public String createQueryString() { + return entityId + " " + entityType; + } + + @Override + public String toString() { + return "ExternalRequestEntitySearchEntity [view=" + view + ", entityId=" + entityId + + ", entityType=" + entityType + "]"; + } +} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/QuerySearchEntity.java b/src/main/java/org/onap/aai/sparky/search/entity/QuerySearchEntity.java index 222a2f7..d90e329 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/QuerySearchEntity.java +++ b/src/main/java/org/onap/aai/sparky/search/entity/QuerySearchEntity.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.viewandinspect.entity; +package org.onap.aai.sparky.search.entity; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -31,7 +31,6 @@ public class QuerySearchEntity { private static final String DEFAULT_MAX_RESULTS = "10"; public String maxResults; - public String queryStr; /** diff --git a/src/main/java/org/onap/aai/sparky/dal/cache/EntityCache.java b/src/main/java/org/onap/aai/sparky/search/entity/SearchSuggestion.java index 04baf7c..823cf5a 100644 --- a/src/main/java/org/onap/aai/sparky/dal/cache/EntityCache.java +++ b/src/main/java/org/onap/aai/sparky/search/entity/SearchSuggestion.java @@ -20,41 +20,18 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.dal.cache; +package org.onap.aai.sparky.search.entity; -import org.onap.aai.sparky.dal.rest.OperationResult; +public interface SearchSuggestion { + public String getHashId(); -/** - * The Interface EntityCache. - * - * @author davea. - */ -public interface EntityCache { + public void setHashId(String hashId); - /** - * Gets the. - * - * @param entityKey the entity key - * @param link the link - * @return the operation result - */ - public OperationResult get(String entityKey, String link); + public String getRoute(); - /** - * Put. - * - * @param entityKey the entity key - * @param result the result - */ - public void put(String entityKey, OperationResult result); + public void setRoute(String route); - /** - * Shutdown. - */ - public void shutdown(); + public String getText(); - /** - * Clear. - */ - public void clear(); + public void setText(String searchText); } diff --git a/src/main/java/org/onap/aai/sparky/search/filters/FilterElasticSearchAdapter.java b/src/main/java/org/onap/aai/sparky/search/filters/FilterElasticSearchAdapter.java index a846e88..5f5dc74 100644 --- a/src/main/java/org/onap/aai/sparky/search/filters/FilterElasticSearchAdapter.java +++ b/src/main/java/org/onap/aai/sparky/search/filters/FilterElasticSearchAdapter.java @@ -34,6 +34,7 @@ import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; +import org.onap.aai.sparky.dataintegrity.config.DiUiConstants; import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.sparky.search.filters.config.UiFilterDataSourceConfig; import org.onap.aai.sparky.search.filters.entity.UiFilterEntity; @@ -42,13 +43,15 @@ import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; /** * Performs all Elasticsearch related queries for filters related to the Sparky-FE. + * + * @author RICHARV */ public class FilterElasticSearchAdapter { private static ElasticSearchConfig esConfig = null; private static SearchAdapter search = null; private static final String ES_SEARCH_API = TierSupportUiConstants.ES_SEARCH_API; - private static final String APP_JSON = "application/json"; + private static final String APP_JSON = DiUiConstants.APP_JSON; private static final Logger LOG = LoggerFactory.getInstance().getLogger(FilterElasticSearchAdapter.class); private static final String AGGS = "aggregations"; @@ -104,7 +107,7 @@ public class FilterElasticSearchAdapter { FilterQueryBuilder.createFilterValueQueryObject(dataSourceConfig.getFieldName()); } - org.onap.aai.sparky.dal.rest.OperationResult opResult = + OperationResult opResult = search.doPost(getFullUrl(dataSourceConfig.getIndexName(), ES_SEARCH_API), filterValueQuery.toString(), APP_JSON); diff --git a/src/main/java/org/onap/aai/sparky/search/filters/FilterProcessor.java b/src/main/java/org/onap/aai/sparky/search/filters/FilterProcessor.java index fdcf6b2..b22db96 100644 --- a/src/main/java/org/onap/aai/sparky/search/filters/FilterProcessor.java +++ b/src/main/java/org/onap/aai/sparky/search/filters/FilterProcessor.java @@ -32,7 +32,6 @@ import org.apache.camel.component.restlet.RestletConstants; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.search.filters.FilteredSearchHelper; import org.onap.aai.sparky.search.filters.entity.UiFilterEntity; import org.onap.aai.sparky.search.filters.entity.UiFiltersEntity; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; diff --git a/src/main/java/org/onap/aai/sparky/search/filters/config/FiltersConfig.java b/src/main/java/org/onap/aai/sparky/search/filters/config/FiltersConfig.java index 3853913..b202684 100644 --- a/src/main/java/org/onap/aai/sparky/search/filters/config/FiltersConfig.java +++ b/src/main/java/org/onap/aai/sparky/search/filters/config/FiltersConfig.java @@ -27,7 +27,7 @@ import java.io.File; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/org/onap/aai/sparky/search/registry/SearchProviderRegistry.java b/src/main/java/org/onap/aai/sparky/search/registry/SearchProviderRegistry.java new file mode 100644 index 0000000..d3cca45 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/search/registry/SearchProviderRegistry.java @@ -0,0 +1,74 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.search.registry; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.aai.sparky.search.api.SearchProvider; + +/** + * Make this a java-scoped singleton to resolve the contextual issue spanning a Spring Context and + * accessing the SPR in other parts of the code that are not directly instantiated by a Spring Bean. + * Eventually the SPR doesn’t have to be a real singleton, it could simply be a Spring bean scoped + * as a singleton and then wired in via dependency injection to the classes that need it. But I’m + * not there yet. This will get a demonstrable extension mechanism in place quickly at practically + * no cost, beyond what’s already in the email plus some testing. + */ + +public class SearchProviderRegistry { + + private List<SearchProvider> searchProviders; + + public SearchProviderRegistry() { + searchProviders = new ArrayList<SearchProvider>(); + } + + public List<SearchProvider> getSearchProviders() { + return searchProviders; + } + + public final void addSearchProvider(SearchProvider searchProvider) { + + if (searchProvider == null) { + return; + } + + if (!searchProviders.contains(searchProvider)) { + searchProviders.add(searchProvider); + } + } + + public final void addSearchProviders(List<SearchProvider> searchProviders) { + + if (searchProviders == null) { + return; + } + + for (SearchProvider searchProvider : searchProviders) { + addSearchProvider(searchProvider); + } + + } + +} diff --git a/src/main/java/org/onap/aai/sparky/security/EcompSso.java b/src/main/java/org/onap/aai/sparky/security/EcompSso.java index 16e01c0..de74a5a 100644 --- a/src/main/java/org/onap/aai/sparky/security/EcompSso.java +++ b/src/main/java/org/onap/aai/sparky/security/EcompSso.java @@ -25,13 +25,12 @@ package org.onap.aai.sparky.security; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.security.portal.config.PortalAuthenticationConfig; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; -import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.security.portal.config.PortalAuthenticationConfig; import org.openecomp.portalsdk.core.onboarding.util.CipherUtil; - +import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; /** * Provides authentication services for onboarded ECOMP applications. @@ -80,7 +79,7 @@ public class EcompSso { * then searches for a CSP cookie; if not found, for a WebJunction header. * * @param request - * @return User ID if the ECOMP cookie is present and the sign-on process established an User ID; + * @return ATT UID if the ECOMP cookie is present and the sign-on process established an ATT UID; * else null. */ public static String validateEcompSso(HttpServletRequest request) { @@ -100,23 +99,23 @@ public class EcompSso { } /** - * Searches the specified request for the CSP cookie, decodes it and gets the User ID. + * Searches the specified request for the CSP cookie, decodes it and gets the ATT UID. * * @param request - * @return User ID if the cookie is present in the request and can be decoded successfully - * (expired cookies do not decode); else null. + * @return ATTUID if the cookie is present in the request and can be decoded successfully (expired + * cookies do not decode); else null. */ private static String getLoginIdFromCookie(HttpServletRequest request) { - String userid = null; + String attuid = null; try { String[] cspFields = getCspData(request); if (cspFields != null && cspFields.length > 5) - userid = cspFields[5]; + attuid = cspFields[5]; } catch (Throwable t) { LOG.info(AaiUiMsgs.LOGIN_FILTER_INFO, "getLoginIdFromCookie failed " + t.getLocalizedMessage()); } - return userid; + return attuid; } /** diff --git a/src/main/java/org/onap/aai/sparky/security/filter/CspCookieFilter.java b/src/main/java/org/onap/aai/sparky/security/filter/CspCookieFilter.java new file mode 100644 index 0000000..51e77bb --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/security/filter/CspCookieFilter.java @@ -0,0 +1,274 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.security.filter; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; + +// import esGateKeeper.esGateKeeper; + +/** + * Redirects to the AT&T global login page if the user is not authenticated.<br> + * Filter properties need to be configured in: csp-cookie-filter.properties + */ +public class CspCookieFilter implements Filter { + + /** Redirect URL for the login page. */ + private String globalLoginUrl; + + /** Application identifier. */ + private String applicationId; + + /** Gatekeeper environment setting (development or production). */ + private String gateKeeperEnvironment; + + private static final String FILTER_PARAMETER_CONFIG = "config"; + private static final String PROPERTY_GLOBAL_LOGIN_URL = "global.login.url"; + private static final String PROPERTY_APPLICATION_ID = "application.id"; + private static final String PROPERTY_GATEKEEPER_ENVIRONMENT = "gatekeeper.environment"; + // valid open redirect domains + private List<String> redirectDomains = new ArrayList<>(); + private static final String PROPERTY_REDIRECT_DOMAINS = "redirect-domain"; + + /** Needed by esGateKeeper, does not accept any other value. */ + private static final String GATEKEEPER_ACCOUNT_NAME = "CSP"; + + private static final Logger LOG = LoggerFactory.getInstance().getLogger(CspCookieFilter.class); + + + /* + * (non-Javadoc) + * + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ + @Override + public void init(FilterConfig filterConfig) throws ServletException { + String txnID = NodeUtils.getRandomTxnId(); + MdcContext.initialize(txnID, "CspCookieFilter", "", "Init", ""); + + try { + setConfigurationProperties(filterConfig); + } catch (IOException exc) { + LOG.error(AaiUiMsgs.ERROR_CSP_CONFIG_FILE); + throw new ServletException(exc); + } + } + + + /* + * (non-Javadoc) + * + * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, + * javax.servlet.FilterChain) + */ + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + Cookie[] cookies = request.getCookies(); + if ((cookies == null) || (cookies.length == 0)) { + doLogin(request, response); + return; + } + + /* + * String attEsSec = getSecurityCookie(cookies); + * + * if (attESSec == null || attESSec.length() == 0) { doLogin(request, response); return; } + * + * String attESSecUnEncrypted = esGateKeeper.esGateKeeper(attESSec, GATEKEEPER_ACCOUNT_NAME, + * gateKeeperEnvironment); if (attESSecUnEncrypted == null) { doLogin(request, response); } else + * { + */ + // LOG.info("User has valid cookie"); + chain.doFilter(request, response); + // } + } + + + /* + * (non-Javadoc) + * + * @see javax.servlet.Filter#destroy() + */ + @Override + public void destroy() {} + + /** + * Sets all required properties needed by this filter. + * + * @param filterConfig the filter configuration defined in the application web.xml + * @throws IOException if the properties failed to load. + */ + private void setConfigurationProperties(FilterConfig filterConfig) throws IOException { + InputStream inputStream = new FileInputStream(TierSupportUiConstants.STATIC_CONFIG_APP_LOCATION + + filterConfig.getInitParameter(FILTER_PARAMETER_CONFIG)); + Properties cspProperties = new Properties(); + cspProperties.load(inputStream); + globalLoginUrl = cspProperties.getProperty(PROPERTY_GLOBAL_LOGIN_URL); + applicationId = cspProperties.getProperty(PROPERTY_APPLICATION_ID); + gateKeeperEnvironment = cspProperties.getProperty(PROPERTY_GATEKEEPER_ENVIRONMENT); + redirectDomains = + Arrays.asList(cspProperties.getProperty(PROPERTY_REDIRECT_DOMAINS).split(",")); + } + + /** + * Returns the attESSec cookie if found in the client. + * + * @param cookies the cookies available in the client + * @return the attESSec authentication cookie generated by the login page. + */ + private String getSecurityCookie(Cookie[] cookies) { + String attEsSec = null; + for (int i = 0; i < cookies.length; i++) { + Cookie thisCookie = cookies[i]; + String cookieName = thisCookie.getName(); + + if ("attESSec".equals(cookieName)) { + attEsSec = thisCookie.getValue(); + break; + } + } + return attEsSec; + } + + /** + * Redirects to the AT&T global login page. If this is an AJAX request it returns an unauthorized + * HTTP error in the response. + * + * @param request the filter request object + * @param response the filter response object + * @throws IOException if there is an error setting the error response + */ + private void doLogin(HttpServletRequest request, HttpServletResponse response) + throws IOException { + if (isAjaxRequest(request)) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, + "User is not authorized. Please login to application"); + } else { + // Fix for Safari 7.0.2 onwards to avoid login page cache + response.addHeader("Cache-Control", "no-cache, no-store"); + String redirectURL = createRedirectUrl(request); + if (this.isValidRedirectURL(redirectURL)) { + response.sendRedirect(redirectURL); + LOG.debug(AaiUiMsgs.VALID_REDIRECT_URL, redirectURL); + } else { + response.sendError(400, "Bad redirect URL: " + redirectURL); + LOG.error(AaiUiMsgs.INVALID_REDIRECT_URL, redirectURL); + } + } + } + + /** + * Checks if a redirect url is valid + * + * @param url URL to validate + * @return true if URL is a valid redirect URL, false otherwise + */ + private boolean isValidRedirectURL(String url) { + String redirectTo = url.substring(url.indexOf("?retURL=") + "?retURL=".length()); + try { + redirectTo = URLDecoder.decode(redirectTo, StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + LOG.error(AaiUiMsgs.UNSUPPORTED_URL_ENCODING, e.getLocalizedMessage()); + return false; + } + for (String domain : this.redirectDomains) { + if (redirectTo.endsWith(domain)) + return true; + } + return false; + } + + + /** + * Returns <code>true</code> if the request is an AJAX request. + * + * @param request the filter request object + * @return <code>true</code> if the request is an AJAX request. + */ + private boolean isAjaxRequest(HttpServletRequest request) { + String headerValue = request.getHeader("X-Requested-With"); + if ("XMLHttpRequest".equals(headerValue)) { + return true; + } + return false; + } + + /** + * Returns the redirection URL to the AT&T Global login page. + * + * @param request the request + * @return the string + * @throws UnsupportedEncodingException the unsupported encoding exception + */ + private String createRedirectUrl(HttpServletRequest request) throws UnsupportedEncodingException { + String returnUrl = getReturnUrl(request); + + return globalLoginUrl + "?retURL=" + returnUrl + "&sysName=" + applicationId; + } + + /** + * Gets the URL encoded return URL. + * + * @param request the HTTP request + * @return an encoded URL to return to following login + * @throws UnsupportedEncodingException the unsupported encoding exception + */ + private String getReturnUrl(HttpServletRequest request) throws UnsupportedEncodingException { + StringBuffer retUrl = request.getRequestURL(); + String urlParams = request.getQueryString(); + if (urlParams != null) { + retUrl.append("?" + urlParams); + } + return URLEncoder.encode(retUrl.toString(), StandardCharsets.UTF_8.toString()); + } +} diff --git a/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java b/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java index 445cfba..2ec6b47 100644 --- a/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java +++ b/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java @@ -36,11 +36,11 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.ws.rs.core.HttpHeaders; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.sparky.security.EcompSso; import org.onap.aai.sparky.security.portal.config.PortalAuthenticationConfig; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler; import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants; import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties; @@ -126,10 +126,17 @@ public class LoginFilter implements Filter { // All other requests require ECOMP Portal authentication if (EcompSso.validateEcompSso(request) == null) { String redirectURL, logMessage; - - // Redirect to Portal UI - redirectURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); - logMessage = "Unauthorized login attempt."; + if (request.getRequestURI().contains("/editAttributes")) { + // If request is for Edit Attributes UI, redirect straight to the application. + String appPath = request.getRequestURI().substring(request.getContextPath().length() + 1) + + (request.getQueryString() != null ? ("?" + request.getQueryString()) : ""); + redirectURL = SSOUtil.getECOMPSSORedirectURL(request, response, appPath); + logMessage = "Unauthenticated Edit Attributes UI login attempt."; + } else { + // Redirect to Portal UI + redirectURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); + logMessage = "Unauthorized login attempt."; + } LOG.debug(AaiUiMsgs.LOGIN_FILTER_DEBUG, logMessage + " | Remote IP: " + request.getRemoteAddr() + " | User agent: " diff --git a/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPIServiceImpl.java b/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPIServiceImpl.java index 050d558..d3ffac3 100644 --- a/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPIServiceImpl.java +++ b/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPIServiceImpl.java @@ -48,34 +48,6 @@ public class PortalRestAPIServiceImpl implements IPortalRestAPIService { private static final Logger LOG = LoggerFactory.getLogger(PortalRestAPIServiceImpl.class); private static final String ERROR_MESSAGE = "Failed to {0} user [loginId:{1}]"; - /** - * @return the userManager - */ - public UserManager getUserManager() { - return userManager; - } - - /** - * @param userManager the userManager to set - */ - public void setUserManager(UserManager userManager) { - this.userManager = userManager; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @return the errorMessage - */ - public static String getErrorMessage() { - return ERROR_MESSAGE; - } - private UserManager userManager; /** @@ -175,8 +147,11 @@ public class PortalRestAPIServiceImpl implements IPortalRestAPIService { ///////////////////////////////////////////////////////////////////////////// // Role interface ///////////////////////////////////////////////////////////////////////////// + public List<EcompRole> getAvailableRoles() throws PortalAPIException { + LOG.debug("Get available roles"); + return UserManager.getRoles(); + } - @Override public List<EcompRole> getAvailableRoles(String requestedLoginId) throws PortalAPIException { LOG.debug("Get available roles"); return UserManager.getRoles(); diff --git a/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java b/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java index 6f103d0..f58fc31 100644 --- a/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java +++ b/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java @@ -28,6 +28,7 @@ import org.onap.aai.sparky.util.ConfigHelper; import org.onap.aai.sparky.util.Encryptor; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; + /** * Provides Portal authentication configuration. */ diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/AbstractEntitySynchronizer.java b/src/main/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizer.java index dde633c..bf1a7ee 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/AbstractEntitySynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizer.java @@ -20,30 +20,28 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.EnumSet; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; import org.onap.aai.sparky.dal.aai.ActiveInventoryEntityStatistics; import org.onap.aai.sparky.dal.aai.ActiveInventoryProcessingExceptionStatistics; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.elasticsearch.ElasticSearchDataProvider; import org.onap.aai.sparky.dal.elasticsearch.ElasticSearchEntityStatistics; import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.dal.rest.RestOperationalStatistics; import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.mdc.MdcContext; + import com.fasterxml.jackson.databind.ObjectMapper; /** @@ -58,7 +56,6 @@ public abstract class AbstractEntitySynchronizer { protected final Logger logger; protected ObjectMapper mapper; - protected OxmModelLoader oxmModelLoader; protected long syncDurationInMs; /** @@ -70,8 +67,8 @@ public abstract class AbstractEntitySynchronizer { protected EnumSet<StatFlag> enabledStatFlags; - protected ActiveInventoryDataProvider aaiDataProvider; - protected ElasticSearchDataProvider esDataProvider; + protected ElasticSearchAdapter elasticSearchAdapter; + protected ActiveInventoryAdapter aaiAdapter; protected ExecutorService synchronizerExecutor; protected ExecutorService aaiExecutor; @@ -87,8 +84,8 @@ public abstract class AbstractEntitySynchronizer { private TaskProcessingStats aaiTaskProcessingStats; private TaskProcessingStats esTaskProcessingStats; - private TransactionRateController aaiTransactionRateController; - private TransactionRateController esTransactionRateController; + private TransactionRateMonitor aaiTransactionRateController; + private TransactionRateMonitor esTransactionRateController; protected AtomicInteger aaiWorkOnHand; protected AtomicInteger esWorkOnHand; @@ -255,7 +252,8 @@ public abstract class AbstractEntitySynchronizer { * @throws Exception the exception */ protected AbstractEntitySynchronizer(Logger logger, String syncName, int numSyncWorkers, - int numActiveInventoryWorkers, int numElasticsearchWorkers, String indexName) + int numActiveInventoryWorkers, int numElasticsearchWorkers, String indexName, + NetworkStatisticsConfig aaiStatConfig, NetworkStatisticsConfig esStatConfig) throws Exception { this.logger = logger; this.synchronizerExecutor = @@ -265,22 +263,19 @@ public abstract class AbstractEntitySynchronizer { this.esExecutor = NodeUtils.createNamedExecutor(syncName + "-ES", numElasticsearchWorkers, logger); this.mapper = new ObjectMapper(); - this.oxmModelLoader = OxmModelLoader.getInstance(); this.indexName = indexName; this.esRestStats = new RestOperationalStatistics(); - this.esEntityStats = new ElasticSearchEntityStatistics(oxmModelLoader); + this.esEntityStats = new ElasticSearchEntityStatistics(); this.aaiRestStats = new RestOperationalStatistics(); - this.aaiEntityStats = new ActiveInventoryEntityStatistics(oxmModelLoader); + this.aaiEntityStats = new ActiveInventoryEntityStatistics(); this.aaiProcessingExceptionStats = new ActiveInventoryProcessingExceptionStatistics(); - this.aaiTaskProcessingStats = - new TaskProcessingStats(ActiveInventoryConfig.getConfig().getTaskProcessorConfig()); - this.esTaskProcessingStats = - new TaskProcessingStats(ElasticSearchConfig.getConfig().getProcessorConfig()); + this.aaiTaskProcessingStats = new TaskProcessingStats(aaiStatConfig); + this.esTaskProcessingStats = new TaskProcessingStats(esStatConfig); this.aaiTransactionRateController = - new TransactionRateController(ActiveInventoryConfig.getConfig().getTaskProcessorConfig()); + new TransactionRateMonitor(numActiveInventoryWorkers, aaiStatConfig); this.esTransactionRateController = - new TransactionRateController(ElasticSearchConfig.getConfig().getProcessorConfig()); + new TransactionRateMonitor(numElasticsearchWorkers, esStatConfig); this.aaiWorkOnHand = new AtomicInteger(0); this.esWorkOnHand = new AtomicInteger(0); @@ -338,11 +333,19 @@ public abstract class AbstractEntitySynchronizer { */ protected void shutdownExecutors() { try { - synchronizerExecutor.shutdown(); - aaiExecutor.shutdown(); - esExecutor.shutdown(); - aaiDataProvider.shutdown(); - esDataProvider.shutdown(); + + if (synchronizerExecutor != null) { + synchronizerExecutor.shutdown(); + } + + if (aaiExecutor != null) { + aaiExecutor.shutdown(); + } + + if (esExecutor != null) { + esExecutor.shutdown(); + } + } catch (Exception exc) { logger.error(AaiUiMsgs.ERROR_SHUTDOWN_EXECUTORS, exc); } @@ -351,26 +354,22 @@ public abstract class AbstractEntitySynchronizer { /** * Clear cache. */ - public void clearCache() { - if (aaiDataProvider != null) { - aaiDataProvider.clearCache(); - } - } + public void clearCache() {} - protected ActiveInventoryDataProvider getAaiDataProvider() { - return aaiDataProvider; + public ElasticSearchAdapter getElasticSearchAdapter() { + return elasticSearchAdapter; } - public void setAaiDataProvider(ActiveInventoryDataProvider aaiDataProvider) { - this.aaiDataProvider = aaiDataProvider; + public void setElasticSearchAdapter(ElasticSearchAdapter elasticSearchAdapter) { + this.elasticSearchAdapter = elasticSearchAdapter; } - protected ElasticSearchDataProvider getEsDataProvider() { - return esDataProvider; + public ActiveInventoryAdapter getAaiAdapter() { + return aaiAdapter; } - public void setEsDataProvider(ElasticSearchDataProvider provider) { - this.esDataProvider = provider; + public void setAaiAdapter(ActiveInventoryAdapter aaiAdapter) { + this.aaiAdapter = aaiAdapter; } /** @@ -472,10 +471,9 @@ public abstract class AbstractEntitySynchronizer { if (enabledStatFlags.contains(StatFlag.ES_TASK_PROCESSING_STATS)) { - esTransactionRateController.trackResponseTime(txn.getOperationResult().getResponseTimeInMs()); + esTransactionRateController.trackResponseTime(txn.getOpTimeInMs()); - esTaskProcessingStats - .updateTaskResponseStatsHistogram(txn.getOperationResult().getResponseTimeInMs()); + esTaskProcessingStats.updateTaskResponseStatsHistogram(txn.getOpTimeInMs()); esTaskProcessingStats.updateTaskAgeStatsHistogram(txn.getTaskAgeInMs()); // don't know the cost of the lengh calc, we'll see if it causes a @@ -533,11 +531,9 @@ public abstract class AbstractEntitySynchronizer { } if (enabledStatFlags.contains(StatFlag.AAI_TASK_PROCESSING_STATS)) { - aaiTransactionRateController - .trackResponseTime(txn.getOperationResult().getResponseTimeInMs()); + aaiTransactionRateController.trackResponseTime(txn.getOpTimeInMs()); - aaiTaskProcessingStats - .updateTaskResponseStatsHistogram(txn.getOperationResult().getResponseTimeInMs()); + aaiTaskProcessingStats.updateTaskResponseStatsHistogram(txn.getOpTimeInMs()); aaiTaskProcessingStats.updateTaskAgeStatsHistogram(txn.getTaskAgeInMs()); // don't know the cost of the lengh calc, we'll see if it causes a diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/ElasticSearchIndexCleaner.java b/src/main/java/org/onap/aai/sparky/sync/ElasticSearchIndexCleaner.java index 59942dc..e1785d4 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/ElasticSearchIndexCleaner.java +++ b/src/main/java/org/onap/aai/sparky/sync/ElasticSearchIndexCleaner.java @@ -20,13 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +package org.onap.aai.sparky.sync; import java.io.IOException; import java.util.ArrayList; @@ -34,14 +28,24 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestDataProvider; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.entity.ObjectIdCollection; -import org.onap.aai.sparky.synchronizer.entity.SearchableEntity; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; +import javax.ws.rs.core.MediaType; + import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.entity.ObjectIdCollection; +import org.onap.aai.sparky.sync.entity.SearchableEntity; +import org.onap.aai.sparky.sync.enumeration.OperationState; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; /** * The Class ElasticSearchIndexCleaner. @@ -57,16 +61,10 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { private ObjectIdCollection before; private ObjectIdCollection after; - private String host; - private String port; - - private String indexName; - private String indexType; - private int scrollContextTimeToLiveInMinutes; - private int numItemsToGetBulkRequest; - - private RestDataProvider restDataProvider; private ObjectMapper mapper; + private ElasticSearchAdapter esAdapter; + private ElasticSearchEndpointConfig endpointConfig; + private ElasticSearchSchemaConfig schemaConfig; /** * Instantiates a new elastic search index cleaner. @@ -79,25 +77,20 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { * @param scrollContextTimeToLiveInMinutes the scroll context time to live in minutes * @param numItemsToGetBulkRequest the num items to get bulk request */ - protected ElasticSearchIndexCleaner(RestDataProvider restDataProvider, String indexName, - String indexType, String host, String port, int scrollContextTimeToLiveInMinutes, - int numItemsToGetBulkRequest) { - this.restDataProvider = restDataProvider; + public ElasticSearchIndexCleaner(ElasticSearchAdapter esAdapter, + ElasticSearchEndpointConfig endpointConfig, ElasticSearchSchemaConfig schemaConfig) { + this.esAdapter = esAdapter; this.before = null; this.after = null; - this.indexName = indexName; - this.indexType = indexType; + this.endpointConfig = endpointConfig; + this.schemaConfig = schemaConfig; this.mapper = new ObjectMapper(); - this.host = host; - this.port = port; - this.scrollContextTimeToLiveInMinutes = scrollContextTimeToLiveInMinutes; - this.numItemsToGetBulkRequest = numItemsToGetBulkRequest; } /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexCleaner#populatePreOperationCollection() + * @see org.openecomp.sparky.synchronizer.IndexCleaner#populatePreOperationCollection() */ @Override public OperationState populatePreOperationCollection() { @@ -106,7 +99,7 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { before = retrieveAllDocumentIdentifiers(); return OperationState.OK; } catch (Exception exc) { - LOG.error(AaiUiMsgs.ES_PRE_SYNC_FAILURE, indexName, exc.getMessage()); + LOG.error(AaiUiMsgs.ES_PRE_SYNC_FAILURE, schemaConfig.getIndexName(), exc.getMessage()); return OperationState.ERROR; } @@ -115,7 +108,7 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexCleaner#populatePostOperationCollection() + * @see org.openecomp.sparky.synchronizer.IndexCleaner#populatePostOperationCollection() */ @Override public OperationState populatePostOperationCollection() { @@ -123,7 +116,7 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { after = retrieveAllDocumentIdentifiers(); return OperationState.OK; } catch (Exception exc) { - LOG.error(AaiUiMsgs.ES_PRE_SYNC_FAILURE, indexName, exc.getMessage()); + LOG.error(AaiUiMsgs.ES_PRE_SYNC_FAILURE, schemaConfig.getIndexName(), exc.getMessage()); return OperationState.ERROR; } } @@ -131,12 +124,12 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexCleaner#performCleanup() + * @see org.openecomp.sparky.synchronizer.IndexCleaner#performCleanup() */ @Override public OperationState performCleanup() { // TODO Auto-generated method stub - LOG.info(AaiUiMsgs.ES_SYNC_CLEAN_UP, indexName); + LOG.info(AaiUiMsgs.ES_SYNC_CLEAN_UP, schemaConfig.getIndexName()); int sizeBefore = before.getSize(); int sizeAfter = after.getSize(); @@ -151,12 +144,12 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { if (sizeAfter > 0) { - Collection<String> presyncIds = before.getImportedObjectIdsAsValues(); - presyncIds.removeAll(after.getImportedObjectIdsAsValues()); + Collection<String> presyncIds = before.getImportedObjectIds(); + presyncIds.removeAll(after.getImportedObjectIds()); try { - LOG.info(AaiUiMsgs.ES_SYNC_SELECTIVE_DELETE, indexName, indexType, - String.valueOf(presyncIds.size())); + LOG.info(AaiUiMsgs.ES_SYNC_SELECTIVE_DELETE, schemaConfig.getIndexName(), + schemaConfig.getIndexDocType(), String.valueOf(presyncIds.size())); ObjectIdCollection bulkIds = new ObjectIdCollection(); @@ -169,10 +162,10 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { bulkIds.addObjectId(it.next()); numItemsInBulkRequest++; - if (numItemsInBulkRequest >= this.numItemsToGetBulkRequest) { - LOG.info(AaiUiMsgs.ES_BULK_DELETE, indexName, String.valueOf(bulkIds.getSize())); - OperationResult bulkDeleteResult = bulkDelete(bulkIds.getImportedObjectIdsAsValues()); - // pegCountersForElasticBulkDelete(bulkDeleteResult); + if (numItemsInBulkRequest >= endpointConfig.getScrollContextBatchRequestSize()) { + LOG.info(AaiUiMsgs.ES_BULK_DELETE, schemaConfig.getIndexName(), + String.valueOf(bulkIds.getSize())); + bulkDelete(bulkIds.getImportedObjectIds()); numItemsRemainingToBeDeleted -= numItemsInBulkRequest; numItemsInBulkRequest = 0; bulkIds.clear(); @@ -180,14 +173,15 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { } if (numItemsRemainingToBeDeleted > 0) { - LOG.info(AaiUiMsgs.ES_BULK_DELETE, indexName, String.valueOf(bulkIds.getSize())); - OperationResult bulkDeleteResult = bulkDelete(bulkIds.getImportedObjectIdsAsValues()); - // pegCountersForElasticBulkDelete(bulkDeleteResult); + LOG.info(AaiUiMsgs.ES_BULK_DELETE, schemaConfig.getIndexName(), + String.valueOf(bulkIds.getSize())); + bulkDelete(bulkIds.getImportedObjectIds()); } } catch (Exception exc) { - LOG.error(AaiUiMsgs.ES_BULK_DELETE_ERROR, indexName, exc.getLocalizedMessage()); + LOG.error(AaiUiMsgs.ES_BULK_DELETE_ERROR, schemaConfig.getIndexName(), + exc.getLocalizedMessage()); } } @@ -197,11 +191,7 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { @Override public String getIndexName() { - return indexName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; + return schemaConfig.getIndexName(); } /** @@ -352,7 +342,8 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { * @return the full url */ private String getFullUrl(String resourceUrl) { - return String.format("http://%s:%s%s", host, port, resourceUrl); + return String.format("http://%s:%s%s", endpointConfig.getEsIpAddress(), + endpointConfig.getEsServerPort(), resourceUrl); } /** @@ -372,13 +363,14 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { // fields.add("entityType"); String scrollRequestPayload = - buildInitialScrollRequestPayload(this.numItemsToGetBulkRequest, fields); + buildInitialScrollRequestPayload(endpointConfig.getScrollContextBatchRequestSize(), fields); - final String fullUrlStr = getFullUrl("/" + indexName + "/" + indexType + "/_search?scroll=" - + this.scrollContextTimeToLiveInMinutes + "m"); + final String fullUrlStr = + getFullUrl("/" + schemaConfig.getIndexName() + "/" + schemaConfig.getIndexDocType() + + "/_search?scroll=" + endpointConfig.getScrollContextTimeToLiveInMinutes() + "m"); OperationResult result = - restDataProvider.doPost(fullUrlStr, scrollRequestPayload, "application/json"); + esAdapter.doPost(fullUrlStr, scrollRequestPayload, MediaType.APPLICATION_JSON_TYPE); if (result.wasSuccessful()) { @@ -435,33 +427,18 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { currentDocumentIds.addObjectId(key); } - /* - * if (key != null) { - * - * JsonNode fieldsNode = jNode.get("fields"); - * - * if (fieldsNode != null) { - * - * JsonNode entityTypeNode = fieldsNode.get("entityType"); - * - * if (entityTypeNode != null) { ArrayNode aNode = (ArrayNode) entityTypeNode; - * - * if (aNode.size() > 0) { value = aNode.get(0).asText(); objAndtTypesMap.put(key, value); - * numRecordsFetched++; } } } } - */ - } int totalRecordsRemainingToFetch = (totalRecordsAvailable - numRecordsFetched); int numRequiredAdditionalFetches = - (totalRecordsRemainingToFetch / this.numItemsToGetBulkRequest); + (totalRecordsRemainingToFetch / endpointConfig.getScrollContextBatchRequestSize()); /* * Do an additional fetch for the remaining items (if needed) */ - if (totalRecordsRemainingToFetch % numItemsToGetBulkRequest != 0) { + if (totalRecordsRemainingToFetch % endpointConfig.getScrollContextBatchRequestSize() != 0) { numRequiredAdditionalFetches += 1; } @@ -511,15 +488,13 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { private OperationState collectItemsFromScrollContext(String scrollId, ObjectIdCollection objectIds) throws IOException { - // ObjectIdCollection documentIdCollection = new ObjectIdCollection(); - - String requestPayload = - buildSubsequentScrollContextRequestPayload(scrollId, scrollContextTimeToLiveInMinutes); + String requestPayload = buildSubsequentScrollContextRequestPayload(scrollId, + endpointConfig.getScrollContextTimeToLiveInMinutes()); final String fullUrlStr = getFullUrl("/_search/scroll"); OperationResult opResult = - restDataProvider.doPost(fullUrlStr, requestPayload, "application/json"); + esAdapter.doPost(fullUrlStr, requestPayload, MediaType.APPLICATION_JSON_TYPE); if (opResult.getResultCode() >= 300) { LOG.warn(AaiUiMsgs.ES_SCROLL_CONTEXT_ERROR, opResult.getResult()); @@ -527,6 +502,11 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { } JsonNode rootNode = parseElasticSearchResult(opResult.getResult()); + boolean timedOut = Boolean.parseBoolean(getFieldValue(rootNode, "timed_out")); + final String tookStr = getFieldValue(rootNode, "took"); + int tookInMs = (tookStr == null) ? 0 : Integer.parseInt(tookStr); + + JsonNode hitsNode = rootNode.get("hits"); /* * Check the result for success / failure, and enumerate all the index ids that resulted in @@ -534,11 +514,6 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { */ if (rootNode != null) { - boolean timedOut = Boolean.parseBoolean(getFieldValue(rootNode, "timed_out")); - final String tookStr = getFieldValue(rootNode, "took"); - int tookInMs = (tookStr == null) ? 0 : Integer.parseInt(tookStr); - - JsonNode hitsNode = rootNode.get("hits"); if (timedOut) { LOG.info(AaiUiMsgs.COLLECT_TIME_WITH_ERROR, "Scroll Context", String.valueOf(tookInMs)); @@ -566,25 +541,9 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { if (key != null) { objectIds.addObjectId(key); - /* - * JsonNode fieldsNode = jNode.get("fields"); - * - * if (fieldsNode != null) { - * - * JsonNode entityTypeNode = fieldsNode.get("entityType"); - * - * if (entityTypeNode != null) { ArrayNode aNode = (ArrayNode) entityTypeNode; - * - * if (aNode.size() > 0) { value = aNode.get(0).asText(); objectIdsAndTypes.put(key, - * value); } } } } - */ - } } - } else { - // scroll context get failed, nothing else to do - LOG.error(AaiUiMsgs.ERROR_GENERIC, opResult.toString()); } return OperationState.OK; @@ -629,163 +588,16 @@ public class ElasticSearchIndexCleaner implements IndexCleaner { StringBuilder sb = new StringBuilder(128); for (String id : docIds) { - sb.append( - String.format(BULK_OP_LINE_TEMPLATE, buildDeleteDataObject(indexName, indexType, id))); + sb.append(String.format(BULK_OP_LINE_TEMPLATE, + buildDeleteDataObject(schemaConfig.getIndexName(), schemaConfig.getIndexDocType(), id))); } sb.append("\n"); final String fullUrlStr = getFullUrl("/_bulk"); - return restDataProvider.doPost(fullUrlStr, sb.toString(), "application/x-www-form-urlencoded"); - - } - - /** - * @return the before - */ - public ObjectIdCollection getBefore() { - return before; - } - - /** - * @param before the before to set - */ - public void setBefore(ObjectIdCollection before) { - this.before = before; - } - - /** - * @return the after - */ - public ObjectIdCollection getAfter() { - return after; - } - - /** - * @param after the after to set - */ - public void setAfter(ObjectIdCollection after) { - this.after = after; - } - - /** - * @return the host - */ - public String getHost() { - return host; - } - - /** - * @param host the host to set - */ - public void setHost(String host) { - this.host = host; - } - - /** - * @return the port - */ - public String getPort() { - return port; - } - - /** - * @param port the port to set - */ - public void setPort(String port) { - this.port = port; - } - - /** - * @return the indexType - */ - public String getIndexType() { - return indexType; - } - - /** - * @param indexType the indexType to set - */ - public void setIndexType(String indexType) { - this.indexType = indexType; - } - - /** - * @return the scrollContextTimeToLiveInMinutes - */ - public int getScrollContextTimeToLiveInMinutes() { - return scrollContextTimeToLiveInMinutes; - } - - /** - * @param scrollContextTimeToLiveInMinutes the scrollContextTimeToLiveInMinutes to set - */ - public void setScrollContextTimeToLiveInMinutes(int scrollContextTimeToLiveInMinutes) { - this.scrollContextTimeToLiveInMinutes = scrollContextTimeToLiveInMinutes; - } + return esAdapter.doPost(fullUrlStr, sb.toString(), MediaType.APPLICATION_FORM_URLENCODED_TYPE); - /** - * @return the numItemsToGetBulkRequest - */ - public int getNumItemsToGetBulkRequest() { - return numItemsToGetBulkRequest; - } - - /** - * @param numItemsToGetBulkRequest the numItemsToGetBulkRequest to set - */ - public void setNumItemsToGetBulkRequest(int numItemsToGetBulkRequest) { - this.numItemsToGetBulkRequest = numItemsToGetBulkRequest; - } - - /** - * @return the restDataProvider - */ - public RestDataProvider getRestDataProvider() { - return restDataProvider; - } - - /** - * @param restDataProvider the restDataProvider to set - */ - public void setRestDataProvider(RestDataProvider restDataProvider) { - this.restDataProvider = restDataProvider; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @return the bulkOpLineTemplate - */ - public static String getBulkOpLineTemplate() { - return BULK_OP_LINE_TEMPLATE; - } - - /** - * @return the timestampFormat - */ - public static String getTimestampFormat() { - return TIMESTAMP_FORMAT; } /* diff --git a/src/main/java/org/onap/aai/sparky/sync/ElasticSearchSchemaFactory.java b/src/main/java/org/onap/aai/sparky/sync/ElasticSearchSchemaFactory.java new file mode 100644 index 0000000..9013600 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/ElasticSearchSchemaFactory.java @@ -0,0 +1,109 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync; + +import java.io.IOException; + +import org.onap.aai.sparky.dal.exception.ElasticSearchOperationException; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.util.ConfigHelper; +import org.onap.aai.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; + +public class ElasticSearchSchemaFactory { + + private static final String SETTINGS = "settings"; + private static final String MAPPINGS = "mappings"; + + private static ObjectMapper mapper = new ObjectMapper(); + + protected static 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 static String getIndexSchema(ElasticSearchSchemaConfig schemaConfig) + throws ElasticSearchOperationException { + + JsonNode esSettingsNode = null; + JsonNode esMappingsNodes = null; + + try { + + if (schemaConfig.getIndexSettingsFileName() != null) { + esSettingsNode = mapper.readTree(getConfigAsString(SETTINGS, + TierSupportUiConstants.getConfigPath(schemaConfig.getIndexSettingsFileName()))); + } + + if (schemaConfig.getIndexMappingsFileName() != null) { + esMappingsNodes = mapper.readTree(getConfigAsString(MAPPINGS, + TierSupportUiConstants.getConfigPath(schemaConfig.getIndexMappingsFileName()))); + } + + } catch (IOException e1) { + + throw new ElasticSearchOperationException( + "Caught an exception building initial ES index. Error: " + e1.getMessage()); + } + + ObjectNode esConfig = null; + + ObjectNode mappings = + (ObjectNode) mapper.createObjectNode().set(schemaConfig.getIndexDocType(), esMappingsNodes); + + if (esSettingsNode == null) { + esConfig = (ObjectNode) mapper.createObjectNode().set(MAPPINGS, mappings); + } else { + esConfig = (ObjectNode) mapper.createObjectNode().set(SETTINGS, esSettingsNode); + esConfig.set(MAPPINGS, mappings); + } + + try { + return mapper.writeValueAsString(esConfig); + } catch (JsonProcessingException exc) { + throw new ElasticSearchOperationException("Error getting object node as string", exc); + } + + } + + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/IndexCleaner.java b/src/main/java/org/onap/aai/sparky/sync/IndexCleaner.java index 4edab03..3b0ec57 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/IndexCleaner.java +++ b/src/main/java/org/onap/aai/sparky/sync/IndexCleaner.java @@ -20,9 +20,9 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.OperationState; /** * The Interface IndexCleaner. diff --git a/src/main/java/org/onap/aai/sparky/sync/IndexIntegrityValidator.java b/src/main/java/org/onap/aai/sparky/sync/IndexIntegrityValidator.java new file mode 100644 index 0000000..a6941ad --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/IndexIntegrityValidator.java @@ -0,0 +1,176 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync; + +import javax.ws.rs.core.MediaType; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; + +/** + * The Class IndexIntegrityValidator. + */ +public class IndexIntegrityValidator implements IndexValidator { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(IndexIntegrityValidator.class); + + private ElasticSearchEndpointConfig endpointConfig; + private ElasticSearchSchemaConfig schemaConfig; + private String tableConfigJson; + + private final ElasticSearchAdapter esAdapter; + + /** + * Instantiates a new index integrity validator. + * + * @param restDataProvider the rest data provider + * @param indexName the index name + * @param indexType the index type + * @param host the host + * @param port the port + * @param tableConfigJson the table config json + */ + public IndexIntegrityValidator(ElasticSearchAdapter esAdapter, + ElasticSearchSchemaConfig esSchemaConfig, ElasticSearchEndpointConfig esEndpointConfig, + String tableConfigJson) { + + this.esAdapter = esAdapter; + this.schemaConfig = esSchemaConfig; + this.endpointConfig = esEndpointConfig; + this.tableConfigJson = tableConfigJson; + } + + public ElasticSearchEndpointConfig getEndpointConfig() { + return endpointConfig; + } + + public void setEndpointConfig(ElasticSearchEndpointConfig endpointConfig) { + this.endpointConfig = endpointConfig; + } + + public ElasticSearchSchemaConfig getSchemaConfig() { + return schemaConfig; + } + + public void setSchemaConfig(ElasticSearchSchemaConfig schemaConfig) { + this.schemaConfig = schemaConfig; + } + + public ElasticSearchAdapter getEsAdapter() { + return esAdapter; + } + + @Override + public String getIndexName() { + return schemaConfig.getIndexName(); + } + + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexValidator#exists() + */ + @Override + public boolean exists() { + final String fullUrlStr = getFullUrl("/" + schemaConfig.getIndexName() + "/"); + OperationResult existsResult = esAdapter.doHead(fullUrlStr, MediaType.APPLICATION_JSON_TYPE); + + int rc = existsResult.getResultCode(); + + if (rc >= 200 && rc < 300) { + LOG.info(AaiUiMsgs.INDEX_EXISTS, schemaConfig.getIndexName()); + return true; + } else { + LOG.info(AaiUiMsgs.INDEX_NOT_EXIST, schemaConfig.getIndexName()); + return false; + } + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexValidator#integrityValid() + */ + @Override + public boolean integrityValid() { + return true; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexValidator#createOrRepair() + */ + @Override + public void createOrRepair() { + + String message = + "IndexIntegrityValidator.createOrRepair() for indexName = " + schemaConfig.getIndexName(); + LOG.info(AaiUiMsgs.INFO_GENERIC, message); + + final String fullUrlStr = getFullUrl("/" + schemaConfig.getIndexName() + "/"); + OperationResult createResult = + esAdapter.doPut(fullUrlStr, tableConfigJson, MediaType.APPLICATION_JSON_TYPE); + + int rc = createResult.getResultCode(); + + if (rc >= 200 && rc < 300) { + LOG.info(AaiUiMsgs.INDEX_RECREATED, schemaConfig.getIndexName()); + } else if (rc == 400) { + LOG.info(AaiUiMsgs.INDEX_ALREADY_EXISTS, schemaConfig.getIndexName()); + } else { + LOG.warn(AaiUiMsgs.INDEX_INTEGRITY_CHECK_FAILED, schemaConfig.getIndexName(), + createResult.getResult()); + } + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexValidator#destroyIndex() + */ + @Override + public void destroyIndex() { + // we don't do this for now + } + + /** + * Gets the full url. + * + * @param resourceUrl the resource url + * @return the full url + */ + private String getFullUrl(String resourceUrl) { + return String.format("http://%s:%s%s", endpointConfig.getEsIpAddress(), + endpointConfig.getEsServerPort(), resourceUrl); + } + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/IndexSynchronizer.java b/src/main/java/org/onap/aai/sparky/sync/IndexSynchronizer.java index f1c6741..6e581f6 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/IndexSynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/sync/IndexSynchronizer.java @@ -20,10 +20,10 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; /** * The Interface IndexSynchronizer. diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/IndexValidator.java b/src/main/java/org/onap/aai/sparky/sync/IndexValidator.java index ae2f6f9..e78d95c 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/IndexValidator.java +++ b/src/main/java/org/onap/aai/sparky/sync/IndexValidator.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; /** * The Interface IndexValidator. diff --git a/src/main/java/org/onap/aai/sparky/sync/SyncController.java b/src/main/java/org/onap/aai/sparky/sync/SyncController.java new file mode 100644 index 0000000..f482c66 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/SyncController.java @@ -0,0 +1,96 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync; + +import java.util.Calendar; +import java.util.Date; + +import org.onap.aai.sparky.sync.SyncControllerImpl.SyncActions; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; + +public interface SyncController { + + String getControllerName(); + + boolean isPeriodicSyncEnabled(); + + boolean isRunOnceSyncEnabled(); + + /** + * Perform action. + * + * @param requestedAction the requested action + * @return + */ + OperationState performAction(SyncActions requestedAction); + + /** + * Register entity synchronizer. + * + * @param entitySynchronizer the entity synchronizer + */ + void registerEntitySynchronizer(IndexSynchronizer entitySynchronizer); + + /** + * Register index validator. + * + * @param indexValidator the index validator + */ + void registerIndexValidator(IndexValidator indexValidator); + + /** + * Register index cleaner. + * + * @param indexCleaner the index cleaner + */ + void registerIndexCleaner(IndexCleaner indexCleaner); + + /** + * Shutdown. + */ + void shutdown(); + + SynchronizerState getState(); + + long getDelayInMs(); + + void setDelayInMs(long delayInMs); + + long getSyncFrequencyInMs(); + + void setSyncFrequencyInMs(long syncFrequencyInMs); + + Date getSyncStartTime(); + + void setSyncStartTime(Date syncStartTime); + + Date getLastExecutionDate(); + + void setLastExecutionDate(Date lastExecutionDate); + + Calendar getCreationTime(); + + String getNextSyncTime(); + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/SyncController.java b/src/main/java/org/onap/aai/sparky/sync/SyncControllerImpl.java index 0f61923..1c3d425 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/SyncController.java +++ b/src/main/java/org/onap/aai/sparky/sync/SyncControllerImpl.java @@ -20,28 +20,35 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; import static java.util.concurrent.CompletableFuture.supplyAsync; +import java.util.Calendar; import java.util.Collection; +import java.util.Date; import java.util.LinkedHashSet; +import java.util.TimeZone; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.util.NodeUtils; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.util.NodeUtils; /** * The Class SyncController. * * @author davea. */ -public class SyncController { - private static final Logger LOG = LoggerFactory.getInstance().getLogger(SyncController.class); +public class SyncControllerImpl implements SyncController { + private static final Logger LOG = LoggerFactory.getInstance().getLogger(SyncControllerImpl.class); /** * The Enum InternalState. @@ -63,7 +70,22 @@ public class SyncController { private InternalState currentInternalState; private ExecutorService syncControllerExecutor; private ExecutorService statReporterExecutor; - private final String controllerName; + + private long delayInMs; + private long syncFrequencyInMs; + private Date syncStartTime; + + private Date lastExecutionDate; + private AtomicInteger runCount; + private Semaphore performingActionGate; + private Calendar creationTime; + + private String syncStartTimeWithTimeZone; + private String controllerName; + + protected SyncControllerConfig syncControllerConfig; + + /** * Instantiates a new sync controller. @@ -71,24 +93,47 @@ public class SyncController { * @param name the name * @throws Exception the exception */ - public SyncController(String name) throws Exception { + public SyncControllerImpl(SyncControllerConfig syncControllerConfig) throws Exception { + this(syncControllerConfig, null); + } - this.controllerName = name; - /* - * Does LHS result in a non-duplicated object collection?? What happens if you double-add an - * object? - */ + public SyncControllerImpl(SyncControllerConfig syncControllerConfig, String targetEntityType) + throws Exception { + + this.syncControllerConfig = syncControllerConfig; + this.delayInMs = 0L; + this.syncFrequencyInMs = 86400000L; + this.syncStartTime = null; + this.lastExecutionDate = null; + this.runCount = new AtomicInteger(0); + this.performingActionGate = new Semaphore(1); registeredSynchronizers = new LinkedHashSet<IndexSynchronizer>(); registeredIndexValidators = new LinkedHashSet<IndexValidator>(); registeredIndexCleaners = new LinkedHashSet<IndexCleaner>(); - this.syncControllerExecutor = NodeUtils.createNamedExecutor("SyncController", 5, LOG); - this.statReporterExecutor = NodeUtils.createNamedExecutor("StatReporter", 1, LOG); + String controllerName = syncControllerConfig.getControllerName(); + + if (targetEntityType != null) { + controllerName += " (" + targetEntityType + ")"; + } + + this.controllerName = controllerName; + + this.syncControllerExecutor = NodeUtils.createNamedExecutor("SyncController-" + controllerName, + syncControllerConfig.getNumSyncControllerWorkers(), LOG); + this.statReporterExecutor = + NodeUtils.createNamedExecutor("StatReporter-" + controllerName, 1, LOG); this.currentInternalState = InternalState.IDLE; + + this.creationTime = Calendar + .getInstance(TimeZone.getTimeZone(syncControllerConfig.getTimeZoneOfSyncStartTimeStamp())); + } + + /** * Change internal state. * @@ -104,36 +149,182 @@ public class SyncController { performStateAction(); } + + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#getDelayInMs() + */ + @Override + public long getDelayInMs() { + return delayInMs; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#setDelayInMs(long) + */ + @Override + public void setDelayInMs(long delayInMs) { + this.delayInMs = delayInMs; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#getSyncFrequencyInMs() + */ + @Override + public long getSyncFrequencyInMs() { + return syncFrequencyInMs; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#setSyncFrequencyInMs(long) + */ + @Override + public void setSyncFrequencyInMs(long syncFrequencyInMs) { + this.syncFrequencyInMs = syncFrequencyInMs; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#getSyncStartTime() + */ + @Override + public Date getSyncStartTime() { + return syncStartTime; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#setSyncStartTime(java.util.Date) + */ + @Override + public void setSyncStartTime(Date syncStartTime) { + this.syncStartTime = syncStartTime; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#getLastExecutionDate() + */ + @Override + public Date getLastExecutionDate() { + return lastExecutionDate; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncController2#setLastExecutionDate(java.util.Date) + */ + @Override + public void setLastExecutionDate(Date lastExecutionDate) { + this.lastExecutionDate = lastExecutionDate; + } + + @Override public String getControllerName() { return controllerName; } - /** - * Perform action. - * - * @param requestedAction the requested action - */ - public void performAction(SyncActions requestedAction) { + + + @Override + public OperationState performAction(SyncActions requestedAction) { if (currentInternalState == InternalState.IDLE) { try { + + /* + * non-blocking semaphore acquire used to guarantee only 1 execution of the synchronization + * at a time. + */ + switch (requestedAction) { case SYNCHRONIZE: - changeInternalState(InternalState.TEST_INDEX_INTEGRITY, requestedAction); + + if (performingActionGate.tryAcquire()) { + try { + + long opStartTime = System.currentTimeMillis(); + + LOG.info(AaiUiMsgs.INFO_GENERIC, + getControllerName() + " started synchronization at " + + SynchronizerConstants.SIMPLE_DATE_FORMAT.format(opStartTime).replaceAll( + SynchronizerConstants.TIME_STD, SynchronizerConstants.TIME_CONFIG_STD)); + + runCount.incrementAndGet(); + + changeInternalState(InternalState.TEST_INDEX_INTEGRITY, requestedAction); + + long opEndTime = System.currentTimeMillis(); + + long opTime = (opEndTime - opStartTime); + + String durationMessage = + String.format(getControllerName() + " synchronization took '%d' ms.", opTime); + + LOG.info(AaiUiMsgs.SYNC_DURATION, durationMessage); + + if (syncControllerConfig.isPeriodicSyncEnabled()) { + + LOG.info(AaiUiMsgs.INFO_GENERIC, + getControllerName() + " next sync to begin at " + getNextSyncTime()); + + TimeZone tz = + TimeZone.getTimeZone(syncControllerConfig.getTimeZoneOfSyncStartTimeStamp()); + + if (opTime > this.getSyncFrequencyInMs()) { + + String durationWasLongerMessage = String.format( + getControllerName() + " synchronization took '%d' ms which is larger than" + + " synchronization interval of '%d' ms.", + opTime, this.getSyncFrequencyInMs()); + + LOG.info(AaiUiMsgs.SYNC_DURATION, durationWasLongerMessage); + } + } + + } catch (Exception syncException) { + String message = "An error occurred while performing action = " + requestedAction + + ". Error = " + syncException.getMessage(); + LOG.error(AaiUiMsgs.ERROR_GENERIC, message); + } finally { + performingActionGate.release(); + } + } else { + return OperationState.IGNORED_SYNC_NOT_IDLE; + } + break; default: break; } + return OperationState.OK; + } catch (Exception exc) { String message = "An error occurred while performing action = " + requestedAction + ". Error = " + exc.getMessage(); LOG.error(AaiUiMsgs.ERROR_GENERIC, message); + return OperationState.ERROR; + } finally { + } } else { LOG.error(AaiUiMsgs.SYNC_NOT_VALID_STATE_DURING_REQUEST, currentInternalState.toString()); + return OperationState.IGNORED_SYNC_NOT_IDLE; } } @@ -182,16 +373,15 @@ public class SyncController { break; } } catch (Exception exc) { + /* + * Perhaps we should abort the sync on an exception + */ String message = "Caught an error which performing action. Error = " + exc.getMessage(); LOG.error(AaiUiMsgs.ERROR_GENERIC, message); } } - /** - * Register entity synchronizer. - * - * @param entitySynchronizer the entity synchronizer - */ + @Override public void registerEntitySynchronizer(IndexSynchronizer entitySynchronizer) { String indexName = entitySynchronizer.getIndexName(); @@ -205,11 +395,7 @@ public class SyncController { } - /** - * Register index validator. - * - * @param indexValidator the index validator - */ + @Override public void registerIndexValidator(IndexValidator indexValidator) { String indexName = indexValidator.getIndexName(); @@ -223,11 +409,7 @@ public class SyncController { } - /** - * Register index cleaner. - * - * @param indexCleaner the index cleaner - */ + @Override public void registerIndexCleaner(IndexCleaner indexCleaner) { String indexName = indexCleaner.getIndexName(); @@ -356,9 +538,12 @@ public class SyncController { } - /** - * Shutdown. + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncControllerInterface#shutdown() */ + @Override public void shutdown() { this.syncControllerExecutor.shutdown(); @@ -420,28 +605,32 @@ public class SyncController { boolean dumpPeriodicStatReport = false; while (!allDone) { - int totalFinished = 0; for (IndexSynchronizer synchronizer : registeredSynchronizers) { if (dumpPeriodicStatReport) { - if (synchronizer.getState() != SynchronizerState.IDLE) { + if (synchronizer.getState() == SynchronizerState.PERFORMING_SYNCHRONIZATION) { String statReport = synchronizer.getStatReport(false); + if (statReport != null) { LOG.info(AaiUiMsgs.INFO_GENERIC, statReport); } } - if (synchronizer.getState() == SynchronizerState.IDLE) { - totalFinished++; - } + } + + if (synchronizer.getState() == SynchronizerState.IDLE + || synchronizer.getState() == SynchronizerState.ABORTED) { + totalFinished++; } } + if (System.currentTimeMillis() > nextReportTimeStampInMs) { dumpPeriodicStatReport = true; nextReportTimeStampInMs = System.currentTimeMillis() + 30000L; } else { dumpPeriodicStatReport = false; } + allDone = (totalFinished == registeredSynchronizers.size()); try { @@ -457,6 +646,12 @@ public class SyncController { } + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.SyncControllerInterface#getState() + */ + @Override public SynchronizerState getState() { switch (currentInternalState) { @@ -473,4 +668,25 @@ public class SyncController { } + @Override + public Calendar getCreationTime() { + return creationTime; + } + + @Override + public String getNextSyncTime() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isPeriodicSyncEnabled() { + return syncControllerConfig.isPeriodicSyncEnabled(); + } + + @Override + public boolean isRunOnceSyncEnabled() { + return syncControllerConfig.isRunOnceSyncEnabled(); + } + } diff --git a/src/main/java/org/onap/aai/sparky/sync/SyncControllerRegistrar.java b/src/main/java/org/onap/aai/sparky/sync/SyncControllerRegistrar.java new file mode 100644 index 0000000..cb2f3ce --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/SyncControllerRegistrar.java @@ -0,0 +1,27 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync; + +public interface SyncControllerRegistrar { + public void registerController(); +} diff --git a/src/main/java/org/onap/aai/sparky/sync/SyncControllerRegistry.java b/src/main/java/org/onap/aai/sparky/sync/SyncControllerRegistry.java new file mode 100644 index 0000000..90845e0 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/SyncControllerRegistry.java @@ -0,0 +1,48 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync; + +import java.util.ArrayList; +import java.util.List; + +public class SyncControllerRegistry { + + private List<SyncController> controllers; + + public SyncControllerRegistry() { + controllers = new ArrayList<SyncController>(); + } + + public void registerSyncController(SyncController controller) { + controllers.add(controller); + } + + public List<SyncController> getControllers() { + return controllers; + } + + public void setControllers(List<SyncController> controllers) { + this.controllers = controllers; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/sync/SyncControllerService.java b/src/main/java/org/onap/aai/sparky/sync/SyncControllerService.java new file mode 100644 index 0000000..a137065 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/SyncControllerService.java @@ -0,0 +1,220 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync; + +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.SyncControllerImpl.SyncActions; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ApplicationContextEvent; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +public class SyncControllerService implements ApplicationListener<ApplicationContextEvent> { + + private SyncControllerRegistry syncControllerRegistry; + private ExecutorService runonceSyncExecutor; + private ScheduledExecutorService periodicSyncExecutor; + private boolean syncStarted; + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(SyncControllerService.class); + + private class SyncControllerTask implements Runnable { + + private SyncController controller; + + public SyncControllerTask(SyncController controller) { + this.controller = controller; + } + + @Override + public void run() { + + try { + + if (controller.getState() == SynchronizerState.IDLE) { + + /* + * This is a blocking-call, but would be nicer if it was async internally within the + * controller but at the moment, that's not the way it works. + */ + + if (controller.performAction(SyncActions.SYNCHRONIZE) != OperationState.OK) { + + LOG.info(AaiUiMsgs.INFO_GENERIC, + controller.getControllerName() + " is not idle, sync attempt has been skipped."); + } + } else { + + LOG.info(AaiUiMsgs.INFO_GENERIC, + controller.getControllerName() + " is not idle, sync attempt has been skipped."); + } + + } catch (Exception exception) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, + "Error while attempting synchronization. Error = " + exception.getMessage()); + } + + } + + } + + public SyncControllerService(SyncControllerRegistry syncControllerRegistry, int numRunOnceWorkers, + int numPeriodicWorkers) { + this.syncControllerRegistry = syncControllerRegistry; + this.syncStarted = false; + + UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() { + + @Override + public void uncaughtException(Thread thread, Throwable exc) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, thread.getName() + ": " + exc); + } + }; + + runonceSyncExecutor = Executors.newFixedThreadPool(numRunOnceWorkers, + new ThreadFactoryBuilder().setNameFormat("RunonceSyncWorker-%d") + .setUncaughtExceptionHandler(uncaughtExceptionHandler).build()); + + + periodicSyncExecutor = Executors.newScheduledThreadPool(numPeriodicWorkers, + new ThreadFactoryBuilder().setNameFormat("PeriodicSyncWorker-%d") + .setUncaughtExceptionHandler(uncaughtExceptionHandler).build()); + + } + + public SyncControllerRegistry getSyncControllerRegistry() { + return syncControllerRegistry; + } + + public void startSync() { + + long syncInitialDelayInMs = 0; + + for (SyncController controller : syncControllerRegistry.getControllers()) { + + syncInitialDelayInMs = controller.getDelayInMs(); + + if (!controller.isPeriodicSyncEnabled()) { + + if (controller.isRunOnceSyncEnabled()) { + LOG.info(AaiUiMsgs.INFO_GENERIC, controller.getControllerName() + " is enabled."); + runonceSyncExecutor.submit(new SyncControllerTask(controller)); + } else { + LOG.info(AaiUiMsgs.INFO_GENERIC, controller.getControllerName() + " is disabled."); + } + + } else { + + /** + * Do both. We'll take one instance of the SyncController and wrap the object instance into + * two SyncControllerTasks. The responsibility for preventing a conflicting sync should live + * in the SyncController instance. If a sync is underway when the periodic sync kicks in, + * then it will be ignored by the SyncController which is already underway. + * + * The SyncController instance itself would then also be stateful such that it would know + * the last time it ran, and the next time it is supposed to run, the number times a sync + * has executed, etc. + */ + + if (controller.isRunOnceSyncEnabled()) { + LOG.info(AaiUiMsgs.INFO_GENERIC, + controller.getControllerName() + " run-once sync is enabled."); + runonceSyncExecutor.submit(new SyncControllerTask(controller)); + } else { + LOG.info(AaiUiMsgs.INFO_GENERIC, + controller.getControllerName() + " run-once sync is disabled."); + } + + /* + * The controller knows it's configuredfrequency and we can just ask it to tell us what the + * delay and frequency needs to be, rather than trying to calculate the configured frequency + * per controller which "could" be different for each controller. + */ + + if (controller.isPeriodicSyncEnabled()) { + + LOG.info(AaiUiMsgs.INFO_GENERIC, + controller.getControllerName() + " periodic sync is enabled and scheduled to start @ " + + controller.getNextSyncTime()); + + periodicSyncExecutor.scheduleAtFixedRate(new SyncControllerTask(controller), + controller.getDelayInMs(), controller.getSyncFrequencyInMs(), TimeUnit.MILLISECONDS); + + } else { + + LOG.info(AaiUiMsgs.INFO_GENERIC, + controller.getControllerName() + " periodic sync is disabled."); + + } + + } + + } + + } + + public void shutdown() { + + if (runonceSyncExecutor != null) { + runonceSyncExecutor.shutdown(); + } + + if (periodicSyncExecutor != null) { + periodicSyncExecutor.shutdown(); + } + + if (syncControllerRegistry != null) { + for (SyncController controller : syncControllerRegistry.getControllers()) { + controller.shutdown(); + } + } + + } + + @Override + public synchronized void onApplicationEvent(ApplicationContextEvent arg0) { + + /* + * Start sync service processing when spring-context-initialization has finished + */ + + if (!syncStarted) { + syncStarted = true; + startSync(); + } + + } + + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/config/SynchronizerConstants.java b/src/main/java/org/onap/aai/sparky/sync/SynchronizerConstants.java index a548c30..73d34bc 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/config/SynchronizerConstants.java +++ b/src/main/java/org/onap/aai/sparky/sync/SynchronizerConstants.java @@ -20,8 +20,9 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.config; +package org.onap.aai.sparky.sync; +import java.text.SimpleDateFormat; import java.util.Date; /** @@ -31,6 +32,13 @@ public final class SynchronizerConstants { // Error values for invalid user input public static final int DEFAULT_CONFIG_ERROR_INT_VALUE = Integer.MAX_VALUE; public static final Date DEFAULT_CONFIG_ERROR_DATE_VALUE = new Date(Long.MAX_VALUE); + public static final SimpleDateFormat SIMPLE_DATE_FORMAT = + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); + + public static final String DEPTH_MODIFIER = "?depth=0"; + public static final String DEPTH_ALL_MODIFIER = "?depth=all"; + public static final String DEPTH_AND_NODES_ONLY_MODIFIER = "?depth=0&nodes-only"; + public static final String NODES_ONLY_MODIFIER = "?nodes-only"; // constants for scheduling synchronizer public static final int COMPONENTS_IN_TIMESTAMP = 2; @@ -48,11 +56,6 @@ public final class SynchronizerConstants { public static final String TIMESTAMP24HOURS_PATTERN = "([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9] UTC[+|-][0-5][0-9]:[0-5][0-9]"; - - - public static final String DEFAULT_SCROLL_CTX_TIME_TO_LIVE_IN_MIN = "5"; - public static final String DEFAULT_NUM_SCROLL_CTX_ITEMS_TO_RETRIEVE_PER_REQ = "5000"; - /** * Instantiates a new synchronizer constants. */ diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/TaskProcessingStats.java b/src/main/java/org/onap/aai/sparky/sync/TaskProcessingStats.java index ef53a75..3e8a0ea 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/TaskProcessingStats.java +++ b/src/main/java/org/onap/aai/sparky/sync/TaskProcessingStats.java @@ -20,10 +20,10 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; import org.onap.aai.sparky.analytics.AbstractStatistics; -import org.onap.aai.sparky.synchronizer.config.TaskProcessorConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; /** * The Class TaskProcessingStats. @@ -41,7 +41,7 @@ public class TaskProcessingStats extends AbstractStatistics { * * @param config the config */ - public TaskProcessingStats(TaskProcessorConfig config) { + public TaskProcessingStats(NetworkStatisticsConfig config) { addHistogram(TASK_AGE_STATS, config.getTaskAgeHistogramLabel(), config.getTaskAgeHistogramMaxYAxis(), config.getTaskAgeHistogramNumBins(), @@ -129,61 +129,5 @@ public class TaskProcessingStats extends AbstractStatistics { } - /** - * @return the tASK_AGE_STATS - */ - public static String getTASK_AGE_STATS() { - return TASK_AGE_STATS; - } - - /** - * @param tASK_AGE_STATS the tASK_AGE_STATS to set - */ - public static void setTASK_AGE_STATS(String tASK_AGE_STATS) { - TASK_AGE_STATS = tASK_AGE_STATS; - } - - /** - * @return the tASK_RESPONSE_STATS - */ - public static String getTASK_RESPONSE_STATS() { - return TASK_RESPONSE_STATS; - } - - /** - * @param tASK_RESPONSE_STATS the tASK_RESPONSE_STATS to set - */ - public static void setTASK_RESPONSE_STATS(String tASK_RESPONSE_STATS) { - TASK_RESPONSE_STATS = tASK_RESPONSE_STATS; - } - - /** - * @return the rESPONSE_SIZE_IN_BYTES - */ - public static String getRESPONSE_SIZE_IN_BYTES() { - return RESPONSE_SIZE_IN_BYTES; - } - - /** - * @param rESPONSE_SIZE_IN_BYTES the rESPONSE_SIZE_IN_BYTES to set - */ - public static void setRESPONSE_SIZE_IN_BYTES(String rESPONSE_SIZE_IN_BYTES) { - RESPONSE_SIZE_IN_BYTES = rESPONSE_SIZE_IN_BYTES; - } - - /** - * @return the tPS - */ - public static String getTPS() { - return TPS; - } - - /** - * @param tPS the tPS to set - */ - public static void setTPS(String tPS) { - TPS = tPS; - } - } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/TransactionRateController.java b/src/main/java/org/onap/aai/sparky/sync/TransactionRateMonitor.java index 76deef3..a120661 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/TransactionRateController.java +++ b/src/main/java/org/onap/aai/sparky/sync/TransactionRateMonitor.java @@ -20,39 +20,28 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.sync; import java.util.concurrent.atomic.AtomicInteger; import org.onap.aai.sparky.analytics.AveragingRingBuffer; -import org.onap.aai.sparky.synchronizer.config.TaskProcessorConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; -/** - * TODO: Fill in description. - * - * @author davea. - */ -public class TransactionRateController { +public class TransactionRateMonitor { + private AtomicInteger numTransactions; private AveragingRingBuffer responseTimeTracker; - private double msPerTransaction; - private int numThreads; - private TaskProcessorConfig config; private long startTimeInMs; - private AtomicInteger numTransactions; /** * Instantiates a new transaction rate controller. * * @param config the config */ - public TransactionRateController(TaskProcessorConfig config) { + public TransactionRateMonitor(int numWorkerThreads, NetworkStatisticsConfig config) { - this.config = config; this.responseTimeTracker = new AveragingRingBuffer( - config.getNumSamplesPerThreadForRunningAverage() * config.getMaxConcurrentWorkers()); - this.msPerTransaction = 1000 / config.getTargetTps(); - this.numThreads = config.getMaxConcurrentWorkers(); + config.getNumSamplesPerThreadForRunningAverage() * numWorkerThreads); this.startTimeInMs = System.currentTimeMillis(); this.numTransactions = new AtomicInteger(0); } @@ -67,32 +56,6 @@ public class TransactionRateController { responseTimeTracker.addSample(responseTimeInMs); } - public long getFixedDelayInMs() { - - /* - * The math here is pretty simple: - * - * 1. Target TPS is 10. Then the msPerTxn = 1000/10 = 100ms - * - * 2. If the calculated avgResponseTime = 40 ms, then the proposed delay is 60ms per thread. - * - * 3. If the calculated avgResponseTime = 200ms, then the proposed delay is -100 ms, which is - * not possible, we can't speed it up, so we don't propose any further delay. - */ - - double proposedDelay = 0; - - if (config.isTransactionRateControllerEnabled()) { - proposedDelay = ((msPerTransaction - responseTimeTracker.getAvg()) * this.numThreads); - - if (proposedDelay > 0) { - return (long) (proposedDelay); - } - } - - return (long) proposedDelay; - } - public long getAvg() { return responseTimeTracker.getAvg(); } diff --git a/src/main/java/org/onap/aai/sparky/sync/config/ElasticSearchEndpointConfig.java b/src/main/java/org/onap/aai/sparky/sync/config/ElasticSearchEndpointConfig.java new file mode 100644 index 0000000..6bea1a4 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/config/ElasticSearchEndpointConfig.java @@ -0,0 +1,70 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync.config; + +public class ElasticSearchEndpointConfig { + + private String esIpAddress; + private String esServerPort; + private int scrollContextTimeToLiveInMinutes; + private int scrollContextBatchRequestSize; + + public ElasticSearchEndpointConfig() { + + } + + public String getEsIpAddress() { + return esIpAddress; + } + + public void setEsIpAddress(String esIpAddress) { + this.esIpAddress = esIpAddress; + } + + public String getEsServerPort() { + return esServerPort; + } + + public void setEsServerPort(String esServerPort) { + this.esServerPort = esServerPort; + } + + public int getScrollContextTimeToLiveInMinutes() { + return scrollContextTimeToLiveInMinutes; + } + + public void setScrollContextTimeToLiveInMinutes(int scrollContextTimeToLiveInMinutes) { + this.scrollContextTimeToLiveInMinutes = scrollContextTimeToLiveInMinutes; + } + + public int getScrollContextBatchRequestSize() { + return scrollContextBatchRequestSize; + } + + public void setScrollContextBatchRequestSize(int scrollContextBatchRequestSize) { + this.scrollContextBatchRequestSize = scrollContextBatchRequestSize; + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/sync/config/ElasticSearchSchemaConfig.java b/src/main/java/org/onap/aai/sparky/sync/config/ElasticSearchSchemaConfig.java new file mode 100644 index 0000000..1e4ba15 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/config/ElasticSearchSchemaConfig.java @@ -0,0 +1,75 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync.config; + +public class ElasticSearchSchemaConfig { + + private String indexName; + private String indexDocType; + private String indexSettingsFileName; + private String indexMappingsFileName; + + public String getIndexName() { + return indexName; + } + + public void setIndexName(String indexName) { + this.indexName = indexName; + } + + public String getIndexDocType() { + return indexDocType; + } + + public void setIndexDocType(String indexDocType) { + this.indexDocType = indexDocType; + } + + public String getIndexSettingsFileName() { + return indexSettingsFileName; + } + + public void setIndexSettingsFileName(String indexSettingsFileName) { + this.indexSettingsFileName = indexSettingsFileName; + } + + public String getIndexMappingsFileName() { + return indexMappingsFileName; + } + + public void setIndexMappingsFileName(String indexMappingsFileName) { + this.indexMappingsFileName = indexMappingsFileName; + } + + @Override + public String toString() { + return "ElasticSearchSchemaConfig [" + + (indexName != null ? "indexName=" + indexName + ", " : "") + + (indexDocType != null ? "indexDocType=" + indexDocType + ", " : "") + + (indexSettingsFileName != null ? "indexSettingsFileName=" + indexSettingsFileName + ", " + : "") + + (indexMappingsFileName != null ? "indexMappingsFileName=" + indexMappingsFileName : "") + + "]"; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/config/NetworkStatisticsConfig.java b/src/main/java/org/onap/aai/sparky/sync/config/NetworkStatisticsConfig.java index 31c8acd..34de88b 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/config/NetworkStatisticsConfig.java +++ b/src/main/java/org/onap/aai/sparky/sync/config/NetworkStatisticsConfig.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.config; +package org.onap.aai.sparky.sync.config; public class NetworkStatisticsConfig { diff --git a/src/main/java/org/onap/aai/sparky/sync/config/SyncControllerConfig.java b/src/main/java/org/onap/aai/sparky/sync/config/SyncControllerConfig.java new file mode 100644 index 0000000..eb3a73f --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/config/SyncControllerConfig.java @@ -0,0 +1,303 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync.config; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.onap.aai.sparky.sync.SynchronizerConstants; + +public class SyncControllerConfig { + + private static final String UNKNOWN_CONTROLLER_NAME = "UnknownControllerName"; + + private String controllerName; + private boolean enabled; + private int syncTaskDelayInMs; + private int syncTaskFrequencyInDays; + + private int numSyncControllerWorkers; + private boolean runOnceSyncEnabled; + private boolean periodicSyncEnabled; + + private String targetSyncStartTimeStamp; + + private int numInternalSyncWorkers; + private int numSyncElasticWorkers; + private int numSyncActiveInventoryWorkers; + + /* + * calculated variables based on incoming config + */ + private String timeZoneOfSyncStartTimeStamp; + private int syncTaskStartTimeHr; + private int syncTaskStartTimeMin; + private int syncTaskStartTimeSec; + + + + public SyncControllerConfig() { + controllerName = UNKNOWN_CONTROLLER_NAME; + enabled = false; + syncTaskDelayInMs = 0; + syncTaskFrequencyInDays = 365; + numSyncControllerWorkers = 1; + runOnceSyncEnabled = false; + periodicSyncEnabled = false; + targetSyncStartTimeStamp = SynchronizerConstants.DEFAULT_START_TIMESTAMP; + numInternalSyncWorkers = 2; + numSyncElasticWorkers = 5; + numSyncActiveInventoryWorkers = 5; + } + + protected void initializeSyncTimeParameters() { + + if (syncTaskDelayInMs < 0) { + throw new IllegalArgumentException("syncTaskDelayInMs must >= 0"); + } + + Pattern pattern = Pattern.compile(SynchronizerConstants.TIMESTAMP24HOURS_PATTERN); + Matcher matcher = pattern.matcher(targetSyncStartTimeStamp); + if (!matcher.matches()) { + throw new IllegalArgumentException("Invalid time format for targetSyncStartTimeStamp"); + } + + List<String> timestampVal = Arrays.asList(targetSyncStartTimeStamp.split(" ")); + + if (timestampVal.size() == SynchronizerConstants.COMPONENTS_IN_TIMESTAMP) { + + // Need both time and timezone offset + timeZoneOfSyncStartTimeStamp = timestampVal + .get(SynchronizerConstants.IDX_TIMEZONE_IN_TIMESTAMP).replaceAll("UTC", "GMT"); + + String time = timestampVal.get(SynchronizerConstants.IDX_TIME_IN_TIMESTAMP); + DateFormat format = new SimpleDateFormat("HH:mm:ss"); + + Date date = null; + + try { + date = format.parse(time); + } catch (ParseException parseException) { + throw new IllegalArgumentException(parseException); + } + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + syncTaskStartTimeHr = calendar.get(Calendar.HOUR_OF_DAY); + syncTaskStartTimeMin = calendar.get(Calendar.MINUTE); + syncTaskStartTimeSec = calendar.get(Calendar.SECOND); + } else { + throw new IllegalArgumentException("Invalid timestamp format from targetSyncStartTimeStamp"); + } + + } + + + public int getNumInternalSyncWorkers() { + return numInternalSyncWorkers; + } + + public void setNumInternalSyncWorkers(int numInternalSyncWorkers) { + this.numInternalSyncWorkers = numInternalSyncWorkers; + } + + public int getNumSyncElasticWorkers() { + return numSyncElasticWorkers; + } + + public void setNumSyncElasticWorkers(int numSyncElasticWorkers) { + this.numSyncElasticWorkers = numSyncElasticWorkers; + } + + public int getNumSyncActiveInventoryWorkers() { + return numSyncActiveInventoryWorkers; + } + + public void setNumSyncActiveInventoryWorkers(int numSyncActiveInventoryWorkers) { + this.numSyncActiveInventoryWorkers = numSyncActiveInventoryWorkers; + } + + public String getTargetSyncStartTimeStamp() { + return targetSyncStartTimeStamp; + } + + public void setTargetSyncStartTimeStamp(String targetSyncStartTimeStamp) { + this.targetSyncStartTimeStamp = targetSyncStartTimeStamp; + initializeSyncTimeParameters(); + } + + public String getControllerName() { + return controllerName; + } + + public void setControllerName(String controllerName) { + this.controllerName = controllerName; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public int getSyncTaskDelayInMs() { + return syncTaskDelayInMs; + } + + public void setSyncTaskDelayInMs(int syncTaskDelayInMs) { + this.syncTaskDelayInMs = syncTaskDelayInMs; + } + + public int getSyncTaskFrequencyInDays() { + return syncTaskFrequencyInDays; + } + + public void setSyncTaskFrequencyInDays(int syncTaskFrequencyInDays) { + this.syncTaskFrequencyInDays = syncTaskFrequencyInDays; + } + + public int getNumSyncControllerWorkers() { + return numSyncControllerWorkers; + } + + public void setNumSyncControllerWorkers(int numSyncControllerWorkers) { + this.numSyncControllerWorkers = numSyncControllerWorkers; + } + + public boolean isRunOnceSyncEnabled() { + return runOnceSyncEnabled; + } + + public void setRunOnceSyncEnabled(boolean runOnceSyncEnabled) { + this.runOnceSyncEnabled = runOnceSyncEnabled; + } + + public boolean isPeriodicSyncEnabled() { + return periodicSyncEnabled; + } + + public void setPeriodicSyncEnabled(boolean periodicSyncEnabled) { + this.periodicSyncEnabled = periodicSyncEnabled; + } + + public long getSyncFrequencyInMs() { + + return (syncTaskFrequencyInDays * SynchronizerConstants.MILLISEC_IN_A_DAY); + + } + + public Calendar getTargetSyncTime() { + + TimeZone tz = TimeZone.getTimeZone(timeZoneOfSyncStartTimeStamp); + Calendar targetSyncTime = Calendar.getInstance(tz); + + targetSyncTime.set(Calendar.HOUR_OF_DAY, syncTaskStartTimeHr); + targetSyncTime.set(Calendar.MINUTE, syncTaskStartTimeMin); + targetSyncTime.set(Calendar.SECOND, syncTaskStartTimeSec); + + return targetSyncTime; + + } + + + public String getNextSyncTime() { + + int taskFrequencyInSeconds = 0; + if (getSyncFrequencyInMs() > 0) { + taskFrequencyInSeconds = (int) (getSyncFrequencyInMs() / 1000); + } + + if (taskFrequencyInSeconds < 86400) { + + TimeZone tz = TimeZone.getTimeZone(timeZoneOfSyncStartTimeStamp); + Calendar targetSyncTime = Calendar.getInstance(tz); + targetSyncTime.add(Calendar.SECOND, taskFrequencyInSeconds); + + return SynchronizerConstants.SIMPLE_DATE_FORMAT.format(targetSyncTime.getTimeInMillis()) + .replaceAll(SynchronizerConstants.TIME_STD, SynchronizerConstants.TIME_CONFIG_STD); + + } else { + + return SynchronizerConstants.SIMPLE_DATE_FORMAT + .format(getNextSyncTime(getTargetSyncTime(), taskFrequencyInSeconds)) + .replaceAll(SynchronizerConstants.TIME_STD, SynchronizerConstants.TIME_CONFIG_STD); + + } + + } + + public long getNextSyncTime(Calendar syncTime, int taskFrequencyInSeconds) { + + TimeZone tz = TimeZone.getTimeZone(timeZoneOfSyncStartTimeStamp); + Calendar timeNow = Calendar.getInstance(tz); + + return getNextSyncTime(syncTime, timeNow.getTimeInMillis(), taskFrequencyInSeconds); + } + + /** + * Gets the first sync time. + * + * @param calendar the calendar + * @param timeNow the time now in ms + * @param taskFrequencyInMs task period in ms + * @return the first sync time + */ + + public long getNextSyncTime(Calendar syncTime, long timeNowInMs, int taskFrequencyInSeconds) { + if (taskFrequencyInSeconds == 0) { + return 0; + } else if (timeNowInMs > syncTime.getTimeInMillis()) { + + /* + * If current time is after the scheduled sync start time, then we'll skip ahead to the next + * sync time period + */ + + syncTime.add(Calendar.SECOND, taskFrequencyInSeconds); + } + + return syncTime.getTimeInMillis(); + } + + public String getTimeZoneOfSyncStartTimeStamp() { + return timeZoneOfSyncStartTimeStamp; + } + + public void setTimeZoneOfSyncStartTimeStamp(String timeZoneOfSyncStartTimeStamp) { + this.timeZoneOfSyncStartTimeStamp = timeZoneOfSyncStartTimeStamp; + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/AggregationEntity.java b/src/main/java/org/onap/aai/sparky/sync/entity/AggregationEntity.java index b2958b1..c4f805e 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/AggregationEntity.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/AggregationEntity.java @@ -20,12 +20,11 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; +package org.onap.aai.sparky.sync.entity; import java.util.HashMap; import java.util.Map; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; import org.onap.aai.sparky.util.NodeUtils; import com.fasterxml.jackson.databind.ObjectMapper; @@ -45,19 +44,10 @@ public class AggregationEntity extends IndexableEntity implements IndexDocument super(); } - /** - * Instantiates a new aggregation entity. - * - * @param loader the loader - */ - public AggregationEntity(OxmModelLoader loader) { - super(loader); - } - /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.entity.IndexDocument#deriveFields() + * @see org.openecomp.sparky.synchronizer.entity.IndexDocument#deriveFields() */ @Override public void deriveFields() { @@ -86,7 +76,7 @@ public class AggregationEntity extends IndexableEntity implements IndexDocument } @Override - public String getIndexDocumentJson() { + public String getAsJson() { ObjectNode rootNode = mapper.createObjectNode(); rootNode.put("link", this.getLink()); rootNode.put("lastmodTimestamp", this.getEntityTimeStamp()); @@ -96,40 +86,6 @@ public class AggregationEntity extends IndexableEntity implements IndexDocument return rootNode.toString(); } - /** - * @return the attributes - */ - public Map<String, String> getAttributes() { - return attributes; - } - - /** - * @param attributes the attributes to set - */ - public void setAttributes(Map<String, String> attributes) { - this.attributes = attributes; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - @Override - public ObjectNode getBulkImportEntity() { - // TODO Auto-generated method stub - return null; - } - /* * (non-Javadoc) * diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/AggregationSuggestionEntity.java b/src/main/java/org/onap/aai/sparky/sync/entity/AggregationSuggestionEntity.java index 412798e..9ee6365 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/AggregationSuggestionEntity.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/AggregationSuggestionEntity.java @@ -20,59 +20,29 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; +package org.onap.aai.sparky.sync.entity; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; +import org.onap.aai.sparky.search.filters.config.FiltersConfig; +import org.onap.aai.sparky.search.filters.config.UiFilterListItemConfig; +import org.onap.aai.sparky.search.filters.config.UiViewListItemConfig; import org.onap.aai.sparky.util.NodeUtils; -public class AggregationSuggestionEntity extends IndexableEntity implements IndexDocument { - - private List<String> inputs = new ArrayList<String>(); - - /** - * @return the inputs - */ - public List<String> getInputs() { - return inputs; - } - - /** - * @param inputs the inputs to set - */ - public void setInputs(List<String> inputs) { - this.inputs = inputs; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } +import com.fasterxml.jackson.databind.ObjectMapper; - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } +public class AggregationSuggestionEntity extends IndexableEntity implements IndexDocument { - /** - * @return the outputString - */ - public String getOutputString() { - return outputString; - } + private static final String FILTER_ID = "filterId"; + private static final String FILTER_LIST = "filterList"; + private List<String> inputs = new ArrayList<>(); private final String outputString = "VNFs"; protected ObjectMapper mapper = new ObjectMapper(); + List<String> filterIds = new ArrayList<>(); public AggregationSuggestionEntity() { super(); @@ -86,8 +56,7 @@ public class AggregationSuggestionEntity extends IndexableEntity implements Inde } @Override - public String getIndexDocumentJson() { - + public String getAsJson() { JSONArray inputArray = new JSONArray(); for (String input : inputs) { input = input.replace(",", ""); @@ -101,7 +70,16 @@ public class AggregationSuggestionEntity extends IndexableEntity implements Inde entitySuggest.put("output", this.outputString); entitySuggest.put("weight", 100); + JSONArray payloadFilters = new JSONArray(); + + for (String filterId : filterIds) { + JSONObject filterPayload = new JSONObject(); + filterPayload.put(FILTER_ID, filterId); + payloadFilters.put(filterPayload); + } + JSONObject payloadNode = new JSONObject(); + payloadNode.put(FILTER_LIST, payloadFilters); entitySuggest.put("payload", payloadNode); JSONObject rootNode = new JSONObject(); @@ -110,10 +88,17 @@ public class AggregationSuggestionEntity extends IndexableEntity implements Inde return rootNode.toString(); } - @Override - public ObjectNode getBulkImportEntity() { - // TODO Auto-generated method stub - return null; + public void initializeFilters() { + for (UiViewListItemConfig view : FiltersConfig.getInstance().getViewsConfig().getViews()) { + if (view.getViewName().equals("vnfSearch")) { + for (UiFilterListItemConfig currentViewFilter : view.getFilters()) { + filterIds.add(currentViewFilter.getFilterId()); + } + } + } } + public void setFilterIds(List<String> filterIds) { + this.filterIds = filterIds; + } } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/IndexDocument.java b/src/main/java/org/onap/aai/sparky/sync/entity/IndexDocument.java index 0633da4..f7818a4 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/IndexDocument.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/IndexDocument.java @@ -20,9 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; - -import com.fasterxml.jackson.databind.node.ObjectNode; +package org.onap.aai.sparky.sync.entity; /** * The Interface IndexDocument. @@ -34,9 +32,8 @@ public interface IndexDocument { */ public void deriveFields(); - public String getIndexDocumentJson(); - public String getId(); - public ObjectNode getBulkImportEntity(); + public String getAsJson() throws Exception; + } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/IndexableCrossEntityReference.java b/src/main/java/org/onap/aai/sparky/sync/entity/IndexableCrossEntityReference.java index 3c454f6..cef7bfe 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/IndexableCrossEntityReference.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/IndexableCrossEntityReference.java @@ -20,15 +20,14 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; +package org.onap.aai.sparky.sync.entity; import java.util.ArrayList; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; import org.onap.aai.sparky.util.NodeUtils; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; /** @@ -38,49 +37,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; public class IndexableCrossEntityReference extends IndexableEntity implements IndexDocument { protected String crossReferenceEntityValues; - - /** - * @return the crossReferenceEntityValues - */ - public String getCrossReferenceEntityValues() { - return crossReferenceEntityValues; - } - - /** - * @param crossReferenceEntityValues the crossReferenceEntityValues to set - */ - public void setCrossReferenceEntityValues(String crossReferenceEntityValues) { - this.crossReferenceEntityValues = crossReferenceEntityValues; - } - - /** - * @return the crossEntityReferenceCollection - */ - public ArrayList<String> getCrossEntityReferenceCollection() { - return crossEntityReferenceCollection; - } - - /** - * @param crossEntityReferenceCollection the crossEntityReferenceCollection to set - */ - public void setCrossEntityReferenceCollection(ArrayList<String> crossEntityReferenceCollection) { - this.crossEntityReferenceCollection = crossEntityReferenceCollection; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - protected ArrayList<String> crossEntityReferenceCollection = new ArrayList<String>(); protected ObjectMapper mapper = new ObjectMapper(); @@ -92,15 +48,6 @@ public class IndexableCrossEntityReference extends IndexableEntity implements In } /** - * Instantiates a new indexable cross entity reference. - * - * @param loader the loader - */ - public IndexableCrossEntityReference(OxmModelLoader loader) { - super(loader); - } - - /** * Adds the cross entity reference value. * * @param crossEntityReferenceValue the cross entity reference value @@ -111,10 +58,18 @@ public class IndexableCrossEntityReference extends IndexableEntity implements In } } + public String getCrossReferenceEntityValues() { + return crossReferenceEntityValues; + } + + public void setCrossReferenceEntityValues(String crossReferenceEntityValues) { + this.crossReferenceEntityValues = crossReferenceEntityValues; + } + /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.entity.IndexDocument#deriveFields() + * @see org.openecomp.sparky.synchronizer.entity.IndexDocument#deriveFields() */ @Override public void deriveFields() { @@ -123,27 +78,12 @@ public class IndexableCrossEntityReference extends IndexableEntity implements In } @Override - public String getIndexDocumentJson() { - ObjectNode rootNode = mapper.createObjectNode(); - rootNode.put("entityType", this.getEntityType()); - rootNode.put("entityPrimaryKeyValue", this.getEntityPrimaryKeyValue()); - rootNode.put("crossEntityReferenceValues", crossReferenceEntityValues); - rootNode.put("link", link); - rootNode.put("lastmodTimestamp", this.getEntityTimeStamp()); - return rootNode.toString(); - } + public String getAsJson() throws JsonProcessingException { + + return NodeUtils.convertObjectToJson(this, false); - @Override - public ObjectNode getBulkImportEntity() { - // TODO Auto-generated method stub - return null; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ @Override public String toString() { return "IndexableCrossEntityReference [" @@ -151,13 +91,9 @@ public class IndexableCrossEntityReference extends IndexableEntity implements In ? "crossReferenceEntityValues=" + crossReferenceEntityValues + ", " : "") + (crossEntityReferenceCollection != null ? "crossEntityReferenceCollection=" + crossEntityReferenceCollection + ", " : "") - + (mapper != null ? "mapper=" + mapper + ", " : "") + (id != null ? "id=" + id + ", " : "") - + (entityType != null ? "entityType=" + entityType + ", " : "") - + (entityPrimaryKeyValue != null ? "entityPrimaryKeyValue=" + entityPrimaryKeyValue + ", " - : "") - + (lastmodTimestamp != null ? "lastmodTimestamp=" + lastmodTimestamp + ", " : "") - + (link != null ? "link=" + link + ", " : "") + (loader != null ? "loader=" + loader : "") - + "]"; + + (mapper != null ? "mapper=" + mapper : "") + "]"; } + + } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/IndexableEntity.java b/src/main/java/org/onap/aai/sparky/sync/entity/IndexableEntity.java index deeac35..5ee9a9f 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/IndexableEntity.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/IndexableEntity.java @@ -20,12 +20,13 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; +package org.onap.aai.sparky.sync.entity; import java.sql.Timestamp; import java.text.SimpleDateFormat; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; /** * The Class IndexableEntity. @@ -35,44 +36,7 @@ public abstract class IndexableEntity { protected String entityType; protected String entityPrimaryKeyValue; protected String lastmodTimestamp; - - /** - * @return the lastmodTimestamp - */ - public String getLastmodTimestamp() { - return lastmodTimestamp; - } - - /** - * @param lastmodTimestamp the lastmodTimestamp to set - */ - public void setLastmodTimestamp(String lastmodTimestamp) { - this.lastmodTimestamp = lastmodTimestamp; - } - - /** - * @return the loader - */ - public OxmModelLoader getLoader() { - return loader; - } - - /** - * @param loader the loader to set - */ - public void setLoader(OxmModelLoader loader) { - this.loader = loader; - } - - /** - * @return the timestampFormat - */ - public static String getTimestampFormat() { - return TIMESTAMP_FORMAT; - } - protected String link; - protected OxmModelLoader loader; private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; @@ -86,28 +50,22 @@ public abstract class IndexableEntity { this.setEntityTimeStamp(currentFormattedTimeStamp); } - /** - * Instantiates a new indexable entity. - * - * @param loader the loader - */ - public IndexableEntity(OxmModelLoader loader) { - this(); - this.loader = loader; - } - + @JsonIgnore public String getId() { return id; } + @JsonProperty("entityType") public String getEntityType() { return entityType; } + @JsonProperty("entityPrimaryKeyValue") public String getEntityPrimaryKeyValue() { return entityPrimaryKeyValue; } + @JsonProperty("lastmodTimestamp") public String getEntityTimeStamp() { return lastmodTimestamp; } @@ -128,6 +86,7 @@ public abstract class IndexableEntity { this.lastmodTimestamp = lastmodTimestamp; } + @JsonProperty("link") public String getLink() { return link; } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/MergableEntity.java b/src/main/java/org/onap/aai/sparky/sync/entity/MergableEntity.java index f998872..10036b3 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/MergableEntity.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/MergableEntity.java @@ -20,14 +20,14 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; - -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; +package org.onap.aai.sparky.sync.entity; import java.util.HashMap; import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; + /** * The Class MergableEntity. */ @@ -35,13 +35,6 @@ public class MergableEntity { private Map<String, String> other = new HashMap<String, String>(); /** - * @param other the other to set - */ - public void setOther(Map<String, String> other) { - this.other = other; - } - - /** * Any. * * @return the map @@ -51,10 +44,6 @@ public class MergableEntity { return other; } - public Map<String, String> getOther() { - return other; - } - /** * Sets the. * diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/ObjectIdCollection.java b/src/main/java/org/onap/aai/sparky/sync/entity/ObjectIdCollection.java index 158cb1d..217dcdf 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/ObjectIdCollection.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/ObjectIdCollection.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; +package org.onap.aai.sparky.sync.entity; import java.util.Collection; import java.util.List; @@ -34,21 +34,7 @@ public class ObjectIdCollection { protected ConcurrentHashMap<String, String> importedObjectIds = new ConcurrentHashMap<String, String>(); - /** - * @return the importedObjectIds - */ - public ConcurrentHashMap<String, String> getImportedObjectIds() { - return importedObjectIds; - } - - /** - * @param importedObjectIds the importedObjectIds to set - */ - public void setImportedObjectIds(ConcurrentHashMap<String, String> importedObjectIds) { - this.importedObjectIds = importedObjectIds; - } - - public Collection<String> getImportedObjectIdsAsValues() { + public Collection<String> getImportedObjectIds() { return importedObjectIds.values(); } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/SearchableEntity.java b/src/main/java/org/onap/aai/sparky/sync/entity/SearchableEntity.java index 08a80ea..dd52bd2 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/SearchableEntity.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/SearchableEntity.java @@ -20,66 +20,30 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; +package org.onap.aai.sparky.sync.entity; import java.util.ArrayList; import java.util.List; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; import org.onap.aai.sparky.util.NodeUtils; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * The Class SearchableEntity. */ public class SearchableEntity extends IndexableEntity implements IndexDocument { - protected List<String> searchTagCollection = new ArrayList<String>(); - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - /** - * @param searchTagCollection the searchTagCollection to set - */ - public void setSearchTagCollection(List<String> searchTagCollection) { - this.searchTagCollection = searchTagCollection; - } - - /** - * @param searchTagIdCollection the searchTagIdCollection to set - */ - public void setSearchTagIdCollection(List<String> searchTagIdCollection) { - this.searchTagIdCollection = searchTagIdCollection; - } - /** - * @param searchTags the searchTags to set - */ - public void setSearchTags(String searchTags) { - this.searchTags = searchTags; - } - - /** - * @param searchTagIDs the searchTagIDs to set - */ - public void setSearchTagIDs(String searchTagIDs) { - this.searchTagIDs = searchTagIDs; - } + @JsonIgnore + protected List<String> searchTagCollection = new ArrayList<String>(); + @JsonIgnore protected List<String> searchTagIdCollection = new ArrayList<String>(); + + @JsonIgnore protected ObjectMapper mapper = new ObjectMapper(); /** @@ -89,19 +53,12 @@ public class SearchableEntity extends IndexableEntity implements IndexDocument { super(); } - /** - * Instantiates a new searchable entity. - * - * @param loader the loader - */ - public SearchableEntity(OxmModelLoader loader) { - super(loader); - } - /* * Generated fields, leave the settings for junit overrides */ + protected String searchTags; // generated based on searchTagCollection values + protected String searchTagIDs; /** @@ -114,7 +71,7 @@ public class SearchableEntity extends IndexableEntity implements IndexDocument { /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.entity.IndexDocument#deriveFields() + * @see org.openecomp.sparky.synchronizer.entity.IndexDocument#deriveFields() */ @Override public void deriveFields() { @@ -145,34 +102,25 @@ public class SearchableEntity extends IndexableEntity implements IndexDocument { return searchTagCollection; } + @JsonProperty("searchTags") public String getSearchTags() { return searchTags; } + @JsonProperty("searchTagIDs") public String getSearchTagIDs() { return searchTagIDs; } + @JsonIgnore public List<String> getSearchTagIdCollection() { return searchTagIdCollection; } @Override - public String getIndexDocumentJson() { - ObjectNode rootNode = mapper.createObjectNode(); - rootNode.put("entityType", this.getEntityType()); - rootNode.put("entityPrimaryKeyValue", this.getEntityPrimaryKeyValue()); - rootNode.put("searchTagIDs", this.getSearchTagIDs()); - rootNode.put("searchTags", this.getSearchTags()); - rootNode.put("link", this.getLink()); - rootNode.put("lastmodTimestamp", this.getEntityTimeStamp()); - return rootNode.toString(); - } - - @Override - public ObjectNode getBulkImportEntity() { - // TODO Auto-generated method stub - return null; + @JsonIgnore + public String getAsJson() throws JsonProcessingException { + return NodeUtils.convertObjectToJson(this, false); } /* diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/SelfLinkDescriptor.java b/src/main/java/org/onap/aai/sparky/sync/entity/SelfLinkDescriptor.java index 20e59ef..9d2886e 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/SelfLinkDescriptor.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/SelfLinkDescriptor.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; +package org.onap.aai.sparky.sync.entity; /** * The Class SelfLinkDescriptor. diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/SuggestionSearchEntity.java b/src/main/java/org/onap/aai/sparky/sync/entity/SuggestionSearchEntity.java index d699031..fdabf86 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/SuggestionSearchEntity.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/SuggestionSearchEntity.java @@ -20,11 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; +package org.onap.aai.sparky.sync.entity; import java.util.ArrayList; import java.util.Arrays; @@ -34,117 +30,82 @@ import java.util.Map; import org.json.JSONArray; import org.json.JSONObject; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.sparky.config.oxm.SuggestionEntityLookup; +import org.onap.aai.sparky.search.filters.config.FiltersConfig; +import org.onap.aai.sparky.search.filters.config.FiltersDetailsConfig; +import org.onap.aai.sparky.search.filters.config.UiFilterConfig; import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.util.SuggestionsPermutation; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; public class SuggestionSearchEntity extends IndexableEntity implements IndexDocument { + private static final String FILTER_ID = "filterId"; + private static final String FILTER_VALUE = "filterValue"; + private static final String FILTER_LIST = "filterList"; private String entityType; private List<String> suggestionConnectorWords = new ArrayList<String>(); private List<String> suggestionAttributeTypes = new ArrayList<String>(); - - /** - * @return the suggestionAttributeTypes - */ - public List<String> getSuggestionAttributeTypes() { - return suggestionAttributeTypes; - } - - /** - * @param suggestionAttributeTypes the suggestionAttributeTypes to set - */ - public void setSuggestionAttributeTypes(List<String> suggestionAttributeTypes) { - this.suggestionAttributeTypes = suggestionAttributeTypes; - } - - /** - * @return the suggestionTypeAliases - */ - public List<String> getSuggestionTypeAliases() { - return suggestionTypeAliases; - } - - /** - * @param suggestionTypeAliases the suggestionTypeAliases to set - */ - public void setSuggestionTypeAliases(List<String> suggestionTypeAliases) { - this.suggestionTypeAliases = suggestionTypeAliases; - } - - /** - * @return the suggestableAttr - */ - public List<String> getSuggestableAttr() { - return suggestableAttr; - } - - /** - * @param suggestableAttr the suggestableAttr to set - */ - public void setSuggestableAttr(List<String> suggestableAttr) { - this.suggestableAttr = suggestableAttr; - } - - /** - * @return the outputString - */ - public StringBuffer getOutputString() { - return outputString; - } - - /** - * @param outputString the outputString to set - */ - public void setOutputString(StringBuffer outputString) { - this.outputString = outputString; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - private List<String> suggestionAttributeValues = new ArrayList<String>(); private List<String> suggestionTypeAliases = new ArrayList<String>(); private List<String> suggestionInputPermutations = new ArrayList<String>(); private List<String> suggestableAttr = new ArrayList<String>(); - private Map<String, String> payload = new HashMap<String, String>(); - private JSONObject payloadJsonNode = new JSONObject(); + + private Map<String, String> inputOutputData = new HashMap<String, String>(); + Map<String, UiFilterConfig> filters = new HashMap<String, UiFilterConfig>(); + private JSONObject payload = new JSONObject(); + private JSONArray payloadFilters = new JSONArray(); private StringBuffer outputString = new StringBuffer(); private String aliasToUse; - public Map<String, String> getPayload() { + private SuggestionEntityLookup entityLookup; + + public JSONObject getPayload() { return payload; } - public void setPayload(Map<String, String> payload) { + public void setPayload(JSONObject payload) { this.payload = payload; } + protected ObjectMapper mapper = new ObjectMapper(); - public JSONObject getPayloadJsonNode() { - return payloadJsonNode; - } + public SuggestionSearchEntity() { + super(); - public void setPayloadJsonNode(JSONObject payloadJsonNode) { - this.payloadJsonNode = payloadJsonNode; + FiltersDetailsConfig filterConfigList = FiltersConfig.getInstance().getFiltersConfig(); + // Populate the map with keys that will match the suggestableAttr values + for (UiFilterConfig filter : filterConfigList.getFilters()) { + if (filter.getDataSource() != null) { + filters.put(filter.getDataSource().getFieldName(), filter); + } + } } + public SuggestionSearchEntity(SuggestionEntityLookup entityLookup) { - protected ObjectMapper mapper = new ObjectMapper(); + this.entityLookup = entityLookup; - public SuggestionSearchEntity() { - super(); + FiltersDetailsConfig filterConfigList = FiltersConfig.getInstance().getFiltersConfig(); + // Populate the map with keys that will match the suggestableAttr values + for (UiFilterConfig filter : filterConfigList.getFilters()) { + if (filter.getDataSource() != null) { + filters.put(filter.getDataSource().getFieldName(), filter); + } + } + } + + public SuggestionSearchEntity(SuggestionEntityLookup entityLookup, FiltersConfig config) { + + FiltersDetailsConfig filterConfigList = config.getFiltersConfig(); + // Populate the map with keys that will match the suggestableAttr values + for (UiFilterConfig filter : filterConfigList.getFilters()) { + if (filter.getDataSource() != null) { + filters.put(filter.getDataSource().getFieldName(), filter); + } + } } public void setSuggestableAttr(ArrayList<String> attributes) { @@ -154,20 +115,67 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu } public void setPayloadFromResponse(JsonNode node) { - Map<String, String> nodePayload = new HashMap<String, String>(); if (suggestableAttr != null) { + JSONObject nodePayload = new JSONObject(); for (String attribute : suggestableAttr) { if (node.get(attribute) != null) { - nodePayload.put(attribute, node.get(attribute).asText()); + inputOutputData.put(attribute, node.get(attribute).asText()); + this.payload.put(attribute, node.get(attribute).asText()); } } - this.setPayload(nodePayload); } } + public void setFilterBasedPayloadFromResponse(JsonNode node, String entityName, + ArrayList<String> uniqueList) { + + HashMap<String, String> desc = entityLookup.getSuggestionSearchEntityOxmModel().get(entityName); + + if (desc == null) { + return; + } + + String attr = desc.get("suggestibleAttributes"); + + if (attr == null) { + return; + } + + List<String> suggestableAttrOxm = Arrays.asList(attr.split(",")); - public SuggestionSearchEntity(OxmModelLoader loader) { - super(loader); + /* + * Note: (1) 'uniqueList' is one item within the power set of the suggestable attributes. (2) + * 'inputeOutputData' is used to generate permutations of strings + */ + for (String selectiveAttr : uniqueList) { + if (node.get(selectiveAttr) != null) { + inputOutputData.put(selectiveAttr, node.get(selectiveAttr).asText()); + } + } + + if (suggestableAttrOxm != null) { + for (String attribute : suggestableAttrOxm) { + if (node.get(attribute) != null && uniqueList.contains(attribute)) { + UiFilterConfig filterConfig = filters.get(attribute); + if (filterConfig != null) { + JSONObject filterPayload = new JSONObject(); + filterPayload.put(FILTER_ID, filterConfig.getFilterId()); + filterPayload.put(FILTER_VALUE, node.get(attribute).asText()); + this.payloadFilters.put(filterPayload); + } else { + this.payload.put(attribute, node.get(attribute).asText()); + } + } else { + UiFilterConfig emptyValueFilterConfig = filters.get(attribute); + if (emptyValueFilterConfig != null) { + JSONObject emptyValueFilterPayload = new JSONObject(); + emptyValueFilterPayload.put(FILTER_ID, emptyValueFilterConfig.getFilterId()); + this.payloadFilters.put(emptyValueFilterPayload); + } + } + } + this.payload.put(FILTER_LIST, this.payloadFilters); + } } @Override @@ -222,10 +230,10 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu public void generateSuggestionInputPermutations() { - List<String> entityNames = new ArrayList<>(); entityNames.add(entityType); - HashMap<String, String> desc = loader.getOxmModel().get(this.entityType); + HashMap<String, String> desc = + entityLookup.getSuggestionSearchEntityOxmModel().get(this.entityType); String attr = desc.get("suggestionAliases"); String[] suggestionAliasesArray = attr.split(","); suggestionTypeAliases = Arrays.asList(suggestionAliasesArray); @@ -233,72 +241,39 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu for (String alias : suggestionTypeAliases) { entityNames.add(alias); } - ArrayList<String> listOfSearchSuggestionPermutations = new ArrayList<>(); - ArrayList<String> listToPermutate = new ArrayList<>(payload.values()); - - for (String entityName : entityNames) { - listToPermutate.add(entityName); - permutateList(listToPermutate, new ArrayList<String>(), listToPermutate.size(), - listOfSearchSuggestionPermutations); - listToPermutate.remove(entityName); - } - suggestionInputPermutations = listOfSearchSuggestionPermutations; - } + ArrayList<String> listToPermutate = new ArrayList<>(inputOutputData.values()); - /** - * Generate all permutations of a list of Strings - * - * @param list - * @param permutation - * @param size - */ - private void permutateList(List<String> list, List<String> permutation, int size, - List<String> listOfSearchSuggestionPermutationList) { - if (permutation.size() == size) { - StringBuilder newPermutation = new StringBuilder(); - - for (int i = 0; i < permutation.size(); i++) { - newPermutation.append(permutation.get(i)).append(" "); + for (String entity : entityNames) { + listToPermutate.add(entity); // add entity-name or alias in list to permutate + List<List<String>> lists = SuggestionsPermutation.getListPermutations(listToPermutate); + for (List<String> li : lists) { + suggestionInputPermutations.add(String.join(" ", li)); } - - listOfSearchSuggestionPermutationList.add(newPermutation.toString().trim()); - - return; - } - - String[] availableItems = list.toArray(new String[0]); - - for (String i : availableItems) { - permutation.add(i); - list.remove(i); - permutateList(list, permutation, size, listOfSearchSuggestionPermutationList); - list.add(i); - permutation.remove(i); + // prepare for the next pass: remove the entity-name or alias from the list + listToPermutate.remove(entity); } } public boolean isSuggestableDoc() { - return this.getPayload().size() != 0; + return this.getPayload().length() != 0; } @Override public void deriveFields() { - int payloadEntryCounter = 1; - for (Map.Entry<String, String> payload : getPayload().entrySet()) { - // Add the payload(status) only if a valid value is present - if (payload.getValue() != null && payload.getValue().length() > 0) { - this.getPayloadJsonNode().put(payload.getKey(), payload.getValue()); - this.outputString.append(payload.getValue()); - if (payloadEntryCounter < getPayload().entrySet().size()) { + int entryCounter = 1; + for (Map.Entry<String, String> outputValue : inputOutputData.entrySet()) { + if (outputValue.getValue() != null && outputValue.getValue().length() > 0) { + this.outputString.append(outputValue.getValue()); + if (entryCounter < inputOutputData.entrySet().size()) { this.outputString.append(" and "); } else { this.outputString.append(" "); } } - payloadEntryCounter++; + entryCounter++; } this.outputString.append(this.getAliasToUse()); @@ -306,7 +281,7 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu } @Override - public String getIndexDocumentJson() { + public String getAsJson() { // TODO Auto-generated method stub JSONObject rootNode = new JSONObject(); @@ -319,18 +294,12 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu entitySuggest.put("input", suggestionsArray); entitySuggest.put("output", this.outputString); - entitySuggest.put("payload", this.payloadJsonNode); + entitySuggest.put("payload", this.payload); rootNode.put("entity_suggest", entitySuggest); return rootNode.toString(); } - @Override - public ObjectNode getBulkImportEntity() { - // TODO Auto-generated method stub - return null; - } - public String getAliasToUse() { return aliasToUse; } @@ -339,6 +308,14 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu this.aliasToUse = aliasToUse; } + public Map<String, String> getInputOutputData() { + return inputOutputData; + } + + public void setInputOutputData(Map<String, String> inputOutputData) { + this.inputOutputData = inputOutputData; + } + @Override public String toString() { return "SuggestionSearchEntity [entityType=" + entityType + ", suggestionConnectorWords=" diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/entity/TransactionStorageType.java b/src/main/java/org/onap/aai/sparky/sync/entity/TransactionStorageType.java index 635281e..8dd25a1 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/entity/TransactionStorageType.java +++ b/src/main/java/org/onap/aai/sparky/sync/entity/TransactionStorageType.java @@ -20,7 +20,7 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.entity; +package org.onap.aai.sparky.sync.entity; /** * The Enum TransactionStorageType. @@ -30,21 +30,6 @@ public enum TransactionStorageType { "aaiOffline/active-inventory-query"); private Integer index; - - /** - * @param index the index to set - */ - public void setIndex(Integer index) { - this.index = index; - } - - /** - * @param outputFolder the outputFolder to set - */ - public void setOutputFolder(String outputFolder) { - this.outputFolder = outputFolder; - } - private String outputFolder; /** diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/enumeration/OperationState.java b/src/main/java/org/onap/aai/sparky/sync/enumeration/OperationState.java index 87d1b88..af25301 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/enumeration/OperationState.java +++ b/src/main/java/org/onap/aai/sparky/sync/enumeration/OperationState.java @@ -20,11 +20,11 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.enumeration; +package org.onap.aai.sparky.sync.enumeration; /** * The Enum OperationState. */ public enum OperationState { - INIT, OK, ERROR, ABORT, PENDING + INIT, OK, ERROR, ABORT, PENDING, IGNORED_SYNC_NOT_IDLE } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/enumeration/SynchronizerState.java b/src/main/java/org/onap/aai/sparky/sync/enumeration/SynchronizerState.java index 0ce5f70..12f0c0a 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/enumeration/SynchronizerState.java +++ b/src/main/java/org/onap/aai/sparky/sync/enumeration/SynchronizerState.java @@ -20,11 +20,11 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.enumeration; +package org.onap.aai.sparky.sync.enumeration; /** * The Enum SynchronizerState. */ public enum SynchronizerState { - IDLE, PERFORMING_SYNCHRONIZATION + IDLE, PERFORMING_SYNCHRONIZATION, ABORTED } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformActiveInventoryRetrieval.java b/src/main/java/org/onap/aai/sparky/sync/task/PerformActiveInventoryRetrieval.java index 33d3610..55c8d47 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformActiveInventoryRetrieval.java +++ b/src/main/java/org/onap/aai/sparky/sync/task/PerformActiveInventoryRetrieval.java @@ -20,17 +20,17 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.task; +package org.onap.aai.sparky.sync.task; import java.util.Map; import java.util.function.Supplier; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; import org.slf4j.MDC; /* @@ -43,10 +43,11 @@ import org.slf4j.MDC; */ public class PerformActiveInventoryRetrieval implements Supplier<NetworkTransaction> { - private static Logger logger = LoggerFactory.getLogger(PerformActiveInventoryRetrieval.class); + private static Logger logger = + LoggerFactory.getInstance().getLogger(PerformActiveInventoryRetrieval.class); private NetworkTransaction txn; - private ActiveInventoryDataProvider aaiProvider; + private ActiveInventoryAdapter aaiAdapter; private Map<String, String> contextMap; /** @@ -56,9 +57,9 @@ public class PerformActiveInventoryRetrieval implements Supplier<NetworkTransact * @param aaiProvider the aai provider */ public PerformActiveInventoryRetrieval(NetworkTransaction txn, - ActiveInventoryDataProvider aaiProvider) { + ActiveInventoryAdapter aaiAdapter) { this.txn = txn; - this.aaiProvider = aaiProvider; + this.aaiAdapter = aaiAdapter; this.contextMap = MDC.getCopyOfContextMap(); } @@ -76,76 +77,24 @@ public class PerformActiveInventoryRetrieval implements Supplier<NetworkTransact MDC.setContextMap(contextMap); OperationResult result = null; try { - // todo: use proper config instead of hard-coding parameters + final String absoluteSelfLink = - ActiveInventoryConfig.getConfig().repairSelfLink(txn.getLink()); - result = aaiProvider.queryActiveInventoryWithRetries(absoluteSelfLink, "application/json", 5); + aaiAdapter.repairSelfLink(txn.getLink(), txn.getQueryParameters()); + result = aaiAdapter.queryActiveInventoryWithRetries(absoluteSelfLink, "application/json", 5); } catch (Exception exc) { - logger.error("Failure to resolve self link from AAI. Error = ", exc); + logger.error(AaiUiMsgs.ERROR_GENERIC, + "Failure to resolve self link from AAI. Error = " + exc.getMessage()); result = new OperationResult(500, "Caught an exception while trying to resolve link = " + exc.getMessage()); } finally { - result.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); txn.setOperationResult(result); + txn.setOpTimeInMs(System.currentTimeMillis() - startTimeInMs); } return txn; } - /** - * @return the logger - */ - public static Logger getLogger() { - return logger; - } - - /** - * @param logger the logger to set - */ - public static void setLogger(Logger logger) { - PerformActiveInventoryRetrieval.logger = logger; - } - - /** - * @return the txn - */ - public NetworkTransaction getTxn() { - return txn; - } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - - /** - * @return the aaiProvider - */ - public ActiveInventoryDataProvider getAaiProvider() { - return aaiProvider; - } - - /** - * @param aaiProvider the aaiProvider to set - */ - public void setAaiProvider(ActiveInventoryDataProvider aaiProvider) { - this.aaiProvider = aaiProvider; - } - - /** - * @return the contextMap - */ - public Map<String, String> getContextMap() { - return contextMap; - } - - /** - * @param contextMap the contextMap to set - */ - public void setContextMap(Map<String, String> contextMap) { + protected void setContextMap(Map<String, String> contextMap) { this.contextMap = contextMap; } - } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformElasticSearchPut.java b/src/main/java/org/onap/aai/sparky/sync/task/PerformElasticSearchPut.java index e1bbd56..6359dbe 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformElasticSearchPut.java +++ b/src/main/java/org/onap/aai/sparky/sync/task/PerformElasticSearchPut.java @@ -20,14 +20,16 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.task; +package org.onap.aai.sparky.sync.task; import java.util.Map; import java.util.function.Supplier; +import javax.ws.rs.core.MediaType; + +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestDataProvider; import org.slf4j.MDC; /** @@ -35,7 +37,7 @@ import org.slf4j.MDC; */ public class PerformElasticSearchPut implements Supplier<NetworkTransaction> { - private RestDataProvider restDataProvider; + private ElasticSearchAdapter esAdapter; private String jsonPayload; private NetworkTransaction txn; private Map<String, String> contextMap; @@ -48,18 +50,18 @@ public class PerformElasticSearchPut implements Supplier<NetworkTransaction> { * @param restDataProvider the rest data provider */ public PerformElasticSearchPut(String jsonPayload, NetworkTransaction txn, - RestDataProvider restDataProvider) { + ElasticSearchAdapter esAdapter) { this.jsonPayload = jsonPayload; this.txn = txn; - this.restDataProvider = restDataProvider; + this.esAdapter = esAdapter; this.contextMap = MDC.getCopyOfContextMap(); } public PerformElasticSearchPut(String jsonPayload, NetworkTransaction txn, - RestDataProvider restDataProvider, Map<String, String> contextMap) { + ElasticSearchAdapter esAdapter, Map<String, String> contextMap) { this.jsonPayload = jsonPayload; this.txn = txn; - this.restDataProvider = restDataProvider; + this.esAdapter = esAdapter; this.contextMap = contextMap; } @@ -71,70 +73,16 @@ public class PerformElasticSearchPut implements Supplier<NetworkTransaction> { @Override public NetworkTransaction get() { txn.setTaskAgeInMs(); - long startTimeInMs = System.currentTimeMillis(); MDC.setContextMap(contextMap); - OperationResult or = restDataProvider.doPut(txn.getLink(), jsonPayload, "application/json"); - - or.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); - txn.setOperationResult(or); - - return txn; - } - - /** - * @return the restDataProvider - */ - public RestDataProvider getRestDataProvider() { - return restDataProvider; - } - - /** - * @param restDataProvider the restDataProvider to set - */ - public void setRestDataProvider(RestDataProvider restDataProvider) { - this.restDataProvider = restDataProvider; - } + long startTimeInMs = System.currentTimeMillis(); - /** - * @return the jsonPayload - */ - public String getJsonPayload() { - return jsonPayload; - } + OperationResult or = + esAdapter.doPut(txn.getLink(), jsonPayload, MediaType.APPLICATION_JSON_TYPE); - /** - * @param jsonPayload the jsonPayload to set - */ - public void setJsonPayload(String jsonPayload) { - this.jsonPayload = jsonPayload; - } + txn.setOperationResult(or); + txn.setOpTimeInMs(System.currentTimeMillis() - startTimeInMs); - /** - * @return the txn - */ - public NetworkTransaction getTxn() { return txn; } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - - /** - * @return the contextMap - */ - public Map<String, String> getContextMap() { - return contextMap; - } - - /** - * @param contextMap the contextMap to set - */ - public void setContextMap(Map<String, String> contextMap) { - this.contextMap = contextMap; - } } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformElasticSearchRetrieval.java b/src/main/java/org/onap/aai/sparky/sync/task/PerformElasticSearchRetrieval.java index f3f3c16..0f37a0d 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformElasticSearchRetrieval.java +++ b/src/main/java/org/onap/aai/sparky/sync/task/PerformElasticSearchRetrieval.java @@ -20,14 +20,16 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.task; +package org.onap.aai.sparky.sync.task; import java.util.Map; import java.util.function.Supplier; +import javax.ws.rs.core.MediaType; + +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestDataProvider; import org.slf4j.MDC; /** @@ -36,7 +38,7 @@ import org.slf4j.MDC; public class PerformElasticSearchRetrieval implements Supplier<NetworkTransaction> { private NetworkTransaction txn; - private RestDataProvider restDataProvider; + private ElasticSearchAdapter esAdapter; private Map<String, String> contextMap; /** @@ -46,9 +48,9 @@ public class PerformElasticSearchRetrieval implements Supplier<NetworkTransactio * @param restDataProvider the rest data provider */ public PerformElasticSearchRetrieval(NetworkTransaction elasticSearchTxn, - RestDataProvider restDataProvider) { + ElasticSearchAdapter esAdapter) { this.txn = elasticSearchTxn; - this.restDataProvider = restDataProvider; + this.esAdapter = esAdapter; this.contextMap = MDC.getCopyOfContextMap(); } @@ -60,51 +62,11 @@ public class PerformElasticSearchRetrieval implements Supplier<NetworkTransactio @Override public NetworkTransaction get() { MDC.setContextMap(contextMap); - OperationResult or = restDataProvider.doGet(txn.getLink(), "application/json"); + long startTimeInMs = System.currentTimeMillis(); + OperationResult or = esAdapter.doGet(txn.getLink(), MediaType.APPLICATION_JSON_TYPE); txn.setOperationResult(or); + txn.setOpTimeInMs(System.currentTimeMillis() - startTimeInMs); return txn; } - /** - * @return the txn - */ - public NetworkTransaction getTxn() { - return txn; - } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - - /** - * @return the restDataProvider - */ - public RestDataProvider getRestDataProvider() { - return restDataProvider; - } - - /** - * @param restDataProvider the restDataProvider to set - */ - public void setRestDataProvider(RestDataProvider restDataProvider) { - this.restDataProvider = restDataProvider; - } - - /** - * @return the contextMap - */ - public Map<String, String> getContextMap() { - return contextMap; - } - - /** - * @param contextMap the contextMap to set - */ - public void setContextMap(Map<String, String> contextMap) { - this.contextMap = contextMap; - } - } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformElasticSearchUpdate.java b/src/main/java/org/onap/aai/sparky/sync/task/PerformElasticSearchUpdate.java index 72b48c9..1d8371f 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/PerformElasticSearchUpdate.java +++ b/src/main/java/org/onap/aai/sparky/sync/task/PerformElasticSearchUpdate.java @@ -20,14 +20,14 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.task; +package org.onap.aai.sparky.sync.task; import java.util.Map; import java.util.function.Supplier; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.elasticsearch.ElasticSearchDataProvider; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.slf4j.MDC; /** @@ -35,7 +35,7 @@ import org.slf4j.MDC; */ public class PerformElasticSearchUpdate implements Supplier<NetworkTransaction> { - private ElasticSearchDataProvider esDataProvider; + private ElasticSearchAdapter esAdapter; private NetworkTransaction operationTracker; private String updatePayload; private String updateUrl; @@ -50,10 +50,10 @@ public class PerformElasticSearchUpdate implements Supplier<NetworkTransaction> * @param transactionTracker the transaction tracker */ public PerformElasticSearchUpdate(String updateUrl, String updatePayload, - ElasticSearchDataProvider esDataProvider, NetworkTransaction transactionTracker) { + ElasticSearchAdapter esAdapter, NetworkTransaction transactionTracker) { this.updateUrl = updateUrl; this.updatePayload = updatePayload; - this.esDataProvider = esDataProvider; + this.esAdapter = esAdapter; this.contextMap = MDC.getCopyOfContextMap(); this.operationTracker = new NetworkTransaction(); operationTracker.setEntityType(transactionTracker.getEntityType()); @@ -69,84 +69,12 @@ public class PerformElasticSearchUpdate implements Supplier<NetworkTransaction> @Override public NetworkTransaction get() { operationTracker.setTaskAgeInMs(); - long startTimeInMs = System.currentTimeMillis(); MDC.setContextMap(contextMap); - OperationResult or = esDataProvider.doBulkOperation(updateUrl, updatePayload); - - or.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); + long startTimeInMs = System.currentTimeMillis(); + OperationResult or = esAdapter.doBulkOperation(updateUrl, updatePayload); operationTracker.setOperationResult(or); - - return operationTracker; - } - - /** - * @return the esDataProvider - */ - public ElasticSearchDataProvider getEsDataProvider() { - return esDataProvider; - } - - /** - * @param esDataProvider the esDataProvider to set - */ - public void setEsDataProvider(ElasticSearchDataProvider esDataProvider) { - this.esDataProvider = esDataProvider; - } - - /** - * @return the operationTracker - */ - public NetworkTransaction getOperationTracker() { + operationTracker.setOpTimeInMs(System.currentTimeMillis() - startTimeInMs); return operationTracker; } - /** - * @param operationTracker the operationTracker to set - */ - public void setOperationTracker(NetworkTransaction operationTracker) { - this.operationTracker = operationTracker; - } - - /** - * @return the updatePayload - */ - public String getUpdatePayload() { - return updatePayload; - } - - /** - * @param updatePayload the updatePayload to set - */ - public void setUpdatePayload(String updatePayload) { - this.updatePayload = updatePayload; - } - - /** - * @return the updateUrl - */ - public String getUpdateUrl() { - return updateUrl; - } - - /** - * @param updateUrl the updateUrl to set - */ - public void setUpdateUrl(String updateUrl) { - this.updateUrl = updateUrl; - } - - /** - * @return the contextMap - */ - public Map<String, String> getContextMap() { - return contextMap; - } - - /** - * @param contextMap the contextMap to set - */ - public void setContextMap(Map<String, String> contextMap) { - this.contextMap = contextMap; - } - } diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/StoreDocumentTask.java b/src/main/java/org/onap/aai/sparky/sync/task/StoreDocumentTask.java index 3e31d12..4ef796d 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/StoreDocumentTask.java +++ b/src/main/java/org/onap/aai/sparky/sync/task/StoreDocumentTask.java @@ -20,15 +20,17 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer.task; +package org.onap.aai.sparky.sync.task; import java.util.Map; import java.util.function.Supplier; +import javax.ws.rs.core.MediaType; + +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestDataProvider; -import org.onap.aai.sparky.synchronizer.entity.IndexDocument; +import org.onap.aai.sparky.sync.entity.IndexDocument; import org.slf4j.MDC; /** @@ -38,65 +40,9 @@ public class StoreDocumentTask implements Supplier<NetworkTransaction> { private IndexDocument doc; - /** - * @return the doc - */ - public IndexDocument getDoc() { - return doc; - } - - /** - * @param doc the doc to set - */ - public void setDoc(IndexDocument doc) { - this.doc = doc; - } - - /** - * @return the txn - */ - public NetworkTransaction getTxn() { - return txn; - } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - - /** - * @return the esDataProvider - */ - public RestDataProvider getEsDataProvider() { - return esDataProvider; - } - - /** - * @param esDataProvider the esDataProvider to set - */ - public void setEsDataProvider(RestDataProvider esDataProvider) { - this.esDataProvider = esDataProvider; - } - - /** - * @return the contextMap - */ - public Map<String, String> getContextMap() { - return contextMap; - } - - /** - * @param contextMap the contextMap to set - */ - public void setContextMap(Map<String, String> contextMap) { - this.contextMap = contextMap; - } - private NetworkTransaction txn; - private RestDataProvider esDataProvider; + private ElasticSearchAdapter esAdapter; private Map<String, String> contextMap; /** @@ -107,10 +53,10 @@ public class StoreDocumentTask implements Supplier<NetworkTransaction> { * @param esDataProvider the es data provider */ public StoreDocumentTask(IndexDocument doc, NetworkTransaction txn, - RestDataProvider esDataProvider) { + ElasticSearchAdapter esAdapter) { this.doc = doc; this.txn = txn; - this.esDataProvider = esDataProvider; + this.esAdapter = esAdapter; this.contextMap = MDC.getCopyOfContextMap(); } @@ -125,11 +71,18 @@ public class StoreDocumentTask implements Supplier<NetworkTransaction> { long startTimeInMs = System.currentTimeMillis(); MDC.setContextMap(contextMap); - OperationResult or = - esDataProvider.doPut(txn.getLink(), doc.getIndexDocumentJson(), "application/json"); - or.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); + OperationResult operationResult = null; + + try { + + operationResult = + esAdapter.doPut(txn.getLink(), doc.getAsJson(), MediaType.APPLICATION_JSON_TYPE); + txn.setOpTimeInMs(System.currentTimeMillis() - startTimeInMs); + } catch (Exception exception) { + operationResult.setResult(500, exception.getMessage()); + } - txn.setOperationResult(or); + txn.setOperationResult(operationResult); return txn; } diff --git a/src/main/java/org/onap/aai/sparky/sync/task/SyncControllerTask.java b/src/main/java/org/onap/aai/sparky/sync/task/SyncControllerTask.java new file mode 100644 index 0000000..959fed1 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/sync/task/SyncControllerTask.java @@ -0,0 +1,53 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.sync.task; + +import org.onap.aai.sparky.sync.SyncController; +import org.onap.aai.sparky.sync.SyncControllerImpl.SyncActions; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; + +public class SyncControllerTask implements Runnable { + + private SyncController controller; + + public SyncControllerTask(SyncController controller) { + this.controller = controller; + } + + @Override + public void run() { + + controller.performAction(SyncActions.SYNCHRONIZE); + + while (controller.getState() == SynchronizerState.PERFORMING_SYNCHRONIZATION) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // exit out of the sync-wait-loop + break; + } + } + + } + +} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/IndexIntegrityValidator.java b/src/main/java/org/onap/aai/sparky/synchronizer/IndexIntegrityValidator.java deleted file mode 100644 index b85dabc..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/IndexIntegrityValidator.java +++ /dev/null @@ -1,227 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer; - -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestDataProvider; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; - -/** - * The Class IndexIntegrityValidator. - * - * @author davea. - */ -public class IndexIntegrityValidator implements IndexValidator { - - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(IndexIntegrityValidator.class); - - private String host; - - /** - * @return the host - */ - public String getHost() { - return host; - } - - /** - * @param host the host to set - */ - public void setHost(String host) { - this.host = host; - } - - /** - * @return the port - */ - public String getPort() { - return port; - } - - /** - * @param port the port to set - */ - public void setPort(String port) { - this.port = port; - } - - /** - * @return the tableConfigJson - */ - public String getTableConfigJson() { - return tableConfigJson; - } - - /** - * @param tableConfigJson the tableConfigJson to set - */ - public void setTableConfigJson(String tableConfigJson) { - this.tableConfigJson = tableConfigJson; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @return the restDataProvider - */ - public RestDataProvider getRestDataProvider() { - return restDataProvider; - } - - private String port; - private String indexName; - private String indexType; - private String tableConfigJson; - - private final RestDataProvider restDataProvider; - - /** - * Instantiates a new index integrity validator. - * - * @param restDataProvider the rest data provider - * @param indexName the index name - * @param indexType the index type - * @param host the host - * @param port the port - * @param tableConfigJson the table config json - */ - public IndexIntegrityValidator(RestDataProvider restDataProvider, String indexName, - String indexType, String host, String port, String tableConfigJson) { - this.restDataProvider = restDataProvider; - this.host = host; - this.port = port; - this.indexName = indexName; - this.indexType = indexType; - this.tableConfigJson = tableConfigJson; - } - - @Override - public String getIndexName() { - return indexName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - - public String getIndexType() { - return indexType; - } - - public void setIndexType(String indexType) { - this.indexType = indexType; - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.synchronizer.IndexValidator#exists() - */ - @Override - public boolean exists() { - final String fullUrlStr = getFullUrl("/" + indexName + "/"); - OperationResult existsResult = restDataProvider.doHead(fullUrlStr, "application/json"); - - int rc = existsResult.getResultCode(); - - if (rc >= 200 && rc < 300) { - LOG.info(AaiUiMsgs.INDEX_EXISTS, indexName); - return true; - } else { - LOG.info(AaiUiMsgs.INDEX_NOT_EXIST, indexName); - return false; - } - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.synchronizer.IndexValidator#integrityValid() - */ - @Override - public boolean integrityValid() { - // TODO Auto-generated method stub - // logger.info("; - // System.out.println("IndexIntegrityValidator.integrityValid() for - // indexName = " + indexName); - return true; - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.synchronizer.IndexValidator#createOrRepair() - */ - @Override - public void createOrRepair() { - // TODO Auto-generated method stub - String message = "IndexIntegrityValidator.createOrRepair() for indexName = " + indexName; - LOG.info(AaiUiMsgs.INFO_GENERIC, message); - - final String fullUrlStr = getFullUrl("/" + indexName + "/"); - OperationResult createResult = - restDataProvider.doPut(fullUrlStr, tableConfigJson, "application/json"); - - int rc = createResult.getResultCode(); - - if (rc >= 200 && rc < 300) { - LOG.info(AaiUiMsgs.INDEX_RECREATED, indexName); - } else if (rc == 400) { - LOG.info(AaiUiMsgs.INDEX_ALREADY_EXISTS, indexName); - } else { - LOG.warn(AaiUiMsgs.INDEX_INTEGRITY_CHECK_FAILED, indexName, createResult.getResult()); - } - - } - - /* - * (non-Javadoc) - * - * @see org.onap.aai.sparky.synchronizer.IndexValidator#destroyIndex() - */ - @Override - public void destroyIndex() { - // TODO Auto-generated method stub - // we don't do this for now - - } - - /** - * Gets the full url. - * - * @param resourceUrl the resource url - * @return the full url - */ - private String getFullUrl(String resourceUrl) { - return String.format("http://%s:%s%s", host, port, resourceUrl); - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/MyErrorHandler.java b/src/main/java/org/onap/aai/sparky/synchronizer/MyErrorHandler.java deleted file mode 100644 index 7a55b15..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/MyErrorHandler.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer; - -import java.io.PrintWriter; - -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * The Class MyErrorHandler. - */ -public class MyErrorHandler implements ErrorHandler { - - /** Error handler output goes here. */ - private PrintWriter out; - - /** - * @return the out - */ - public PrintWriter getOut() { - return out; - } - - /** - * @param out the out to set - */ - public void setOut(PrintWriter out) { - this.out = out; - } - - /** - * Instantiates a new my error handler. - * - * @param out the out - */ - public MyErrorHandler(PrintWriter out) { - this.out = out; - } - - /** - * Returns a string describing parse exception details. - * - * @param spe the spe - * @return the parses the exception info - */ - private String getParseExceptionInfo(SAXParseException spe) { - String systemId = spe.getSystemId(); - if (systemId == null) { - systemId = "null"; - } - String info = "URI=" + systemId + " Line=" + spe.getLineNumber() + ": " + spe.getMessage(); - return info; - } - - // The following methods are standard SAX ErrorHandler methods. - // See SAX documentation for more info. - - /* - * (non-Javadoc) - * - * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) - */ - @Override - public void warning(SAXParseException spe) throws SAXException { - out.println("Warning: " + getParseExceptionInfo(spe)); - } - - /* - * (non-Javadoc) - * - * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) - */ - @Override - public void error(SAXParseException spe) throws SAXException { - String message = "Error: " + getParseExceptionInfo(spe); - throw new SAXException(message); - } - - /* - * (non-Javadoc) - * - * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) - */ - @Override - public void fatalError(SAXParseException spe) throws SAXException { - String message = "Fatal Error: " + getParseExceptionInfo(spe); - throw new SAXException(message); - } -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/SyncHelper.java b/src/main/java/org/onap/aai/sparky/synchronizer/SyncHelper.java deleted file mode 100644 index 9081d41..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/SyncHelper.java +++ /dev/null @@ -1,568 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; - -import java.lang.Thread.UncaughtExceptionHandler; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.aai.ActiveInventoryAdapter; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryRestConfig; -import org.onap.aai.sparky.dal.cache.EntityCache; -import org.onap.aai.sparky.dal.cache.InMemoryEntityCache; -import org.onap.aai.sparky.dal.cache.PersistentEntityCache; -import org.onap.aai.sparky.dal.elasticsearch.ElasticSearchAdapter; -import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; -import org.onap.aai.sparky.dal.rest.RestClientBuilder; -import org.onap.aai.sparky.dal.rest.RestfulDataAccessor; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.SyncController.SyncActions; -import org.onap.aai.sparky.synchronizer.config.SynchronizerConfiguration; -import org.onap.aai.sparky.synchronizer.config.SynchronizerConstants; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.util.ErrorUtil; -import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.slf4j.MDC; - -/** - * The Class SyncHelper. - * - * @author davea. - */ -public class SyncHelper { - - private final Logger LOG = LoggerFactory.getInstance().getLogger(SyncHelper.class); - private SyncController syncController = null; - private SyncController entityCounterHistorySummarizer = null; - - private ScheduledExecutorService oneShotExecutor = Executors.newSingleThreadScheduledExecutor(); - private ScheduledExecutorService periodicExecutor = null; - private ScheduledExecutorService historicalExecutor = - Executors.newSingleThreadScheduledExecutor(); - - private SynchronizerConfiguration syncConfig; - private ElasticSearchConfig esConfig; - private OxmModelLoader oxmModelLoader; - - private Boolean initialSyncRunning = false; - private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - private AtomicLong timeNextSync = new AtomicLong(); - Map<String, String> contextMap; - - /** - * The Class SyncTask. - */ - private class SyncTask implements Runnable { - - private boolean isInitialSync; - - public boolean isInitialSync() { - return isInitialSync; - } - - public void setInitialSync(boolean isInitialSync) { - this.isInitialSync = isInitialSync; - } - - /** - * Instantiates a new sync task. - * - * @param initialSync the initial sync - */ - public SyncTask(boolean initialSync) { - this.isInitialSync = initialSync; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - long opStartTime = System.currentTimeMillis(); - MDC.setContextMap(contextMap); - - LOG.info(AaiUiMsgs.SEARCH_ENGINE_SYNC_STARTED, sdf.format(opStartTime) - .replaceAll(SynchronizerConstants.TIME_STD, SynchronizerConstants.TIME_CONFIG_STD)); - - try { - - if (syncController == null) { - LOG.error(AaiUiMsgs.SYNC_SKIPPED_SYNCCONTROLLER_NOT_INITIALIZED); - return; - } - - int taskFrequencyInDays = SynchronizerConfiguration.getConfig().getSyncTaskFrequencyInDay(); - - /* - * Do nothing if the initial start-up sync hasn't finished yet, but the regular sync - * scheduler fired up a regular sync. - */ - if (!initialSyncRunning) { - if (isInitialSync) { - initialSyncRunning = true; - } else { - // update 'timeNextSync' for periodic sync - timeNextSync.getAndAdd(taskFrequencyInDays * SynchronizerConstants.MILLISEC_IN_A_DAY); - - } - - LOG.info(AaiUiMsgs.INFO_GENERIC, "SyncTask, starting syncrhonization"); - - syncController.performAction(SyncActions.SYNCHRONIZE); - - while (syncController.getState() == SynchronizerState.PERFORMING_SYNCHRONIZATION) { - Thread.sleep(1000); - } - - } else { - LOG.info(AaiUiMsgs.SKIP_PERIODIC_SYNC_AS_SYNC_DIDNT_FINISH, sdf.format(opStartTime) - .replaceAll(SynchronizerConstants.TIME_STD, SynchronizerConstants.TIME_CONFIG_STD)); - - return; - } - - long opEndTime = System.currentTimeMillis(); - - if (isInitialSync) { - /* - * Handle corner case when start-up sync operation overlapped with a scheduled - * sync-start-time. Note that the scheduled sync does nothing if 'initialSyncRunning' is - * TRUE. So the actual next-sync is one more sync-cycle away - */ - long knownNextSyncTime = timeNextSync.get(); - if (knownNextSyncTime != SynchronizerConstants.DELAY_NO_PERIODIC_SYNC_IN_MS - && opEndTime > knownNextSyncTime) { - timeNextSync.compareAndSet(knownNextSyncTime, - knownNextSyncTime + taskFrequencyInDays * SynchronizerConstants.MILLISEC_IN_A_DAY); - initialSyncRunning = false; - } - } - - String durationMessage = - String.format(syncController.getControllerName() + " synchronization took '%d' ms.", - (opEndTime - opStartTime)); - - LOG.info(AaiUiMsgs.SYNC_DURATION, durationMessage); - - // Provide log about the time for next synchronization - if (syncConfig.isConfigOkForPeriodicSync() - && timeNextSync.get() != SynchronizerConstants.DELAY_NO_PERIODIC_SYNC_IN_MS) { - TimeZone tz = TimeZone.getTimeZone(syncConfig.getSyncTaskStartTimeTimeZone()); - sdf.setTimeZone(tz); - if (opEndTime - opStartTime > taskFrequencyInDays - * SynchronizerConstants.MILLISEC_IN_A_DAY) { - String durationWasLongerMessage = String.format( - syncController.getControllerName() - + " synchronization took '%d' ms which is larger than" - + " synchronization interval of '%d' ms.", - (opEndTime - opStartTime), - taskFrequencyInDays * SynchronizerConstants.MILLISEC_IN_A_DAY); - - LOG.info(AaiUiMsgs.SYNC_DURATION, durationWasLongerMessage); - } - - LOG.info(AaiUiMsgs.SYNC_TO_BEGIN, syncController.getControllerName(), - sdf.format(timeNextSync).replaceAll(SynchronizerConstants.TIME_STD, - SynchronizerConstants.TIME_CONFIG_STD)); - } - - } catch (Exception exc) { - String message = "Caught an exception while attempt to synchronize elastic search " - + "with an error cause = " + ErrorUtil.extractStackTraceElements(5, exc); - LOG.error(AaiUiMsgs.ERROR_GENERIC, message); - } - - } - - } - - - /** - * Gets the first sync time. - * - * @param calendar the calendar - * @param timeNow the time now - * @param taskFreqInDay the task freq in day - * @return the first sync time - */ - public long getFirstSyncTime(Calendar calendar, long timeNow, int taskFreqInDay) { - if (taskFreqInDay == SynchronizerConstants.DELAY_NO_PERIODIC_SYNC_IN_MS) { - return SynchronizerConstants.DELAY_NO_PERIODIC_SYNC_IN_MS; - } else if (timeNow > calendar.getTimeInMillis()) { - calendar.add(Calendar.DAY_OF_MONTH, taskFreqInDay); - } - return calendar.getTimeInMillis(); - } - - /** - * Boot strap and configure the moving pieces of the Sync Controller. - */ - - private void initializeSyncController() { - - try { - - /* - * TODO: it would be nice to have XML IoC / dependency injection kind of thing for these - * pieces maybe Spring? - */ - - /* - * Sync Controller itself - */ - - syncController = new SyncController("entitySyncController"); - - /* - * Create common elements - */ - - ActiveInventoryAdapter aaiAdapter = new ActiveInventoryAdapter(new RestClientBuilder()); - ActiveInventoryRestConfig aaiRestConfig = - ActiveInventoryConfig.getConfig().getAaiRestConfig(); - - - EntityCache cache = null; - - if (aaiRestConfig.isCacheEnabled()) { - cache = new PersistentEntityCache(aaiRestConfig.getStorageFolderOverride(), - aaiRestConfig.getNumCacheWorkers()); - } else { - cache = new InMemoryEntityCache(); - } - - RestClientBuilder clientBuilder = new RestClientBuilder(); - - aaiAdapter.setCacheEnabled(true); - aaiAdapter.setEntityCache(cache); - - clientBuilder.setUseHttps(false); - - RestfulDataAccessor nonCachingRestProvider = new RestfulDataAccessor(clientBuilder); - - ElasticSearchConfig esConfig = ElasticSearchConfig.getConfig(); - ElasticSearchAdapter esAdapter = new ElasticSearchAdapter(nonCachingRestProvider, esConfig); - - /* - * Register Index Validators - */ - - IndexIntegrityValidator entitySearchIndexValidator = - new IndexIntegrityValidator(nonCachingRestProvider, esConfig.getIndexName(), - esConfig.getType(), esConfig.getIpAddress(), esConfig.getHttpPort(), - esConfig.buildElasticSearchTableConfig()); - - syncController.registerIndexValidator(entitySearchIndexValidator); - - // TODO: Insert IndexValidator for TopographicalEntityIndex - // we should have one, but one isn't 100% required as none of the fields are analyzed - - /* - * Register Synchronizers - */ - - SearchableEntitySynchronizer ses = new SearchableEntitySynchronizer(esConfig.getIndexName()); - ses.setAaiDataProvider(aaiAdapter); - ses.setEsDataProvider(esAdapter); - syncController.registerEntitySynchronizer(ses); - - CrossEntityReferenceSynchronizer cers = new CrossEntityReferenceSynchronizer( - esConfig.getIndexName(), ActiveInventoryConfig.getConfig()); - cers.setAaiDataProvider(aaiAdapter); - cers.setEsDataProvider(esAdapter); - syncController.registerEntitySynchronizer(cers); - - if (syncConfig.isAutosuggestSynchronizationEnabled()) { - initAutoSuggestionSynchronizer(esConfig, aaiAdapter, esAdapter, nonCachingRestProvider); - initAggregationSynchronizer(esConfig, aaiAdapter, esAdapter, nonCachingRestProvider); - } - - /* - * Register Cleaners - */ - - IndexCleaner searchableIndexCleaner = new ElasticSearchIndexCleaner(nonCachingRestProvider, - esConfig.getIndexName(), esConfig.getType(), esConfig.getIpAddress(), - esConfig.getHttpPort(), syncConfig.getScrollContextTimeToLiveInMinutes(), - syncConfig.getNumScrollContextItemsToRetrievePerRequest()); - - syncController.registerIndexCleaner(searchableIndexCleaner); - - } catch (Exception exc) { - String message = "Error: failed to sync with message = " + exc.getMessage(); - LOG.error(AaiUiMsgs.ERROR_GENERIC, message); - } - - } - - private List<String> getAutosuggestableEntitiesFromOXM() { - Map<String, OxmEntityDescriptor> map = oxmModelLoader.getSuggestionSearchEntityDescriptors(); - List<String> suggestableEntities = new ArrayList<String>(); - - for (String entity : map.keySet()) { - suggestableEntities.add(entity); - } - return suggestableEntities; - } - - /** - * Initialize the AutosuggestionSynchronizer and AggregationSuggestionSynchronizer - * - * @param esConfig - * @param aaiAdapter - * @param esAdapter - * @param nonCachingRestProvider - */ - private void initAutoSuggestionSynchronizer(ElasticSearchConfig esConfig, - ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, - RestfulDataAccessor nonCachingRestProvider) { - LOG.info(AaiUiMsgs.INFO_GENERIC, "initAutoSuggestionSynchronizer"); - - // Initialize for entityautosuggestindex - try { - IndexIntegrityValidator autoSuggestionIndexValidator = - new IndexIntegrityValidator(nonCachingRestProvider, esConfig.getAutosuggestIndexname(), - esConfig.getType(), esConfig.getIpAddress(), esConfig.getHttpPort(), - esConfig.buildAutosuggestionTableConfig()); - - syncController.registerIndexValidator(autoSuggestionIndexValidator); - - AutosuggestionSynchronizer suggestionSynchronizer = - new AutosuggestionSynchronizer(esConfig.getAutosuggestIndexname()); - suggestionSynchronizer.setAaiDataProvider(aaiAdapter); - suggestionSynchronizer.setEsDataProvider(esAdapter); - syncController.registerEntitySynchronizer(suggestionSynchronizer); - - AggregationSuggestionSynchronizer aggregationSuggestionSynchronizer = - new AggregationSuggestionSynchronizer(esConfig.getAutosuggestIndexname()); - aggregationSuggestionSynchronizer.setEsDataProvider(esAdapter); - syncController.registerEntitySynchronizer(aggregationSuggestionSynchronizer); - - IndexCleaner autosuggestIndexCleaner = new ElasticSearchIndexCleaner(nonCachingRestProvider, - esConfig.getAutosuggestIndexname(), esConfig.getType(), esConfig.getIpAddress(), - esConfig.getHttpPort(), syncConfig.getScrollContextTimeToLiveInMinutes(), - syncConfig.getNumScrollContextItemsToRetrievePerRequest()); - - syncController.registerIndexCleaner(autosuggestIndexCleaner); - } catch (Exception exc) { - String message = "Error: failed to sync with message = " + exc.getMessage(); - LOG.error(AaiUiMsgs.ERROR_GENERIC, message); - } - } - - /** - * Initialize the AggregationSynchronizer - * - * @param esConfig - * @param aaiAdapter - * @param esAdapter - * @param nonCachingRestProvider - */ - private void initAggregationSynchronizer(ElasticSearchConfig esConfig, - ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, - RestfulDataAccessor nonCachingRestProvider) { - LOG.info(AaiUiMsgs.INFO_GENERIC, "initAggregationSynchronizer"); - - List<String> aggregationEntities = getAutosuggestableEntitiesFromOXM(); - - // For each index: create an IndexValidator, a Synchronizer, and an IndexCleaner - for (String entity : aggregationEntities) { - try { - String indexName = TierSupportUiConstants.getAggregationIndexName(entity); - - IndexIntegrityValidator aggregationIndexValidator = new IndexIntegrityValidator( - nonCachingRestProvider, indexName, esConfig.getType(), esConfig.getIpAddress(), - esConfig.getHttpPort(), esConfig.buildAggregationTableConfig()); - - syncController.registerIndexValidator(aggregationIndexValidator); - - /* - * TODO: This per-entity-synchronizer approach will eventually result in AAI / ES overload - * because of the existing dedicated thread pools for ES + AAI operations within the - * synchronizer. If we had 50 types to sync then the thread pools within each Synchronizer - * would cause some heartburn as there would be hundreds of threads trying to talk to AAI. - * Given that we our running out of time, let's make sure we can get it functional and then - * we'll re-visit. - */ - AggregationSynchronizer aggSynchronizer = new AggregationSynchronizer(entity, indexName); - aggSynchronizer.setAaiDataProvider(aaiAdapter); - aggSynchronizer.setEsDataProvider(esAdapter); - syncController.registerEntitySynchronizer(aggSynchronizer); - - IndexCleaner entityDataIndexCleaner = new ElasticSearchIndexCleaner(nonCachingRestProvider, - indexName, esConfig.getType(), esConfig.getIpAddress(), esConfig.getHttpPort(), - syncConfig.getScrollContextTimeToLiveInMinutes(), - syncConfig.getNumScrollContextItemsToRetrievePerRequest()); - - syncController.registerIndexCleaner(entityDataIndexCleaner); - - } catch (Exception exc) { - String message = "Error: failed to sync with message = " + exc.getMessage(); - LOG.error(AaiUiMsgs.ERROR_GENERIC, message); - } - } - } - - /** - * Instantiates a new sync helper. - * - * @param loader the loader - */ - public SyncHelper(OxmModelLoader loader) { - try { - this.contextMap = MDC.getCopyOfContextMap(); - this.syncConfig = SynchronizerConfiguration.getConfig(); - this.esConfig = ElasticSearchConfig.getConfig(); - this.oxmModelLoader = loader; - - UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() { - - @Override - public void uncaughtException(Thread thread, Throwable exc) { - LOG.error(AaiUiMsgs.ERROR_GENERIC, thread.getName() + ": " + exc); - } - }; - - ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("SyncHelper-%d") - .setUncaughtExceptionHandler(uncaughtExceptionHandler).build(); - - periodicExecutor = Executors.newScheduledThreadPool(3, namedThreadFactory); - - /* - * We only want to initialize the synchronizer if sync has been configured to start - */ - if (syncConfig.isConfigOkForStartupSync() || syncConfig.isConfigOkForPeriodicSync()) { - initializeSyncController(); - } - - // schedule startup synchronization - if (syncConfig.isConfigOkForStartupSync()) { - - long taskInitialDelayInMs = syncConfig.getSyncTaskInitialDelayInMs(); - if (taskInitialDelayInMs != SynchronizerConstants.DELAY_NO_STARTUP_SYNC_IN_MS) { - oneShotExecutor.schedule(new SyncTask(true), taskInitialDelayInMs, TimeUnit.MILLISECONDS); - LOG.info(AaiUiMsgs.INFO_GENERIC, "Search Engine startup synchronization is enabled."); - } else { - LOG.info(AaiUiMsgs.INFO_GENERIC, "Search Engine startup synchronization is disabled."); - } - } - - // schedule periodic synchronization - if (syncConfig.isConfigOkForPeriodicSync()) { - - TimeZone tz = TimeZone.getTimeZone(syncConfig.getSyncTaskStartTimeTimeZone()); - Calendar calendar = Calendar.getInstance(tz); - sdf.setTimeZone(tz); - - calendar.set(Calendar.HOUR_OF_DAY, syncConfig.getSyncTaskStartTimeHr()); - calendar.set(Calendar.MINUTE, syncConfig.getSyncTaskStartTimeMin()); - calendar.set(Calendar.SECOND, syncConfig.getSyncTaskStartTimeSec()); - - long timeCurrent = calendar.getTimeInMillis(); - int taskFrequencyInDay = syncConfig.getSyncTaskFrequencyInDay(); - timeNextSync.getAndSet(getFirstSyncTime(calendar, timeCurrent, taskFrequencyInDay)); - - long delayUntilFirstRegSyncInMs = 0; - delayUntilFirstRegSyncInMs = timeNextSync.get() - timeCurrent; - - // Do all calculation in milliseconds - long taskFreqencyInMs = taskFrequencyInDay * SynchronizerConstants.MILLISEC_IN_A_DAY; - - if (taskFreqencyInMs != SynchronizerConstants.DELAY_NO_PERIODIC_SYNC_IN_MS) { - periodicExecutor.scheduleAtFixedRate(new SyncTask(false), delayUntilFirstRegSyncInMs, - taskFreqencyInMs, TimeUnit.MILLISECONDS); - LOG.info(AaiUiMsgs.INFO_GENERIC, "Search Engine periodic synchronization is enabled."); - // case: when - startup sync is misconfigured or is disabled - // - give a clue to user when is the next periodic sync - if (!syncConfig.isConfigOkForStartupSync() - || syncConfig.isConfigDisabledForInitialSync()) { - LOG.info(AaiUiMsgs.SYNC_TO_BEGIN, syncController.getControllerName(), - sdf.format(timeNextSync).replaceAll(SynchronizerConstants.TIME_STD, - SynchronizerConstants.TIME_CONFIG_STD)); - } - } else { - LOG.info(AaiUiMsgs.INFO_GENERIC, "Search Engine periodic synchronization is disabled."); - } - } - - } catch (Exception exc) { - String message = "Caught an exception while starting up the SyncHelper. Error cause = \n" - + ErrorUtil.extractStackTraceElements(5, exc); - LOG.error(AaiUiMsgs.ERROR_GENERIC, message); - } - } - - - /** - * Shutdown. - */ - public void shutdown() { - - if (oneShotExecutor != null) { - oneShotExecutor.shutdown(); - } - - if (periodicExecutor != null) { - periodicExecutor.shutdown(); - } - - if (historicalExecutor != null) { - historicalExecutor.shutdown(); - } - - if (syncController != null) { - syncController.shutdown(); - } - - if (entityCounterHistorySummarizer != null) { - entityCounterHistorySummarizer.shutdown(); - } - - } - - public OxmModelLoader getOxmModelLoader() { - return oxmModelLoader; - } - - public void setOxmModelLoader(OxmModelLoader oxmModelLoader) { - this.oxmModelLoader = oxmModelLoader; - } -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/config/SynchronizerConfiguration.java b/src/main/java/org/onap/aai/sparky/synchronizer/config/SynchronizerConfiguration.java deleted file mode 100644 index 8762a0f..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/config/SynchronizerConfiguration.java +++ /dev/null @@ -1,544 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.config; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.text.ParseException; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Properties; -import java.util.TimeZone; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.util.ConfigHelper; -import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; - - -/** - * The Class SynchronizerConfiguration. - */ -public class SynchronizerConfiguration { - - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(SynchronizerConfiguration.class); - - public static final String CONFIG_FILE = - TierSupportUiConstants.DYNAMIC_CONFIG_APP_LOCATION + "synchronizer.properties"; - - private static SynchronizerConfiguration instance; - - public static final String DEPTH_MODIFIER = "?depth=0"; - public static final String DEPTH_ALL_MODIFIER = "?depth=all"; - public static final String DEPTH_AND_NODES_ONLY_MODIFIER = "?depth=0&nodes-only"; - public static final String NODES_ONLY_MODIFIER = "?nodes-only"; - - public static SynchronizerConfiguration getConfig() throws Exception { - - if (instance == null) { - instance = new SynchronizerConfiguration(); - } - - return instance; - } - - /** - * Instantiates a new synchronizer configuration. - */ - public SynchronizerConfiguration() - throws NumberFormatException, PatternSyntaxException, ParseException { - Properties props = ConfigHelper.loadConfigFromExplicitPath(CONFIG_FILE); - initialize(props); - } - - public SynchronizerConfiguration(Properties props) - throws NumberFormatException, PatternSyntaxException, ParseException { - initialize(props); - } - - /** - * Initialize. - * - * @throws Exception the exception - */ - protected void initialize(Properties props) - throws NumberFormatException, PatternSyntaxException, ParseException { - - // parse config for startup sync - try { - syncTaskInitialDelayInMs = - Integer.parseInt(props.getProperty("synchronizer.syncTask.initialDelayInMs", - SynchronizerConstants.DEFAULT_INITIAL_DELAY_IN_MS)); - if (syncTaskInitialDelayInMs < 0) { - throw new NumberFormatException("Error. Sync Task Delay has to be positive"); - } - } catch (NumberFormatException exc) { - this.setConfigOkForStartupSync(false); - syncTaskInitialDelayInMs = SynchronizerConstants.DEFAULT_CONFIG_ERROR_INT_VALUE; - String message = "Invalid configuration for synchronizer parameter:" - + " 'synchronizer.syncTask.initialDelayInMs'"; - LOG.error(AaiUiMsgs.SYNC_INVALID_CONFIG_PARAM, message); - } - - // parse config for periodic sync - try { - syncTaskFrequencyInDay = - Integer.parseInt(props.getProperty("synchronizer.syncTask.taskFrequencyInDay", - SynchronizerConstants.DEFAULT_TASK_FREQUENCY_IN_DAY)); - if (syncTaskFrequencyInDay < 0) { - throw new NumberFormatException("Error. Sync Task Frequency has to be positive"); - } - } catch (NumberFormatException exc) { - this.setConfigOkForPeriodicSync(false); - syncTaskFrequencyInDay = SynchronizerConstants.DEFAULT_CONFIG_ERROR_INT_VALUE; - String message = "Invalid configuration for synchronizer parameter:" - + " 'synchronizer.syncTask.taskFrequencyInDay'"; - LOG.error(AaiUiMsgs.SYNC_INVALID_CONFIG_PARAM, message); - } - - try { - syncTaskStartTime = props.getProperty("synchronizer.syncTask.startTimestamp", - SynchronizerConstants.DEFAULT_START_TIMESTAMP); // Default 05:00:00 UTC - Pattern pattern = Pattern.compile(SynchronizerConstants.TIMESTAMP24HOURS_PATTERN); - Matcher matcher = pattern.matcher(syncTaskStartTime); - if (!matcher.matches()) { - throw new PatternSyntaxException("Pattern Mismatch", - "The erroneous pattern is not available", -1); - } - - List<String> timestampVal = Arrays.asList(syncTaskStartTime.split(" ")); - - if (timestampVal.size() == SynchronizerConstants.COMPONENTS_IN_TIMESTAMP) { - // Need both time and timezone offset - syncTaskStartTimeTimeZone = timestampVal - .get(SynchronizerConstants.IDX_TIMEZONE_IN_TIMESTAMP).replaceAll("UTC", "GMT"); - - String time = timestampVal.get(SynchronizerConstants.IDX_TIME_IN_TIMESTAMP); - DateFormat format = new SimpleDateFormat("HH:mm:ss"); - Date date = format.parse(time); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(date); - - syncTaskStartTimeHr = calendar.get(Calendar.HOUR_OF_DAY); - syncTaskStartTimeMin = calendar.get(Calendar.MINUTE); - syncTaskStartTimeSec = calendar.get(Calendar.SECOND); - } else { - LOG.info(AaiUiMsgs.SYNC_START_TIME); - } - } catch (ParseException exc) { - this.setConfigOkForPeriodicSync(false); - String message = "Invalid configuration for synchronizer parameter:" - + " 'synchronizer.syncTask.startTimestamp'"; - LOG.error(AaiUiMsgs.SYNC_INVALID_CONFIG_PARAM, message); - } - - scrollContextTimeToLiveInMinutes = - Integer.parseInt(props.getProperty("synchronizer.scrollContextTimeToLiveInMinutes", "5")); - numScrollContextItemsToRetrievePerRequest = Integer.parseInt( - props.getProperty("synchronizer.numScrollContextItemsToRetrievePerRequest", "5000")); - - resolverProgressLogFrequencyInMs = Long - .parseLong(props.getProperty("synchronizer.resolver.progressLogFrequencyInMs", "60000")); - resolverQueueMonitorFrequencyInMs = Long - .parseLong(props.getProperty("synchronizer.resolver.queueMonitorFrequencyInMs", "1000")); - - indexIntegrityValidatorEnabled = Boolean - .parseBoolean(props.getProperty("synchronizer.indexIntegrityValidator.enabled", "false")); - indexIntegrityValidatorFrequencyInMs = Long.parseLong( - props.getProperty("synchronizer.indexIntegrityValidatorFrequencyInMs", "300000")); - - displayVerboseQueueManagerStats = Boolean - .parseBoolean(props.getProperty("synchronizer.resolver.displayVerboseQueueManagerStats")); - - resourceNotFoundErrorsSupressed = - Boolean.parseBoolean(props.getProperty("synchronizer.suppressResourceNotFoundErrors")); - - nodesOnlyModifierEnabled = - Boolean.parseBoolean(props.getProperty("synchronizer.applyNodesOnlyModifier")); - - autosuggestSynchronizationEnabled = Boolean - .parseBoolean(props.getProperty("synchronizer.autosuggestSynchronizationEnabled", "true")); - - if (LOG.isDebugEnabled()) { - LOG.debug(AaiUiMsgs.DEBUG_GENERIC, this.toString()); - } - } - - public boolean isNodesOnlyModifierEnabled() { - return nodesOnlyModifierEnabled; - } - - public void setNodesOnlyModifierEnabled(boolean nodesOnlyModifierEnabled) { - this.nodesOnlyModifierEnabled = nodesOnlyModifierEnabled; - } - - public int getSyncTaskInitialDelayInMs() { - return syncTaskInitialDelayInMs; - } - - public void setSyncTaskInitialDelayInMs(int syncTaskInitialDelayInMs) { - this.syncTaskInitialDelayInMs = syncTaskInitialDelayInMs; - } - - public boolean isDisplayVerboseQueueManagerStats() { - return displayVerboseQueueManagerStats; - } - - public void setDisplayVerboseQueueManagerStats(boolean displayVerboseQueueManagerStats) { - this.displayVerboseQueueManagerStats = displayVerboseQueueManagerStats; - } - - private int syncTaskInitialDelayInMs; - - private int syncTaskFrequencyInMs; - - private int scrollContextTimeToLiveInMinutes; - - private int numScrollContextItemsToRetrievePerRequest; - - private long resolverProgressLogFrequencyInMs; - - private long resolverQueueMonitorFrequencyInMs; - - private boolean indexIntegrityValidatorEnabled; - - private long indexIntegrityValidatorFrequencyInMs; - - private int syncTaskFrequencyInDay; - - private String syncTaskStartTime; - - private int syncTaskStartTimeHr = 5; // for default sync start time - - private int syncTaskStartTimeMin; - - private int syncTaskStartTimeSec; - - private String syncTaskStartTimeTimeZone; - - private boolean displayVerboseQueueManagerStats; - - private boolean resourceNotFoundErrorsSupressed; - - private boolean nodesOnlyModifierEnabled; - - private boolean autosuggestSynchronizationEnabled; - - private boolean configOkForStartupSync = true; - - private boolean configOkForPeriodicSync = true; - - public boolean isResourceNotFoundErrorsSupressed() { - return resourceNotFoundErrorsSupressed; - } - - public void setResourceNotFoundErrorsSupressed(boolean resourceNotFoundErrorsSupressed) { - this.resourceNotFoundErrorsSupressed = resourceNotFoundErrorsSupressed; - } - - public int getScrollContextTimeToLiveInMinutes() { - return scrollContextTimeToLiveInMinutes; - } - - public void setScrollContextTimeToLiveInMinutes(int scrollContextTimeToLiveInMinutes) { - this.scrollContextTimeToLiveInMinutes = scrollContextTimeToLiveInMinutes; - } - - public int getNumScrollContextItemsToRetrievePerRequest() { - return numScrollContextItemsToRetrievePerRequest; - } - - public void setNumScrollContextItemsToRetrievePerRequest( - int numScrollContextItemsToRetrievePerRequest) { - this.numScrollContextItemsToRetrievePerRequest = numScrollContextItemsToRetrievePerRequest; - } - - public int getSyncTaskFrequencyInDay() { - return syncTaskFrequencyInDay; - } - - public void setSyncTaskFrequencyInDay(int syncTaskFrequencyInDay) { - this.syncTaskFrequencyInDay = syncTaskFrequencyInDay; - } - - public String getSyncTaskStartTime() { - return syncTaskStartTime; - } - - public void setSyncTaskStartTime(String syncTaskStartTime) { - this.syncTaskStartTime = syncTaskStartTime; - } - - public int getSyncTaskStartTimeHr() { - return syncTaskStartTimeHr; - } - - public void setSyncTaskStartTimeHr(int syncTaskStartTimeHr) { - this.syncTaskStartTimeHr = syncTaskStartTimeHr; - } - - public int getSyncTaskStartTimeMin() { - return syncTaskStartTimeMin; - } - - public void setSyncTaskStartTimeMin(int syncTaskStartTimeMin) { - this.syncTaskStartTimeMin = syncTaskStartTimeMin; - } - - public int getSyncTaskStartTimeSec() { - return syncTaskStartTimeSec; - } - - public void setSyncTaskStartTimeSec(int syncTaskStartTimeSec) { - this.syncTaskStartTimeSec = syncTaskStartTimeSec; - } - - public String getSyncTaskStartTimeTimeZone() { - return syncTaskStartTimeTimeZone; - } - - public void setSyncTaskStartTimeTimeZone(String syncTaskStartTimeTimeZone) { - this.syncTaskStartTimeTimeZone = syncTaskStartTimeTimeZone; - } - - public int getSyncTaskFrequencyInMs() { - return syncTaskFrequencyInMs; - } - - public void setSyncTaskFrequencyInMs(int syncTaskFrequencyInMs) { - this.syncTaskFrequencyInMs = syncTaskFrequencyInMs; - } - - public long getResolverProgressLogFrequencyInMs() { - return resolverProgressLogFrequencyInMs; - } - - public void setResolverProgressLogFrequencyInMs(long resolverProgressLogFrequencyInMs) { - this.resolverProgressLogFrequencyInMs = resolverProgressLogFrequencyInMs; - } - - public long getResolverQueueMonitorFrequencyInMs() { - return resolverQueueMonitorFrequencyInMs; - } - - public void setResolverQueueMonitorFrequencyInMs(long resolverQueueMonitorFrequencyInMs) { - this.resolverQueueMonitorFrequencyInMs = resolverQueueMonitorFrequencyInMs; - } - - public boolean isIndexIntegrityValidatorEnabled() { - return indexIntegrityValidatorEnabled; - } - - public void setIndexIntegrityValidatorEnabled(boolean indexIntegrityValidatorEnabled) { - this.indexIntegrityValidatorEnabled = indexIntegrityValidatorEnabled; - } - - public long getIndexIntegrityValidatorFrequencyInMs() { - return indexIntegrityValidatorFrequencyInMs; - } - - public void setIndexIntegrityValidatorFrequencyInMs(long indexIntegrityValidatorFrequencyInMs) { - this.indexIntegrityValidatorFrequencyInMs = indexIntegrityValidatorFrequencyInMs; - } - - public boolean isConfigOkForStartupSync() { - return configOkForStartupSync; - } - - public void setConfigOkForStartupSync(boolean configOkForStartupSync) { - this.configOkForStartupSync = configOkForStartupSync; - } - - public boolean isConfigOkForPeriodicSync() { - return configOkForPeriodicSync; - } - - public void setConfigOkForPeriodicSync(boolean configOkForPeriodicSync) { - this.configOkForPeriodicSync = configOkForPeriodicSync; - } - - public boolean isConfigDisabledForInitialSync() { - return syncTaskInitialDelayInMs == SynchronizerConstants.DELAY_NO_STARTUP_SYNC_IN_MS; - } - - public boolean isAutosuggestSynchronizationEnabled() { - return autosuggestSynchronizationEnabled; - } - - public void setAutosuggestSynchronizationEnabled(boolean autosuggestSynchronizationEnabled) { - this.autosuggestSynchronizationEnabled = autosuggestSynchronizationEnabled; - } - - public Calendar getTargetSyncTime() { - - TimeZone tz = TimeZone.getTimeZone(getSyncTaskStartTimeTimeZone()); - Calendar targetSyncTime = Calendar.getInstance(tz); - - targetSyncTime.set(Calendar.HOUR_OF_DAY, getSyncTaskStartTimeHr()); - targetSyncTime.set(Calendar.MINUTE, getSyncTaskStartTimeMin()); - targetSyncTime.set(Calendar.SECOND, getSyncTaskStartTimeSec()); - - return targetSyncTime; - - } - - public long getDefaultInitialSyncDelayInMs(Calendar timeNow) { - - int taskFrequencyInDays = getSyncTaskFrequencyInDay(); - - long nextSyncTimeInMs = getNextSyncTime(getTargetSyncTime(), timeNow.getTimeInMillis(), - taskFrequencyInDays * 86400); - - /* - * If the the current time is after the scheduled start time, then delay by the initial task - * delay configuration value - */ - long delayUntilNextSyncInMs = - Math.max(getSyncTaskInitialDelayInMs(), nextSyncTimeInMs - timeNow.getTimeInMillis()); - - return delayUntilNextSyncInMs; - - } - - public long getNextSyncTime(Calendar syncTime, int taskFrequencyInSeconds) { - - TimeZone tz = TimeZone.getTimeZone(getSyncTaskStartTimeTimeZone()); - Calendar timeNow = Calendar.getInstance(tz); - - return getNextSyncTime(syncTime, timeNow.getTimeInMillis(), taskFrequencyInSeconds); - } - - /** - * Gets the first sync time. - * - * @param calendar the calendar - * @param timeNow the time now in ms - * @param taskFrequencyInMs task period in ms - * @return the first sync time - */ - public long getNextSyncTime(Calendar syncTime, long timeNowInMs, int taskFrequencyInSeconds) { - if (taskFrequencyInSeconds == 0) { - return 0; - } else if (timeNowInMs > syncTime.getTimeInMillis()) { - - /* - * If current time is after the scheduled sync start time, then we'll skip ahead to the next - * sync time period - */ - - syncTime.add(Calendar.SECOND, taskFrequencyInSeconds); - } - - return syncTime.getTimeInMillis(); - } - - /** - * @return the instance - */ - public static SynchronizerConfiguration getInstance() { - return instance; - } - - /** - * @param instance the instance to set - */ - public static void setInstance(SynchronizerConfiguration instance) { - SynchronizerConfiguration.instance = instance; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @return the configFile - */ - public static String getConfigFile() { - return CONFIG_FILE; - } - - /** - * @return the depthModifier - */ - public static String getDepthModifier() { - return DEPTH_MODIFIER; - } - - /** - * @return the depthAllModifier - */ - public static String getDepthAllModifier() { - return DEPTH_ALL_MODIFIER; - } - - /** - * @return the depthAndNodesOnlyModifier - */ - public static String getDepthAndNodesOnlyModifier() { - return DEPTH_AND_NODES_ONLY_MODIFIER; - } - - /** - * @return the nodesOnlyModifier - */ - public static String getNodesOnlyModifier() { - return NODES_ONLY_MODIFIER; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "SynchronizerConfiguration [syncTaskInitialDelayInMs=" + syncTaskInitialDelayInMs - + ", syncTaskFrequencyInMs=" + syncTaskFrequencyInMs + ", scrollContextTimeToLiveInMinutes=" - + scrollContextTimeToLiveInMinutes + ", numScrollContextItemsToRetrievePerRequest=" - + numScrollContextItemsToRetrievePerRequest + ", resolverProgressLogFrequencyInMs=" - + resolverProgressLogFrequencyInMs + ", resolverQueueMonitorFrequencyInMs=" - + resolverQueueMonitorFrequencyInMs + ", indexIntegrityValidatorEnabled=" - + indexIntegrityValidatorEnabled + ", indexIntegrityValidatorFrequencyInMs=" - + indexIntegrityValidatorFrequencyInMs + ", ssyncTaskFrequencyInDay=" - + syncTaskFrequencyInDay + ", syncTaskStartTime=" + syncTaskStartTime - + ", syncTaskStartTimeHr=" + syncTaskStartTimeHr + ", syncTaskStartTimeMin=" - + syncTaskStartTimeMin + ", syncTaskStartTimeSec=" + syncTaskStartTimeSec - + ", syncTaskStartTimeTimeZone=" + syncTaskStartTimeTimeZone - + ", displayVerboseQueueManagerStats=" + displayVerboseQueueManagerStats - + ", resourceNotFoundErrorsSupressed=" + resourceNotFoundErrorsSupressed - + ", nodesOnlyModifierEnabled=" + nodesOnlyModifierEnabled + ", configOKForStartupSync=" - + configOkForStartupSync + ", configOKForPeriodicSync=" + configOkForPeriodicSync - + ", autosuggestSynchronizationEnabled=" + autosuggestSynchronizationEnabled + "]"; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/config/TaskProcessorConfig.java b/src/main/java/org/onap/aai/sparky/synchronizer/config/TaskProcessorConfig.java deleted file mode 100644 index 73f4f77..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/config/TaskProcessorConfig.java +++ /dev/null @@ -1,325 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.config; - -import java.util.Properties; - -/** - * TODO: Fill in description. - * - * @author davea. - */ -public class TaskProcessorConfig { - /** - * Initialize from properties. - * - * @param props the props - */ - public void initializeFromProperties(Properties props) { - - if (props == null) { - return; - } - - maxConcurrentWorkers = Integer.parseInt(props.getProperty("maxConcurrentWorkers")); - transactionRateControllerEnabled = - Boolean.parseBoolean(props.getProperty("transactionRateControllerEnabled")); - numSamplesPerThreadForRunningAverage = - Integer.parseInt(props.getProperty("numSamplesPerThreadForRunningAverage")); - targetTps = Double.parseDouble(props.getProperty("targetTPS")); - bytesHistogramLabel = props.getProperty("bytesHistogramLabel"); - bytesHistogramMaxYAxis = Long.parseLong(props.getProperty("bytesHistogramMaxYAxis")); - bytesHistogramNumBins = Integer.parseInt(props.getProperty("bytesHistogramNumBins")); - bytesHistogramNumDecimalPoints = - Integer.parseInt(props.getProperty("bytesHistogramNumDecimalPoints")); - queueLengthHistogramLabel = props.getProperty("queueLengthHistogramLabel"); - queueLengthHistogramMaxYAxis = - Long.parseLong(props.getProperty("queueLengthHistogramMaxYAxis")); - queueLengthHistogramNumBins = - Integer.parseInt(props.getProperty("queueLengthHistogramNumBins")); - queueLengthHistogramNumDecimalPoints = - Integer.parseInt(props.getProperty("queueLengthHistogramNumDecimalPoints")); - - taskAgeHistogramLabel = props.getProperty("taskAgeHistogramLabel"); - taskAgeHistogramMaxYAxis = Long.parseLong(props.getProperty("taskAgeHistogramMaxYAxis")); - taskAgeHistogramNumBins = Integer.parseInt(props.getProperty("taskAgeHistogramNumBins")); - taskAgeHistogramNumDecimalPoints = - Integer.parseInt(props.getProperty("taskAgeHistogramNumDecimalPoints")); - - responseTimeHistogramLabel = props.getProperty("responseTimeHistogramLabel"); - responseTimeHistogramMaxYAxis = - Long.parseLong(props.getProperty("responseTimeHistogramMaxYAxis")); - responseTimeHistogramNumBins = - Integer.parseInt(props.getProperty("responseTimeHistogramNumBins")); - responseTimeHistogramNumDecimalPoints = - Integer.parseInt(props.getProperty("responseTimeHistogramNumDecimalPoints")); - - tpsHistogramLabel = props.getProperty("tpsHistogramLabel"); - tpsHistogramMaxYAxis = Long.parseLong(props.getProperty("tpsHistogramMaxYAxis")); - tpsHistogramNumBins = Integer.parseInt(props.getProperty("tpsHistogramNumBins")); - tpsHistogramNumDecimalPoints = - Integer.parseInt(props.getProperty("tpsHistogramNumDecimalPoints")); - - } - - private int maxConcurrentWorkers; - - private boolean transactionRateControllerEnabled; - - private int numSamplesPerThreadForRunningAverage; - - private double targetTps; - - private String bytesHistogramLabel; - - private long bytesHistogramMaxYAxis; - - private int bytesHistogramNumBins; - - private int bytesHistogramNumDecimalPoints; - - private String queueLengthHistogramLabel; - - private long queueLengthHistogramMaxYAxis; - - private int queueLengthHistogramNumBins; - - private int queueLengthHistogramNumDecimalPoints; - - private String taskAgeHistogramLabel; - - private long taskAgeHistogramMaxYAxis; - - private int taskAgeHistogramNumBins; - - private int taskAgeHistogramNumDecimalPoints; - - private String responseTimeHistogramLabel; - - private long responseTimeHistogramMaxYAxis; - - private int responseTimeHistogramNumBins; - - private int responseTimeHistogramNumDecimalPoints; - - private String tpsHistogramLabel; - - private long tpsHistogramMaxYAxis; - - private int tpsHistogramNumBins; - - private int tpsHistogramNumDecimalPoints; - - public String getBytesHistogramLabel() { - return bytesHistogramLabel; - } - - public void setBytesHistogramLabel(String bytesHistogramLabel) { - this.bytesHistogramLabel = bytesHistogramLabel; - } - - public long getBytesHistogramMaxYAxis() { - return bytesHistogramMaxYAxis; - } - - public void setBytesHistogramMaxYAxis(long bytesHistogramMaxYAxis) { - this.bytesHistogramMaxYAxis = bytesHistogramMaxYAxis; - } - - public int getBytesHistogramNumBins() { - return bytesHistogramNumBins; - } - - public void setBytesHistogramNumBins(int bytesHistogramNumBins) { - this.bytesHistogramNumBins = bytesHistogramNumBins; - } - - public int getBytesHistogramNumDecimalPoints() { - return bytesHistogramNumDecimalPoints; - } - - public void setBytesHistogramNumDecimalPoints(int bytesHistogramNumDecimalPoints) { - this.bytesHistogramNumDecimalPoints = bytesHistogramNumDecimalPoints; - } - - public String getQueueLengthHistogramLabel() { - return queueLengthHistogramLabel; - } - - public void setQueueLengthHistogramLabel(String queueLengthHistogramLabel) { - this.queueLengthHistogramLabel = queueLengthHistogramLabel; - } - - public long getQueueLengthHistogramMaxYAxis() { - return queueLengthHistogramMaxYAxis; - } - - public void setQueueLengthHistogramMaxYAxis(long queueLengthHistogramMaxYAxis) { - this.queueLengthHistogramMaxYAxis = queueLengthHistogramMaxYAxis; - } - - public int getQueueLengthHistogramNumBins() { - return queueLengthHistogramNumBins; - } - - public void setQueueLengthHistogramNumBins(int queueLengthHistogramNumBins) { - this.queueLengthHistogramNumBins = queueLengthHistogramNumBins; - } - - public int getQueueLengthHistogramNumDecimalPoints() { - return queueLengthHistogramNumDecimalPoints; - } - - public void setQueueLengthHistogramNumDecimalPoints(int queueLengthHistogramNumDecimalPoints) { - this.queueLengthHistogramNumDecimalPoints = queueLengthHistogramNumDecimalPoints; - } - - public boolean isTransactionRateControllerEnabled() { - return transactionRateControllerEnabled; - } - - public void setTransactionRateControllerEnabled(boolean transactionRateControllerEnabled) { - this.transactionRateControllerEnabled = transactionRateControllerEnabled; - } - - public int getNumSamplesPerThreadForRunningAverage() { - return numSamplesPerThreadForRunningAverage; - } - - public void setNumSamplesPerThreadForRunningAverage(int numSamplesPerThreadForRunningAverage) { - this.numSamplesPerThreadForRunningAverage = numSamplesPerThreadForRunningAverage; - } - - public double getTargetTps() { - return targetTps; - } - - public void setTargetTps(double targetTps) { - this.targetTps = targetTps; - } - - public int getMaxConcurrentWorkers() { - return maxConcurrentWorkers; - } - - public void setMaxConcurrentWorkers(int maxConcurrentWorkers) { - this.maxConcurrentWorkers = maxConcurrentWorkers; - } - - public String getTaskAgeHistogramLabel() { - return taskAgeHistogramLabel; - } - - public void setTaskAgeHistogramLabel(String taskAgeHistogramLabel) { - this.taskAgeHistogramLabel = taskAgeHistogramLabel; - } - - public long getTaskAgeHistogramMaxYAxis() { - return taskAgeHistogramMaxYAxis; - } - - public void setTaskAgeHistogramMaxYAxis(long taskAgeHistogramMaxYAxis) { - this.taskAgeHistogramMaxYAxis = taskAgeHistogramMaxYAxis; - } - - public int getTaskAgeHistogramNumBins() { - return taskAgeHistogramNumBins; - } - - public void setTaskAgeHistogramNumBins(int taskAgeHistogramNumBins) { - this.taskAgeHistogramNumBins = taskAgeHistogramNumBins; - } - - public int getTaskAgeHistogramNumDecimalPoints() { - return taskAgeHistogramNumDecimalPoints; - } - - public void setTaskAgeHistogramNumDecimalPoints(int taskAgeHistogramNumDecimalPoints) { - this.taskAgeHistogramNumDecimalPoints = taskAgeHistogramNumDecimalPoints; - } - - public String getResponseTimeHistogramLabel() { - return responseTimeHistogramLabel; - } - - public void setResponseTimeHistogramLabel(String responseTimeHistogramLabel) { - this.responseTimeHistogramLabel = responseTimeHistogramLabel; - } - - public long getResponseTimeHistogramMaxYAxis() { - return responseTimeHistogramMaxYAxis; - } - - public void setResponseTimeHistogramMaxYAxis(long responseTimeHistogramMaxYAxis) { - this.responseTimeHistogramMaxYAxis = responseTimeHistogramMaxYAxis; - } - - public int getResponseTimeHistogramNumBins() { - return responseTimeHistogramNumBins; - } - - public void setResponseTimeHistogramNumBins(int responseTimeHistogramNumBins) { - this.responseTimeHistogramNumBins = responseTimeHistogramNumBins; - } - - public int getResponseTimeHistogramNumDecimalPoints() { - return responseTimeHistogramNumDecimalPoints; - } - - public void setResponseTimeHistogramNumDecimalPoints(int responseTimeHistogramNumDecimalPoints) { - this.responseTimeHistogramNumDecimalPoints = responseTimeHistogramNumDecimalPoints; - } - - public String getTpsHistogramLabel() { - return tpsHistogramLabel; - } - - public void setTpsHistogramLabel(String tpsHistogramLabel) { - this.tpsHistogramLabel = tpsHistogramLabel; - } - - public long getTpsHistogramMaxYAxis() { - return tpsHistogramMaxYAxis; - } - - public void setTpsHistogramMaxYAxis(long tpsHistogramMaxYAxis) { - this.tpsHistogramMaxYAxis = tpsHistogramMaxYAxis; - } - - public int getTpsHistogramNumBins() { - return tpsHistogramNumBins; - } - - public void setTpsHistogramNumBins(int tpsHistogramNumBins) { - this.tpsHistogramNumBins = tpsHistogramNumBins; - } - - public int getTpsHistogramNumDecimalPoints() { - return tpsHistogramNumDecimalPoints; - } - - public void setTpsHistogramNumDecimalPoints(int tpsHistogramNumDecimalPoints) { - this.tpsHistogramNumDecimalPoints = tpsHistogramNumDecimalPoints; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/filter/ElasticSearchSynchronizerFilter.java b/src/main/java/org/onap/aai/sparky/synchronizer/filter/ElasticSearchSynchronizerFilter.java deleted file mode 100644 index ef199f7..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/filter/ElasticSearchSynchronizerFilter.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.filter; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.SyncHelper; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.cl.mdc.MdcContext; - -/* - * This is a wire-frame for an experiment to get the jetty filter-lifecyle initialization method to - * setup a scheduled thread executor with an ElasticSearchSynchronization task, which (I'm hoping) - * will allow us to do periodic ES <=> AAI synchronization. - * - * Alternatively, if the embedded java approach doesn't work we could try instead to do a - * System.exec( "perl refreshElasticSearchInstance.pl"). We have two options, I'm hoping the - * embedded options will work for us. - */ - -/** - * The Class ElasticSearchSynchronizerFilter. - */ -public class ElasticSearchSynchronizerFilter implements Filter { - - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(ElasticSearchSynchronizerFilter.class); - - private SyncHelper syncHelper; - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#destroy() - */ - @Override - public void destroy() { - - if (syncHelper != null) { - syncHelper.shutdown(); - } - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, - * javax.servlet.FilterChain) - */ - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - - /* - * However, we will setup the filtermap with a url that should never get it, so we shouldn't - * ever be in here. - */ - - chain.doFilter(request, response); - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) - */ - @Override - public void init(FilterConfig filterConfig) throws ServletException { - String txnID = NodeUtils.getRandomTxnId(); - MdcContext.initialize(txnID, "ElasticSearchSynchronizerFilter", "", "Init", ""); - - LOG.debug(AaiUiMsgs.DEBUG_GENERIC, "init()"); - - try { - new SyncHelper(OxmModelLoader.getInstance()); - } catch (Exception exc) { - throw new ServletException("Caught an exception while initializing filter", exc); - } - - } - - /** - * @return the syncHelper - */ - public SyncHelper getSyncHelper() { - return syncHelper; - } - - /** - * @param syncHelper the syncHelper to set - */ - public void setSyncHelper(SyncHelper syncHelper) { - this.syncHelper = syncHelper; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/CollectEntitySelfLinkTask.java b/src/main/java/org/onap/aai/sparky/synchronizer/task/CollectEntitySelfLinkTask.java deleted file mode 100644 index b12a1d9..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/CollectEntitySelfLinkTask.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.task; - -import java.util.function.Supplier; - -import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; -import org.onap.aai.sparky.dal.rest.OperationResult; - -/** - * The Class CollectEntitySelfLinkTask. - */ -public class CollectEntitySelfLinkTask implements Supplier<NetworkTransaction> { - - private NetworkTransaction txn; - - private ActiveInventoryDataProvider provider; - - /** - * Instantiates a new collect entity self link task. - * - * @param txn the txn - * @param provider the provider - */ - public CollectEntitySelfLinkTask(NetworkTransaction txn, ActiveInventoryDataProvider provider) { - this.txn = txn; - this.provider = provider; - } - - /* - * (non-Javadoc) - * - * @see java.util.function.Supplier#get() - */ - @Override - public NetworkTransaction get() { - - txn.setTaskAgeInMs(); - - long startTimeInMs = System.currentTimeMillis(); - OperationResult result = null; - try { - result = provider.queryActiveInventoryWithRetries(txn.getLink(), "application/json", 5); - } catch (Exception exc) { - result = new OperationResult(500, - "Caught an exception while trying to resolve link = " + exc.getMessage()); - } finally { - result.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); - txn.setOperationResult(result); - } - - return txn; - } - - /** - * @return the txn - */ - public NetworkTransaction getTxn() { - return txn; - } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - - /** - * @return the provider - */ - public ActiveInventoryDataProvider getProvider() { - return provider; - } - - /** - * @param provider the provider to set - */ - public void setProvider(ActiveInventoryDataProvider provider) { - this.provider = provider; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/CollectEntityTypeSelfLinksTask.java b/src/main/java/org/onap/aai/sparky/synchronizer/task/CollectEntityTypeSelfLinksTask.java deleted file mode 100644 index 712a2e3..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/CollectEntityTypeSelfLinksTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.task; - -import java.util.function.Supplier; - -import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; -import org.onap.aai.sparky.dal.rest.OperationResult; - -/** - * The Class CollectEntityTypeSelfLinksTask. - */ -public class CollectEntityTypeSelfLinksTask implements Supplier<NetworkTransaction> { - - private ActiveInventoryDataProvider aaiProvider; - - private NetworkTransaction txn; - - /** - * Instantiates a new collect entity type self links task. - * - * @param txn the txn - * @param provider the provider - */ - public CollectEntityTypeSelfLinksTask(NetworkTransaction txn, - ActiveInventoryDataProvider provider) { - this.aaiProvider = provider; - this.txn = txn; - } - - /* - * (non-Javadoc) - * - * @see java.util.function.Supplier#get() - */ - @Override - public NetworkTransaction get() { - - txn.setTaskAgeInMs(); - - long startTimeInMs = System.currentTimeMillis(); - OperationResult result = null; - try { - result = aaiProvider.queryActiveInventoryWithRetries(txn.getLink(), "application/json", 5); - } catch (Exception exc) { - result = new OperationResult(500, - "Caught an exception while trying to resolve link = " + exc.getMessage()); - } finally { - result.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); - txn.setOperationResult(result); - } - - return txn; - } - - /** - * @return the aaiProvider - */ - public ActiveInventoryDataProvider getAaiProvider() { - return aaiProvider; - } - - /** - * @param aaiProvider the aaiProvider to set - */ - public void setAaiProvider(ActiveInventoryDataProvider aaiProvider) { - this.aaiProvider = aaiProvider; - } - - /** - * @return the txn - */ - public NetworkTransaction getTxn() { - return txn; - } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/GetCrossEntityReferenceEntityTask.java b/src/main/java/org/onap/aai/sparky/synchronizer/task/GetCrossEntityReferenceEntityTask.java deleted file mode 100644 index 8c1e0b7..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/GetCrossEntityReferenceEntityTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.task; - -import java.util.function.Supplier; - -import org.onap.aai.sparky.dal.NetworkTransaction; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; -import org.onap.aai.sparky.dal.rest.OperationResult; - -/** - * The Class GetCrossEntityReferenceEntityTask. - */ -public class GetCrossEntityReferenceEntityTask implements Supplier<NetworkTransaction> { - - private NetworkTransaction txn; - - private ActiveInventoryDataProvider provider; - - /** - * Instantiates a new gets the cross entity reference entity task. - * - * @param txn the txn - * @param provider the provider - */ - public GetCrossEntityReferenceEntityTask(NetworkTransaction txn, - ActiveInventoryDataProvider provider) { - this.txn = txn; - this.provider = provider; - } - - /* - * (non-Javadoc) - * - * @see java.util.function.Supplier#get() - */ - @Override - public NetworkTransaction get() { - - txn.setTaskAgeInMs(); - - long startTimeInMs = System.currentTimeMillis(); - OperationResult result = null; - try { - result = provider.queryActiveInventoryWithRetries(txn.getLink(), "application/json", 5); - } catch (Exception exc) { - result = new OperationResult(500, - "Caught an exception while trying to resolve link = " + exc.getMessage()); - } finally { - result.setResponseTimeInMs(System.currentTimeMillis() - startTimeInMs); - txn.setOperationResult(result); - } - - return txn; - } - - /** - * @return the txn - */ - public NetworkTransaction getTxn() { - return txn; - } - - /** - * @param txn the txn to set - */ - public void setTxn(NetworkTransaction txn) { - this.txn = txn; - } - - /** - * @return the provider - */ - public ActiveInventoryDataProvider getProvider() { - return provider; - } - - /** - * @param provider the provider to set - */ - public void setProvider(ActiveInventoryDataProvider provider) { - this.provider = provider; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/PersistOperationResultToDisk.java b/src/main/java/org/onap/aai/sparky/synchronizer/task/PersistOperationResultToDisk.java deleted file mode 100644 index 0ab331e..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/PersistOperationResultToDisk.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.task; - -import java.io.File; -import java.util.Map; -import java.util.function.Supplier; - -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.cl.api.Logger; -import org.slf4j.MDC; - -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * The Class PersistOperationResultToDisk. - */ -public class PersistOperationResultToDisk implements Supplier<Void> { - - private String fullPath; - private OperationResult dataToStore; - private ObjectMapper mapper; - private Logger logger; - private Map<String, String> contextMap; - - /** - * Instantiates a new persist operation result to disk. - * - * @param fullPath the full path - * @param dataToStore the data to store - * @param mapper the mapper - * @param logger the logger - */ - public PersistOperationResultToDisk(String fullPath, OperationResult dataToStore, - ObjectMapper mapper, Logger logger) { - - this.fullPath = fullPath; - this.mapper = mapper; - this.dataToStore = dataToStore; - this.logger = logger; - this.contextMap = MDC.getCopyOfContextMap(); - } - - /* - * (non-Javadoc) - * - * @see java.util.function.Supplier#get() - */ - @Override - public Void get() { - MDC.setContextMap(contextMap); - File file = new File(fullPath); - if (!file.exists()) { - try { - mapper.writeValue(new File(fullPath), dataToStore); - } catch (Exception exc) { - logger.error(AaiUiMsgs.DISK_DATA_WRITE_IO_ERROR, exc.toString()); - } - } - - return null; - } - - /** - * @return the fullPath - */ - public String getFullPath() { - return fullPath; - } - - /** - * @param fullPath the fullPath to set - */ - public void setFullPath(String fullPath) { - this.fullPath = fullPath; - } - - /** - * @return the dataToStore - */ - public OperationResult getDataToStore() { - return dataToStore; - } - - /** - * @param dataToStore the dataToStore to set - */ - public void setDataToStore(OperationResult dataToStore) { - this.dataToStore = dataToStore; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - /** - * @return the logger - */ - public Logger getLogger() { - return logger; - } - - /** - * @param logger the logger to set - */ - public void setLogger(Logger logger) { - this.logger = logger; - } - - /** - * @return the contextMap - */ - public Map<String, String> getContextMap() { - return contextMap; - } - - /** - * @param contextMap the contextMap to set - */ - public void setContextMap(Map<String, String> contextMap) { - this.contextMap = contextMap; - } - - - -} diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/task/RetrieveOperationResultFromDisk.java b/src/main/java/org/onap/aai/sparky/synchronizer/task/RetrieveOperationResultFromDisk.java deleted file mode 100644 index 0e11319..0000000 --- a/src/main/java/org/onap/aai/sparky/synchronizer/task/RetrieveOperationResultFromDisk.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.synchronizer.task; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.function.Supplier; - -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.cl.api.Logger; - -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * The Class RetrieveOperationResultFromDisk. - */ -public class RetrieveOperationResultFromDisk implements Supplier<OperationResult> { - - private String fullPath; - private ObjectMapper mapper; - private Logger logger; - - /** - * Instantiates a new retrieve operation result from disk. - * - * @param fullPath the full path - * @param mapper the mapper - * @param logger the logger - */ - public RetrieveOperationResultFromDisk(String fullPath, ObjectMapper mapper, Logger logger) { - - this.fullPath = fullPath; - this.mapper = mapper; - this.logger = logger; - } - - /* - * (non-Javadoc) - * - * @see java.util.function.Supplier#get() - */ - @Override - public OperationResult get() { - - try { - File file = new File(fullPath); - if (file.exists()) { - if (logger.isDebugEnabled()) { - logger.debug(AaiUiMsgs.WILL_RETRIEVE_TXN, fullPath); - } - - Path path = Paths.get(fullPath); - byte[] byteBuffer = Files.readAllBytes(path); - - OperationResult opResult = mapper.readValue(byteBuffer, OperationResult.class); - - return opResult; - } else { - logger.debug(AaiUiMsgs.FAILED_TO_RESTORE_TXN_FILE_MISSING, fullPath); - } - } catch (IOException exc) { - logger.error(AaiUiMsgs.DISK_CACHE_READ_IO_ERROR, exc.getLocalizedMessage()); - } - return null; - } - - /** - * @return the fullPath - */ - public String getFullPath() { - return fullPath; - } - - /** - * @param fullPath the fullPath to set - */ - public void setFullPath(String fullPath) { - this.fullPath = fullPath; - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - /** - * @return the logger - */ - public Logger getLogger() { - return logger; - } - - /** - * @param logger the logger to set - */ - public void setLogger(Logger logger) { - this.logger = logger; - } - -} diff --git a/src/main/java/org/onap/aai/sparky/topology/sync/GeoSyncController.java b/src/main/java/org/onap/aai/sparky/topology/sync/GeoSyncController.java new file mode 100644 index 0000000..a2acc06 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/topology/sync/GeoSyncController.java @@ -0,0 +1,95 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.topology.sync; + +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.sync.ElasticSearchIndexCleaner; +import org.onap.aai.sparky.sync.ElasticSearchSchemaFactory; +import org.onap.aai.sparky.sync.IndexCleaner; +import org.onap.aai.sparky.sync.IndexIntegrityValidator; +import org.onap.aai.sparky.sync.SyncControllerImpl; +import org.onap.aai.sparky.sync.SyncControllerRegistrar; +import org.onap.aai.sparky.sync.SyncControllerRegistry; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; + +public class GeoSyncController extends SyncControllerImpl implements SyncControllerRegistrar { + + private SyncControllerRegistry syncControllerRegistry; + + public GeoSyncController(SyncControllerConfig syncControllerConfig, + ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, + ElasticSearchSchemaConfig schemaConfig, ElasticSearchEndpointConfig endpointConfig, + NetworkStatisticsConfig aaiStatConfig, NetworkStatisticsConfig esStatConfig) + throws Exception { + super(syncControllerConfig); + + // final String controllerName = "Inventory Geo Synchronizer"; + + IndexIntegrityValidator indexValidator = new IndexIntegrityValidator(esAdapter, schemaConfig, + endpointConfig, ElasticSearchSchemaFactory.getIndexSchema(schemaConfig)); + + registerIndexValidator(indexValidator); + + GeoSynchronizer synchronizer = + new GeoSynchronizer(schemaConfig, syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + + synchronizer.setAaiAdapter(aaiAdapter); + synchronizer.setElasticSearchAdapter(esAdapter); + + registerEntitySynchronizer(synchronizer); + + + IndexCleaner indexCleaner = + new ElasticSearchIndexCleaner(esAdapter, endpointConfig, schemaConfig); + + registerIndexCleaner(indexCleaner); + + } + + public SyncControllerRegistry getSyncControllerRegistry() { + return syncControllerRegistry; + } + + public void setSyncControllerRegistry(SyncControllerRegistry syncControllerRegistry) { + this.syncControllerRegistry = syncControllerRegistry; + } + + @Override + public void registerController() { + + if (syncControllerRegistry != null) { + if (syncControllerConfig.isEnabled()) { + syncControllerRegistry.registerSyncController(this); + } + } + } + + + +} diff --git a/src/main/java/org/onap/aai/sparky/topology/sync/GeoSynchronizer.java b/src/main/java/org/onap/aai/sparky/topology/sync/GeoSynchronizer.java new file mode 100644 index 0000000..f075ff8 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/topology/sync/GeoSynchronizer.java @@ -0,0 +1,497 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.topology.sync; + +import static java.util.concurrent.CompletableFuture.supplyAsync; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.function.Supplier; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.config.oxm.GeoEntityLookup; +import org.onap.aai.sparky.config.oxm.GeoOxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.dal.NetworkTransaction; +import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; +import org.onap.aai.sparky.dal.rest.HttpMethod; +import org.onap.aai.sparky.inventory.entity.GeoIndexDocument; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.entity.SelfLinkDescriptor; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.task.PerformActiveInventoryRetrieval; +import org.onap.aai.sparky.sync.task.StoreDocumentTask; +import org.onap.aai.sparky.util.NodeUtils; +import org.slf4j.MDC; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + + +/** + * The Class GeoSynchronizer. + */ +public class GeoSynchronizer extends AbstractEntitySynchronizer implements IndexSynchronizer { + + private static final Logger LOG = LoggerFactory.getInstance().getLogger(GeoSynchronizer.class); + + private boolean allWorkEnumerated; + private Deque<SelfLinkDescriptor> selflinks; + + private ElasticSearchConfig elasticConfig = null; + private Map<String, GeoOxmEntityDescriptor> geoDescriptorMap = null; + + /** + * Instantiates a new geo synchronizer. + * + * @param indexName the index name + * @throws Exception the exception + */ + public GeoSynchronizer(ElasticSearchSchemaConfig schemaConfig, int internalSyncWorkers, + int aaiWorkers, int esWorkers, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + + super(LOG, "GEO", internalSyncWorkers, aaiWorkers, esWorkers, schemaConfig.getIndexName(), + aaiStatConfig, esStatConfig); + this.allWorkEnumerated = false; + this.selflinks = new ConcurrentLinkedDeque<SelfLinkDescriptor>(); + this.synchronizerName = "Geo Synchronizer"; + this.geoDescriptorMap = GeoEntityLookup.getInstance().getGeoEntityDescriptors(); + this.aaiEntityStats.intializeEntityCounters(geoDescriptorMap.keySet()); + this.esEntityStats.intializeEntityCounters(geoDescriptorMap.keySet()); + this.syncDurationInMs = -1; + } + + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#doSync() + */ + @Override + public OperationState doSync() { + this.syncDurationInMs = -1; + resetCounters(); + setShouldSkipSync(false); + allWorkEnumerated = false; + syncStartedTimeStampInMs = System.currentTimeMillis(); + String txnID = NodeUtils.getRandomTxnId(); + MdcContext.initialize(txnID, "GeoSynchronizer", "", "Sync", ""); + + collectAllTheWork(); + return OperationState.OK; + } + + + /** + * Collect all the work. + * + * @return the operation state + */ + public OperationState collectAllTheWork() { + final Map<String, String> contextMap = MDC.getCopyOfContextMap(); + if (elasticConfig == null) { + try { + elasticConfig = ElasticSearchConfig.getConfig(); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.CONFIGURATION_ERROR, "Search"); + } + } + + if (geoDescriptorMap.isEmpty()) { + setShouldSkipSync(true); + LOG.error(AaiUiMsgs.OXM_FAILED_RETRIEVAL, "geo entities"); + return OperationState.ERROR; + } + + Collection<String> syncTypes = geoDescriptorMap.keySet(); + + try { + + /* + * launch a parallel async thread to process the documents for each entity-type (to max the of + * the configured executor anyway) + */ + + aaiWorkOnHand.set(syncTypes.size()); + + for (String key : syncTypes) { + + supplyAsync(new Supplier<Void>() { + + @Override + public Void get() { + MDC.setContextMap(contextMap); + OperationResult typeLinksResult = null; + try { + typeLinksResult = aaiAdapter.getSelfLinksByEntityType(key); + aaiWorkOnHand.decrementAndGet(); + processEntityTypeSelfLinks(typeLinksResult); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GETTING_DATA_FROM_AAI, exc); + } + + return null; + } + + }, aaiExecutor).whenComplete((result, error) -> { + + if (error != null) { + LOG.error(AaiUiMsgs.ERROR_GETTING_DATA_FROM_AAI, error.getMessage()); + } + }); + + } + + while (aaiWorkOnHand.get() != 0) { + + if (LOG.isDebugEnabled()) { + LOG.debug(AaiUiMsgs.WAIT_FOR_ALL_SELFLINKS_TO_BE_COLLECTED); + } + + Thread.sleep(1000); + } + + aaiWorkOnHand.set(selflinks.size()); + allWorkEnumerated = true; + syncEntityTypes(); + + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ERROR_GETTING_DATA_FROM_AAI, exc); + } + return OperationState.OK; + } + + /** + * Sync entity types. + */ + private void syncEntityTypes() { + + while (selflinks.peek() != null) { + + SelfLinkDescriptor linkDescriptor = selflinks.poll(); + aaiWorkOnHand.decrementAndGet(); + + OxmEntityDescriptor descriptor = null; + + if (linkDescriptor.getSelfLink() != null && linkDescriptor.getEntityType() != null) { + + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors() + .get(linkDescriptor.getEntityType()); + + if (descriptor == null) { + LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, linkDescriptor.getEntityType()); + // go to next element in iterator + continue; + } + + NetworkTransaction txn = new NetworkTransaction(); + txn.setDescriptor(descriptor); + txn.setLink(linkDescriptor.getSelfLink()); + txn.setOperationType(HttpMethod.GET); + txn.setEntityType(linkDescriptor.getEntityType()); + + aaiWorkOnHand.incrementAndGet(); + + supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiAdapter), aaiExecutor) + .whenComplete((result, error) -> { + + aaiWorkOnHand.decrementAndGet(); + + if (error != null) { + LOG.error(AaiUiMsgs.ERROR_GETTING_DATA_FROM_AAI, error.getMessage()); + } else { + if (result == null) { + LOG.error(AaiUiMsgs.SELF_LINK_GET_NO_RESPONSE, linkDescriptor.getSelfLink()); + } else { + processEntityTypeSelfLinkResult(result); + } + } + }); + } + } + } + + /** + * Process entity type self links. + * + * @param operationResult the operation result + */ + private void processEntityTypeSelfLinks(OperationResult operationResult) { + + JsonNode rootNode = null; + + final String jsonResult = operationResult.getResult(); + + if (jsonResult != null && jsonResult.length() > 0 && operationResult.wasSuccessful()) { + + try { + rootNode = mapper.readTree(jsonResult); + } catch (IOException exc) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, exc); + } + + JsonNode resultData = rootNode.get("result-data"); + ArrayNode resultDataArrayNode = null; + + if (resultData.isArray()) { + resultDataArrayNode = (ArrayNode) resultData; + + Iterator<JsonNode> elementIterator = resultDataArrayNode.elements(); + JsonNode element = null; + + while (elementIterator.hasNext()) { + element = elementIterator.next(); + + final String resourceType = NodeUtils.getNodeFieldAsText(element, "resource-type"); + final String resourceLink = NodeUtils.getNodeFieldAsText(element, "resource-link"); + + if (resourceType != null && resourceLink != null) { + + if (geoDescriptorMap.containsKey(resourceType)) { + selflinks.add(new SelfLinkDescriptor(resourceLink + "?nodes-only", resourceType)); + } else { + LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, resourceType); + // go to next element in iterator + continue; + } + + } + } + } + } + + } + + /** + * Process entity type self link result. + * + * @param txn the txn + */ + private void processEntityTypeSelfLinkResult(NetworkTransaction txn) { + + updateActiveInventoryCounters(txn); + + if (!txn.getOperationResult().wasSuccessful()) { + return; + } + + GeoOxmEntityDescriptor descriptor = geoDescriptorMap.get(txn.getEntityType()); + + if (descriptor == null) { + return; + } + + try { + if (descriptor.hasGeoEntity()) { + + GeoIndexDocument geoDoc = new GeoIndexDocument(); + + final String jsonResult = txn.getOperationResult().getResult(); + + if (jsonResult != null && jsonResult.length() > 0) { + + populateGeoDocument(geoDoc, jsonResult, txn.getDescriptor(), txn.getLink()); + + if (!geoDoc.isValidGeoDocument()) { + + LOG.info(AaiUiMsgs.GEO_SYNC_IGNORING_ENTITY, geoDoc.getEntityType(), geoDoc.toString()); + + } else { + + String link = null; + try { + link = getElasticFullUrl("/" + geoDoc.getId(), getIndexName(), "default"); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ES_FAILED_TO_CONSTRUCT_URI, exc); + } + + if (link != null) { + + NetworkTransaction n2 = new NetworkTransaction(); + n2.setLink(link); + n2.setEntityType(txn.getEntityType()); + n2.setDescriptor(txn.getDescriptor()); + n2.setOperationType(HttpMethod.PUT); + + esWorkOnHand.incrementAndGet(); + + supplyAsync(new StoreDocumentTask(geoDoc, n2, elasticSearchAdapter), esExecutor) + .whenComplete((result, error) -> { + + esWorkOnHand.decrementAndGet(); + + if (error != null) { + LOG.error(AaiUiMsgs.ES_STORE_FAILURE, error.getMessage()); + } else { + updateElasticSearchCounters(result); + processStoreDocumentResult(result); + } + }); + } + } + } + } + } catch (JsonProcessingException exc) { + LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, exc); + } catch (IOException exc) { + LOG.error(AaiUiMsgs.JSON_PROCESSING_ERROR, exc); + } + + return; + } + + + /** + * Process store document result. + * + * @param txn the txn + */ + private void processStoreDocumentResult(NetworkTransaction txn) { + + OperationResult or = txn.getOperationResult(); + + if (!or.wasSuccessful()) { + LOG.error(AaiUiMsgs.ES_STORE_FAILURE, or.toString()); + /* + * if(or.getResultCode() != 404 || (or.getResultCode() == 404 && + * !synchronizerConfig.isResourceNotFoundErrorsSupressed())) { logger.error( + * "Skipping failed resource = " + "link" + " RC=[" + or.getResultCode() + "]. Message: " + + * or.getResult()); } + */ + + } + + } + + + @Override + public SynchronizerState getState() { + + if (!isSyncDone()) { + return SynchronizerState.PERFORMING_SYNCHRONIZATION; + } + + return SynchronizerState.IDLE; + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) + */ + @Override + public String getStatReport(boolean showFinalReport) { + syncDurationInMs = System.currentTimeMillis() - syncStartedTimeStampInMs; + return this.getStatReport(syncDurationInMs, showFinalReport); + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#shutdown() + */ + @Override + public void shutdown() { + this.shutdownExecutors(); + } + + /** + * Populate geo document. + * + * @param doc the doc + * @param result the result + * @param resultDescriptor the result descriptor + * @param entityLink the entity link + * @throws JsonProcessingException the json processing exception + * @throws IOException Signals that an I/O exception has occurred. + */ + protected void populateGeoDocument(GeoIndexDocument doc, String result, + OxmEntityDescriptor resultDescriptor, String entityLink) + throws JsonProcessingException, IOException { + + doc.setSelfLink(entityLink); + doc.setEntityType(resultDescriptor.getEntityName()); + + JsonNode entityNode = mapper.readTree(result); + + List<String> primaryKeyValues = new ArrayList<String>(); + String pkeyValue = null; + + for (String keyName : resultDescriptor.getPrimaryKeyAttributeNames()) { + pkeyValue = NodeUtils.getNodeFieldAsText(entityNode, keyName); + if (pkeyValue != null) { + primaryKeyValues.add(pkeyValue); + } else { + LOG.warn(AaiUiMsgs.ES_PKEYVALUE_NULL, resultDescriptor.getEntityName()); + } + } + + final String primaryCompositeKeyValue = NodeUtils.concatArray(primaryKeyValues, "/"); + doc.setEntityPrimaryKeyValue(primaryCompositeKeyValue); + + GeoOxmEntityDescriptor descriptor = geoDescriptorMap.get(resultDescriptor.getEntityName()); + + String geoLatKey = descriptor.getGeoLatName(); + String geoLongKey = descriptor.getGeoLongName(); + + doc.setLatitude(NodeUtils.getNodeFieldAsText(entityNode, geoLatKey)); + doc.setLongitude(NodeUtils.getNodeFieldAsText(entityNode, geoLongKey)); + doc.deriveFields(); + + } + + @Override + protected boolean isSyncDone() { + if (shouldSkipSync()) { + syncDurationInMs = System.currentTimeMillis() - syncStartedTimeStampInMs; + return true; + } + + int totalWorkOnHand = aaiWorkOnHand.get() + esWorkOnHand.get(); + + if (totalWorkOnHand > 0 || !allWorkEnumerated) { + return false; + } + + return true; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/util/ConfigHelper.java b/src/main/java/org/onap/aai/sparky/util/ConfigHelper.java index bad916b..c9a2414 100644 --- a/src/main/java/org/onap/aai/sparky/util/ConfigHelper.java +++ b/src/main/java/org/onap/aai/sparky/util/ConfigHelper.java @@ -32,9 +32,9 @@ import java.io.InputStream; import java.util.Properties; import java.util.Set; -import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; /** * The Class ConfigHelper. diff --git a/src/main/java/org/onap/aai/sparky/util/Encryptor.java b/src/main/java/org/onap/aai/sparky/util/Encryptor.java index 80aefd0..15b735b 100644 --- a/src/main/java/org/onap/aai/sparky/util/Encryptor.java +++ b/src/main/java/org/onap/aai/sparky/util/Encryptor.java @@ -28,18 +28,39 @@ import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.eclipse.jetty.util.security.Password; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sparky.logging.AaiUiMsgs; /** * The Class Encryptor. */ public class Encryptor { + private static final Logger LOG = LoggerFactory.getInstance().getLogger(Encryptor.class); + /** * Instantiates a new encryptor. */ public Encryptor() {} /** + * Encrypt value. + * + * @param value to encrypt + * @return the encrypted string + */ + public String encryptValue(String value) { + String encyptedValue = ""; + try { + encyptedValue = Password.obfuscate(value); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.ENCRYPTION_ERROR, value, exc.toString()); + } + return encyptedValue; + } + + /** * Decrypt value. * * @param value the value @@ -47,8 +68,11 @@ public class Encryptor { */ public String decryptValue(String value) { String decyptedValue = ""; - - decyptedValue = Password.deobfuscate(value); + try { + decyptedValue = Password.deobfuscate(value); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.DECRYPTION_ERROR, value, exc.toString()); + } return decyptedValue; } @@ -76,4 +100,54 @@ public class Encryptor { System.exit(1); } + /** + * The main method. + * + * @param args the arguments + */ + public static void main(String[] args) { + + Options options = new Options(); + options.addOption("d", true, "value to decrypt"); + options.addOption("h", false, "show help"); + options.addOption("?", false, "show help"); + + String value = null; + boolean encrypt = false; + boolean decrypt = false; + + CommandLineParser parser = new BasicParser(); + CommandLine cmd = null; + + try { + cmd = parser.parse(options, args); + + if (cmd.hasOption("d")) { + value = cmd.getOptionValue("d"); + decrypt = true; + } + + if (cmd.hasOption("?") || cmd.hasOption("h")) { + usage(); + System.exit(0); + } + + if ((encrypt && decrypt) || (!encrypt && !decrypt)) { + usage("Must specify one (and only one) of the -e or -d options"); + } + + Encryptor encryptor = new Encryptor(); + + if (decrypt) { + String out = encryptor.decryptValue(value); + System.out.println(out); + } + } catch (ParseException exc) { + System.out.println("Failed to parse command line properties: " + exc.toString()); + } catch (Exception exc) { + System.out.println("Failure: " + exc.toString()); + } + + System.exit(0); + } } diff --git a/src/main/java/org/onap/aai/sparky/util/ErrorUtil.java b/src/main/java/org/onap/aai/sparky/util/ErrorUtil.java index 0bf6d38..e661b73 100644 --- a/src/main/java/org/onap/aai/sparky/util/ErrorUtil.java +++ b/src/main/java/org/onap/aai/sparky/util/ErrorUtil.java @@ -20,7 +20,6 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ - package org.onap.aai.sparky.util; /** diff --git a/src/main/java/org/onap/aai/sparky/util/KeystoreBuilder.java b/src/main/java/org/onap/aai/sparky/util/KeystoreBuilder.java index d3ae421..05ba3d2 100644 --- a/src/main/java/org/onap/aai/sparky/util/KeystoreBuilder.java +++ b/src/main/java/org/onap/aai/sparky/util/KeystoreBuilder.java @@ -111,20 +111,6 @@ public class KeystoreBuilder { private List<EndPoint> endpoints = new ArrayList<EndPoint>(); /** - * @return the endpoints - */ - public List<EndPoint> getEndpoints() { - return endpoints; - } - - /** - * @param endpoints the endpoints to set - */ - public void setEndpoints(List<EndPoint> endpoints) { - this.endpoints = endpoints; - } - - /** * Initialize end points list. * * @param endpointList the endpoint list @@ -209,7 +195,7 @@ public class KeystoreBuilder { } else { System.out.println("keystore file doesn't exist, preloading new file with jssecacerts"); } - password = keystorePassword; + password = "changeit"; } @@ -260,8 +246,8 @@ public class KeystoreBuilder { private X509Certificate[] getCertificateChainForRemoteEndpoint(String hostname, int port) throws UnknownHostException, IOException { - System.out.println("Opening connection to " + hostname + ":" + port + ".."); - SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(hostname, port); + System.out.println("Opening connection to localhost:8442.."); + SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket("aai-int1.dev.att.com", 8440); socket.setSoTimeout(10000); try { @@ -272,8 +258,6 @@ public class KeystoreBuilder { System.exit(0); } catch (SSLException exc) { System.out.println("\nCaught SSL exception, we are not authorized to access this server yet"); - throw new SSLException( - "\nCaught SSL exception, we are not authorized to access this server yet"); // e.printStackTrace(System.out); } @@ -523,6 +507,8 @@ public class KeystoreBuilder { */ public static void main(String[] args) throws Exception { + // String endpointList = "aai-int1.test.att.com:8440;aai-int1.dev.att.com:8442"; + /* * Examples: localhost:8440;localhost:8442 d:\1\adhoc_keystore.jks aaiDomain2 false * localhost:8440;localhost:8442 d:\1\adhoc_keystore.jks aaiDomain2 true diff --git a/src/main/java/org/onap/aai/sparky/util/NodeUtils.java b/src/main/java/org/onap/aai/sparky/util/NodeUtils.java index 20e547f..a34c07d 100644 --- a/src/main/java/org/onap/aai/sparky/util/NodeUtils.java +++ b/src/main/java/org/onap/aai/sparky/util/NodeUtils.java @@ -27,8 +27,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.Thread.UncaughtExceptionHandler; +import java.net.URI; import java.nio.ByteBuffer; import java.security.SecureRandom; +import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -50,15 +52,17 @@ import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.xml.stream.XMLStreamConstants; +import org.onap.aai.cl.api.Logger; import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.cl.api.Logger; +import org.restlet.Request; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.ser.FilterProvider; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -68,33 +72,8 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; public class NodeUtils { private static SecureRandom sRandom = new SecureRandom(); - /** - * @return the sRandom - */ - public static SecureRandom getsRandom() { - return sRandom; - } - - /** - * @param sRandom the sRandom to set - */ - public static void setsRandom(SecureRandom sRandom) { - NodeUtils.sRandom = sRandom; - } - - /** - * @return the entityResourceKeyFormat - */ - public static String getEntityResourceKeyFormat() { - return ENTITY_RESOURCE_KEY_FORMAT; - } + private static final Pattern AAI_VERSION_PREFIX = Pattern.compile("/aai/v[0-9]+/(.*)"); - /** - * @return the timeBreakDownFormat - */ - public static String getTimeBreakDownFormat() { - return TIME_BREAK_DOWN_FORMAT; - } public static synchronized String getRandomTxnId() { byte bytes[] = new byte[6]; @@ -118,6 +97,31 @@ public class NodeUtils { return sb.toString(); } + + public static String extractRawPathWithoutVersion(String selfLinkUri) { + + try { + + String rawPath = new URI(selfLinkUri).getRawPath(); + + Matcher m = AAI_VERSION_PREFIX.matcher(rawPath); + + if (m.matches()) { + + // System.out.println(m.group(0)); + if (m.groupCount() >= 1) { + return m.group(1); + } + // System.out.println(m.group(2)); + + } + } catch (Exception e) { + } + + return null; + + } + /** * Checks if is numeric. * @@ -296,6 +300,14 @@ public class NodeUtils { return concatArray(list, " "); } + private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + + public static String getCurrentTimeStamp() { + SimpleDateFormat dateFormat = new SimpleDateFormat(TIMESTAMP_FORMAT); + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + return dateFormat.format(timestamp); + } + /** * Concat array. * @@ -395,12 +407,12 @@ public class NodeUtils { String resourceId = null; if ("/".equals(link.substring(linkLength - 1))) { // Use-case: - // https://<AAI-hostname>:9292/aai/v7/business/customers/customer/1607_20160524Func_Ak1_01/service-subscriptions/service-subscription/uCPE-VMS/ + // https://aai-ext1.test.att.com:9292/aai/v7/business/customers/customer/1607_20160524Func_Ak1_01/service-subscriptions/service-subscription/uCPE-VMS/ startIndex = link.lastIndexOf("/", linkLength - 2); resourceId = link.substring(startIndex + 1, linkLength - 1); } else { // Use-case: - // https://<AAI-Hostname>:9292/aai/v7/business/customers/customer/1607_20160524Func_Ak1_01/service-subscriptions/service-subscription/uCPE-VMS + // https://aai-ext1.test.att.com:9292/aai/v7/business/customers/customer/1607_20160524Func_Ak1_01/service-subscriptions/service-subscription/uCPE-VMS startIndex = link.lastIndexOf("/"); resourceId = link.substring(startIndex + 1, linkLength); } @@ -492,6 +504,33 @@ public class NodeUtils { } /** + * Convert object to json by selectively choosing certain fields thru filters. Example use case: + * based on request type we might need to send different serialization of the UiViewFilterEntity + * + * @param object the object + * @param pretty the pretty + * @return the string + * @throws JsonProcessingException the json processing exception + */ + public static String convertObjectToJson(Object object, boolean pretty, FilterProvider filters) + throws JsonProcessingException { + ObjectWriter ow = null; + + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + + if (pretty) { + ow = mapper.writer(filters).withDefaultPrettyPrinter(); + + } else { + ow = mapper.writer(filters); + } + + return ow.writeValueAsString(object); + } + + + /** * Convert json str to json node. * * @param jsonStr the json str @@ -687,13 +726,39 @@ public class NodeUtils { * @throws IOException Signals that an I/O exception has occurred. */ public static String getBody(HttpServletRequest request) throws IOException { + InputStream inputStream = request.getInputStream(); + return getBodyFromStream(inputStream); + } + + + + /** + * Gets the Restlet Request payload. + * + * @param request the request + * @return the body + * @throws IOException Signals that an I/O exception has occurred. + */ + public static String getBody(Request request) throws IOException { + InputStream inputStream = request.getEntity().getStream(); + return getBodyFromStream(inputStream); + } + + + /** + * Gets the payload from the input stream of a request. + * + * @param request the request + * @return the body + * @throws IOException Signals that an I/O exception has occurred. + */ + public static String getBodyFromStream(InputStream inputStream) throws IOException { String body = null; StringBuilder stringBuilder = new StringBuilder(); BufferedReader bufferedReader = null; try { - InputStream inputStream = request.getInputStream(); if (inputStream != null) { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); char[] charBuffer = new char[128]; @@ -719,4 +784,23 @@ public class NodeUtils { body = stringBuilder.toString(); return body; } + + + /** + * The main method. + * + * @param args the arguments + * @throws ParseException the parse exception + */ + public static void main(String[] args) throws ParseException { + String date = "20170110T112312Z"; + SimpleDateFormat originalFormat = new SimpleDateFormat("yyyyMMdd'T'hhmmss'Z'"); + Date toDate = originalFormat.parse(date); + SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss'Z'"); + System.out.println(newFormat.format(toDate)); + + } + + + } diff --git a/src/main/java/org/onap/aai/sparky/util/RestletUtils.java b/src/main/java/org/onap/aai/sparky/util/RestletUtils.java new file mode 100644 index 0000000..06c8c05 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/util/RestletUtils.java @@ -0,0 +1,118 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.util; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.restlet.Response; +import org.restlet.data.MediaType; +import org.restlet.data.Status; + +public class RestletUtils { + /** + * Returns an HttpServletResponse based on values from a Restlet Response + * + * @param restletResponse Restlet Response to be converted to an HttpServletResponse + * @return An HttpServletResponse object built from the values of a Restlet Response + */ + public HttpServletResponse convertRestletResponseToHttpServletResponse(Response restletResponse) { + return org.restlet.ext.servlet.ServletUtils.getResponse(restletResponse); + } + + /** + * Execute post query + * + * @param logger The logger + * @param search The searchAdapter + * @param response The response + * @param requestUrl The request URL + * @param requestJsonPayload The request JSON payload + * @return The operation result + */ + public OperationResult executePostQuery(Logger logger, SearchAdapter search, Response response, + String requestUrl, String requestJsonPayload) { + + OperationResult opResult = search.doPost(requestUrl, requestJsonPayload, "application/json"); + + if (opResult.getResultCode() > 300) { + setRestletResponse(logger, true, opResult.getResultCode(), response, opResult.getResult()); + } else { + response.setStatus(new Status(opResult.getResultCode())); + } + + return opResult; + } + + /** + * Generate JSON error response + * + * @param message The error message + * @return The error message formatted as a JSON string + */ + public String generateJsonErrorResponse(String message) { + return String.format("{ \"errorMessage\" : \"%s\" }", message); + } + + /** + * Log Restlet exceptions/errors & prepare Response object with exception/errors info + * + * @param logger The logger + * @param errorMsg The error message + * @param exc The exception + * @param response The response + */ + public void handleRestletErrors(Logger logger, String errorMsg, Exception exc, + Response response) { + String errorLogMsg = + (exc == null ? errorMsg : errorMsg + ". Error:" + exc.getLocalizedMessage()); + logger.error(AaiUiMsgs.ERROR_GENERIC, errorLogMsg); + response.setEntity(generateJsonErrorResponse(errorMsg), MediaType.APPLICATION_JSON); + } + + /** + * Sets the Restlet response + * + * @param logger The logger + * @param isError The error + * @param responseCode The response code + * @param response The response + * @param postPayload The post payload + */ + public void setRestletResponse(Logger logger, boolean isError, int responseCode, + Response response, String postPayload) { + + if (isError) { + logger.error(AaiUiMsgs.ERROR_GENERIC, postPayload); + } + + response.setStatus(new Status(responseCode)); + + if (postPayload != null) { + response.setEntity(postPayload, MediaType.APPLICATION_JSON); + } + } +} diff --git a/src/main/java/org/onap/aai/sparky/util/SuggestionsPermutation.java b/src/main/java/org/onap/aai/sparky/util/SuggestionsPermutation.java index 463d122..ba51254 100644 --- a/src/main/java/org/onap/aai/sparky/util/SuggestionsPermutation.java +++ b/src/main/java/org/onap/aai/sparky/util/SuggestionsPermutation.java @@ -36,44 +36,63 @@ public class SuggestionsPermutation { *
* @return A Arraylist which contains a array list of all possible combinations
*/
- @SuppressWarnings("serial")
- public ArrayList<ArrayList<String>> getSuggestionsPermutation(List<String> list) {
- List<String> statusList = new ArrayList<>(list);
- List<String> dupStatusList;
- ArrayList<ArrayList<String>> uniqueList = new ArrayList<ArrayList<String>>();
- int mainLoopIndexCounter = 0;
- for (String status : statusList) {
- // Add the single entity subset
- uniqueList.add(new ArrayList<String>() {
- {
- add(status);
- }
- });
- // Remove all the elements to left till the current index
- dupStatusList = truncateListUntill(statusList, mainLoopIndexCounter);
+ public static ArrayList<ArrayList<String>> getUniqueListForSuggestions(
+ List<String> originalList) {
+ ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
+ if (originalList.isEmpty()) {
+ lists.add(new ArrayList<String>());
+ return lists;
+ }
+ List<String> list = new ArrayList<String>(originalList);
+ String head = list.get(0);
+ ArrayList<String> rest = new ArrayList<String>(list.subList(1, list.size()));
- while (dupStatusList.size() > 0) {
- ArrayList<String> suggListInIterate = new ArrayList<>();
- suggListInIterate.add(status);
- for (String dupStatus : dupStatusList) {
- suggListInIterate.add(dupStatus);
- }
- uniqueList.add(suggListInIterate);
- dupStatusList.remove(0);
- }
- mainLoopIndexCounter++;
+ for (ArrayList<String> activeList : getUniqueListForSuggestions(rest)) {
+ ArrayList<String> newList = new ArrayList<String>();
+ newList.add(head);
+ newList.addAll(activeList);
+ lists.add(newList);
+ lists.add(activeList);
}
- return uniqueList;
+ return lists;
+ }
+ public static ArrayList<ArrayList<String>> getNonEmptyUniqueLists(List<String> list) {
+ ArrayList<ArrayList<String>> lists = getUniqueListForSuggestions(list);
+ // remove empty list from the power set
+ for (ArrayList<String> emptyList : lists) {
+ if (emptyList.isEmpty()) {
+ lists.remove(emptyList);
+ break;
+ }
+ }
+ return lists;
}
- private List<String> truncateListUntill(List<String> lists, int index) {
- List<String> truncatedList = new ArrayList<>(lists);
- int counter = 0;
- while (counter <= index) {
- truncatedList.remove(0);
- counter++;
+ public static List<List<String>> getListPermutations(List<String> list) {
+ List<String> inputList = new ArrayList<String>();
+ inputList.addAll(list);
+ if (inputList.size() == 0) {
+ List<List<String>> result = new ArrayList<List<String>>();
+ result.add(new ArrayList<String>());
+ return result;
}
- return truncatedList;
+
+ List<List<String>> listOfLists = new ArrayList<List<String>>();
+
+ String firstElement = inputList.remove(0);
+
+ List<List<String>> recursiveReturn = getListPermutations(inputList);
+ for (List<String> li : recursiveReturn) {
+
+ for (int index = 0; index <= li.size(); index++) {
+ List<String> temp = new ArrayList<String>(li);
+ temp.add(index, firstElement);
+ listOfLists.add(temp);
+ }
+
+ }
+ return listOfLists;
}
+
}
diff --git a/src/main/java/org/onap/aai/sparky/util/TreeWalker.java b/src/main/java/org/onap/aai/sparky/util/TreeWalker.java index 6306a30..2221475 100644 --- a/src/main/java/org/onap/aai/sparky/util/TreeWalker.java +++ b/src/main/java/org/onap/aai/sparky/util/TreeWalker.java @@ -22,17 +22,17 @@ */ package org.onap.aai.sparky.util; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; - import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Lists; + /** * The Class TreeWalker. */ diff --git a/src/main/java/org/onap/aai/sparky/util/test/Encryptor.java b/src/main/java/org/onap/aai/sparky/util/test/Encryptor.java deleted file mode 100644 index c24f2c2..0000000 --- a/src/main/java/org/onap/aai/sparky/util/test/Encryptor.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.util.test; - -import org.apache.commons.cli.BasicParser; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.eclipse.jetty.util.security.Password; - -/** - * The Class Encryptor. - */ -public class Encryptor { - - /** - * Instantiates a new encryptor. - */ - public Encryptor() {} - - /** - * Decrypt value. - * - * @param value the value - * @return the string - */ - public String decryptValue(String value) { - String decyptedValue = ""; - - try { - decyptedValue = Password.deobfuscate(value); - } catch (Exception exc) { - System.err.println("Cannot decrypt '" + value + "': " + exc.toString()); - } - - return decyptedValue; - } - - /** - * Usage. - */ - public static void usage() { - usage(null); - } - - /** - * Usage. - * - * @param msg the msg - */ - public static void usage(String msg) { - if (msg != null) { - System.err.println(msg); - } - System.err.println("Usage: java Encryptor -e value"); - System.err.println("\tEncrypt the given value"); - System.err.println("Usage: java Encryptor -d value"); - System.err.println("\tDecrypt the given value"); - System.exit(1); - } - -} diff --git a/src/main/java/org/onap/aai/sparky/util/test/KeystoreBuilder.java b/src/main/java/org/onap/aai/sparky/util/test/KeystoreBuilder.java deleted file mode 100644 index e771066..0000000 --- a/src/main/java/org/onap/aai/sparky/util/test/KeystoreBuilder.java +++ /dev/null @@ -1,541 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.util.test; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateParsingException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -/** - * The Class KeystoreBuilder. - */ -public class KeystoreBuilder { - - /** - * The Class EndPoint. - */ - private class EndPoint { - private String hostname; - private int port; - - /** - * Instantiates a new end point. - */ - @SuppressWarnings("unused") - public EndPoint() {} - - /** - * Instantiates a new end point. - * - * @param host the host - * @param port the port - */ - public EndPoint(String host, int port) { - this.hostname = host; - this.port = port; - } - - public String getHostname() { - return hostname; - } - - @SuppressWarnings("unused") - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "EndPoint [hostname=" + hostname + ", port=" + port + "]"; - } - - } - - private List<EndPoint> endpoints = new ArrayList<EndPoint>(); - - /** - * @return the endpoints - */ - public List<EndPoint> getEndpoints() { - return endpoints; - } - - /** - * @param endpoints the endpoints to set - */ - public void setEndpoints(List<EndPoint> endpoints) { - this.endpoints = endpoints; - } - - /** - * Initialize end points list. - * - * @param endpointList the endpoint list - */ - private void initializeEndPointsList(String endpointList) { - String[] endpointUris = endpointList.split(";"); - - for (String endpointUri : endpointUris) { - - String ipAndPort = endpointUri.replaceAll("http://", ""); - ipAndPort = endpointUri.replaceAll("https://", ""); - - // System.out.println("ipAndPortUrl = " + ipAndPort); - - String[] hostAndPort = ipAndPort.split(":"); - - String hostname = hostAndPort[0]; - int port = Integer.parseInt(hostAndPort[1]); - - EndPoint ep = new EndPoint(hostname, port); - endpoints.add(ep); - } - - } - - /** - * Instantiates a new keystore builder. - * - * @param endpointList the endpoint list - * @throws NoSuchAlgorithmException the no such algorithm exception - */ - public KeystoreBuilder(String endpointList) throws NoSuchAlgorithmException { - initializeEndPointsList(endpointList); - sha1 = MessageDigest.getInstance("SHA1"); - md5 = MessageDigest.getInstance("MD5"); - } - - private static final String SEP = File.separator; - private SavingTrustManager savingTrustManager; - private SSLSocketFactory sslSocketFactory; - private MessageDigest sha1; - private MessageDigest md5; - private KeyStore ks; - private String keystoreFileName; - private String keystorePassword; - private boolean dumpCertDetails = false; - - public void setDumpCertDetails(boolean shouldSet) { - dumpCertDetails = shouldSet; - } - - /** - * Update keystore. - * - * @param keystoreFileName the keystore file name - * @param keystorePassword the keystore password - * @throws KeyStoreException the key store exception - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws CertificateException the certificate exception - * @throws IOException Signals that an I/O exception has occurred. - * @throws KeyManagementException the key management exception - */ - public void updateKeystore(String keystoreFileName, String keystorePassword) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, - KeyManagementException { - - this.keystoreFileName = keystoreFileName; - this.keystorePassword = keystorePassword; - - File file = new File(keystoreFileName); - String password = keystorePassword; - - if (file.isFile() == false) { - - File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"); - file = new File(dir, "jssecacerts"); - if (file.isFile() == false) { - - file = new File(dir, "cacerts"); - System.out.println("keystore file doesn't exist, preloading new file with cacerts"); - - } else { - System.out.println("keystore file doesn't exist, preloading new file with jssecacerts"); - } - password = "changeit"; - - } - - InputStream in = new FileInputStream(file); - ks = KeyStore.getInstance(KeyStore.getDefaultType()); - ks.load(in, password.toCharArray()); - in.close(); - - SSLContext context = SSLContext.getInstance("TLS"); - TrustManagerFactory tmf = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(ks); - X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; - savingTrustManager = new SavingTrustManager(defaultTrustManager); - context.init(null, new TrustManager[] {savingTrustManager}, null); - sslSocketFactory = context.getSocketFactory(); - - System.out.println("About to add the following endpoint server certificates to the keystore:"); - for (EndPoint ep : endpoints) { - System.out.println("\t--------------------------"); - System.out.println("\t" + ep.toString()); - - X509Certificate[] certChain = - getCertificateChainForRemoteEndpoint(ep.getHostname(), ep.getPort()); - - if (certChain == null) { - System.out.println("Could not obtain server certificate chain"); - return; - } - - dumpCertChainInfo(certChain); - - updateKeyStoreWithCertChain(certChain); - - } - - } - - /** - * Gets the certificate chain for remote endpoint. - * - * @param hostname the hostname - * @param port the port - * @return the certificate chain for remote endpoint - * @throws UnknownHostException the unknown host exception - * @throws IOException Signals that an I/O exception has occurred. - */ - private X509Certificate[] getCertificateChainForRemoteEndpoint(String hostname, int port) - throws UnknownHostException, IOException { - - System.out.println("Opening connection to " + hostname + ":" + port + ".."); - SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(hostname, port); - socket.setSoTimeout(10000); - - try { - System.out.println("Starting SSL handshake..."); - socket.startHandshake(); - socket.close(); - System.out.println("\nNo errors, certificate is already trusted"); - System.exit(0); - } catch (SSLException exc) { - System.out.println("\nCaught SSL exception, we are not authorized to access this server yet"); - // e.printStackTrace(System.out); - } - - return savingTrustManager.chain; - - } - - /** - * Dump cert chain info. - * - * @param chain the chain - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws CertificateEncodingException the certificate encoding exception - * @throws CertificateParsingException the certificate parsing exception - */ - private void dumpCertChainInfo(X509Certificate[] chain) - throws NoSuchAlgorithmException, CertificateEncodingException, CertificateParsingException { - - System.out.println(); - System.out.println("Server sent " + chain.length + " certificate(s):"); - System.out.println(); - - for (int i = 0; i < chain.length; i++) { - X509Certificate cert = chain[i]; - - if (dumpCertDetails) { - System.out.println("Full cert details @ index = " + i + " \n" + cert.toString()); - } - - System.out.println("Subject: " + cert.getSubjectDN()); - System.out.println("Issuer: " + cert.getIssuerDN()); - System.out.println("SubjectAlternativeNames: "); - - /* - * RFC-5280, pg. 38, section 4.2.1.6 ( Subject Alternative Names ) - * - * Finally, the semantics of subject alternative names that include wildcard characters (e.g., - * as a placeholder for a set of names) are not addressed by this specification. Applications - * with specific requirements MAY use such names, but they must define the semantics. - * - * id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } - * - * SubjectAltName ::= GeneralNames - * - * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - * - * GeneralName ::= CHOICE { otherName [0] OtherName, rfc822Name [1] IA5String, dNSName [2] - * IA5String, <-- the 2 in the output is a type operand x400Address [3] ORAddress, - * directoryName [4] Name, ediPartyName [5] EDIPartyName, uniformResourceIdentifier [6] - * IA5String, iPAddress [7] OCTET STRING, registeredID [8] OBJECT IDENTIFIER } - * - * OtherName ::= SEQUENCE { type-id OBJECT IDENTIFIER, value [0] EXPLICIT ANY DEFINED BY - * type-id } - * - * EDIPartyName ::= SEQUENCE { nameAssigner [0] DirectoryString OPTIONAL, partyName [1] - * DirectoryString } - * - */ - - Collection<List<?>> sans = cert.getSubjectAlternativeNames(); - - for (List<?> san : sans) { - - /* - * It seems the structure of the array elements contained within the SAN is: [<sanType>, - * <sanValue>]* - * - */ - - int type = ((Integer) san.get(0)).intValue(); - String typeStr = getSanType(type); - String value = (String) san.get(1); - - System.out.println(String.format("\tType:'%s', Value: '%s'.", typeStr, value)); - - } - - } - - } - - /** - * Gets the subject alternative names. - * - * @param cert the cert - * @return the subject alternative names - * @throws CertificateParsingException the certificate parsing exception - */ - private List<String> getSubjectAlternativeNames(X509Certificate cert) - throws CertificateParsingException { - - Collection<List<?>> sans = cert.getSubjectAlternativeNames(); - List<String> subjectAlternativeNames = new ArrayList<String>(); - - for (List<?> san : sans) { - - /* - * It seems the structure of the array elements contained within the SAN is: [<sanType>, - * <sanValue>]* - * - */ - - String value = (String) san.get(1); - subjectAlternativeNames.add(value); - } - - return subjectAlternativeNames; - } - - /** - * Update key store with cert chain. - * - * @param chain the chain - * @throws NoSuchAlgorithmException the no such algorithm exception - * @throws KeyStoreException the key store exception - * @throws CertificateException the certificate exception - * @throws IOException Signals that an I/O exception has occurred. - */ - private void updateKeyStoreWithCertChain(X509Certificate[] chain) - throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { - - for (X509Certificate cert : chain) { - - List<String> sans = getSubjectAlternativeNames(cert); - - for (String san : sans) { - ks.setCertificateEntry(san, cert); - System.out.println( - "Added certificate to keystore '" + keystoreFileName + "' using alias '" + san + "'"); - } - } - - OutputStream out = new FileOutputStream(keystoreFileName); - ks.store(out, keystorePassword.toCharArray()); - out.close(); - - } - - - /** - * The Class SavingTrustManager. - */ - private static class SavingTrustManager implements X509TrustManager { - - private final X509TrustManager tm; - private X509Certificate[] chain; - - /** - * Instantiates a new saving trust manager. - * - * @param tm the tm - */ - SavingTrustManager(X509TrustManager tm) { - this.tm = tm; - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], - * java.lang.String) - */ - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * - * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], - * java.lang.String) - */ - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - this.chain = chain; - tm.checkServerTrusted(chain, authType); - } - } - - private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); - - /** - * Gets the san type. - * - * @param type the type - * @return the san type - */ - // TODO: convert to enum(int,string) - private String getSanType(int type) { - switch (type) { - case 0: - return "otherName"; - case 1: - return "rfc822Name"; - case 2: - return "dNSName"; - case 3: - return "x400Address"; - case 4: - return "directoryName"; - case 5: - return "ediPartyName"; - case 6: - return "uniformResourceIdentifier"; - case 7: - return "iPAddress"; - case 8: - return "registeredID"; - default: - return "unknownSanType"; - } - } - - - /** - * To hex string. - * - * @param bytes the bytes - * @return the string - */ - private static String toHexString(byte[] bytes) { - StringBuilder sb = new StringBuilder(bytes.length * 3); - for (int b : bytes) { - b &= 0xff; - sb.append(HEXDIGITS[b >> 4]); - sb.append(HEXDIGITS[b & 15]); - sb.append(' '); - } - return sb.toString(); - } - - - - /** - * The main method. - * - * @param args the arguments - * @throws Exception the exception - */ - public static void main(String[] args) throws Exception { - - /* - * Examples: localhost:8440;localhost:8442 d:\1\adhoc_keystore.jks aaiDomain2 false - * localhost:8440;localhost:8442 d:\1\adhoc_keystore.jks aaiDomain2 true - */ - - if (args.length != 4) { - System.out.println("Usage: KeyBuilder <[ip:port];*> <keystoreFileName>" - + " <keystorePassword> <dumpCertDetails> "); - System.exit(1); - } - KeystoreBuilder kb = new KeystoreBuilder(args[0]); - kb.setDumpCertDetails(Boolean.parseBoolean(args[3])); - kb.updateKeystore(args[1], args[2]); - - } -} - - diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/EntityTypeAggregation.java b/src/main/java/org/onap/aai/sparky/viewandinspect/EntityTypeAggregation.java index ff8d5d8..594b49f 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/EntityTypeAggregation.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/EntityTypeAggregation.java @@ -22,13 +22,10 @@ */ package org.onap.aai.sparky.viewandinspect; -import com.fasterxml.jackson.core.JsonProcessingException; - import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.sparky.viewandinspect.EntityTypeAggregation; + /** * The Class EntityTypeAggregation. @@ -38,13 +35,6 @@ public class EntityTypeAggregation { private ConcurrentHashMap<String, AtomicInteger> counters; /** - * @param counters the counters to set - */ - public void setCounters(ConcurrentHashMap<String, AtomicInteger> counters) { - this.counters = counters; - } - - /** * Instantiates a new entity type aggregation. */ public EntityTypeAggregation() { @@ -64,4 +54,5 @@ public class EntityTypeAggregation { public ConcurrentHashMap<String, AtomicInteger> getCounters() { return counters; } + } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/SchemaVisualizationProcessor.java b/src/main/java/org/onap/aai/sparky/viewandinspect/SchemaVisualizationProcessor.java new file mode 100644 index 0000000..822b14b --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/SchemaVisualizationProcessor.java @@ -0,0 +1,174 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.viewandinspect; + +import java.security.SecureRandom; +import java.util.concurrent.ExecutorService; + +import org.apache.camel.Exchange; +import org.apache.camel.component.restlet.RestletConstants; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; +import org.onap.aai.sparky.viewandinspect.entity.ActiveInventoryNode; +import org.onap.aai.sparky.viewandinspect.entity.JsonNode; +import org.onap.aai.sparky.viewandinspect.entity.NodeMeta; +import org.onap.aai.sparky.viewandinspect.entity.QueryRequest; +import org.onap.aai.sparky.viewandinspect.services.VisualizationContext; +import org.onap.aai.sparky.viewandinspect.services.VisualizationService; +import org.onap.aai.sparky.viewandinspect.services.VisualizationTransformer; +import org.onap.aai.sparky.viewinspect.sync.ViewInspectSyncController; +import org.restlet.Request; +import org.restlet.Response; +import org.restlet.data.ClientInfo; +import org.restlet.data.MediaType; +import org.restlet.data.Status; + +public class SchemaVisualizationProcessor { + + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(SchemaVisualizationProcessor.class); + + private final VisualizationService visualizationService; + private VisualizationTransformer visualizationTransformer; + private VisualizationContext visualizationContext; + private NodeMeta nodeMeta; + private JsonNode jsonNode; + private ActiveInventoryNode activeInventoryNode; + private final ExecutorService tabularExecutorService; + private final ExecutorService aaiExecutorService; + private final SecureRandom secureRandom; + private ActiveInventoryAdapter aaiAdapter; + private ElasticSearchAdapter esAdapter; + private ElasticSearchEndpointConfig endpointConfig; + private ElasticSearchSchemaConfig schemaConfig; + private ActiveInventoryConfig aaiConfig; + + public SchemaVisualizationProcessor(VisualizationConfigs visualizationConfigs, + OxmModelLoader oxmModelLoader, ViewInspectSyncController viewInspectSynController) + throws Exception { + + this.aaiAdapter = viewInspectSynController.getAaiAdapter(); + this.esAdapter = viewInspectSynController.getElasticSearchAdapter(); + this.endpointConfig = viewInspectSynController.getendpointConfig(); + this.schemaConfig = viewInspectSynController.getschemaConfig(); + + this.visualizationService = new VisualizationService(oxmModelLoader, visualizationConfigs, + aaiAdapter, esAdapter, endpointConfig, schemaConfig); + this.activeInventoryNode = new ActiveInventoryNode(visualizationConfigs); + this.nodeMeta = new NodeMeta(visualizationConfigs); + secureRandom = new SecureRandom(); + this.tabularExecutorService = NodeUtils.createNamedExecutor("TABULAR-WORKER", + visualizationConfigs.getNumOfThreadsToFetchNodeIntegrity(), LOG); + /* + * Fix ActiveInvenotryConfig with properly wired in properties + */ + this.aaiConfig = ActiveInventoryConfig.getConfig(); + this.aaiExecutorService = NodeUtils.createNamedExecutor("SLNC-WORKER", + aaiConfig.getAaiRestConfig().getNumResolverWorkers(), LOG); + + this.visualizationContext = new VisualizationContext(secureRandom.nextLong(), aaiAdapter, + tabularExecutorService, aaiExecutorService, visualizationConfigs); + this.visualizationTransformer = new VisualizationTransformer(visualizationConfigs); + this.jsonNode = new JsonNode(activeInventoryNode, visualizationConfigs); + + } + + protected String generateJsonErrorResponse(String message) { + return String.format("{ \"errorMessage\" : %s }", message); + } + + public void processVisualizationRequest(Exchange exchange) { + + String visualizationPayload = ""; + QueryRequest hashId = null; + OperationResult operationResult = null; + Request request = null; + Response response = null; + Object xTransactionId = null; + Object partnerName = null; + + xTransactionId = exchange.getIn().getHeader("X-TransactionId"); + if (xTransactionId == null) { + xTransactionId = NodeUtils.getRandomTxnId(); + } + partnerName = exchange.getIn().getHeader("X-FromAppId"); + if (partnerName == null) { + partnerName = "Browser"; + } + + request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); + response = exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); + + /* + * Disables automatic Apache Camel Restlet component logging which prints out an undesirable log + * entry which includes client (e.g. browser) information + */ + request.setLoggable(false); + + ClientInfo clientInfo = request.getClientInfo(); + MdcContext.initialize((String) xTransactionId, "AAI-UI", "", (String) partnerName, + clientInfo.getAddress() + ":" + clientInfo.getPort()); + + visualizationPayload = exchange.getIn().getBody(String.class); + hashId = visualizationService.analyzeQueryRequestBody(visualizationPayload); + + if (hashId != null) { + + operationResult = visualizationService.buildVisualizationUsingGenericQuery(hashId); + + if (operationResult.getResultCode() == Status.SUCCESS_OK.getCode()) { + + response.setStatus(Status.SUCCESS_OK); + } else { + response.setStatus(Status.SERVER_ERROR_INTERNAL); + LOG.error(AaiUiMsgs.FAILURE_TO_PROCESS_REQUEST, String + .format("Failed to process Visualization Schema Payload = '%s'", visualizationPayload)); + } + + } else { + operationResult = new OperationResult(); + operationResult.setResult(String + .format("Failed to analyze Visualization Schema Payload = '%s'", visualizationPayload)); + response.setStatus(Status.SERVER_ERROR_INTERNAL); + LOG.error(AaiUiMsgs.FAILED_TO_ANALYZE, String + .format("Failed to analyze Visualization Schema Payload = '%s'", visualizationPayload)); + + } + + + response.setEntity(operationResult.getResult(), MediaType.APPLICATION_JSON); + exchange.getOut().setBody(response); + } +} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/config/TierSupportUiConstants.java b/src/main/java/org/onap/aai/sparky/viewandinspect/config/TierSupportUiConstants.java index 77a34da..7050595 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/config/TierSupportUiConstants.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/config/TierSupportUiConstants.java @@ -45,16 +45,28 @@ public class TierSupportUiConstants { public static String CONFIG_AUTH_LOCATION = CONFIG_HOME + "auth" + FILESEP; public static String HOST = "host"; + public static String IP_ADDRESS = "ipAddress"; public static String PORT = "port"; + public static String HTTP_PORT = "httpPort"; public static String RETRIES = "numRequestRetries"; public static String RESOURCE_VERSION = "resource-version"; public static String URI = "URI"; + public static String AUTHORIZED_USERS_FILE_LOCATION = + DYNAMIC_CONFIG_APP_LOCATION + "authorized-users.config"; public static String USERS_FILE_LOCATION = DYNAMIC_CONFIG_APP_LOCATION + "users.config"; public static String ROLES_FILE_LOCATION = DYNAMIC_CONFIG_APP_LOCATION + "roles.config"; public static String PORTAL_AUTHENTICATION_FILE_LOCATION = DYNAMIC_CONFIG_APP_LOCATION + "portal" + FILESEP + "portal-authentication.properties"; + // Related to data-router properties + public static String DR_URI_SUFFIX = "uriSuffix"; + public static String DR_CERT_NAME = "cert-name"; + public static String DR_KEYSTORE_PASSWORD = "keystore-password"; + public static String DR_KEYSTORE = "keystore"; + public static String DR_CONNECT_TIMEOUT = "connectTimeoutMs"; + public static String DR_READ_TIMEOUT = "readTimeoutMs"; + public static final String ES_SUGGEST_API = "_suggest"; public static final String ES_COUNT_API = "_count"; public static final String ES_SEARCH_API = "_search"; @@ -74,10 +86,7 @@ public class TierSupportUiConstants { public static final String FILTER_MAPPING_FILE_DEFAULT = CONFIG_FILTERS_BASE_LOCATION + "filters" + FILESEP + "aaiui_views.json"; - // JUnit testing synchronizer.properties file - public static String TEST_CONFIG_FILE = - System.getProperty("user.dir") + FILESEP + "bundleconfig-local" + FILESEP + "etc" + FILESEP - + "appprops" + FILESEP + "synchronizer.properties"; + public static final String SUGGESTION_TEXT_SEPARATOR = " -- "; // Injected Attributes public static String URI_ATTR_NAME = "uri"; @@ -88,339 +97,4 @@ public class TierSupportUiConstants { return AJSC_HOME + FILESEP + configFile; } - public static final String getAggregationIndexName(String entityType) { - return "aggregate_" + entityType + "_index"; - } - - /** - * @return the aPP_NAME - */ - public static String getAPP_NAME() { - return APP_NAME; - } - - /** - * @param aPP_NAME the aPP_NAME to set - */ - public static void setAPP_NAME(String aPP_NAME) { - APP_NAME = aPP_NAME; - } - - /** - * @return the cONFIG_HOME - */ - public static String getCONFIG_HOME() { - return CONFIG_HOME; - } - - /** - * @param cONFIG_HOME the cONFIG_HOME to set - */ - public static void setCONFIG_HOME(String cONFIG_HOME) { - CONFIG_HOME = cONFIG_HOME; - } - - /** - * @return the aJSC_HOME - */ - public static String getAJSC_HOME() { - return AJSC_HOME; - } - - /** - * @param aJSC_HOME the aJSC_HOME to set - */ - public static void setAJSC_HOME(String aJSC_HOME) { - AJSC_HOME = aJSC_HOME; - } - - /** - * @return the cONFIG_ROOT_LOCATION - */ - public static String getCONFIG_ROOT_LOCATION() { - return CONFIG_ROOT_LOCATION; - } - - /** - * @param cONFIG_ROOT_LOCATION the cONFIG_ROOT_LOCATION to set - */ - public static void setCONFIG_ROOT_LOCATION(String cONFIG_ROOT_LOCATION) { - CONFIG_ROOT_LOCATION = cONFIG_ROOT_LOCATION; - } - - /** - * @return the sTATIC_CONFIG_APP_LOCATION - */ - public static String getSTATIC_CONFIG_APP_LOCATION() { - return STATIC_CONFIG_APP_LOCATION; - } - - /** - * @param sTATIC_CONFIG_APP_LOCATION the sTATIC_CONFIG_APP_LOCATION to set - */ - public static void setSTATIC_CONFIG_APP_LOCATION(String sTATIC_CONFIG_APP_LOCATION) { - STATIC_CONFIG_APP_LOCATION = sTATIC_CONFIG_APP_LOCATION; - } - - /** - * @return the dYNAMIC_CONFIG_APP_LOCATION - */ - public static String getDYNAMIC_CONFIG_APP_LOCATION() { - return DYNAMIC_CONFIG_APP_LOCATION; - } - - /** - * @param dYNAMIC_CONFIG_APP_LOCATION the dYNAMIC_CONFIG_APP_LOCATION to set - */ - public static void setDYNAMIC_CONFIG_APP_LOCATION(String dYNAMIC_CONFIG_APP_LOCATION) { - DYNAMIC_CONFIG_APP_LOCATION = dYNAMIC_CONFIG_APP_LOCATION; - } - - /** - * @return the cONFIG_OXM_LOCATION - */ - public static String getCONFIG_OXM_LOCATION() { - return CONFIG_OXM_LOCATION; - } - - /** - * @param cONFIG_OXM_LOCATION the cONFIG_OXM_LOCATION to set - */ - public static void setCONFIG_OXM_LOCATION(String cONFIG_OXM_LOCATION) { - CONFIG_OXM_LOCATION = cONFIG_OXM_LOCATION; - } - - /** - * @return the cONFIG_FILTERS_BASE_LOCATION - */ - public static String getCONFIG_FILTERS_BASE_LOCATION() { - return CONFIG_FILTERS_BASE_LOCATION; - } - - /** - * @param cONFIG_FILTERS_BASE_LOCATION the cONFIG_FILTERS_BASE_LOCATION to set - */ - public static void setCONFIG_FILTERS_BASE_LOCATION(String cONFIG_FILTERS_BASE_LOCATION) { - CONFIG_FILTERS_BASE_LOCATION = cONFIG_FILTERS_BASE_LOCATION; - } - - - /** - * @return the cONFIG_AUTH_LOCATION - */ - public static String getCONFIG_AUTH_LOCATION() { - return CONFIG_AUTH_LOCATION; - } - - /** - * @param cONFIG_AUTH_LOCATION the cONFIG_AUTH_LOCATION to set - */ - public static void setCONFIG_AUTH_LOCATION(String cONFIG_AUTH_LOCATION) { - CONFIG_AUTH_LOCATION = cONFIG_AUTH_LOCATION; - } - - /** - * @return the hOST - */ - public static String getHOST() { - return HOST; - } - - /** - * @param hOST the hOST to set - */ - public static void setHOST(String hOST) { - HOST = hOST; - } - - /** - * @return the pORT - */ - public static String getPORT() { - return PORT; - } - - /** - * @param pORT the pORT to set - */ - public static void setPORT(String pORT) { - PORT = pORT; - } - - /** - * @return the rETRIES - */ - public static String getRETRIES() { - return RETRIES; - } - - /** - * @param rETRIES the rETRIES to set - */ - public static void setRETRIES(String rETRIES) { - RETRIES = rETRIES; - } - - /** - * @return the rESOURCE_VERSION - */ - public static String getRESOURCE_VERSION() { - return RESOURCE_VERSION; - } - - /** - * @param rESOURCE_VERSION the rESOURCE_VERSION to set - */ - public static void setRESOURCE_VERSION(String rESOURCE_VERSION) { - RESOURCE_VERSION = rESOURCE_VERSION; - } - - /** - * @return the uRI - */ - public static String getURI() { - return URI; - } - - /** - * @param uRI the uRI to set - */ - public static void setURI(String uRI) { - URI = uRI; - } - - /** - * @return the uSERS_FILE_LOCATION - */ - public static String getUSERS_FILE_LOCATION() { - return USERS_FILE_LOCATION; - } - - /** - * @param uSERS_FILE_LOCATION the uSERS_FILE_LOCATION to set - */ - public static void setUSERS_FILE_LOCATION(String uSERS_FILE_LOCATION) { - USERS_FILE_LOCATION = uSERS_FILE_LOCATION; - } - - /** - * @return the rOLES_FILE_LOCATION - */ - public static String getROLES_FILE_LOCATION() { - return ROLES_FILE_LOCATION; - } - - /** - * @param rOLES_FILE_LOCATION the rOLES_FILE_LOCATION to set - */ - public static void setROLES_FILE_LOCATION(String rOLES_FILE_LOCATION) { - ROLES_FILE_LOCATION = rOLES_FILE_LOCATION; - } - - /** - * @return the pORTAL_AUTHENTICATION_FILE_LOCATION - */ - public static String getPORTAL_AUTHENTICATION_FILE_LOCATION() { - return PORTAL_AUTHENTICATION_FILE_LOCATION; - } - - /** - * @param pORTAL_AUTHENTICATION_FILE_LOCATION the pORTAL_AUTHENTICATION_FILE_LOCATION to set - */ - public static void setPORTAL_AUTHENTICATION_FILE_LOCATION( - String pORTAL_AUTHENTICATION_FILE_LOCATION) { - PORTAL_AUTHENTICATION_FILE_LOCATION = pORTAL_AUTHENTICATION_FILE_LOCATION; - } - - /** - * @return the tEST_CONFIG_FILE - */ - public static String getTEST_CONFIG_FILE() { - return TEST_CONFIG_FILE; - } - - /** - * @param tEST_CONFIG_FILE the tEST_CONFIG_FILE to set - */ - public static void setTEST_CONFIG_FILE(String tEST_CONFIG_FILE) { - TEST_CONFIG_FILE = tEST_CONFIG_FILE; - } - - /** - * @return the uRI_ATTR_NAME - */ - public static String getURI_ATTR_NAME() { - return URI_ATTR_NAME; - } - - /** - * @param uRI_ATTR_NAME the uRI_ATTR_NAME to set - */ - public static void setURI_ATTR_NAME(String uRI_ATTR_NAME) { - URI_ATTR_NAME = uRI_ATTR_NAME; - } - - /** - * @return the filesep - */ - public static String getFilesep() { - return FILESEP; - } - - /** - * @return the esSuggestApi - */ - public static String getEsSuggestApi() { - return ES_SUGGEST_API; - } - - /** - * @return the esCountApi - */ - public static String getEsCountApi() { - return ES_COUNT_API; - } - - /** - * @return the esSearchApi - */ - public static String getEsSearchApi() { - return ES_SEARCH_API; - } - - /** - * @return the entityAutoSuggestIndexNameDefault - */ - public static String getEntityAutoSuggestIndexNameDefault() { - return ENTITY_AUTO_SUGGEST_INDEX_NAME_DEFAULT; - } - - /** - * @return the entityAutoSuggestSettingsFileDefault - */ - public static String getEntityAutoSuggestSettingsFileDefault() { - return ENTITY_AUTO_SUGGEST_SETTINGS_FILE_DEFAULT; - } - - /** - * @return the entityAutoSuggestMappingsFileDefault - */ - public static String getEntityAutoSuggestMappingsFileDefault() { - return ENTITY_AUTO_SUGGEST_MAPPINGS_FILE_DEFAULT; - } - - /** - * @return the entityDynamicMappingsFileDefault - */ - public static String getEntityDynamicMappingsFileDefault() { - return ENTITY_DYNAMIC_MAPPINGS_FILE_DEFAULT; - } - - /** - * @return the uriVersionRegexPattern - */ - public static String getUriVersionRegexPattern() { - return URI_VERSION_REGEX_PATTERN; - } - } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/config/VisualizationConfig.java b/src/main/java/org/onap/aai/sparky/viewandinspect/config/VisualizationConfigs.java index 77f3d97..9fc9030 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/config/VisualizationConfig.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/config/VisualizationConfigs.java @@ -22,14 +22,10 @@ */ package org.onap.aai.sparky.viewandinspect.config; -import java.util.Properties; - -import org.onap.aai.sparky.util.ConfigHelper; - /** * The Class VisualizationConfig. */ -public class VisualizationConfig { +public class VisualizationConfigs { private int maxSelfLinkTraversalDepth; @@ -43,53 +39,17 @@ public class VisualizationConfig { private String selectedSearchedNodeClassName; + private int numOfThreadsToFetchNodeIntegrity; + private String entityTypesToSummarize; private String vnfEntityTypes; private boolean makeAllNeighborsBidirectional; - private static VisualizationConfig instance; - - public static VisualizationConfig getConfig() { - - if (instance == null) { - instance = new VisualizationConfig(); - } - - return instance; - - } - /** * Instantiates a new visualization config. */ - public VisualizationConfig() { - - Properties visualizationProps = - ConfigHelper.loadConfigFromExplicitPath(TierSupportUiConstants.STATIC_CONFIG_APP_LOCATION - + TierSupportUiConstants.FILESEP + "visualization.properties"); - - maxSelfLinkTraversalDepth = - Integer.parseInt(visualizationProps.getProperty("maxSelfLinkTraversalDepth", "2")); - visualizationDebugEnabled = - Boolean.parseBoolean(visualizationProps.getProperty("visualizationDebugEnabled", "false")); - aaiEntityNodeDescriptors = visualizationProps.getProperty("aaiEntityNodeDescriptors", null); - generalNodeClassName = - visualizationProps.getProperty("generalNodeClassName", "unknownClassName"); - searchNodeClassName = - visualizationProps.getProperty("searchedNodeClassName", "unknownClassName"); - selectedSearchedNodeClassName = - visualizationProps.getProperty("selectedSearchedNodeClassName", "unknownClassName"); - - entityTypesToSummarize = visualizationProps.getProperty("entityTypesToSummarize", - "customer,service-instance,complex,pserver,vserver,vnf"); - - vnfEntityTypes = visualizationProps.getProperty("vnfEntityTypes", "generic-vnf,newvce,vce,vpe"); - - makeAllNeighborsBidirectional = Boolean - .parseBoolean(visualizationProps.getProperty("makeAllNeighborsBidirectional", "false")); - - } + public VisualizationConfigs() {} @@ -154,6 +114,14 @@ public class VisualizationConfig { return maxSelfLinkTraversalDepth; } + public int getNumOfThreadsToFetchNodeIntegrity() { + return numOfThreadsToFetchNodeIntegrity; + } + + public void setNumOfThreadsToFetchNodeIntegrity(int numOfThreadsToFetchNodeIntegrity) { + this.numOfThreadsToFetchNodeIntegrity = numOfThreadsToFetchNodeIntegrity; + } + public String getEntityTypesToSummarize() { return entityTypesToSummarize; } @@ -170,30 +138,11 @@ public class VisualizationConfig { this.vnfEntityTypes = vnfEntityTypes; } - /** - * @return the instance - */ - public static VisualizationConfig getInstance() { - return instance; - } - /** - * @param instance the instance to set - */ - public static void setInstance(VisualizationConfig instance) { - VisualizationConfig.instance = instance; - } - - /** - * @return the makeAllNeighborsBidirectional - */ - public boolean isMakeAllNeighborsBidirectional() { - return makeAllNeighborsBidirectional; - } @Override public String toString() { - return "VisualizationConfig [maxSelfLinkTraversalDepth=" + maxSelfLinkTraversalDepth + return "VisualizationConfigs [maxSelfLinkTraversalDepth=" + maxSelfLinkTraversalDepth + ", visualizationDebugEnabled=" + visualizationDebugEnabled + ", " + (aaiEntityNodeDescriptors != null ? "aaiEntityNodeDescriptors=" + aaiEntityNodeDescriptors + ", " : "") @@ -202,6 +151,7 @@ public class VisualizationConfig { + (searchNodeClassName != null ? "searchNodeClassName=" + searchNodeClassName + ", " : "") + (selectedSearchedNodeClassName != null ? "selectedSearchedNodeClassName=" + selectedSearchedNodeClassName + ", " : "") + + "numOfThreadsToFetchNodeIntegrity=" + numOfThreadsToFetchNodeIntegrity + ", " + (entityTypesToSummarize != null ? "entityTypesToSummarize=" + entityTypesToSummarize + ", " : "") + (vnfEntityTypes != null ? "vnfEntityTypes=" + vnfEntityTypes + ", " : "") diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/ActiveInventoryNode.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/ActiveInventoryNode.java index d87aad8..8d74d68 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/ActiveInventoryNode.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/ActiveInventoryNode.java @@ -36,14 +36,15 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.viewandinspect.config.VisualizationConfig; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; import org.onap.aai.sparky.viewandinspect.enumeration.NodeProcessingAction; import org.onap.aai.sparky.viewandinspect.enumeration.NodeProcessingState; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -70,7 +71,6 @@ public class ActiveInventoryNode { private int nodeDepth; private OperationResult opResult; - private boolean processingErrorOccurred; private List<String> errorCauses; private boolean selflinkRetrievalFailure; @@ -88,14 +88,16 @@ public class ActiveInventoryNode { private boolean selfLinkDeterminationPending; private AtomicBoolean selfLinkProcessed; + private AtomicBoolean nodeIntegrityProcessed; private OxmModelLoader oxmModelLoader; - private VisualizationConfig visualizationConfig; + private VisualizationConfigs visualizationConfigs; private String entityType; private String primaryKeyName; private String primaryKeyValue; + private boolean nodeValidated; private boolean nodeIssue; private boolean ignoredByFilter; @@ -108,17 +110,10 @@ public class ActiveInventoryNode { /** * Instantiates a new active inventory node. - */ - public ActiveInventoryNode() { - this(null); - } - - /** - * Instantiates a new active inventory node. * * @param key the key */ - public ActiveInventoryNode(String key) { + public ActiveInventoryNode(VisualizationConfigs visualizationConfigs) { this.nodeId = null; this.entityType = null; this.selfLink = null; @@ -127,13 +122,15 @@ public class ActiveInventoryNode { this.errorCauses = new ArrayList<String>(); this.selflinkRetrievalFailure = false; this.nodeIssue = false; + this.nodeValidated = false; this.state = NodeProcessingState.INIT; this.selfLinkPendingResolve = false; this.selfLinkDeterminationPending = false; selfLinkProcessed = new AtomicBoolean(Boolean.FALSE); + nodeIntegrityProcessed = new AtomicBoolean(Boolean.FALSE); oxmModelLoader = null; - visualizationConfig = null; + this.visualizationConfigs = visualizationConfigs; isRootNode = false; inboundNeighbors = new ConcurrentLinkedDeque<String>(); @@ -165,7 +162,7 @@ public class ActiveInventoryNode { public void addQueryParams(Collection<String> params) { - if (params != null && !params.isEmpty()) { + if (params != null & params.size() > 0) { for (String param : params) { addQueryParam(param); @@ -215,8 +212,8 @@ public class ActiveInventoryNode { * * @return the visualization config */ - public VisualizationConfig getvisualizationConfig() { - return visualizationConfig; + public VisualizationConfigs getvisualizationConfigs() { + return visualizationConfigs; } public int getNodeDepth() { @@ -232,8 +229,8 @@ public class ActiveInventoryNode { * * @param visualizationConfig the new visualization config */ - public void setvisualizationConfig(VisualizationConfig visualizationConfig) { - this.visualizationConfig = visualizationConfig; + public void setvisualizationConfig(VisualizationConfigs visualizationConfigs) { + this.visualizationConfigs = visualizationConfigs; } public OxmModelLoader getOxmModelLoader() { @@ -252,6 +249,14 @@ public class ActiveInventoryNode { this.primaryKeyValue = primaryKeyValue; } + public boolean isNodeValidated() { + return nodeValidated; + } + + public void setNodeValidated(boolean nodeValidated) { + this.nodeValidated = nodeValidated; + } + public boolean isNodeIssue() { return nodeIssue; } @@ -338,7 +343,7 @@ public class ActiveInventoryNode { } public boolean isAtMaxDepth() { - return (nodeDepth >= VisualizationConfig.getConfig().getMaxSelfLinkTraversalDepth()); + return (nodeDepth >= this.visualizationConfigs.getMaxSelfLinkTraversalDepth()); } public ConcurrentLinkedDeque<String> getInboundNeighbors() { @@ -443,8 +448,16 @@ public class ActiveInventoryNode { this.selfLinkProcessed.set(selfLinkProcessed); } + public boolean getNodeIntegrityProcessed() { + return nodeIntegrityProcessed.get(); + } + + public void setNodeIntegrityProcessed(boolean nodeIntegrityProcessed) { + this.nodeIntegrityProcessed.set(nodeIntegrityProcessed); + } + public boolean isDirectSelfLink() { - // https://<AAI-Hostname>:8443/aai/v8/resources/id/2458124400 + // https://aai-int1.test.att.com:8443/aai/v8/resources/id/2458124400 return isDirectSelfLink(this.selfLink); } @@ -455,7 +468,7 @@ public class ActiveInventoryNode { * @return true, if is direct self link */ public static boolean isDirectSelfLink(String link) { - // https://<AAI-Hostname>:8443/aai/v8/resources/id/2458124400 + // https://aai-int1.test.att.com:8443/aai/v8/resources/id/2458124400 if (link == null) { return false; @@ -625,7 +638,7 @@ public class ActiveInventoryNode { * probably more likely just for array node types, but we'll see. */ - if (oxmModelLoader.getEntityDescriptor(fieldName) == null) { + if (OxmEntityLookup.getInstance().getEntityDescriptors().get(fieldName) == null) { /* * this is no an entity type as far as we can tell, so we can add it to our property * set. @@ -645,7 +658,8 @@ public class ActiveInventoryNode { * complex group or relationship. */ - if (oxmModelLoader.getEntityDescriptor(field.getKey()) == null) { + if (OxmEntityLookup.getInstance().getEntityDescriptors() + .get(field.getKey()) == null) { /* * this is no an entity type as far as we can tell, so we can add it to our property * set. diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/D3VisualizationOutput.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/D3VisualizationOutput.java index e29f6df..69971c5 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/D3VisualizationOutput.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/D3VisualizationOutput.java @@ -22,10 +22,6 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; - import java.util.ArrayList; import java.util.List; @@ -91,67 +87,5 @@ public class D3VisualizationOutput { this.inlineMessage = inlineMessage; } - /** - * @return the nodes - */ - public List<JsonNode> getNodes() { - return nodes; - } - - /** - * @param nodes the nodes to set - */ - public void setNodes(List<JsonNode> nodes) { - this.nodes = nodes; - } - - /** - * @return the links - */ - public List<JsonNodeLink> getLinks() { - return links; - } - - /** - * @param links the links to set - */ - public void setLinks(List<JsonNodeLink> links) { - this.links = links; - } - - /** - * The main method. - * - * @param args the arguments - * @throws JsonProcessingException the json processing exception - */ - public static final void main(String[] args) throws JsonProcessingException { - - ActiveInventoryNode pserverAin = new ActiveInventoryNode(); - pserverAin.setNodeId("pserver.76786asd87asgd"); - JsonNode pserver = new JsonNode(pserverAin); - - List<JsonNode> nodes = new ArrayList<JsonNode>(); - nodes.add(pserver); - - JsonNodeLink l1 = new JsonNodeLink(); - l1.setSource(pserverAin.getNodeId()); - l1.setTarget(pserverAin.getNodeId()); - l1.setId(l1.getSource() + "_" + l1.getTarget()); - - List<JsonNodeLink> links = new ArrayList<JsonNodeLink>(); - links.add(l1); - - D3VisualizationOutput output = new D3VisualizationOutput(); - output.addNodes(nodes); - output.addLinks(links); - - - ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); - String json = ow.writeValueAsString(output); - - System.out.println(json); - - } } diff --git a/src/main/java/org/onap/aai/sparky/suggestivesearch/SuggestionEntity.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/GraphRequest.java index 92be827..678a00f 100644 --- a/src/main/java/org/onap/aai/sparky/suggestivesearch/SuggestionEntity.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/GraphRequest.java @@ -1,61 +1,56 @@ -/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017 Amdocs
- * ================================================================================
- * 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 is a trademark and service mark of AT&T Intellectual Property.
- */
-package org.onap.aai.sparky.suggestivesearch;
-
-public class SuggestionEntity {
- private String route;
- private String hashId;
- private String text;
-
- public SuggestionEntity() {}
-
- public SuggestionEntity(String route, String hashId, String text) {
- this.route = route;
- this.hashId = hashId;
- this.text = text;
- }
-
- public String getRoute() {
- return route;
- }
-
- public void setRoute(String route) {
- this.route = route;
- }
-
- public String getHashId() {
- return hashId;
- }
-
- public void setHashId(String hashId) {
- this.hashId = hashId;
- }
-
- public String getText() {
- return text;
- }
-
- public void setText(String text) {
- this.text = text;
- }
-}
+/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.viewandinspect.entity; + +public class GraphRequest { + + private String hashId; + private boolean includeGraphMeta; + + public GraphRequest() { + + } + + public String getHashId() { + return hashId; + } + + public void setHashId(String hashId) { + this.hashId = hashId; + } + + public boolean isIncludeGraphMeta() { + return includeGraphMeta; + } + + public void setIncludeGraphMeta(boolean includeGraphMeta) { + this.includeGraphMeta = includeGraphMeta; + } + + @Override + public String toString() { + return "QueryRequest [" + (hashId != null ? "hashId=" + hashId + ", " : "") + + "includeGraphMeta=" + includeGraphMeta + "]"; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/JsonNode.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/JsonNode.java index 3f9d0f2..4d1c458 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/JsonNode.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/JsonNode.java @@ -22,13 +22,14 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import com.fasterxml.jackson.annotation.JsonIgnore; - import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; + +import com.fasterxml.jackson.annotation.JsonIgnore; /* * We can use annotations to differentiate between intermediate data we use to build the node, and @@ -77,12 +78,15 @@ public class JsonNode { @JsonIgnore private static final Logger LOG = Logger.getLogger(JsonNode.class); + private VisualizationConfigs visualizationConfigs; + + /** * Instantiates a new json node. * * @param ain the ain */ - public JsonNode(ActiveInventoryNode ain) { + public JsonNode(ActiveInventoryNode ain, VisualizationConfigs visualizationConfigs) { this.resourceKey = ain.getNodeId(); this.itemProperties = ain.getProperties(); this.setItemType(ain.getEntityType()); @@ -90,6 +94,7 @@ public class JsonNode { this.setItemNameValue(ain.getPrimaryKeyValue()); this.setId(ain.getNodeId()); this.isRootNode = ain.isRootNode(); + this.visualizationConfigs = visualizationConfigs; if (LOG.isDebugEnabled()) { LOG.debug("---"); @@ -100,9 +105,10 @@ public class JsonNode { inboundNeighbors = ain.getInboundNeighbors(); outboundNeighbors = ain.getOutboundNeighbors(); - nodeMeta = new NodeMeta(); + nodeMeta = new NodeMeta(this.visualizationConfigs); nodeMeta.setNodeIssue(ain.isNodeIssue()); + nodeMeta.setNodeValidated(ain.isNodeValidated()); nodeMeta.setNodeDepth(ain.getNodeDepth()); nodeMeta.setNumInboundNeighbors(ain.getInboundNeighbors().size()); @@ -177,55 +183,11 @@ public class JsonNode { return isRootNode; } - /** - * @return the inboundNeighbors - */ - public Collection<String> getInboundNeighbors() { - return inboundNeighbors; - } - - /** - * @param inboundNeighbors the inboundNeighbors to set - */ - public void setInboundNeighbors(Collection<String> inboundNeighbors) { - this.inboundNeighbors = inboundNeighbors; - } - - /** - * @return the outboundNeighbors - */ - public Collection<String> getOutboundNeighbors() { - return outboundNeighbors; - } - - /** - * @param outboundNeighbors the outboundNeighbors to set + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() */ - public void setOutboundNeighbors(Collection<String> outboundNeighbors) { - this.outboundNeighbors = outboundNeighbors; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @param itemProperties the itemProperties to set - */ - public void setItemProperties(Map<String, String> itemProperties) { - this.itemProperties = itemProperties; - } - - /** - * @param isRootNode the isRootNode to set - */ - public void setRootNode(boolean isRootNode) { - this.isRootNode = isRootNode; - } - @Override public String toString() { return "JsonNode [" + (id != null ? "id=" + id + ", " : "") @@ -233,8 +195,8 @@ public class JsonNode { + (itemNameKey != null ? "itemNameKey=" + itemNameKey + ", " : "") + (itemNameValue != null ? "itemNameValue=" + itemNameValue + ", " : "") + (itemProperties != null ? "itemProperties=" + itemProperties + ", " : "") - + (nodeMeta != null ? "nodeMeta=" + nodeMeta + ", " : "") + "isRootNode=" + isRootNode - + ", " + (resourceKey != null ? "resourceKey=" + resourceKey + ", " : "") + + (nodeMeta != null ? "nodeMeta=" + nodeMeta + ", " : "") + + (resourceKey != null ? "resourceKey=" + resourceKey + ", " : "") + (inboundNeighbors != null ? "inboundNeighbors=" + inboundNeighbors + ", " : "") + (outboundNeighbors != null ? "outboundNeighbors=" + outboundNeighbors : "") + "]"; } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeMeta.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeMeta.java index c55f838..26a027f 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeMeta.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeMeta.java @@ -22,7 +22,7 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import org.onap.aai.sparky.viewandinspect.config.VisualizationConfig; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; import org.onap.aai.sparky.viewandinspect.enumeration.NodeProcessingState; /** @@ -32,7 +32,6 @@ public class NodeMeta { private String className; - private boolean isEnrichableNode; private boolean isSearchTarget; private NodeDebug nodeDebug; @@ -51,14 +50,19 @@ public class NodeMeta { private NodeProcessingState processingState; + private VisualizationConfigs visualizationConfigs; + + + /** * Instantiates a new node meta. */ - public NodeMeta() { + public NodeMeta(VisualizationConfigs visualizationConfigs) { this.isSearchTarget = false; - this.isEnrichableNode = false; + this.visualizationConfigs = visualizationConfigs; + - if (VisualizationConfig.getConfig().isVisualizationDebugEnabled()) { + if (this.visualizationConfigs.isVisualizationDebugEnabled()) { nodeDebug = new NodeDebug(); } this.numInboundNeighbors = 0; @@ -166,10 +170,6 @@ public class NodeMeta { return selfLinkResponseTimeInMs; } - public boolean isEnrichableNode() { - return isEnrichableNode; - } - public boolean isNodeIssue() { return nodeIssue; } @@ -186,10 +186,6 @@ public class NodeMeta { this.className = className; } - public void setEnrichableNode(boolean isEnrichableNode) { - this.isEnrichableNode = isEnrichableNode; - } - public void setNodeIssue(boolean nodeIssue) { this.nodeIssue = nodeIssue; } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeProcessingTransaction.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeProcessingTransaction.java index ca55f09..22bea15 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeProcessingTransaction.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/NodeProcessingTransaction.java @@ -22,7 +22,7 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import org.onap.aai.sparky.dal.rest.OperationResult; +import org.onap.aai.restclient.client.OperationResult; /** * The Class NodeProcessingTransaction. diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Relationship.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Relationship.java index 7e5519c..135ddcc 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Relationship.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Relationship.java @@ -22,10 +22,10 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * The Class Relationship. */ diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/RelationshipList.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/RelationshipList.java index 8dd61d4..d758543 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/RelationshipList.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/RelationshipList.java @@ -22,10 +22,10 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonProperty; + /** * The Class RelationshipList. */ @@ -42,20 +42,6 @@ public class RelationshipList { this.relationship = relationship; } - /** - * @return the relationship - */ - public Relationship[] getRelationship() { - return relationship; - } - - /** - * @param relationship the relationship to set - */ - public void setRelationship(Relationship[] relationship) { - this.relationship = relationship; - } - /* * (non-Javadoc) * diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SearchableEntityList.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SearchableEntityList.java new file mode 100644 index 0000000..bed2602 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SearchableEntityList.java @@ -0,0 +1,115 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.viewandinspect.entity; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.onap.aai.sparky.sync.entity.SearchableEntity; + +import java.util.Set; + +public class SearchableEntityList { + + private List<SearchableEntity> entities; + + public SearchableEntityList() { + entities = new ArrayList<SearchableEntity>(); + } + + public List<SearchableEntity> getEntities() { + return entities; + } + + public void setEntities(List<SearchableEntity> entities) { + this.entities = entities; + } + + public void addEntity(SearchableEntity entity) { + + if (!entities.contains(entity)) { + entities.add(entity); + } + + } + + protected static SearchableEntity buildEntity(String entityType, String pkeyValue, String link, + Map<String, String> searchTags) { + + SearchableEntity se = new SearchableEntity(); + + se.setEntityType(entityType); + se.setEntityPrimaryKeyValue(pkeyValue); + se.setLink(link); + + if (searchTags != null) { + + Set<Entry<String, String>> entrySet = searchTags.entrySet(); + + for (Entry<String, String> entry : entrySet) { + se.addSearchTagWithKey(entry.getKey(), entry.getValue()); + } + } + + se.deriveFields(); + + return se; + + } + + protected static Map<String, String> getSearchTagMap(String... tags) { + + HashMap<String, String> dataMap = new HashMap<String, String>(); + + if (tags != null && tags.length >= 2) { + + int numTags = tags.length; + int index = 0; + + while (index < numTags) { + + if (index + 1 < numTags) { + // we have enough parameters for the current set + dataMap.put(tags[index], tags[index + 1]); + index += 2; + } else { + break; + } + } + + } + + return dataMap; + + + } + + @Override + public String toString() { + return "SearchableEntityList [" + (entities != null ? "entities=" + entities : "") + "]"; + } + +} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SelfLinkDeterminationTransaction.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SelfLinkDeterminationTransaction.java index 21af9cf..204b930 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SelfLinkDeterminationTransaction.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/SelfLinkDeterminationTransaction.java @@ -22,7 +22,7 @@ */ package org.onap.aai.sparky.viewandinspect.entity; -import org.onap.aai.sparky.dal.rest.OperationResult; +import org.onap.aai.restclient.client.OperationResult; public class SelfLinkDeterminationTransaction { @@ -33,7 +33,6 @@ public class SelfLinkDeterminationTransaction { private OperationResult opResult; - public String getParentNodeId() { return parentNodeId; } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Violations.java b/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Violations.java deleted file mode 100644 index 4968de4..0000000 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/entity/Violations.java +++ /dev/null @@ -1,125 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.viewandinspect.entity; - -import com.att.aft.dme2.internal.jackson.annotate.JsonProperty; - -/** - * The Class Violations. - */ -public class Violations { - - private String severity; - - private String category; - - private String type; - - private String timestamp; - - private String details; - - @JsonProperty("error-message") - private String errorMessage; - - /** - * Instantiates a new violations. - * - * @param severity the severity - * @param category the category - * @param type the type - * @param timestamp the timestamp - * @param errorMessage the error message - */ - public Violations(String severity, String category, String type, String timestamp, - String errorMessage) { - this.severity = severity; - this.category = category; - this.type = type; - this.timestamp = timestamp; - this.errorMessage = errorMessage; - } - - public String getSeverity() { - return severity; - } - - public void setSeverity(String severity) { - this.severity = severity; - } - - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - - public String getTimestamp() { - return timestamp; - } - - public void setTimestamp(String timestamp) { - this.timestamp = timestamp; - } - - /* - * public Map<String, Object> getDetails() { return details; } - * - * public void setDetails(Map<String, Object> details) { this.details = details; } - */ - - public String getErrorMessage() { - return errorMessage; - } - - public void setErrorMessage(String errorMessage) { - this.errorMessage = errorMessage; - } - - /** - * @return the details - */ - public String getDetails() { - return details; - } - - /** - * @param details the details to set - */ - public void setDetails(String details) { - this.details = details; - } - - -} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/enumeration/NodeProcessingAction.java b/src/main/java/org/onap/aai/sparky/viewandinspect/enumeration/NodeProcessingAction.java index 2550ed7..b7038bf 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/enumeration/NodeProcessingAction.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/enumeration/NodeProcessingAction.java @@ -28,3 +28,4 @@ package org.onap.aai.sparky.viewandinspect.enumeration; public enum NodeProcessingAction { SELF_LINK_SET, NEW_NODE_PROCESSED, SELF_LINK_RESOLVE_ERROR, SELF_LINK_DETERMINATION_ERROR, SELF_LINK_RESOLVE_OK, SELF_LINK_RESPONSE_PARSE_ERROR, SELF_LINK_RESPONSE_PARSE_OK, NEIGHBORS_PROCESSED_ERROR, NEIGHBORS_PROCESSED_OK, COMPLEX_ATTRIBUTE_GROUP_PARSE_ERROR, COMPLEX_ATTRIBUTE_GROUP_PARSE_OK, NODE_IDENTITY_ERROR, UNEXPECTED_STATE_TRANSITION } + diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/search/ViewInspectSearchProvider.java b/src/main/java/org/onap/aai/sparky/viewandinspect/search/ViewInspectSearchProvider.java new file mode 100644 index 0000000..5101c28 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/search/ViewInspectSearchProvider.java @@ -0,0 +1,440 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.viewandinspect.search; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.common.search.CommonSearchSuggestion; +import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.config.oxm.OxmModelLoader; +import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; +import org.onap.aai.sparky.dal.sas.config.SearchServiceConfig; +import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.search.api.SearchProvider; +import org.onap.aai.sparky.search.config.SuggestionConfig; +import org.onap.aai.sparky.search.entity.QuerySearchEntity; +import org.onap.aai.sparky.search.entity.SearchSuggestion; +import org.onap.aai.sparky.util.NodeUtils; +import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; + +public class ViewInspectSearchProvider implements SearchProvider { + + private static final Logger LOG = + LoggerFactory.getInstance().getLogger(ViewInspectSearchProvider.class); + + private SearchServiceConfig sasConfig = null; + private SearchAdapter search = null; + private OxmModelLoader oxmModelLoader; + private String additionalSearchSuggestionText; + + private static final String KEY_SEARCH_RESULT = "searchResult"; + private static final String KEY_HITS = "hits"; + private static final String KEY_DOCUMENT = "document"; + private static final String KEY_CONTENT = "content"; + + private static final String VI_SUGGESTION_ROUTE = "schema"; // TODO -> Read route from + // suggestive-search.properties + // instead of hard coding + + private static final String KEY_SEARCH_TAG_IDS = "searchTagIDs"; + private static final String KEY_SEARCH_TAGS = "searchTags"; + private static final String KEY_LINK = "link"; + private static final String KEY_ENTITY_TYPE = "entityType"; + private static final String VALUE_QUERY = "query"; + + public ViewInspectSearchProvider(OxmModelLoader oxmModelLoader) throws Exception { + + sasConfig = SearchServiceConfig.getConfig(); + search = new SearchAdapter(); + suggestionConfig = SuggestionConfig.getConfig(); + this.oxmModelLoader = oxmModelLoader; + additionalSearchSuggestionText = null; + + } + + @Override + public List<SearchSuggestion> search(QuerySearchEntity queryRequest) { + + List<SearchSuggestion> suggestionEntityList = new ArrayList<SearchSuggestion>(); + + + /* + * Based on the configured stop words, we need to strip any matched stop-words ( case + * insensitively ) from the query string, before hitting elastic to prevent the words from being + * used against the elastic view-and-inspect index. Another alternative to this approach would + * be to define stop words on the elastic search index configuration for the + * entity-search-index, but but that may be more complicated / more risky than just a simple bug + * fix, but it's something we should think about for the future. + */ + + try { + final String queryStringWithoutStopWords = + stripStopWordsFromQuery(queryRequest.getQueryStr()); + + final String fullUrlStr = getSasFullUrl(sasConfig.getIndexName(), VALUE_QUERY, + sasConfig.getIpAddress(), sasConfig.getHttpPort(), sasConfig.getVersion()); + + String postBody = String.format(VIUI_SEARCH_TEMPLATE, + Integer.parseInt(queryRequest.getMaxResults()), queryStringWithoutStopWords); + + OperationResult opResult = search.doPost(fullUrlStr, postBody, "application/json"); + if (opResult.getResultCode() == 200) { + suggestionEntityList = + generateSuggestionsForSearchResponse(opResult.getResult(), queryRequest.getQueryStr()); + } + } catch (Exception exc) { + LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, + "View and inspect query failed with error = " + exc.getMessage()); + } + return suggestionEntityList; + + + } + + public String getAdditionalSearchSuggestionText() { + return additionalSearchSuggestionText; + } + + public void setAdditionalSearchSuggestionText(String additionalSearchSuggestionText) { + this.additionalSearchSuggestionText = additionalSearchSuggestionText; + } + + /** + * Get Full URL for search + * + * @param api the api + * @param indexName + * @return the full url + */ + private String getSasFullUrl(String indexName, String type, String ipAddress, String port, + String version) { + + return String.format("https://%s:%s/services/search-data-service/%s/search/indexes/%s/%s", + ipAddress, port, version, indexName, type); + } + + + + /** + * Builds the search response. + * + * @param operationResult The Elasticsearch query result + * @param queryStr The string the user typed into the search bar + * @return A list of search suggestions and corresponding UI filter values + */ + private List<SearchSuggestion> generateSuggestionsForSearchResponse(String operationResult, + String queryStr) { + + + if (operationResult == null || operationResult.length() == 0) { + return null; + } + + ObjectMapper mapper = new ObjectMapper(); + JsonNode rootNode = null; + List<SearchSuggestion> suggestionEntityList = new ArrayList<SearchSuggestion>(); + try { + rootNode = mapper.readTree(operationResult); + + JsonNode hitsNode = rootNode.get(KEY_SEARCH_RESULT); + + + + // Check if there are hits that are coming back + if (hitsNode.has(KEY_HITS)) { + ArrayNode hitsArray = (ArrayNode) hitsNode.get(KEY_HITS); + + /* + * next we iterate over the values in the hit array elements + */ + + Iterator<JsonNode> nodeIterator = hitsArray.elements(); + JsonNode entityNode = null; + CommonSearchSuggestion suggestionEntity = null; + JsonNode sourceNode = null; + while (nodeIterator.hasNext()) { + entityNode = nodeIterator.next(); + sourceNode = entityNode.get(KEY_DOCUMENT).get(KEY_CONTENT); + + // do the point transformation as we build the response? + suggestionEntity = new CommonSearchSuggestion(); + suggestionEntity.setRoute(VI_SUGGESTION_ROUTE); + + /* + * This is where we probably want to annotate the search tags because we also have access + * to the seachTagIds + */ + + String searchTagIds = getValueFromNode(sourceNode, KEY_SEARCH_TAG_IDS); + String searchTags = getValueFromNode(sourceNode, KEY_SEARCH_TAGS); + String entityType = getValueFromNode(sourceNode, KEY_ENTITY_TYPE); + String link = getValueFromNode(sourceNode, KEY_LINK); + + if (link != null) { + suggestionEntity.setHashId(NodeUtils.generateUniqueShaDigest(link)); + } + + try { + suggestionEntity + .setText(annotateSearchTags(searchTags, searchTagIds, entityType, queryStr)); + } catch (Exception exc) { + LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), + exc.getLocalizedMessage()); + // at least send back the un-annotated search tags + suggestionEntity.setText(searchTags); + } + + if (getAdditionalSearchSuggestionText() != null) { + String suggestionText = suggestionEntity.getText(); + suggestionText += TierSupportUiConstants.SUGGESTION_TEXT_SEPARATOR + + getAdditionalSearchSuggestionText(); + suggestionEntity.setText(suggestionText); + } + + if (searchTags != null) { + suggestionEntityList.add(suggestionEntity); + } + + } + } + } catch (IOException exc) { + LOG.warn(AaiUiMsgs.SEARCH_RESPONSE_BUILDING_EXCEPTION, exc.getLocalizedMessage()); + } + return suggestionEntityList; + } + + + + /** + * The current format of an UI-dropdown-item is like: "search-terms entityType att1=attr1_val". + * Example, for pserver: search-terms pserver hostname=djmAG-72060, + * pserver-name2=example-pserver-name2-val-17254, pserver-id=example-pserver-id-val-17254, + * ipv4-oam-address=example-ipv4-oam-address-val-17254 SearchController.js parses the above + * format. So if you are modifying the parsing below, please update SearchController.js as well. + * + * @param searchTags the search tags + * @param searchTagIds the search tag ids + * @param entityType the entity type + * @param queryStr the query str + * @return the string + */ + + private String annotateSearchTags(String searchTags, String searchTagIds, String entityType, + String queryStr) { + + if (searchTags == null || searchTagIds == null) { + String valueOfSearchTags = String.valueOf(searchTags); + String valueOfSearchTagIds = String.valueOf(searchTagIds); + + LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, "See error", + "Search tags = " + valueOfSearchTags + " and Seach tag IDs = " + valueOfSearchTagIds); + return searchTags; + } + + if (entityType == null) { + LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), "EntityType is null"); + return searchTags; + } + + if (queryStr == null) { + LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), + "Query string is null"); + return searchTags; + } + + /* + * The ElasticSearch analyzer has already applied the lowercase filter, so we don't have to + * covert them again + */ + String[] searchTagsArray = searchTags.split(";"); + String[] searchTagIdsArray = searchTagIds.split(";"); + + // specifically apply lower case to the the query terms to make matching + // simpler + String[] queryTerms = queryStr.toLowerCase().split(" "); + + OxmEntityDescriptor desc = OxmEntityLookup.getInstance().getEntityDescriptors().get(entityType); + + if (desc == null) { + LOG.error(AaiUiMsgs.ENTITY_NOT_FOUND_IN_OXM, entityType.toString()); + return searchTags; + } + + String primaryKeyName = NodeUtils.concatArray(desc.getPrimaryKeyAttributeNames(), "/"); + String primaryKeyValue = null; + + /* + * For each used attribute, get the fieldName for the attribute index and transform the search + * tag into t1,t2,t3 => h1=t1, h2=t2, h3=t3; + */ + StringBuilder searchTagsBuilder = new StringBuilder(128); + searchTagsBuilder.append(entityType); + + String primaryKeyConjunctionValue = null; + boolean queryTermsMatchedSearchTags = false; + + if (searchTagsArray.length == searchTagIdsArray.length) { + for (int i = 0; i < searchTagsArray.length; i++) { + String searchTagAttributeId = searchTagIdsArray[i]; + String searchTagAttributeValue = searchTagsArray[i]; + + // Find the concat conjunction + Map<String, String> pairConjunctionList = suggestionConfig.getPairingList(); + + String suggConjunction = null; + if (pairConjunctionList.get(searchTagAttributeId) != null) { + suggConjunction = pairConjunctionList.get(searchTagAttributeId); + } else { + suggConjunction = suggestionConfig.getDefaultPairingValue(); + } + + if (primaryKeyName.equals(searchTagAttributeId)) { + primaryKeyValue = searchTagAttributeValue; + primaryKeyConjunctionValue = suggConjunction; + } + + if (queryTermsMatchSearchTag(queryTerms, searchTagAttributeValue)) { + searchTagsBuilder.append(" " + suggConjunction + " " + searchTagAttributeValue); + queryTermsMatchedSearchTags = true; + } + } + } else { + String errorMessage = + "Search tags length did not match search tag ID length for entity type " + entityType; + LOG.error(AaiUiMsgs.ENTITY_SYNC_SEARCH_TAG_ANNOTATION_FAILED, errorMessage); + } + + + + /* + * if none of the user query terms matched the index entity search tags then we should still tag + * the matched entity with a conjunction set to at least it's entity primary key value to + * discriminate between the entities of the same type in the search results displayed in the UI + * search bar results + */ + + if (!queryTermsMatchedSearchTags) { + + if (primaryKeyValue != null && primaryKeyConjunctionValue != null) { + searchTagsBuilder.append(" " + primaryKeyConjunctionValue + " " + primaryKeyValue); + } else { + LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, "See error", + "Could not annotate user query terms " + queryStr + + " from available entity search tags = " + searchTags); + return searchTags; + } + + } + + return searchTagsBuilder.toString(); + + } + + /** + * Query terms match search tag. + * + * @param queryTerms the query terms + * @param searchTag the search tag + * @return true, if successful @return. + */ + private boolean queryTermsMatchSearchTag(String[] queryTerms, String searchTag) { + + if (queryTerms == null || queryTerms.length == 0 || searchTag == null) { + return false; + } + + for (String queryTerm : queryTerms) { + if (searchTag.toLowerCase().contains(queryTerm.toLowerCase())) { + return true; + } + } + + return false; + + } + + /** + * Gets the value from node. + * + * @param node the node + * @param fieldName the field name + * @return the value from node + */ + private String getValueFromNode(JsonNode node, String fieldName) { + + if (node == null || fieldName == null) { + return null; + } + + JsonNode valueNode = node.get(fieldName); + + if (valueNode != null) { + return valueNode.asText(); + } + + return null; + + } + + private static final String VIUI_SEARCH_TEMPLATE = + "{ " + "\"results-start\": 0," + "\"results-size\": %d," + "\"queries\": [{" + "\"must\": {" + + "\"match\": {" + "\"field\": \"entityType searchTags crossEntityReferenceValues\"," + + "\"value\": \"%s\"," + "\"operator\": \"and\", " + + "\"analyzer\": \"whitespace_analyzer\"" + "}" + "}" + "}]" + "}"; + + private SuggestionConfig suggestionConfig = null; + + /** + * @param queryStr - space separate query search terms + * @return - query string with stop-words removed + */ + private String stripStopWordsFromQuery(String queryStr) { + + if (queryStr == null) { + return queryStr; + } + + Collection<String> stopWords = suggestionConfig.getStopWords(); + ArrayList<String> queryTerms = + new ArrayList<String>(Arrays.asList(queryStr.toLowerCase().split(" "))); + + queryTerms.removeAll(stopWords); + + return String.join(" ", queryTerms); + } + +} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/services/SearchServiceWrapper.java b/src/main/java/org/onap/aai/sparky/viewandinspect/services/SearchServiceWrapper.java deleted file mode 100644 index ebce18e..0000000 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/services/SearchServiceWrapper.java +++ /dev/null @@ -1,980 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.viewandinspect.services; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONException; -import org.json.JSONObject; -import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.elasticsearch.HashQueryResponse; -import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.sas.config.SearchServiceConfig; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.search.VnfSearchService; -import org.onap.aai.sparky.search.config.SuggestionConfig; -import org.onap.aai.sparky.suggestivesearch.SuggestionEntity; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.sparky.viewandinspect.entity.QuerySearchEntity; -import org.onap.aai.sparky.viewandinspect.entity.SearchResponse; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; - -/** - * The Class SearchServlet. - */ - -public class SearchServiceWrapper { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(SearchServiceWrapper.class); - - private SearchServiceConfig sasConfig = null; - private SuggestionConfig suggestionConfig = null; - private SearchAdapter search = null; - private ObjectMapper mapper; - private OxmModelLoader oxmModelLoader; - private VnfSearchService vnfSearch = null; - - private static final String SEARCH_STRING = "search"; - private static final String COUNT_STRING = "count"; - private static final String QUERY_SEARCH = SEARCH_STRING + "/querysearch"; - private static final String SUMMARY_BY_ENTITY_TYPE_API = SEARCH_STRING + "/summarybyentitytype"; - private static final String SUMMARY_BY_ENTITY_TYPE_COUNT_API = - SUMMARY_BY_ENTITY_TYPE_API + "/" + COUNT_STRING; - - private static final String VALUE_ANYKEY = "anyKey"; - private static final String VALUE_QUERY = "query"; - - private static final String KEY_HASH_ID = "hashId"; - private static final String KEY_GROUP_BY = "groupby"; - private static final String KEY_SEARCH_RESULT = "searchResult"; - private static final String KEY_HITS = "hits"; - private static final String KEY_PAYLOAD = "payload"; - private static final String KEY_DOCUMENT = "document"; - private static final String KEY_CONTENT = "content"; - private static final String KEY_SEARCH_TAG_IDS = "searchTagIDs"; - private static final String KEY_SEARCH_TAGS = "searchTags"; - private static final String KEY_LINK = "link"; - private static final String KEY_ENTITY_TYPE = "entityType"; - - private static final String VI_SUGGESTION_ROUTE = "viewInspect"; // TODO -> Read route from - // suggestive-search.properties - // instead of hard coding - - private static final String VIUI_SEARCH_TEMPLATE = - "{ " + "\"results-start\": 0," + "\"results-size\": %d," + "\"queries\": [{" + "\"must\": {" - + "\"match\": {" + "\"field\": \"entityType searchTags crossEntityReferenceValues\"," - + "\"value\": \"%s\"," + "\"operator\": \"and\", " - + "\"analyzer\": \"whitespace_analyzer\"" + "}" + "}" + "}]" + "}"; - - /** - * Instantiates a new search service wrapper - */ - public SearchServiceWrapper() { - this.mapper = new ObjectMapper(); - vnfSearch = new VnfSearchService(); - - try { - if (sasConfig == null) { - sasConfig = SearchServiceConfig.getConfig(); - } - - if (suggestionConfig == null) { - suggestionConfig = SuggestionConfig.getConfig(); - } - - if (search == null) { - search = new SearchAdapter(); - } - - if (oxmModelLoader == null) { - oxmModelLoader = OxmModelLoader.getInstance(); - - if (OxmModelLoader.getInstance().getSearchableEntityDescriptors().isEmpty()) { - LOG.error(AaiUiMsgs.ENTITY_NOT_FOUND_IN_OXM, "searchable entity"); - } - } - } catch (Exception exc) { - new ServletException( - "Caught an exception while getting an instance of servlet configuration from SearchServlet.", - exc); - } - } - - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doPost(request, response); - } - - public void setSasConfig(SearchServiceConfig sasConfig) { - this.sasConfig = sasConfig; - } - - public SearchServiceConfig getSasConfig() { - return sasConfig; - } - - public void setSuggestionConfig(SuggestionConfig suggestionConfig) { - this.suggestionConfig = suggestionConfig; - } - - public void setSearch(SearchAdapter search) { - this.search = search; - } - - public SuggestionConfig getSuggestionConfig() { - return suggestionConfig; - } - - public SearchAdapter getSearch() { - return search; - } - - public void setOxmModelLoader(OxmModelLoader oxmModelLoader) { - this.oxmModelLoader = oxmModelLoader; - } - - public OxmModelLoader getOxmModelLoader() { - return oxmModelLoader; - } - - public VnfSearchService getVnfSearch() { - return vnfSearch; - } - - public void setVnfSearch(VnfSearchService vnfSearch) { - this.vnfSearch = vnfSearch; - } - - /** - * Get Full URL for search - * - * @param api the api - * @param indexName - * @return the full url - */ - private String getSasFullUrl(String indexName, String type, String ipAddress, String port, - String version) { - - return String.format("https://%s:%s/services/search-data-service/%s/search/indexes/%s/%s", - ipAddress, port, version, indexName, type); - } - - /** - * Handle search service do query. - * - * @param app the app - * @param request the request - * @param response the response - * @throws Exception the exception - */ - - protected JSONObject getRequestParamsFromHeader(HttpServletRequest request) { - StringBuffer br = new StringBuffer(); - String line = null; - try { - BufferedReader reader = request.getReader(); - while ((line = reader.readLine()) != null) { - br.append(line); - } - } catch (Exception exc) { - LOG.error(AaiUiMsgs.ERROR_READING_HTTP_REQ_PARAMS); - } - - String output = br.toString(); - - return new JSONObject(output); - } - - protected void handleSummaryByEntityTypeCount(HttpServletRequest request, - HttpServletResponse response) throws Exception { - JSONObject parameters = getRequestParamsFromHeader(request); - String hashId = null; - if (parameters.has(KEY_HASH_ID)) { - hashId = parameters.get(KEY_HASH_ID).toString(); - } else { - vnfSearch.setZeroCountResponse(response); - LOG.error(AaiUiMsgs.ERROR_HASH_NOT_FOUND); - return; - } - HashQueryResponse hashQueryResponse = getResponseForQueryByHash(hashId, response); - Map<String, String> hashQueryResponsePayloadParams = new HashMap<String, String>(); - if (hashQueryResponse.getJsonPayload() != null) { - hashQueryResponsePayloadParams = getPayloadParams(hashQueryResponse.getJsonPayload()); - vnfSearch.getEntityCountResults(response, hashQueryResponsePayloadParams); - } else { - vnfSearch.setZeroCountResponse(response); - LOG.error(AaiUiMsgs.ERROR_INVALID_HASH, hashId); - } - } - - protected Map<String, String> getPayloadParams(String parameters) { - Map<String, String> payloadParams = new HashMap<String, String>(); - try { - JSONObject json = new JSONObject(parameters); - JSONObject payload = json.getJSONObject(KEY_PAYLOAD); - if (payload.length() > 0) { - for (String key : JSONObject.getNames(payload)) { - payloadParams.put(key, payload.getString(key)); - } - } - } catch (JSONException exc) { - LOG.error(AaiUiMsgs.ERROR_PARSING_PARAMS, exc); - } - return payloadParams; - } - - protected HashQueryResponse getResponseForQueryByHash(String hashId, - HttpServletResponse response) { - return vnfSearch.getJSONPayloadFromHash(hashId); - } - - protected void handleSummaryByEntityType(HttpServletRequest request, HttpServletResponse response) - throws Exception { - JSONObject parameters = getRequestParamsFromHeader(request); - String hashId = null; - if (parameters.has(KEY_HASH_ID)) { - hashId = parameters.get(KEY_HASH_ID).toString(); - } else { - vnfSearch.setZeroCountResponse(response); - LOG.error(AaiUiMsgs.ERROR_HASH_NOT_FOUND); - return; - } - HashQueryResponse hashQueryResponse = getResponseForQueryByHash(hashId, response); - Map<String, String> hashQueryResponsePayloadParams = new HashMap<String, String>(); - if (hashQueryResponse.getJsonPayload() != null) { - hashQueryResponsePayloadParams = getPayloadParams(hashQueryResponse.getJsonPayload()); - if (parameters.has(KEY_GROUP_BY)) { - String groupByKey = parameters.getString(KEY_GROUP_BY); - vnfSearch.getSummaryByEntityType(response, hashQueryResponsePayloadParams, groupByKey); - } - } else { - LOG.error(AaiUiMsgs.ERROR_INVALID_HASH, hashId); - vnfSearch.setEmptyAggResponse(response); - } - } - - /** - * Gets the value from node. - * - * @param node the node - * @param fieldName the field name - * @return the value from node - */ - private String getValueFromNode(JsonNode node, String fieldName) { - - if (node == null || fieldName == null) { - return null; - } - - JsonNode valueNode = node.get(fieldName); - - if (valueNode != null) { - return valueNode.asText(); - } - - return null; - - } - - /** - * Builds the search response. - * - * @param operationResult the operation result - * @param queryStr the query str - * @return TODO - * @return the search response - */ - private List<SuggestionEntity> generateSuggestionsForSearchResponse(String operationResult, - String queryStr) { - - - if (operationResult == null || operationResult.length() == 0) { - return null; - } - - ObjectMapper mapper = new ObjectMapper(); - JsonNode rootNode = null; - List<SuggestionEntity> suggestionEntityList = new ArrayList<SuggestionEntity>(); - try { - rootNode = mapper.readTree(operationResult); - - JsonNode hitsNode = rootNode.get(KEY_SEARCH_RESULT); - - - // Check if there are hits that are coming back - if (hitsNode.has(KEY_HITS)) { - ArrayNode hitsArray = (ArrayNode) hitsNode.get(KEY_HITS); - - /* - * next we iterate over the values in the hit array elements - */ - - Iterator<JsonNode> nodeIterator = hitsArray.elements(); - JsonNode entityNode = null; - SuggestionEntity suggestionEntity = null; - JsonNode sourceNode = null; - while (nodeIterator.hasNext()) { - entityNode = nodeIterator.next(); - sourceNode = entityNode.get(KEY_DOCUMENT).get(KEY_CONTENT); - - // do the point transformation as we build the response? - suggestionEntity = new SuggestionEntity(); - suggestionEntity.setRoute(VI_SUGGESTION_ROUTE); - - /* - * This is where we probably want to annotate the search tags because we also have access - * to the seachTagIds - */ - - String searchTagIds = getValueFromNode(sourceNode, KEY_SEARCH_TAG_IDS); - String searchTags = getValueFromNode(sourceNode, KEY_SEARCH_TAGS); - String link = getValueFromNode(sourceNode, KEY_LINK); - String entityType = getValueFromNode(sourceNode, KEY_ENTITY_TYPE); - if (link != null) { - suggestionEntity.setHashId(NodeUtils.generateUniqueShaDigest(link)); - } - - try { - suggestionEntity - .setText(annotateSearchTags(searchTags, searchTagIds, entityType, queryStr)); - } catch (Exception exc) { - LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), - exc.getLocalizedMessage()); - // at least send back the un-annotated search tags - suggestionEntity.setText(searchTags); - } - - if (searchTags != null) { - suggestionEntityList.add(suggestionEntity); - } - - } - } - } catch (IOException exc) { - LOG.warn(AaiUiMsgs.SEARCH_RESPONSE_BUILDING_EXCEPTION, exc.getLocalizedMessage()); - } - return suggestionEntityList; - } - - /* - */ - - /** - * Query terms match search tag. - * - * @param queryTerms the query terms - * @param searchTag the search tag - * @return true, if successful @return. - */ - private boolean queryTermsMatchSearchTag(String[] queryTerms, String searchTag) { - - if (queryTerms == null || queryTerms.length == 0 || searchTag == null) { - return false; - } - - for (String queryTerm : queryTerms) { - if (searchTag.toLowerCase().contains(queryTerm.toLowerCase())) { - return true; - } - } - - return false; - - } - - /** - * The current format of an UI-dropdown-item is like: "search-terms entityType att1=attr1_val". - * Example, for pserver: search-terms pserver hostname=djmAG-72060, - * pserver-name2=example-pserver-name2-val-17254, pserver-id=example-pserver-id-val-17254, - * ipv4-oam-address=example-ipv4-oam-address-val-17254 SearchController.js parses the above - * format. So if you are modifying the parsing below, please update SearchController.js as well. - * - * @param searchTags the search tags - * @param searchTagIds the search tag ids - * @param entityType the entity type - * @param queryStr the query str - * @return the string - */ - - private String annotateSearchTags(String searchTags, String searchTagIds, String entityType, - String queryStr) { - - if (searchTags == null || searchTagIds == null) { - String valueOfSearchTags = String.valueOf(searchTags); - String valueOfSearchTagIds = String.valueOf(searchTagIds); - - LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, "See error", - "Search tags = " + valueOfSearchTags + " and Seach tag IDs = " + valueOfSearchTagIds); - return searchTags; - } - - if (entityType == null) { - LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), "EntityType is null"); - return searchTags; - } - - if (queryStr == null) { - LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, searchTags.toString(), - "Query string is null"); - return searchTags; - } - - /* - * The ElasticSearch analyzer has already applied the lowercase filter, so we don't have to - * covert them again - */ - String[] searchTagsArray = searchTags.split(";"); - String[] searchTagIdsArray = searchTagIds.split(";"); - - // specifically apply lower case to the the query terms to make matching - // simpler - String[] queryTerms = queryStr.toLowerCase().split(" "); - - OxmEntityDescriptor desc = oxmModelLoader.getSearchableEntityDescriptors().get(entityType); - - if (desc == null) { - LOG.error(AaiUiMsgs.ENTITY_NOT_FOUND_IN_OXM, entityType.toString()); - return searchTags; - } - - String primaryKeyName = NodeUtils.concatArray(desc.getPrimaryKeyAttributeName(), "/"); - String primaryKeyValue = null; - - /* - * For each used attribute, get the fieldName for the attribute index and transform the search - * tag into t1,t2,t3 => h1=t1, h2=t2, h3=t3; - */ - StringBuilder searchTagsBuilder = new StringBuilder(128); - searchTagsBuilder.append(entityType); - - String primaryKeyConjunctionValue = null; - boolean queryTermsMatchedSearchTags = false; - - if (searchTagsArray.length == searchTagIdsArray.length) { - for (int i = 0; i < searchTagsArray.length; i++) { - String searchTagAttributeId = searchTagIdsArray[i]; - String searchTagAttributeValue = searchTagsArray[i]; - - // Find the concat conjunction - Map<String, String> pairConjunctionList = suggestionConfig.getPairingList(); - - String suggConjunction = null; - if (pairConjunctionList.get(searchTagAttributeId) != null) { - suggConjunction = pairConjunctionList.get(searchTagAttributeId); - } else { - suggConjunction = suggestionConfig.getDefaultPairingValue(); - } - - if (primaryKeyName.equals(searchTagAttributeId)) { - primaryKeyValue = searchTagAttributeValue; - primaryKeyConjunctionValue = suggConjunction; - } - - if (queryTermsMatchSearchTag(queryTerms, searchTagAttributeValue)) { - searchTagsBuilder.append(" " + suggConjunction + " " + searchTagAttributeValue); - queryTermsMatchedSearchTags = true; - } - } - } else { - String errorMessage = - "Search tags length did not match search tag ID length for entity type " + entityType; - LOG.error(AaiUiMsgs.ENTITY_SYNC_SEARCH_TAG_ANNOTATION_FAILED, errorMessage); - } - - /* - * if none of the user query terms matched the index entity search tags then we should still tag - * the matched entity with a conjunction set to at least it's entity primary key value to - * discriminate between the entities of the same type in the search results displayed in the UI - * search bar results - */ - - if (!queryTermsMatchedSearchTags) { - - if (primaryKeyValue != null && primaryKeyConjunctionValue != null) { - searchTagsBuilder.append(" " + primaryKeyConjunctionValue + " " + primaryKeyValue); - } else { - LOG.error(AaiUiMsgs.SEARCH_TAG_ANNOTATION_ERROR, "See error", - "Could not annotate user query terms " + queryStr - + " from available entity search tags = " + searchTags); - return searchTags; - } - - } - - return searchTagsBuilder.toString(); - - } - - - /** - * @param queryStr - space separate query search terms - * @return - query string with stop-words removed - */ - private String stripStopWordsFromQuery(String queryStr) { - - if (queryStr == null) { - return queryStr; - } - - Collection<String> stopWords = suggestionConfig.getStopWords(); - ArrayList<String> queryTerms = - new ArrayList<String>(Arrays.asList(queryStr.toLowerCase().split(" "))); - - queryTerms.removeAll(stopWords); - - return String.join(" ", queryTerms); - } - - /* - * Expected query: - * - * POST /search/viuiSearch/ - * - * { "maxResults" : "10", "searchStr" : "<search bar text>" } - */ - - /** - * Handle view and inspect search. - * - * @param request the request - * @param maxResults Max number of results to return - * @param response the response - * @return - * @throws IOException Signals that an I/O exception has occurred. - */ - protected List<SuggestionEntity> performViewAndInspectQuerySearch( - QuerySearchEntity querySearchEntity, int maxResults) throws IOException { - List<SuggestionEntity> suggestionEntityList = new ArrayList<SuggestionEntity>(); - - /* - * Based on the configured stop words, we need to strip any matched stop-words ( case - * insensitively ) from the query string, before hitting elastic to prevent the words from being - * used against the elastic view-and-inspect index. Another alternative to this approach would - * be to define stop words on the elastic search index configuration for the - * entity-search-index, but but that may be more complicated / more risky than just a simple bug - * fix, but it's something we should think about for the future. - */ - - try { - final String queryStringWithoutStopWords = - stripStopWordsFromQuery(querySearchEntity.getQueryStr()); - - final String fullUrlStr = getSasFullUrl(sasConfig.getIndexName(), VALUE_QUERY, - sasConfig.getIpAddress(), sasConfig.getHttpPort(), sasConfig.getVersion()); - - String postBody = - String.format(VIUI_SEARCH_TEMPLATE, maxResults, queryStringWithoutStopWords); - - OperationResult opResult = search.doPost(fullUrlStr, postBody, "application/json"); - if (opResult.getResultCode() == 200) { - suggestionEntityList = generateSuggestionsForSearchResponse(opResult.getResult(), - querySearchEntity.getQueryStr()); - } - } catch (Exception exc) { - LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, - "View and inspect query failed with error = " + exc.getMessage()); - } - return suggestionEntityList; - } - - protected List<SuggestionEntity> performVnfQuerySearch(QuerySearchEntity querySearchEntity, - int resultCountLimit) throws Exception { - return vnfSearch.getSuggestionsResults(querySearchEntity, resultCountLimit); - } - - protected void handleQuerySearch(HttpServletRequest request, HttpServletResponse response) - throws IOException { - String payload = NodeUtils.getBody(request); - if (payload == null || payload.isEmpty()) { - handleSearchServletErrors("Unable to parse payload", null, response); - } else { - QuerySearchEntity querySearchEntity = mapper.readValue(payload, QuerySearchEntity.class); - int maxResultsPerSearch = Integer.valueOf(querySearchEntity.getMaxResults()); - try { - SearchResponse searchResponse = new SearchResponse(); - List<SuggestionEntity> viewAndInspectsuggestionEntityList = - new ArrayList<SuggestionEntity>(); - List<SuggestionEntity> vnfSuggestionEntityList = new ArrayList<SuggestionEntity>(); - long processTime = System.currentTimeMillis(); - for (String searchService : suggestionConfig.getSearchIndexToSearchService().values()) { - if (searchService.equals(SearchServiceWrapper.class.getSimpleName())) { - viewAndInspectsuggestionEntityList = - performViewAndInspectQuerySearch(querySearchEntity, maxResultsPerSearch); - } else if (searchService.equals(VnfSearchService.class.getSimpleName())) { - vnfSuggestionEntityList = performVnfQuerySearch(querySearchEntity, maxResultsPerSearch); - } - } - - int totalAdded = 0; - for (int i = 0; i < maxResultsPerSearch; i++) { - if (i < viewAndInspectsuggestionEntityList.size() && totalAdded < maxResultsPerSearch) { - searchResponse.addSuggestion(viewAndInspectsuggestionEntityList.get(i)); - totalAdded++; - } - if (i < vnfSuggestionEntityList.size() && totalAdded < maxResultsPerSearch) { - searchResponse.addSuggestion(vnfSuggestionEntityList.get(i)); - totalAdded++; - } - if (totalAdded >= maxResultsPerSearch) { - break; - } - } - searchResponse.addToTotalFound(totalAdded); - String searchResponseJson = NodeUtils.convertObjectToJson(searchResponse, true); - - processTime = System.currentTimeMillis() - processTime; - searchResponse.setProcessingTimeInMs(processTime); - setServletResponse(response, searchResponseJson); - } catch (Exception exc) { - LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, - "Query search failed with error = " + exc.getMessage()); - } - } - } - - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - String api = null; - try { - - // set default response - response.setStatus(200); - - if (request.getRequestURI().contains(QUERY_SEARCH)) { - api = QUERY_SEARCH; - handleQuerySearch(request, response); - return; - } else if (request.getRequestURI().contains(SUMMARY_BY_ENTITY_TYPE_COUNT_API)) { - api = SUMMARY_BY_ENTITY_TYPE_COUNT_API; - handleSummaryByEntityTypeCount(request, response); - return; - } else if (request.getRequestURI().contains(SUMMARY_BY_ENTITY_TYPE_API)) { - api = SUMMARY_BY_ENTITY_TYPE_API; - handleSummaryByEntityType(request, response); - return; - } else { - - final String errorMessage = "Ignored request-uri = " + request.getRequestURI(); - LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, errorMessage); - response.setStatus(404); - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.println(generateJsonErrorResponse(errorMessage)); - out.close(); - - - } - } catch (JSONException je) { - handleSearchServletErrors("Caught an exception while parsing json in processing for " + api, - je, response); - } catch (Exception e1) { - handleSearchServletErrors("Caught an exception while communicating with elasticsearch", e1, - response); - } - } - - /** - * Generate json error response. - * - * @param message the message - * @return the string - */ - /* - * This is the manual approach, however we could also create an object container for the error - * then use the Jackson ObjectWrite to dump the object to json instead. If it gets any more - * complicated we could do that approach so we don't have to manually trip over the JSON - * formatting. - */ - protected String generateJsonErrorResponse(String message) { - return String.format("{ \"errorMessage\" : %s }", message); - } - - /** - * Handle search servlet errors. - * - * @param errorMsg the error msg - * @param exc the exc - * @param response the response - * @throws IOException Signals that an I/O exception has occurred. - */ - public void handleSearchServletErrors(String errorMsg, Exception exc, - HttpServletResponse response) throws IOException { - - String errorLogMsg = - (exc == null ? errorMsg : errorMsg + ". Error:" + exc.getLocalizedMessage()); - - LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, errorLogMsg); - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.println(generateJsonErrorResponse(errorMsg)); - out.close(); - } - - - /** - * Execute query. - * - * @param response the response - * @param requestUrl the request url - * @param requestJsonPayload the request json payload - * @throws Exception the exception - */ - public void executeQuery(HttpServletResponse response, String requestUrl, - String requestJsonPayload) throws Exception { - - OperationResult opResult = search.doPost(requestUrl, requestJsonPayload, "application/json"); - - if (opResult != null) { - - response.setStatus(opResult.getResultCode()); - String finalOutput = opResult.getResult(); - - // example: failed to populate drop-down items from formatOutputJson() - if (finalOutput != null) { - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.println(finalOutput); - out.close(); - } - - } else { - response.setStatus(500); - } - - } - - /** - * Sets the servlet response. - * - * @param response the response - * @param postPayload the post payload - * - * @throws IOException Signals that an I/O exception has occurred. - */ - private void setServletResponse(HttpServletResponse response, String postPayload) - throws IOException { - - if (postPayload != null) { - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.println(postPayload); - out.close(); - } - } - - /** - * @return the mapper - */ - public ObjectMapper getMapper() { - return mapper; - } - - /** - * @param mapper the mapper to set - */ - public void setMapper(ObjectMapper mapper) { - this.mapper = mapper; - } - - /** - * @return the serialversionuid - */ - public static long getSerialversionuid() { - return serialVersionUID; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @return the searchString - */ - public static String getSearchString() { - return SEARCH_STRING; - } - - /** - * @return the countString - */ - public static String getCountString() { - return COUNT_STRING; - } - - /** - * @return the querySearch - */ - public static String getQuerySearch() { - return QUERY_SEARCH; - } - - /** - * @return the summaryByEntityTypeApi - */ - public static String getSummaryByEntityTypeApi() { - return SUMMARY_BY_ENTITY_TYPE_API; - } - - /** - * @return the summaryByEntityTypeCountApi - */ - public static String getSummaryByEntityTypeCountApi() { - return SUMMARY_BY_ENTITY_TYPE_COUNT_API; - } - - /** - * @return the valueAnykey - */ - public static String getValueAnykey() { - return VALUE_ANYKEY; - } - - /** - * @return the valueQuery - */ - public static String getValueQuery() { - return VALUE_QUERY; - } - - /** - * @return the keyHashId - */ - public static String getKeyHashId() { - return KEY_HASH_ID; - } - - /** - * @return the keyGroupBy - */ - public static String getKeyGroupBy() { - return KEY_GROUP_BY; - } - - /** - * @return the keySearchResult - */ - public static String getKeySearchResult() { - return KEY_SEARCH_RESULT; - } - - /** - * @return the keyHits - */ - public static String getKeyHits() { - return KEY_HITS; - } - - /** - * @return the keyPayload - */ - public static String getKeyPayload() { - return KEY_PAYLOAD; - } - - /** - * @return the keyDocument - */ - public static String getKeyDocument() { - return KEY_DOCUMENT; - } - - /** - * @return the keyContent - */ - public static String getKeyContent() { - return KEY_CONTENT; - } - - /** - * @return the keySearchTagIds - */ - public static String getKeySearchTagIds() { - return KEY_SEARCH_TAG_IDS; - } - - /** - * @return the keySearchTags - */ - public static String getKeySearchTags() { - return KEY_SEARCH_TAGS; - } - - /** - * @return the keyLink - */ - public static String getKeyLink() { - return KEY_LINK; - } - - /** - * @return the keyEntityType - */ - public static String getKeyEntityType() { - return KEY_ENTITY_TYPE; - } - - /** - * @return the viSuggestionRoute - */ - public static String getViSuggestionRoute() { - return VI_SUGGESTION_ROUTE; - } - - /** - * @return the viuiSearchTemplate - */ - public static String getViuiSearchTemplate() { - return VIUI_SEARCH_TEMPLATE; - } - - - -} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationContext.java b/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationContext.java index e3f469f..b2ed4a4 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationContext.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationContext.java @@ -36,16 +36,19 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; import org.apache.http.client.utils.URIBuilder; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.entity.SearchableEntity; +import org.onap.aai.sparky.sync.entity.SearchableEntity; import org.onap.aai.sparky.util.NodeUtils; import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants; -import org.onap.aai.sparky.viewandinspect.config.VisualizationConfig; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; import org.onap.aai.sparky.viewandinspect.entity.ActiveInventoryNode; import org.onap.aai.sparky.viewandinspect.entity.InlineMessage; import org.onap.aai.sparky.viewandinspect.entity.NodeProcessingTransaction; @@ -58,8 +61,6 @@ import org.onap.aai.sparky.viewandinspect.enumeration.NodeProcessingAction; import org.onap.aai.sparky.viewandinspect.enumeration.NodeProcessingState; import org.onap.aai.sparky.viewandinspect.task.PerformNodeSelfLinkProcessingTask; import org.onap.aai.sparky.viewandinspect.task.PerformSelfLinkDeterminationTask; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.JsonNode; @@ -78,17 +79,18 @@ public class VisualizationContext { private static final Logger LOG = LoggerFactory.getInstance().getLogger(VisualizationContext.class); - private final ActiveInventoryDataProvider aaiProvider; + private final ActiveInventoryAdapter aaiAdapter; private int maxSelfLinkTraversalDepth; private AtomicInteger numLinksDiscovered; private AtomicInteger numSuccessfulLinkResolveFromCache; private AtomicInteger numSuccessfulLinkResolveFromFromServer; private AtomicInteger numFailedLinkResolve; + private AtomicInteger nodeIntegrityWorkOnHand; private AtomicInteger aaiWorkOnHand; private ActiveInventoryConfig aaiConfig; - private VisualizationConfig visualizationConfig; + private VisualizationConfigs visualizationConfigs; private List<String> shallowEntities; private AtomicInteger totalLinksRetrieved; @@ -100,6 +102,7 @@ public class VisualizationContext { private ObjectMapper mapper; private InlineMessage inlineMessage = null; + private ExecutorService tabularExecutorService; private ExecutorService aaiExecutorService; /* @@ -115,14 +118,16 @@ public class VisualizationContext { * @param loader the loader * @throws Exception the exception */ - public VisualizationContext(long contextId, ActiveInventoryDataProvider aaiDataProvider, - ExecutorService aaiExecutorService, OxmModelLoader loader) throws Exception { + public VisualizationContext(long contextId, ActiveInventoryAdapter aaiAdapter, + ExecutorService tabularExecutorService, ExecutorService aaiExecutorService, + VisualizationConfigs visualizationConfigs) throws Exception { this.contextId = contextId; this.contextIdStr = "[Context-Id=" + contextId + "]"; - this.aaiProvider = aaiDataProvider; + this.aaiAdapter = aaiAdapter; + this.tabularExecutorService = tabularExecutorService; this.aaiExecutorService = aaiExecutorService; - this.loader = loader; + this.visualizationConfigs = visualizationConfigs; this.nodeCache = new ConcurrentHashMap<String, ActiveInventoryNode>(); this.numLinksDiscovered = new AtomicInteger(0); @@ -130,13 +135,13 @@ public class VisualizationContext { this.numSuccessfulLinkResolveFromCache = new AtomicInteger(0); this.numSuccessfulLinkResolveFromFromServer = new AtomicInteger(0); this.numFailedLinkResolve = new AtomicInteger(0); + this.nodeIntegrityWorkOnHand = new AtomicInteger(0); this.aaiWorkOnHand = new AtomicInteger(0); this.aaiConfig = ActiveInventoryConfig.getConfig(); - this.visualizationConfig = VisualizationConfig.getConfig(); this.shallowEntities = aaiConfig.getAaiRestConfig().getShallowEntities(); - this.maxSelfLinkTraversalDepth = visualizationConfig.getMaxSelfLinkTraversalDepth(); + this.maxSelfLinkTraversalDepth = this.visualizationConfigs.getMaxSelfLinkTraversalDepth(); this.mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_EMPTY); @@ -164,7 +169,8 @@ public class VisualizationContext { return queryParams; } - Map<String, OxmEntityDescriptor> entityDescriptors = loader.getEntityDescriptors(); + Map<String, OxmEntityDescriptor> entityDescriptors = + OxmEntityLookup.getInstance().getEntityDescriptors(); try { @@ -183,7 +189,7 @@ public class VisualizationContext { if (descriptor != null) { entityType = urlPathElements[index]; - primaryKeyNames = descriptor.getPrimaryKeyAttributeName(); + primaryKeyNames = descriptor.getPrimaryKeyAttributeNames(); /* * Make sure from what ever index we matched the parent entity-type on that we can extract @@ -270,7 +276,7 @@ public class VisualizationContext { * */ - ActiveInventoryNode newNode = new ActiveInventoryNode(); + ActiveInventoryNode newNode = new ActiveInventoryNode(this.visualizationConfigs); newNode.setEntityType(entityType); /* @@ -337,7 +343,7 @@ public class VisualizationContext { */ String selfLinkQuery = - aaiProvider.getGenericQueryForSelfLink(entityType, newNode.getQueryParams()); + aaiAdapter.getGenericQueryForSelfLink(entityType, newNode.getQueryParams()); /** * <li>get the self-link @@ -355,7 +361,7 @@ public class VisualizationContext { txn.setNewNode(newNode); txn.setParentNodeId(ain.getNodeId()); aaiWorkOnHand.incrementAndGet(); - supplyAsync(new PerformSelfLinkDeterminationTask(txn, null, aaiProvider), + supplyAsync(new PerformSelfLinkDeterminationTask(txn, null, aaiAdapter), aaiExecutorService).whenComplete((nodeTxn, error) -> { aaiWorkOnHand.decrementAndGet(); if (error != null) { @@ -368,15 +374,13 @@ public class VisualizationContext { if (opResult != null && opResult.wasSuccessful()) { - if (opResult.isResolvedLinkFailure()) { + if (!opResult.wasSuccessful()) { numFailedLinkResolve.incrementAndGet(); } - if (opResult.isResolvedLinkFromCache()) { + if (opResult.isFromCache()) { numSuccessfulLinkResolveFromCache.incrementAndGet(); - } - - if (opResult.isResolvedLinkFromServer()) { + } else { numSuccessfulLinkResolveFromFromServer.incrementAndGet(); } @@ -425,7 +429,6 @@ public class VisualizationContext { newChildNode.setSelfLinkPendingResolve(false); newChildNode.setSelfLinkProcessed(true); - newChildNode.changeState(NodeProcessingState.NEIGHBORS_UNPROCESSED, NodeProcessingAction.SELF_LINK_RESPONSE_PARSE_OK); @@ -542,7 +545,7 @@ public class VisualizationContext { if (nodeValue != null && nodeValue.isValueNode()) { - if (loader.getEntityDescriptor(fieldName) == null) { + if (OxmEntityLookup.getInstance().getEntityDescriptors().get(fieldName) == null) { /* * entity property name is not an entity, thus we can add this property name and value @@ -557,7 +560,7 @@ public class VisualizationContext { if (nodeValue.isArray()) { - if (loader.getEntityDescriptor(fieldName) == null) { + if (OxmEntityLookup.getInstance().getEntityDescriptors().get(fieldName) == null) { /* * entity property name is not an entity, thus we can add this property name and value @@ -623,10 +626,10 @@ public class VisualizationContext { */ ain.clearQueryParams(); ain.addQueryParams(extractQueryParamsFromSelfLink(ain.getSelfLink())); - ain.changeState(NodeProcessingState.NEIGHBORS_UNPROCESSED, NodeProcessingAction.SELF_LINK_RESPONSE_PARSE_OK); + } /** @@ -678,7 +681,7 @@ public class VisualizationContext { txn.setProcessingNode(ain); txn.setRequestParameters(depthModifier); aaiWorkOnHand.incrementAndGet(); - supplyAsync(new PerformNodeSelfLinkProcessingTask(txn, depthModifier, aaiProvider, aaiConfig), + supplyAsync(new PerformNodeSelfLinkProcessingTask(txn, depthModifier, aaiAdapter, aaiConfig), aaiExecutorService).whenComplete((nodeTxn, error) -> { aaiWorkOnHand.decrementAndGet(); if (error != null) { @@ -703,15 +706,13 @@ public class VisualizationContext { if (opResult != null && opResult.wasSuccessful()) { - if (opResult.isResolvedLinkFailure()) { + if (!opResult.wasSuccessful()) { numFailedLinkResolve.incrementAndGet(); } - if (opResult.isResolvedLinkFromCache()) { + if (opResult.isFromCache()) { numSuccessfulLinkResolveFromCache.incrementAndGet(); - } - - if (opResult.isResolvedLinkFromServer()) { + } else { numSuccessfulLinkResolveFromFromServer.incrementAndGet(); } @@ -871,7 +872,7 @@ public class VisualizationContext { * around the root node. */ - if (!rootNodeDiscovered || cacheNode.getNodeDepth() < VisualizationConfig.getConfig() + if (!rootNodeDiscovered || cacheNode.getNodeDepth() < this.visualizationConfigs .getMaxSelfLinkTraversalDepth()) { if (LOG.isDebugEnabled()) { @@ -959,7 +960,7 @@ public class VisualizationContext { LOG.debug(AaiUiMsgs.DEBUG_GENERIC, "Unexpected array type with a key = " + fieldName); } } else if (fieldValue.isValueNode()) { - if (loader.getEntityDescriptor(field.getKey()) == null) { + if (OxmEntityLookup.getInstance().getEntityDescriptors().get(field.getKey()) == null) { /* * property key is not an entity type, add it to our property set. */ @@ -1101,8 +1102,8 @@ public class VisualizationContext { return false; } - List<String> pkeyNames = - loader.getEntityDescriptor(ain.getEntityType()).getPrimaryKeyAttributeName(); + List<String> pkeyNames = OxmEntityLookup.getInstance().getEntityDescriptors() + .get(ain.getEntityType()).getPrimaryKeyAttributeNames(); if (pkeyNames == null || pkeyNames.size() == 0) { LOG.error(AaiUiMsgs.FAILED_TO_DETERMINE_NODE_ID, "Primary key names is empty"); @@ -1179,10 +1180,9 @@ public class VisualizationContext { return false; } - OxmModelLoader modelLoader = OxmModelLoader.getInstance(); - Relationship[] relationshipArray = relationshipList.getRelationshipList(); OxmEntityDescriptor descriptor = null; + String repairedSelfLink = null; if (relationshipArray != null) { @@ -1203,7 +1203,7 @@ public class VisualizationContext { return false; } - newNode = new ActiveInventoryNode(); + newNode = new ActiveInventoryNode(this.visualizationConfigs); String entityType = r.getRelatedTo(); @@ -1213,7 +1213,7 @@ public class VisualizationContext { } } - descriptor = modelLoader.getEntityDescriptor(r.getRelatedTo()); + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors().get(r.getRelatedTo()); newNode.setNodeId(nodeId); newNode.setEntityType(entityType); @@ -1223,7 +1223,7 @@ public class VisualizationContext { if (descriptor != null) { - List<String> pkeyNames = descriptor.getPrimaryKeyAttributeName(); + List<String> pkeyNames = descriptor.getPrimaryKeyAttributeNames(); newNode.changeState(NodeProcessingState.SELF_LINK_UNRESOLVED, NodeProcessingAction.SELF_LINK_SET); @@ -1337,7 +1337,7 @@ public class VisualizationContext { return; } - ActiveInventoryNode newNode = new ActiveInventoryNode(); + ActiveInventoryNode newNode = new ActiveInventoryNode(this.visualizationConfigs); newNode.setNodeId(searchTargetEntity.getId()); newNode.setEntityType(searchTargetEntity.getEntityType()); @@ -1399,7 +1399,7 @@ public class VisualizationContext { case NEIGHBORS_UNPROCESSED: { - if (n.getNodeDepth() < VisualizationConfig.getConfig().getMaxSelfLinkTraversalDepth()) { + if (n.getNodeDepth() < this.visualizationConfigs.getMaxSelfLinkTraversalDepth()) { /* * Only process our neighbors relationships if our current depth is less than the max * depth @@ -1528,7 +1528,7 @@ public class VisualizationContext { targetNode.addInboundNeighbor(srcNode.getNodeId()); - if (VisualizationConfig.getConfig().makeAllNeighborsBidirectional()) { + if (this.visualizationConfigs.makeAllNeighborsBidirectional()) { targetNode.addOutboundNeighbor(srcNode.getNodeId()); } @@ -1626,7 +1626,8 @@ public class VisualizationContext { return null; } - OxmEntityDescriptor descriptor = loader.getEntityDescriptor(entityType); + OxmEntityDescriptor descriptor = + OxmEntityLookup.getInstance().getEntityDescriptors().get(entityType); if (descriptor == null) { LOG.error(AaiUiMsgs.FAILED_TO_DETERMINE, @@ -1634,7 +1635,7 @@ public class VisualizationContext { return null; } - List<String> pkeyNames = descriptor.getPrimaryKeyAttributeName(); + List<String> pkeyNames = descriptor.getPrimaryKeyAttributeNames(); if (pkeyNames == null || pkeyNames.size() == 0) { LOG.error(AaiUiMsgs.FAILED_TO_DETERMINE, diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationService.java b/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationService.java index 0a9797f..69ef774 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationService.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationService.java @@ -30,30 +30,24 @@ import java.util.concurrent.ExecutorService; import javax.servlet.ServletException; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.aai.ActiveInventoryAdapter; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryRestConfig; -import org.onap.aai.sparky.dal.cache.EntityCache; -import org.onap.aai.sparky.dal.cache.PersistentEntityCache; -import org.onap.aai.sparky.dal.elasticsearch.ElasticSearchAdapter; -import org.onap.aai.sparky.dal.elasticsearch.ElasticSearchDataProvider; -import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.rest.RestClientBuilder; -import org.onap.aai.sparky.dal.rest.RestfulDataAccessor; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.entity.SearchableEntity; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.entity.SearchableEntity; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.sparky.viewandinspect.config.VisualizationConfig; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; import org.onap.aai.sparky.viewandinspect.entity.ActiveInventoryNode; import org.onap.aai.sparky.viewandinspect.entity.D3VisualizationOutput; import org.onap.aai.sparky.viewandinspect.entity.GraphMeta; import org.onap.aai.sparky.viewandinspect.entity.QueryParams; import org.onap.aai.sparky.viewandinspect.entity.QueryRequest; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; @@ -66,63 +60,50 @@ public class VisualizationService { private static final Logger LOG = LoggerFactory.getInstance().getLogger(VisualizationService.class); - private OxmModelLoader loader; private ObjectMapper mapper = new ObjectMapper(); - private final ActiveInventoryDataProvider aaiProvider; - private final ActiveInventoryRestConfig aaiRestConfig; - private final ElasticSearchDataProvider esProvider; - private final ElasticSearchConfig esConfig; + private final ActiveInventoryAdapter aaiAdapter; + private final ElasticSearchAdapter esAdapter; + private final ExecutorService tabularExecutorService; private final ExecutorService aaiExecutorService; private ConcurrentHashMap<Long, VisualizationContext> contextMap; private final SecureRandom secureRandom; private ActiveInventoryConfig aaiConfig; - private VisualizationConfig visualizationConfig; - - public VisualizationService(OxmModelLoader loader) throws Exception { - this.loader = loader; + private VisualizationConfigs visualizationConfigs; + private ElasticSearchEndpointConfig endpointEConfig; + private ElasticSearchSchemaConfig schemaEConfig; - aaiRestConfig = ActiveInventoryConfig.getConfig().getAaiRestConfig(); + public VisualizationService(OxmModelLoader loader, VisualizationConfigs visualizationConfigs, + ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, + ElasticSearchEndpointConfig endpointConfig, ElasticSearchSchemaConfig schemaConfig) + throws Exception { - EntityCache cache = null; - secureRandom = new SecureRandom(); - - ActiveInventoryAdapter aaiAdapter = new ActiveInventoryAdapter(new RestClientBuilder()); - if (aaiRestConfig.isCacheEnabled()) { - cache = new PersistentEntityCache(aaiRestConfig.getStorageFolderOverride(), - aaiRestConfig.getNumCacheWorkers()); + this.visualizationConfigs = visualizationConfigs; + this.endpointEConfig = endpointConfig; + this.schemaEConfig = schemaConfig; - aaiAdapter.setCacheEnabled(true); - aaiAdapter.setEntityCache(cache); - } + secureRandom = new SecureRandom(); - this.aaiProvider = aaiAdapter; + /* + * Fix constructor with properly wired in properties + */ - RestClientBuilder esClientBuilder = new RestClientBuilder(); - esClientBuilder.setUseHttps(false); - RestfulDataAccessor nonCachingRestProvider = new RestfulDataAccessor(esClientBuilder); - this.esConfig = ElasticSearchConfig.getConfig(); - this.esProvider = new ElasticSearchAdapter(nonCachingRestProvider, this.esConfig); + this.aaiAdapter = aaiAdapter; + this.esAdapter = esAdapter; this.mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.contextMap = new ConcurrentHashMap<Long, VisualizationContext>(); - this.visualizationConfig = VisualizationConfig.getConfig(); + this.tabularExecutorService = NodeUtils.createNamedExecutor("TABULAR-WORKER", + this.visualizationConfigs.getNumOfThreadsToFetchNodeIntegrity(), LOG); this.aaiConfig = ActiveInventoryConfig.getConfig(); this.aaiExecutorService = NodeUtils.createNamedExecutor("SLNC-WORKER", aaiConfig.getAaiRestConfig().getNumResolverWorkers(), LOG); - } - public OxmModelLoader getLoader() { - return loader; - } - - public void setLoader(OxmModelLoader loader) { - this.loader = loader; } /** @@ -222,7 +203,9 @@ public class VisualizationService { * Here is where we need to make a dip to elastic-search for the self-link by entity-id (link * hash). */ - dataCollectionResult = esProvider.retrieveEntityById(queryRequest.getHashId()); + dataCollectionResult = esAdapter.retrieveEntityById(endpointEConfig.getEsIpAddress(), + endpointEConfig.getEsServerPort(), schemaEConfig.getIndexName(), + schemaEConfig.getIndexDocType(), queryRequest.getHashId()); sourceEntity = extractSearchableEntityFromElasticEntity(dataCollectionResult); if (sourceEntity != null) { @@ -243,7 +226,8 @@ public class VisualizationService { try { - d3OutputJsonOutput = getVisualizationOutputBasedonGenericQuery(sourceEntity, queryParams); + d3OutputJsonOutput = + getVisualizationOutputBasedonGenericQuery(sourceEntity, queryParams, queryRequest); if (LOG.isDebugEnabled()) { LOG.debug(AaiUiMsgs.DEBUG_GENERIC, @@ -270,22 +254,22 @@ public class VisualizationService { } + /** * Gets the visualization output basedon generic query. * - * @param searchtargetEntity entity that will be used to start visualization flow - * @param queryParams the query params - * @return the visualization output basedon generic query - * @throws ServletException the servlet exception + * @param searchtargetEntity entity that will be used to start visualization flow @param + * queryParams the query params @return the visualization output basedon generic + * query @throws ServletException the servlet exception @throws */ private String getVisualizationOutputBasedonGenericQuery(SearchableEntity searchtargetEntity, - QueryParams queryParams) throws ServletException { + QueryParams queryParams, QueryRequest request) throws ServletException { long opStartTimeInMs = System.currentTimeMillis(); VisualizationTransformer transformer = null; try { - transformer = new VisualizationTransformer(); + transformer = new VisualizationTransformer(visualizationConfigs); } catch (Exception exc) { throw new ServletException( "Failed to create VisualizationTransformer instance because of execption", exc); @@ -294,7 +278,8 @@ public class VisualizationService { VisualizationContext visContext = null; long contextId = secureRandom.nextLong(); try { - visContext = new VisualizationContext(contextId, aaiProvider, aaiExecutorService, loader); + visContext = new VisualizationContext(contextId, this.aaiAdapter, tabularExecutorService, + aaiExecutorService, this.visualizationConfigs); contextMap.putIfAbsent(contextId, visContext); } catch (Exception e1) { LOG.error(AaiUiMsgs.EXCEPTION_CAUGHT, @@ -349,9 +334,10 @@ public class VisualizationService { try { output = transformer .generateVisualizationOutput((System.currentTimeMillis() - opStartTimeInMs), graphMeta); - } catch (Exception exc) { - LOG.error(AaiUiMsgs.FAILURE_TO_PROCESS_REQUEST, exc.getLocalizedMessage()); + } catch (JsonProcessingException exc) { throw new ServletException("Caught an exception while generation visualization output", exc); + } catch (IOException exc) { + LOG.error(AaiUiMsgs.FAILURE_TO_PROCESS_REQUEST, exc.getLocalizedMessage()); } output.setInlineMessage(visContext.getInlineMessage()); @@ -378,8 +364,8 @@ public class VisualizationService { } public void shutdown() { - aaiProvider.shutdown(); + tabularExecutorService.shutdown(); aaiExecutorService.shutdown(); - esProvider.shutdown(); } + } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationTransformer.java b/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationTransformer.java index fdc078e..7c1d16d 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationTransformer.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/services/VisualizationTransformer.java @@ -27,21 +27,19 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; -import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.sparky.util.ConfigHelper; -import org.onap.aai.sparky.viewandinspect.config.VisualizationConfig; +import org.onap.aai.sparky.viewandinspect.config.VisualizationConfigs; import org.onap.aai.sparky.viewandinspect.entity.ActiveInventoryNode; import org.onap.aai.sparky.viewandinspect.entity.D3VisualizationOutput; import org.onap.aai.sparky.viewandinspect.entity.GraphMeta; import org.onap.aai.sparky.viewandinspect.entity.JsonNode; import org.onap.aai.sparky.viewandinspect.entity.JsonNodeLink; import org.onap.aai.sparky.viewandinspect.entity.NodeDebug; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -63,7 +61,6 @@ public class VisualizationTransformer { LoggerFactory.getInstance().getLogger(VisualizationTransformer.class); List<JsonNode> flatNodeArray = new ArrayList<JsonNode>(); - Set<String> enrichableUriPrefixes = null; /* * Maybe this isn't a string but Json-Model objects that we will convert to final string @@ -75,7 +72,7 @@ public class VisualizationTransformer { - private VisualizationConfig visualizationConfig; + private VisualizationConfigs visualizationConfigs; /** @@ -83,9 +80,8 @@ public class VisualizationTransformer { * * @throws Exception the exception */ - public VisualizationTransformer() throws Exception { - visualizationConfig = VisualizationConfig.getConfig(); - + public VisualizationTransformer(VisualizationConfigs visualizationConfigs) throws Exception { + this.visualizationConfigs = visualizationConfigs; } @@ -108,7 +104,7 @@ public class VisualizationTransformer { for (JsonNode n : flatNodeArray) { if (n.isRootNode()) { n.getNodeMeta().setSearchTarget(true); - n.getNodeMeta().setClassName(visualizationConfig.getSelectedSearchedNodeClassName()); + n.getNodeMeta().setClassName(this.visualizationConfigs.getSelectedSearchedNodeClassName()); } } @@ -160,7 +156,7 @@ public class VisualizationTransformer { ObjectMapper mapper = new ObjectMapper(); final String fileContent = ConfigHelper.getFileContents( - System.getProperty("AJSC_HOME") + visualizationConfig.getAaiEntityNodeDescriptors()); + System.getProperty("AJSC_HOME") + this.visualizationConfigs.getAaiEntityNodeDescriptors()); com.fasterxml.jackson.databind.JsonNode aaiEntityNodeDefinitions = mapper.readTree(fileContent); graphMeta.setAaiEntityNodeDescriptors(aaiEntityNodeDefinitions); @@ -211,7 +207,7 @@ public class VisualizationTransformer { * current node. */ - if (ain.getNodeDepth() < VisualizationConfig.getConfig().getMaxSelfLinkTraversalDepth()) { + if (ain.getNodeDepth() < this.visualizationConfigs.getMaxSelfLinkTraversalDepth()) { Collection<String> outboundNeighbors = ain.getOutboundNeighbors(); @@ -266,17 +262,13 @@ public class VisualizationTransformer { for (ActiveInventoryNode n : nodeMap.values()) { - if (n.getNodeDepth() <= VisualizationConfig.getConfig().getMaxSelfLinkTraversalDepth()) { - - JsonNode jsonNode = new JsonNode(n); + if (n.getNodeDepth() <= this.visualizationConfigs.getMaxSelfLinkTraversalDepth()) { - if (this.isUriEnrichable(n.getSelfLink())) { - jsonNode.getNodeMeta().setEnrichableNode(true); - } + JsonNode jsonNode = new JsonNode(n, this.visualizationConfigs); - jsonNode.getNodeMeta().setClassName(visualizationConfig.getGeneralNodeClassName()); + jsonNode.getNodeMeta().setClassName(this.visualizationConfigs.getGeneralNodeClassName()); - if (VisualizationConfig.getConfig().isVisualizationDebugEnabled()) { + if (this.visualizationConfigs.isVisualizationDebugEnabled()) { NodeDebug nodeDebug = jsonNode.getNodeMeta().getNodeDebug(); @@ -295,92 +287,4 @@ public class VisualizationTransformer { } } - /** - * Checks if is uri enrichable. - * - * @param uri the uri - * @return true, if is uri enrichable - */ - private boolean isUriEnrichable(String uri) { - if (enrichableUriPrefixes != null) { - for (String prefix : enrichableUriPrefixes) { - if (uri.contains(prefix)) { // AAI-4089 - return true; - } - } - } - return false; - } - - - /** - * @return the flatNodeArray - */ - public List<JsonNode> getFlatNodeArray() { - return flatNodeArray; - } - - - /** - * @param flatNodeArray the flatNodeArray to set - */ - public void setFlatNodeArray(List<JsonNode> flatNodeArray) { - this.flatNodeArray = flatNodeArray; - } - - - /** - * @return the enrichableUriPrefixes - */ - public Set<String> getEnrichableUriPrefixes() { - return enrichableUriPrefixes; - } - - - /** - * @param enrichableUriPrefixes the enrichableUriPrefixes to set - */ - public void setEnrichableUriPrefixes(Set<String> enrichableUriPrefixes) { - this.enrichableUriPrefixes = enrichableUriPrefixes; - } - - - /** - * @return the linkArrayOutput - */ - public List<JsonNodeLink> getLinkArrayOutput() { - return linkArrayOutput; - } - - - /** - * @param linkArrayOutput the linkArrayOutput to set - */ - public void setLinkArrayOutput(List<JsonNodeLink> linkArrayOutput) { - this.linkArrayOutput = linkArrayOutput; - } - - - /** - * @return the visualizationConfig - */ - public VisualizationConfig getVisualizationConfig() { - return visualizationConfig; - } - - - /** - * @param visualizationConfig the visualizationConfig to set - */ - public void setVisualizationConfig(VisualizationConfig visualizationConfig) { - this.visualizationConfig = visualizationConfig; - } - - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } } diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/servlet/SearchServlet.java b/src/main/java/org/onap/aai/sparky/viewandinspect/servlet/SearchServlet.java deleted file mode 100644 index 5a84346..0000000 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/servlet/SearchServlet.java +++ /dev/null @@ -1,224 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.viewandinspect.servlet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.json.JSONException; -import org.json.JSONObject; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.elasticsearch.SearchAdapter; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.sas.config.SearchServiceConfig; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.search.VnfSearchService; -import org.onap.aai.sparky.search.config.SuggestionConfig; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.sparky.viewandinspect.services.SearchServiceWrapper; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.cl.mdc.MdcContext; - -/** - * The Class SearchServlet. - */ - -public class SearchServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - - /** - * @return the searchWrapper - */ - public SearchServiceWrapper getSearchWrapper() { - return searchWrapper; - } - - /** - * @param searchWrapper the searchWrapper to set - */ - public void setSearchWrapper(SearchServiceWrapper searchWrapper) { - this.searchWrapper = searchWrapper; - } - - /** - * @return the serialversionuid - */ - public static long getSerialversionuid() { - return serialVersionUID; - } - - /** - * @return the log - */ - public static Logger getLog() { - return LOG; - } - - /** - * @return the keyPayload - */ - public static String getKeyPayload() { - return KEY_PAYLOAD; - } - - - private static final Logger LOG = LoggerFactory.getInstance().getLogger(SearchServlet.class); - - private SearchServiceWrapper searchWrapper = null; - - private static final String KEY_PAYLOAD = "payload"; - - /** - * Instantiates a new search servlet. - */ - public SearchServlet() {} - - /* - * (non-Javadoc) - * - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doPost(request, response); - } - - public void destroy() { - // TODO Auto-generated method stub - super.destroy(); - } - - public void init() throws ServletException { - super.init(); - searchWrapper = new SearchServiceWrapper(); - } - - protected Map<String, String> getPayloadParams(JSONObject parameters) { - Map<String, String> payloadParams = new HashMap<String, String>(); - try { - JSONObject payload = parameters.getJSONObject(KEY_PAYLOAD); - if (payload.length() > 0) { - for (String key : JSONObject.getNames(payload)) { - payloadParams.put(key, payload.getString(key)); - } - } - } catch (JSONException exc) { - LOG.error(AaiUiMsgs.ERROR_PARSING_PARAMS, exc); - } - return payloadParams; - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - public void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String txnID = request.getHeader("X-TransactionId"); - if (txnID == null) { - txnID = NodeUtils.getRandomTxnId(); - } - - String partnerName = request.getHeader("X-FromAppId"); - if (partnerName == null) { - partnerName = "Browser"; - } - MdcContext.initialize(txnID, "AAI_UI", "", partnerName, request.getRemoteAddr()); - searchWrapper.doPost(request, response); - } - - /** - * Generate json error response. - * - * @param message the message - * @return the string - */ - /* - * This is the manual approach, however we could also create an object container for the error - * then use the Jackson ObjectWrite to dump the object to json instead. If it gets any more - * complicated we could do that approach so we don't have to manually trip over the JSON - * formatting. - */ - protected String generateJsonErrorResponse(String message) { - return String.format("{ \"errorMessage\" : %s }", message); - } - - /** - * Handle search servlet errors. - * - * @param errorMsg the error msg - * @param exc the exc - * @param response the response - * @throws IOException Signals that an I/O exception has occurred. - */ - public void handleSearchServletErrors(String errorMsg, Exception exc, - HttpServletResponse response) throws IOException { - - String errorLogMsg = - (exc == null ? errorMsg : errorMsg + ". Error:" + exc.getLocalizedMessage()); - - LOG.error(AaiUiMsgs.SEARCH_SERVLET_ERROR, errorLogMsg); - - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.println(generateJsonErrorResponse(errorMsg)); - out.close(); - } - - - /** - * Sets the servlet response. - * - * @param response the response - * @param postPayload the post payload - * - * @throws IOException Signals that an I/O exception has occurred. - */ - private void setServletResponse(HttpServletResponse response, String postPayload) - throws IOException { - - if (postPayload != null) { - response.setContentType("application/json"); - PrintWriter out = response.getWriter(); - out.println(postPayload); - out.close(); - } - } - - - -} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/servlet/VisualizationServlet.java b/src/main/java/org/onap/aai/sparky/viewandinspect/servlet/VisualizationServlet.java deleted file mode 100644 index 85ebe50..0000000 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/servlet/VisualizationServlet.java +++ /dev/null @@ -1,200 +0,0 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs - * ================================================================================ - * 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 is a trademark and service mark of AT&T Intellectual Property. - */ -package org.onap.aai.sparky.viewandinspect.servlet; - -import java.io.IOException; -import java.io.PrintWriter; - -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.io.IOUtils; -import org.onap.aai.sparky.config.oxm.OxmModelLoader; -import org.onap.aai.sparky.dal.rest.OperationResult; -import org.onap.aai.sparky.dal.servlet.ResettableStreamHttpServletRequest; -import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.sparky.viewandinspect.entity.QueryRequest; -import org.onap.aai.sparky.viewandinspect.services.VisualizationService; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; -import org.onap.aai.cl.mdc.MdcContext; - -/** - * A dedicated servlet for handling Front-End Visualization Requests and performing feats of magic - * to execute the right model/type/config driven queries to build the D3 visualization output JSON - * back to the FE. - * - * @author DAVEA - * - */ -public class VisualizationServlet extends HttpServlet { - - /** - * - */ - private static final long serialVersionUID = 4678831934652478571L; - private static final Logger LOG = - LoggerFactory.getInstance().getLogger(VisualizationServlet.class); - private static final String VISUALIZATION_API_ENDPOINT = "prepareVisualization"; - private final VisualizationService visualizationService; - - /** - * Instantiates a new visualization servlet. - * - * @throws Exception the exception - */ - public VisualizationServlet() throws Exception { - this.visualizationService = new VisualizationService(OxmModelLoader.getInstance()); - } - - /** - * Inits the. - * - * @param filterConfig the filter config - * @throws ServletException the servlet exception - */ - public void init(FilterConfig filterConfig) throws ServletException { - LOG.debug(AaiUiMsgs.DEBUG_GENERIC, "init()"); - } - - /** - * Gets the request body. - * - * @param request the request - * @return the request body - */ - private String getRequestBody(HttpServletRequest request) { - - ResettableStreamHttpServletRequest requestWrapper = - new ResettableStreamHttpServletRequest(request); - - String body = null; - try { - body = IOUtils.toString(requestWrapper.getRequestBody()); - } catch (IOException exc) { - LOG.error(AaiUiMsgs.EXCEPTION_CAUGHT, "Trying to get body from request", - exc.getLocalizedMessage()); - } - - return body; - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doPost(request, response); - } - - /* - * (non-Javadoc) - * - * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String txnID = request.getHeader("X-TransactionId"); - if (txnID == null) { - txnID = NodeUtils.getRandomTxnId(); - } - - String partnerName = request.getHeader("X-FromAppId"); - if (partnerName == null) { - partnerName = "Browser"; - } - - MdcContext.initialize(txnID, "AAI-UI", "", partnerName, request.getRemoteAddr()); - - String postRequestBody = getRequestBody(request); - - String requestUri = request.getRequestURI(); - OperationResult operationResult = null; - - /* - * For now we only have a single API call but there could be more in the future - */ - if (requestUri.endsWith(VISUALIZATION_API_ENDPOINT)) { - - /* - * Work our magic and determine the best way to interrogate AAI to get the stuff we are - * interested in. Perhaps it should be an edge-tag-query or perhaps it is a straight up - * derived self-link query. - */ - - /* - * Map request body to an interpreted API PoJo object - */ - QueryRequest queryRequest = visualizationService.analyzeQueryRequestBody(postRequestBody); - - if (queryRequest != null) { - operationResult = visualizationService.buildVisualizationUsingGenericQuery(queryRequest); - } else { - LOG.error(AaiUiMsgs.FAILED_TO_ANALYZE, - String.format("Failed to analyze post request query body = '%s'", postRequestBody)); - - operationResult = new OperationResult(); - operationResult.setResult(500, - String.format("Failed to analyze post request query body = '%s'", postRequestBody)); - - } - - } else { - // unhandled type - LOG.error(AaiUiMsgs.UNKNOWN_SERVER_ERROR, "Unhandled requestUri - " + requestUri); - operationResult = new OperationResult(); - operationResult.setResult(500, "Unknown Server Error: Unhandled requestUri = " + requestUri); - } - - PrintWriter out = response.getWriter(); - response.addHeader("Content-Type", "application/xml"); - - response.setStatus(operationResult.getResultCode()); - - if (operationResult.getResultCode() == 200) { - response.setContentLength(operationResult.getResult().length()); - out.print(operationResult.getResult()); - out.print("\n"); - } else { - response.setContentLength(operationResult.getResult().length()); - out.print(operationResult.getResult()); - out.print("\n"); - } - } - - @Override - public void destroy() { - super.destroy(); - visualizationService.shutdown(); - } -} diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/task/CollectNodeSelfLinkTask.java b/src/main/java/org/onap/aai/sparky/viewandinspect/task/CollectNodeSelfLinkTask.java index 3b750b3..8683299 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/task/CollectNodeSelfLinkTask.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/task/CollectNodeSelfLinkTask.java @@ -33,35 +33,6 @@ import org.onap.aai.sparky.dal.rest.OperationResult; public class CollectNodeSelfLinkTask implements Supplier<OperationResult> { private String selfLink; - - /** - * @return the selfLink - */ - public String getSelfLink() { - return selfLink; - } - - /** - * @param selfLink the selfLink to set - */ - public void setSelfLink(String selfLink) { - this.selfLink = selfLink; - } - - /** - * @return the aaiProvider - */ - public ActiveInventoryDataProvider getAaiProvider() { - return aaiProvider; - } - - /** - * @param aaiProvider the aaiProvider to set - */ - public void setAaiProvider(ActiveInventoryDataProvider aaiProvider) { - this.aaiProvider = aaiProvider; - } - private ActiveInventoryDataProvider aaiProvider; /** diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformNodeSelfLinkProcessingTask.java b/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformNodeSelfLinkProcessingTask.java index 518d569..7c59ffa 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformNodeSelfLinkProcessingTask.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformNodeSelfLinkProcessingTask.java @@ -25,13 +25,13 @@ package org.onap.aai.sparky.viewandinspect.task; import java.util.Map; import java.util.function.Supplier; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.sparky.viewandinspect.entity.NodeProcessingTransaction; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.slf4j.MDC; /** @@ -43,7 +43,7 @@ public class PerformNodeSelfLinkProcessingTask implements Supplier<NodeProcessin LoggerFactory.getInstance().getLogger(PerformNodeSelfLinkProcessingTask.class); private NodeProcessingTransaction txn; - private ActiveInventoryDataProvider aaiProvider; + private ActiveInventoryAdapter aaiAdapter; private Map<String, String> contextMap; private ActiveInventoryConfig aaiConfig; @@ -51,12 +51,19 @@ public class PerformNodeSelfLinkProcessingTask implements Supplier<NodeProcessin * Instantiates a new perform node self link processing task. * * @param txn the txn - * @param requestParameters the request parameters * @param aaiProvider the aai provider + * @param aaiConfig the aai config + */ + /** + * + * @param txn + * @param requestParameters + * @param aaiProvider + * @param aaiConfig */ public PerformNodeSelfLinkProcessingTask(NodeProcessingTransaction txn, String requestParameters, - ActiveInventoryDataProvider aaiProvider, ActiveInventoryConfig aaiConfig) { - this.aaiProvider = aaiProvider; + ActiveInventoryAdapter aaiAdapter, ActiveInventoryConfig aaiConfig) { + this.aaiAdapter = aaiAdapter; this.txn = txn; this.contextMap = MDC.getCopyOfContextMap(); this.aaiConfig = aaiConfig; @@ -72,11 +79,13 @@ public class PerformNodeSelfLinkProcessingTask implements Supplier<NodeProcessin MDC.setContextMap(contextMap); OperationResult opResult = new OperationResult(); String link = txn.getSelfLink(); + if (link == null) { opResult.setResult(500, "Aborting self-link processing because self link is null"); txn.setOpResult(opResult); return txn; } + /** * Rebuild the self link: * @@ -85,7 +94,7 @@ public class PerformNodeSelfLinkProcessingTask implements Supplier<NodeProcessin * */ - final String urlSchemeAndAuthority = aaiConfig.repairSelfLink(""); + final String urlSchemeAndAuthority = aaiAdapter.repairSelfLink(""); String parameters = txn.getRequestParameters(); link = urlSchemeAndAuthority + link; @@ -101,8 +110,8 @@ public class PerformNodeSelfLinkProcessingTask implements Supplier<NodeProcessin } try { - opResult = aaiProvider.queryActiveInventoryWithRetries(link, "application/json", - ActiveInventoryConfig.getConfig().getAaiRestConfig().getNumRequestRetries()); + opResult = aaiAdapter.queryActiveInventoryWithRetries(link, "application/json", + aaiConfig.getAaiRestConfig().getNumRequestRetries()); } catch (Exception exc) { opResult = new OperationResult(); opResult.setResult(500, "Querying AAI with retry failed due to an exception."); diff --git a/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformSelfLinkDeterminationTask.java b/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformSelfLinkDeterminationTask.java index 1b71971..b041a7d 100644 --- a/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformSelfLinkDeterminationTask.java +++ b/src/main/java/org/onap/aai/sparky/viewandinspect/task/PerformSelfLinkDeterminationTask.java @@ -25,13 +25,13 @@ package org.onap.aai.sparky.viewandinspect.task; import java.util.Map; import java.util.function.Supplier; -import org.onap.aai.sparky.dal.aai.ActiveInventoryDataProvider; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; import org.onap.aai.sparky.viewandinspect.entity.SelfLinkDeterminationTransaction; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.slf4j.MDC; public class PerformSelfLinkDeterminationTask @@ -41,7 +41,7 @@ public class PerformSelfLinkDeterminationTask LoggerFactory.getInstance().getLogger(PerformSelfLinkDeterminationTask.class); private SelfLinkDeterminationTransaction txn; - private ActiveInventoryDataProvider aaiProvider; + private ActiveInventoryAdapter aaiAdapter; private Map<String, String> contextMap; @@ -53,9 +53,9 @@ public class PerformSelfLinkDeterminationTask * @param aaiProvider the aai provider */ public PerformSelfLinkDeterminationTask(SelfLinkDeterminationTransaction txn, - String requestParameters, ActiveInventoryDataProvider aaiProvider) { + String requestParameters, ActiveInventoryAdapter aaiAdapter) { - this.aaiProvider = aaiProvider; + this.aaiAdapter = aaiAdapter; this.txn = txn; this.contextMap = MDC.getCopyOfContextMap(); } @@ -78,7 +78,7 @@ public class PerformSelfLinkDeterminationTask OperationResult opResult = null; try { opResult = - aaiProvider.queryActiveInventoryWithRetries(txn.getQueryString(), "application/json", + aaiAdapter.queryActiveInventoryWithRetries(txn.getQueryString(), "application/json", ActiveInventoryConfig.getConfig().getAaiRestConfig().getNumRequestRetries()); } catch (Exception exc) { opResult = new OperationResult(); diff --git a/src/main/java/org/onap/aai/sparky/synchronizer/SearchableEntitySynchronizer.java b/src/main/java/org/onap/aai/sparky/viewinspect/sync/ViewInspectEntitySynchronizer.java index e10163f..ccce3b0 100644 --- a/src/main/java/org/onap/aai/sparky/synchronizer/SearchableEntitySynchronizer.java +++ b/src/main/java/org/onap/aai/sparky/viewinspect/sync/ViewInspectEntitySynchronizer.java @@ -20,22 +20,11 @@ * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ -package org.onap.aai.sparky.synchronizer; +package org.onap.aai.sparky.viewinspect.sync; import static java.util.concurrent.CompletableFuture.supplyAsync; -import org.onap.aai.cl.mdc.MdcContext; - -import org.onap.aai.cl.mdc.MdcContext; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.node.ArrayNode; - import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Deque; @@ -47,32 +36,45 @@ import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ExecutorService; import java.util.function.Supplier; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.sparky.config.oxm.OxmEntityDescriptor; +import org.onap.aai.sparky.config.oxm.OxmEntityLookup; +import org.onap.aai.sparky.config.oxm.SearchableEntityLookup; +import org.onap.aai.sparky.config.oxm.SearchableOxmEntityDescriptor; import org.onap.aai.sparky.dal.NetworkTransaction; import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig; import org.onap.aai.sparky.dal.elasticsearch.config.ElasticSearchConfig; import org.onap.aai.sparky.dal.rest.HttpMethod; -import org.onap.aai.sparky.dal.rest.OperationResult; import org.onap.aai.sparky.logging.AaiUiMsgs; -import org.onap.aai.sparky.synchronizer.config.SynchronizerConfiguration; -import org.onap.aai.sparky.synchronizer.entity.MergableEntity; -import org.onap.aai.sparky.synchronizer.entity.SearchableEntity; -import org.onap.aai.sparky.synchronizer.entity.SelfLinkDescriptor; -import org.onap.aai.sparky.synchronizer.enumeration.OperationState; -import org.onap.aai.sparky.synchronizer.enumeration.SynchronizerState; -import org.onap.aai.sparky.synchronizer.task.PerformActiveInventoryRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchPut; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchRetrieval; -import org.onap.aai.sparky.synchronizer.task.PerformElasticSearchUpdate; +import org.onap.aai.sparky.sync.AbstractEntitySynchronizer; +import org.onap.aai.sparky.sync.IndexSynchronizer; +import org.onap.aai.sparky.sync.SynchronizerConstants; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.entity.MergableEntity; +import org.onap.aai.sparky.sync.entity.SearchableEntity; +import org.onap.aai.sparky.sync.entity.SelfLinkDescriptor; +import org.onap.aai.sparky.sync.enumeration.OperationState; +import org.onap.aai.sparky.sync.enumeration.SynchronizerState; +import org.onap.aai.sparky.sync.task.PerformActiveInventoryRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchPut; +import org.onap.aai.sparky.sync.task.PerformElasticSearchRetrieval; +import org.onap.aai.sparky.sync.task.PerformElasticSearchUpdate; import org.onap.aai.sparky.util.NodeUtils; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.slf4j.MDC; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.node.ArrayNode; + /** * The Class SearchableEntitySynchronizer. */ -public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer +public class ViewInspectEntitySynchronizer extends AbstractEntitySynchronizer implements IndexSynchronizer { /** @@ -103,7 +105,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer } private static final Logger LOG = - LoggerFactory.getInstance().getLogger(SearchableEntitySynchronizer.class); + LoggerFactory.getInstance().getLogger(ViewInspectEntitySynchronizer.class); private boolean allWorkEnumerated; private Deque<SelfLinkDescriptor> selflinks; @@ -117,18 +119,21 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer * @param indexName the index name * @throws Exception the exception */ - public SearchableEntitySynchronizer(String indexName) throws Exception { - super(LOG, "SES", 2, 5, 5, indexName); + public ViewInspectEntitySynchronizer(ElasticSearchSchemaConfig schemaConfig, + int internalSyncWorkers, int aaiWorkers, int esWorkers, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(LOG, "SES", internalSyncWorkers, aaiWorkers, esWorkers, schemaConfig.getIndexName(), + aaiStatConfig, esStatConfig); this.allWorkEnumerated = false; this.selflinks = new ConcurrentLinkedDeque<SelfLinkDescriptor>(); this.retryQueue = new ConcurrentLinkedDeque<RetrySearchableEntitySyncContainer>(); this.retryLimitTracker = new ConcurrentHashMap<String, Integer>(); this.synchronizerName = "Searchable Entity Synchronizer"; this.esPutExecutor = NodeUtils.createNamedExecutor("SES-ES-PUT", 5, LOG); - this.aaiEntityStats.initializeCountersFromOxmEntityDescriptors( - oxmModelLoader.getSearchableEntityDescriptors()); - this.esEntityStats.initializeCountersFromOxmEntityDescriptors( - oxmModelLoader.getSearchableEntityDescriptors()); + this.aaiEntityStats.intializeEntityCounters( + SearchableEntityLookup.getInstance().getSearchableEntityDescriptors().keySet()); + this.esEntityStats.intializeEntityCounters( + SearchableEntityLookup.getInstance().getSearchableEntityDescriptors().keySet()); this.syncDurationInMs = -1; } @@ -139,8 +144,8 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer */ private OperationState collectAllTheWork() { final Map<String, String> contextMap = MDC.getCopyOfContextMap(); - Map<String, OxmEntityDescriptor> descriptorMap = - oxmModelLoader.getSearchableEntityDescriptors(); + Map<String, SearchableOxmEntityDescriptor> descriptorMap = + SearchableEntityLookup.getInstance().getSearchableEntityDescriptors(); if (descriptorMap.isEmpty()) { LOG.error(AaiUiMsgs.ERROR_LOADING_OXM_SEARCHABLE_ENTITIES); @@ -172,7 +177,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer MDC.setContextMap(contextMap); OperationResult typeLinksResult = null; try { - typeLinksResult = aaiDataProvider.getSelfLinksByEntityType(key); + typeLinksResult = aaiAdapter.getSelfLinksByEntityType(key); aaiWorkOnHand.decrementAndGet(); processEntityTypeSelfLinks(typeLinksResult); } catch (Exception exc) { @@ -226,7 +231,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#doSync() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#doSync() */ @Override public OperationState doSync() { @@ -278,11 +283,12 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer final String resourceType = NodeUtils.getNodeFieldAsText(element, "resource-type"); final String resourceLink = NodeUtils.getNodeFieldAsText(element, "resource-link"); - OxmEntityDescriptor descriptor = null; + SearchableOxmEntityDescriptor descriptor = null; if (resourceType != null && resourceLink != null) { - descriptor = oxmModelLoader.getEntityDescriptor(resourceType); + descriptor = SearchableEntityLookup.getInstance().getSearchableEntityDescriptors() + .get(resourceType); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, resourceType); @@ -292,7 +298,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer if (descriptor.hasSearchableAttributes()) { selflinks.add(new SelfLinkDescriptor(resourceLink, - SynchronizerConfiguration.NODES_ONLY_MODIFIER, resourceType)); + SynchronizerConstants.NODES_ONLY_MODIFIER, resourceType)); } } @@ -316,7 +322,8 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer if (linkDescriptor.getSelfLink() != null && linkDescriptor.getEntityType() != null) { - descriptor = oxmModelLoader.getEntityDescriptor(linkDescriptor.getEntityType()); + descriptor = OxmEntityLookup.getInstance().getEntityDescriptors() + .get(linkDescriptor.getEntityType()); if (descriptor == null) { LOG.error(AaiUiMsgs.MISSING_ENTITY_DESCRIPTOR, linkDescriptor.getEntityType()); @@ -332,7 +339,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer aaiWorkOnHand.incrementAndGet(); - supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiDataProvider), aaiExecutor) + supplyAsync(new PerformActiveInventoryRetrieval(txn, aaiAdapter), aaiExecutor) .whenComplete((result, error) -> { aaiWorkOnHand.decrementAndGet(); @@ -423,7 +430,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer String responseSource = NodeUtils.convertObjectToJson(sourceObject.get(0), false); MergableEntity me = mapper.readValue(responseSource, MergableEntity.class); ObjectReader updater = mapper.readerForUpdating(me); - MergableEntity merged = updater.readValue(se.getIndexDocumentJson()); + MergableEntity merged = updater.readValue(NodeUtils.convertObjectToJson(se, false)); jsonPayload = mapper.writeValueAsString(merged); } } catch (IOException exc) { @@ -434,14 +441,15 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer return; } } else { - jsonPayload = se.getIndexDocumentJson(); + jsonPayload = se.getAsJson(); } if (wasEntryDiscovered) { if (versionNumber != null && jsonPayload != null) { - String requestPayload = esDataProvider.buildBulkImportOperationRequest(getIndexName(), - ElasticSearchConfig.getConfig().getType(), se.getId(), versionNumber, jsonPayload); + String requestPayload = elasticSearchAdapter.buildBulkImportOperationRequest( + getIndexName(), ElasticSearchConfig.getConfig().getType(), se.getId(), versionNumber, + jsonPayload); NetworkTransaction transactionTracker = new NetworkTransaction(); transactionTracker.setEntityType(esGetTxn.getEntityType()); @@ -450,7 +458,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer esWorkOnHand.incrementAndGet(); supplyAsync(new PerformElasticSearchUpdate(ElasticSearchConfig.getConfig().getBulkUrl(), - requestPayload, esDataProvider, transactionTracker), esPutExecutor) + requestPayload, elasticSearchAdapter, transactionTracker), esPutExecutor) .whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -467,6 +475,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer } } else { + if (link != null && jsonPayload != null) { NetworkTransaction updateElasticTxn = new NetworkTransaction(); @@ -476,7 +485,8 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer updateElasticTxn.setOperationType(HttpMethod.PUT); esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchPut(jsonPayload, updateElasticTxn, esDataProvider), + supplyAsync( + new PerformElasticSearchPut(jsonPayload, updateElasticTxn, elasticSearchAdapter), esPutExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -518,7 +528,10 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer List<String> primaryKeyValues = new ArrayList<String>(); String pkeyValue = null; - for (String keyName : resultDescriptor.getPrimaryKeyAttributeName()) { + SearchableOxmEntityDescriptor searchableDescriptor = SearchableEntityLookup.getInstance() + .getSearchableEntityDescriptors().get(resultDescriptor.getEntityName()); + + for (String keyName : searchableDescriptor.getPrimaryKeyAttributeNames()) { pkeyValue = NodeUtils.getNodeFieldAsText(entityNode, keyName); if (pkeyValue != null) { primaryKeyValues.add(pkeyValue); @@ -532,7 +545,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer final String primaryCompositeKeyValue = NodeUtils.concatArray(primaryKeyValues, "/"); doc.setEntityPrimaryKeyValue(primaryCompositeKeyValue); - final List<String> searchTagFields = resultDescriptor.getSearchableAttributes(); + final List<String> searchTagFields = searchableDescriptor.getSearchableAttributes(); /* * Based on configuration, use the configured field names for this entity-Type to build a @@ -558,13 +571,16 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer return; } + SearchableOxmEntityDescriptor searchableDescriptor = SearchableEntityLookup.getInstance() + .getSearchableEntityDescriptors().get(txn.getDescriptor().getEntityName()); + try { - if (txn.getDescriptor().hasSearchableAttributes()) { + if (searchableDescriptor.hasSearchableAttributes()) { final String jsonResult = txn.getOperationResult().getResult(); if (jsonResult != null && jsonResult.length() > 0) { - SearchableEntity se = new SearchableEntity(oxmModelLoader); + SearchableEntity se = new SearchableEntity(); se.setLink(ActiveInventoryConfig.extractResourcePath(txn.getLink())); populateSearchableEntityDocument(se, jsonResult, txn.getDescriptor()); se.deriveFields(); @@ -585,7 +601,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer esWorkOnHand.incrementAndGet(); - supplyAsync(new PerformElasticSearchRetrieval(n2, esDataProvider), esExecutor) + supplyAsync(new PerformElasticSearchRetrieval(n2, elasticSearchAdapter), esExecutor) .whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -677,7 +693,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer * called incrementAndGet when queuing the failed PUT! */ - supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, esDataProvider), + supplyAsync(new PerformElasticSearchRetrieval(retryTransaction, elasticSearchAdapter), esExecutor).whenComplete((result, error) -> { esWorkOnHand.decrementAndGet(); @@ -735,7 +751,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#getStatReport(boolean) */ @Override public String getStatReport(boolean showFinalReport) { @@ -746,7 +762,7 @@ public class SearchableEntitySynchronizer extends AbstractEntitySynchronizer /* * (non-Javadoc) * - * @see org.onap.aai.sparky.synchronizer.IndexSynchronizer#shutdown() + * @see org.openecomp.sparky.synchronizer.IndexSynchronizer#shutdown() */ @Override public void shutdown() { diff --git a/src/main/java/org/onap/aai/sparky/viewinspect/sync/ViewInspectSyncController.java b/src/main/java/org/onap/aai/sparky/viewinspect/sync/ViewInspectSyncController.java new file mode 100644 index 0000000..c2ecbb1 --- /dev/null +++ b/src/main/java/org/onap/aai/sparky/viewinspect/sync/ViewInspectSyncController.java @@ -0,0 +1,129 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * ================================================================================ + * 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 is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.sparky.viewinspect.sync; + +import org.onap.aai.sparky.crossentityreference.sync.CrossEntityReferenceSynchronizer; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.sync.ElasticSearchIndexCleaner; +import org.onap.aai.sparky.sync.ElasticSearchSchemaFactory; +import org.onap.aai.sparky.sync.IndexCleaner; +import org.onap.aai.sparky.sync.IndexIntegrityValidator; +import org.onap.aai.sparky.sync.SyncControllerImpl; +import org.onap.aai.sparky.sync.SyncControllerRegistrar; +import org.onap.aai.sparky.sync.SyncControllerRegistry; +import org.onap.aai.sparky.sync.config.ElasticSearchEndpointConfig; +import org.onap.aai.sparky.sync.config.ElasticSearchSchemaConfig; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; +import org.onap.aai.sparky.sync.config.SyncControllerConfig; + +public class ViewInspectSyncController extends SyncControllerImpl + implements SyncControllerRegistrar { + + private SyncControllerRegistry syncControllerRegistry; + private ActiveInventoryAdapter aaiAdapter; + private ElasticSearchAdapter esAdapter; + private ElasticSearchSchemaConfig schemaConfig; + private ElasticSearchEndpointConfig endpointConfig; + + public ViewInspectSyncController(SyncControllerConfig syncControllerConfig, + ActiveInventoryAdapter aaiAdapter, ElasticSearchAdapter esAdapter, + ElasticSearchSchemaConfig schemaConfig, ElasticSearchEndpointConfig endpointConfig, + NetworkStatisticsConfig aaiStatConfig, NetworkStatisticsConfig esStatConfig) + throws Exception { + super(syncControllerConfig); + + + // final String controllerName = "View and Inspect Entity Synchronizer"; + + this.aaiAdapter = aaiAdapter; + this.esAdapter = esAdapter; + this.schemaConfig = schemaConfig; + this.endpointConfig = endpointConfig; + IndexIntegrityValidator indexValidator = new IndexIntegrityValidator(esAdapter, schemaConfig, + endpointConfig, ElasticSearchSchemaFactory.getIndexSchema(schemaConfig)); + + registerIndexValidator(indexValidator); + + + ViewInspectEntitySynchronizer ses = new ViewInspectEntitySynchronizer(schemaConfig, + syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + ses.setAaiAdapter(aaiAdapter); + ses.setElasticSearchAdapter(esAdapter); + + registerEntitySynchronizer(ses); + + CrossEntityReferenceSynchronizer cers = new CrossEntityReferenceSynchronizer(schemaConfig, + syncControllerConfig.getNumInternalSyncWorkers(), + syncControllerConfig.getNumSyncActiveInventoryWorkers(), + syncControllerConfig.getNumSyncElasticWorkers(), aaiStatConfig, esStatConfig); + + cers.setAaiAdapter(aaiAdapter); + cers.setElasticSearchAdapter(esAdapter); + + registerEntitySynchronizer(cers); + + IndexCleaner indexCleaner = + new ElasticSearchIndexCleaner(esAdapter, endpointConfig, schemaConfig); + + registerIndexCleaner(indexCleaner); + + } + + public SyncControllerRegistry getSyncControllerRegistry() { + return syncControllerRegistry; + } + + public void setSyncControllerRegistry(SyncControllerRegistry syncControllerRegistry) { + this.syncControllerRegistry = syncControllerRegistry; + } + + public ActiveInventoryAdapter getAaiAdapter() { + return this.aaiAdapter; + } + + public ElasticSearchAdapter getElasticSearchAdapter() { + return this.esAdapter; + } + + public ElasticSearchEndpointConfig getendpointConfig() { + return this.endpointConfig; + } + + public ElasticSearchSchemaConfig getschemaConfig() { + return this.schemaConfig; + } + + + @Override + public void registerController() { + if (syncControllerRegistry != null) { + if (syncControllerConfig.isEnabled()) { + syncControllerRegistry.registerSyncController(this); + } + } + + } +} |