aboutsummaryrefslogtreecommitdiffstats
path: root/aai-core/src/main
diff options
context:
space:
mode:
authorKajur, Harish (vk250x) <vk250x@att.com>2020-02-21 14:34:10 -0500
committerHarish Venkata Kajur <vk250x@att.com>2020-02-25 23:59:33 -0500
commit98749c47bbb5f5ddcc1c4f0690b79c7288f6bdd6 (patch)
treea472ce2edabd497b643917f44785b775fa16e15e /aai-core/src/main
parente654645a50a0d028d8e67ea997f84efe8d28a6a0 (diff)
Enhancements for the aai-common library
Issue-ID: AAI-2806 Change-Id: I2dbb46b897b35136ac1bb802978d3f974af1b307 Signed-off-by: Kajur, Harish (vk250x) <vk250x@att.com>
Diffstat (limited to 'aai-core/src/main')
-rw-r--r--aai-core/src/main/java/org/onap/aai/audit/ListEndpoints.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/auth/AAIAuthCore.java372
-rw-r--r--aai-core/src/main/java/org/onap/aai/auth/AAIUser.java81
-rw-r--r--aai-core/src/main/java/org/onap/aai/auth/exceptions/AAIUnrecognizedFunctionException.java46
-rw-r--r--aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java4
-rw-r--r--aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java2
-rw-r--r--aai-core/src/main/java/org/onap/aai/config/XmlFormatTransformerConfiguration.java (renamed from aai-core/src/main/java/org/onap/aai/logging/CustomLogPatternLayoutEncoder.java)25
-rw-r--r--aai-core/src/main/java/org/onap/aai/db/props/AAIProperties.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java238
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java94
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java59
-rw-r--r--aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSConsumer.java109
-rw-r--r--aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSProducer.java8
-rw-r--r--aai-core/src/main/java/org/onap/aai/dmaap/MessageProducer.java1
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/model/AAIResources.java4
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java161
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessage.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageData.java16
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageDatum.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessages.java24
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restPolicyException/Fault.java376
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restPolicyException/ObjectFactory.java93
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restPolicyException/PolicyException.java132
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RESTResponse.java86
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RequestError.java86
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/Info.java380
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/ObjectFactory.java93
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restServiceException/Fault.java376
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restServiceException/ObjectFactory.java93
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restServiceException/RESTResponse.java86
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restServiceException/RequestError.java86
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/restServiceException/ServiceException.java132
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntries.java21
-rw-r--r--aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntry.java112
-rw-r--r--aai-core/src/main/java/org/onap/aai/exceptions/AAIException.java153
-rw-r--r--aai-core/src/main/java/org/onap/aai/exceptions/AAIExceptionWithInfo.java135
-rw-r--r--aai-core/src/main/java/org/onap/aai/extensions/ExtensionController.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/Introspector.java56
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/IntrospectorWalker.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/JSONStrategy.java7
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/MoxyStrategy.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/generator/CreateExample.java8
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/sideeffect/DataCopy.java27
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/sideeffect/PrivateEdge.java75
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffectRunner.java4
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/CNName.java99
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/DME2RestFlag.java55
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompElapsedTime.java66
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompEncoder.java38
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompErrorCategory.java42
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompPatternLayout.java36
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompResponseCode.java39
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompResponseDescription.java47
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompServiceName.java36
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompStartTime.java39
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EcompStatusCode.java36
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/EelfClassOfCaller.java43
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/ErrorLogHelper.java633
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/ErrorObject.java359
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/ErrorObjectNotFoundException.java51
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/LogFormatTools.java123
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/LoggingContext.java417
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/StopWatch.java56
-rw-r--r--aai-core/src/main/java/org/onap/aai/logging/StopWatchNotStartedException.java42
-rw-r--r--aai-core/src/main/java/org/onap/aai/parsers/query/LegacyQueryParser.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/parsers/query/RelationshipQueryParser.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/Validation.java92
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java51
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java299
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceNoAuthClient.java79
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceOneWayClient.java92
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceRestClient.java108
-rw-r--r--aai-core/src/main/java/org/onap/aai/prevalidation/Violation.java128
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java124
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java122
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/GremlinTraversal.java1
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/HistoryGremlinTraversal.java170
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/HistoryTraversalURIOptimizedQuery.java93
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java175
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/TraversalQuery.java12
-rw-r--r--aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java3
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/db/DBRequest.java3
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java768
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java5
-rw-r--r--aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java82
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/RESTAPI.java115
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/search/AAIAbstractGroovyShell.java23
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java7
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java19
-rw-r--r--aai-core/src/main/java/org/onap/aai/restcore/util/URITools.java34
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java1368
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/db/GraphSingleton.java8
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/db/ImpliedDelete.java205
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/db/InMemoryGraphSingleton.java5
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/InMemoryDBEngine.java18
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/JanusGraphDBEngine.java17
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/QueryStyle.java2
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/TransactionalGraphEngine.java52
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java30
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java7
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java313
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/ChangesFormat.java95
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Console.java10
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java15
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java2
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java41
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java3
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java87
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java12
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/HistoryFormat.java246
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java112
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java313
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java76
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java112
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java77
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java109
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/ResourceWithSoT.java30
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/StateFormat.java144
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/AsTree.java (renamed from aai-core/src/main/java/org/onap/aai/logging/LoggingContextNotExistsException.java)8
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/EndTs.java (renamed from aai-core/src/main/java/org/onap/aai/logging/ErrorObjectFormatException.java)12
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/StartTs.java (renamed from aai-core/src/main/java/org/onap/aai/logging/CustomLogPatternLayout.java)12
-rw-r--r--aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/QueryParamInjector.java28
-rw-r--r--aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/tasks/ScheduledTasks.java42
-rw-r--r--aai-core/src/main/java/org/onap/aai/transforms/XmlFormatTransformer.java70
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/AAIConfig.java232
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/AAIConstants.java129
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/FileWatcher.java60
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/FormatDate.java47
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java61
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java71
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/MapperUtil.java121
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/PojoUtils.java6
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/RestController.java99
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java97
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/delta/DeltaAction.java30
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java136
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java126
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java79
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/delta/PropertyDeltaFactory.java34
-rw-r--r--aai-core/src/main/java/org/onap/aai/util/delta/RelationshipDelta.java133
-rw-r--r--aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java6
-rw-r--r--aai-core/src/main/resources/specs/transform-related-to-node.json21
-rw-r--r--aai-core/src/main/resources/swagger.html.ftl241
150 files changed, 6549 insertions, 7680 deletions
diff --git a/aai-core/src/main/java/org/onap/aai/audit/ListEndpoints.java b/aai-core/src/main/java/org/onap/aai/audit/ListEndpoints.java
index dcfd58a5..fe2e1ff7 100644
--- a/aai-core/src/main/java/org/onap/aai/audit/ListEndpoints.java
+++ b/aai-core/src/main/java/org/onap/aai/audit/ListEndpoints.java
@@ -22,8 +22,8 @@
package org.onap.aai.audit;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.CaseFormat;
import java.util.ArrayList;
@@ -53,7 +53,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
*/
public class ListEndpoints {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ListEndpoints.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(ListEndpoints.class);
private static final String START = "inventory";
private static final String[] blacklist = {"search", "aai-internal"};
diff --git a/aai-core/src/main/java/org/onap/aai/auth/AAIAuthCore.java b/aai-core/src/main/java/org/onap/aai/auth/AAIAuthCore.java
deleted file mode 100644
index cde2faa3..00000000
--- a/aai-core/src/main/java/org/onap/aai/auth/AAIAuthCore.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.auth;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import org.eclipse.jetty.util.security.Password;
-import org.eclipse.persistence.internal.oxm.conversion.Base64;
-import org.onap.aai.auth.exceptions.AAIUnrecognizedFunctionException;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.LoggingContext.StatusCode;
-import org.onap.aai.util.AAIConfig;
-import org.onap.aai.util.AAIConstants;
-import org.onap.aai.util.FileWatcher;
-
-/**
- * The Class AAIAuthCore.
- */
-public final class AAIAuthCore {
-
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIAuthCore.class);
-
- private static final String ERROR_CODE_AAI_4001 = "AAI_4001";
-
- private String globalAuthFileName = AAIConstants.AAI_AUTH_CONFIG_FILENAME;
-
- private final Pattern AUTH_POLICY_PATTERN;
- private final Set<String> validFunctions = new HashSet<>();
- private Map<String, AAIUser> users;
- private boolean timerSet = false;
- private Timer timer = null;
-
- private String basePath;
-
- /**
- * Instantiates a new AAI auth core.
- */
- public AAIAuthCore(String basePath) {
- this.basePath = basePath;
- AUTH_POLICY_PATTERN = Pattern.compile("^" + this.basePath + "/v\\d+/([\\w\\-]*)");
- init();
- }
-
- /**
- * Inits the.
- */
- private synchronized void init() {
-
- LOGGER.debug("Initializing Auth Policy Config");
-
- reloadUsers();
-
- /*
- * this timer code is setting up a recurring task that checks if the
- * auth config file has been updated and reloads the users if so to get
- * the most up to date info (that update check logic is within
- * FileWatcher)
- *
- * the timing this method uses is coarser than the frequency of requests
- * AI&I gets so we're looking at better ways of doing this (TODO)
- */
- TimerTask task = new FileWatcher(new File(globalAuthFileName)) {
- @Override
- protected void onChange(File file) {
- reloadUsers();
- }
- };
-
- if (!timerSet) {
- timerSet = true;
- timer = new Timer();
-
- // repeat the check every second
- timer.schedule(task, new Date(), 10000);
- }
- LOGGER.debug("Static Initializiation complete");
- }
-
- /**
- * Cleanup.
- */
- // just ends the auth config file update checking timer
- public void cleanup() {
- timer.cancel();
- }
-
- /**
- * Reload users.
- */
- /*
- * this essentially takes the data file, which is organized role-first with
- * users under each role and converts it to data organized user-first with
- * each user containing their role with its associated allowed functions
- * this data stored in the class field users
- */
- private synchronized void reloadUsers() {
-
- Map<String, AAIUser> tempUsers = new HashMap<>();
-
- try {
- LOGGER.debug("Reading from " + globalAuthFileName);
- String authFile = new String(Files.readAllBytes(Paths.get(globalAuthFileName)));
-
- JsonParser parser = new JsonParser();
- JsonObject authObject = parser.parse(authFile).getAsJsonObject();
- if (authObject.has("roles")) {
- JsonArray roles = authObject.getAsJsonArray("roles");
- for (JsonElement role : roles) {
- if (role.isJsonObject()) {
- JsonObject roleObject = role.getAsJsonObject();
- String roleName = roleObject.get("name").getAsString();
- Map<String, Boolean> usrs = this.getUsernamesFromRole(roleObject);
- List<String> aaiFunctions = this.getAAIFunctions(roleObject);
-
- usrs.forEach((key, value) -> {
- final AAIUser au = tempUsers.getOrDefault(key, new AAIUser(key, value));
- au.addRole(roleName);
- aaiFunctions.forEach(f -> {
- List<String> httpMethods = this.getRoleHttpMethods(f, roleObject);
- httpMethods.forEach(hm -> au.setUserAccess(f, hm));
- this.validFunctions.add(f);
- });
-
- tempUsers.put(key, au);
-
- });
- }
- }
- if (!tempUsers.isEmpty()) {
- users = tempUsers;
- }
- }
- } catch (FileNotFoundException e) {
- ErrorLogHelper.logError(ERROR_CODE_AAI_4001, globalAuthFileName + ". Exception: " + e);
- } catch (JsonProcessingException e) {
- ErrorLogHelper.logError(ERROR_CODE_AAI_4001, globalAuthFileName + ". Not valid JSON: " + e);
- } catch (Exception e) {
- ErrorLogHelper.logError(ERROR_CODE_AAI_4001, globalAuthFileName + ". Exception caught: " + e);
- }
- }
-
- private List<String> getRoleHttpMethods(String aaiFunctionName, JsonObject roleObject) {
- List<String> httpMethods = new ArrayList<>();
-
- JsonArray ja = roleObject.getAsJsonArray("functions");
- for (JsonElement je : ja) {
- if (je.isJsonObject() && je.getAsJsonObject().has("name")
- && je.getAsJsonObject().get("name").getAsString().equals(aaiFunctionName)) {
- JsonArray jaMeth = je.getAsJsonObject().getAsJsonArray("methods");
- for (JsonElement jeMeth : jaMeth) {
- if (jeMeth.isJsonObject() && jeMeth.getAsJsonObject().has("name")) {
- httpMethods.add(jeMeth.getAsJsonObject().get("name").getAsString());
- }
- }
- }
- }
-
- return httpMethods;
- }
-
- private List<String> getAAIFunctions(JsonObject roleObject) {
- List<String> aaiFunctions = new ArrayList<>();
-
- JsonArray ja = roleObject.getAsJsonArray("functions");
- for (JsonElement je : ja) {
- if (je.isJsonObject() && je.getAsJsonObject().has("name")) {
- aaiFunctions.add(je.getAsJsonObject().get("name").getAsString());
- }
- }
-
- return aaiFunctions;
- }
-
- private Map<String, Boolean> getUsernamesFromRole(JsonObject roleObject) throws UnsupportedEncodingException {
- Map<String, Boolean> usernames = new HashMap<>();
-
- JsonArray uja = roleObject.getAsJsonArray("users");
- for (JsonElement je : uja) {
- if (je.isJsonObject()) {
- if (je.getAsJsonObject().has("username")) {
- if (je.getAsJsonObject().has("is-wildcard-id")) {
- usernames.put(je.getAsJsonObject().get("username").getAsString().toLowerCase(),
- je.getAsJsonObject().get("is-wildcard-id").getAsBoolean());
- } else {
- usernames.put(je.getAsJsonObject().get("username").getAsString().toLowerCase(), false);
- }
- } else if (je.getAsJsonObject().has("user")) {
- String auth = je.getAsJsonObject().get("user").getAsString() + ":"
- + Password.deobfuscate(je.getAsJsonObject().get("pass").getAsString());
- String authorizationCode = new String(Base64.base64Encode(auth.getBytes("utf-8")));
- usernames.put(authorizationCode, false);
- }
- }
- }
-
- return usernames;
- }
-
- public String getAuthPolicyFunctName(String uri) {
- String authPolicyFunctionName = "";
- if (uri.startsWith(basePath + "/search")) {
- authPolicyFunctionName = "search";
- } else if (uri.startsWith(basePath + "/recents")) {
- authPolicyFunctionName = "recents";
- } else if (uri.startsWith(basePath + "/cq2gremlin")) {
- authPolicyFunctionName = "cq2gremlin";
- } else if (uri.startsWith(basePath + "/cq2gremlintest")) {
- authPolicyFunctionName = "cq2gremlintest";
- } else if (uri.startsWith(basePath + "/util/echo")) {
- authPolicyFunctionName = "util";
- } else if (uri.startsWith(basePath + "/tools")) {
- authPolicyFunctionName = "tools";
- } else {
- Matcher match = AUTH_POLICY_PATTERN.matcher(uri);
- if (match.find()) {
- authPolicyFunctionName = match.group(1);
- }
- }
- return authPolicyFunctionName;
- }
-
- /**
- * for backwards compatibility
- *
- * @param username
- * @param uri
- * @param httpMethod
- * @param haProxyUser
- * @return
- * @throws AAIUnrecognizedFunctionException
- */
- public boolean authorize(String username, String uri, String httpMethod, String haProxyUser)
- throws AAIUnrecognizedFunctionException {
- return authorize(username, uri, httpMethod, haProxyUser, null);
- }
-
- /**
- *
- * @param username
- * @param uri
- * @param httpMethod
- * @param haProxyUser
- * @param issuer issuer of the cert
- * @return
- * @throws AAIUnrecognizedFunctionException
- */
- public boolean authorize(String username, String uri, String httpMethod, String haProxyUser, String issuer)
- throws AAIUnrecognizedFunctionException {
- String aaiMethod = this.getAuthPolicyFunctName(uri);
- if (!this.validFunctions.contains(aaiMethod)) {
- throw new AAIUnrecognizedFunctionException(aaiMethod);
- }
- boolean wildcardCheck = isWildcardIssuer(issuer);
- boolean authorized;
- LOGGER.debug(
- "Authorizing the user for the request cert {}, haproxy header {}, aai method {}, httpMethod {}, cert issuer {}",
- username, haProxyUser, aaiMethod, httpMethod, issuer);
- Optional<AAIUser> oau = this.getUser(username, wildcardCheck);
- if (oau.isPresent()) {
- AAIUser au = oau.get();
- if (au.hasRole("HAProxy")) {
- LOGGER.debug("User has HAProxy role");
- if ("GET".equalsIgnoreCase(httpMethod) && "util".equalsIgnoreCase(aaiMethod) && haProxyUser.isEmpty()) {
- LOGGER.debug("Authorized user has HAProxy role with echo request");
- authorized = this.authorize(au, aaiMethod, httpMethod);
- } else {
- authorized = this.authorize(haProxyUser, uri, httpMethod, "", issuer);
- }
- } else {
- LOGGER.debug("User doesn't have HAProxy role so assuming its a regular client");
- authorized = this.authorize(au, aaiMethod, httpMethod);
- }
- } else {
- LOGGER.debug("User not found: " + username + " on function " + aaiMethod + " request type " + httpMethod);
- authorized = false;
- }
-
- return authorized;
- }
-
- private boolean isWildcardIssuer(String issuer) {
- if (issuer != null && !issuer.isEmpty()) {
- List<String> validIssuers = Arrays
- .asList(AAIConfig.get("aaf.valid.issuer.wildcard", UUID.randomUUID().toString()).split("\\|"));
- for (String validIssuer : validIssuers) {
- if (issuer.contains(validIssuer)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * returns aai user either matching the username or containing the wildcard.
- *
- * @param username
- * @return
- */
- public Optional<AAIUser> getUser(String username, boolean wildcardCheck) {
- if (users.containsKey(username)) {
- return Optional.of(users.get(username));
- } else if (wildcardCheck) {
- List<AAIUser> laus =
- users.entrySet().stream().filter(e -> e.getValue().isWildcard() && username.contains(e.getKey()))
- .map(Map.Entry::getValue).collect(Collectors.toList());
- if (!laus.isEmpty()) {
- return Optional.of(laus.get(0));
- }
- }
- return Optional.empty();
- }
-
- /**
- *
- * @param aaiUser
- * aai user with the username
- * @param aaiMethod
- * aai function the authorization is required on
- * @param httpMethod
- * http action user is attempting
- * @return true, if successful
- */
- private boolean authorize(AAIUser aaiUser, String aaiMethod, String httpMethod) {
- if (aaiUser.hasAccess(aaiMethod, httpMethod)) {
- LoggingContext.statusCode(StatusCode.COMPLETE);
- LOGGER.debug("AUTH ACCEPTED: " + aaiUser.getUsername() + " on function " + aaiMethod + " request type "
- + httpMethod);
- return true;
- } else {
- LoggingContext.statusCode(StatusCode.ERROR);
- LOGGER.debug("AUTH FAILED: " + aaiUser.getUsername() + " on function " + aaiMethod + " request type "
- + httpMethod);
- return false;
- }
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/auth/AAIUser.java b/aai-core/src/main/java/org/onap/aai/auth/AAIUser.java
deleted file mode 100644
index f1e1b084..00000000
--- a/aai-core/src/main/java/org/onap/aai/auth/AAIUser.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Modifications Copyright © 2018 IBM.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.auth;
-
-import java.util.*;
-
-public class AAIUser {
-
- private String username;
-
- private boolean isWildcard = false;
- private Set<String> roles;
- private Map<String, Set<String>> aaiFunctionToHttpMethod;
-
- public AAIUser(String username) {
- this(username, false);
- }
-
- public AAIUser(String username, boolean isWildcard) {
- this.username = username;
- this.roles = new HashSet<>();
- this.aaiFunctionToHttpMethod = new HashMap<>();
- this.isWildcard = isWildcard;
- }
-
- public boolean isWildcard() {
- return isWildcard;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void addRole(String role) {
- this.roles.add(role);
- }
-
- public boolean hasRole(String role) {
- return this.roles.contains(role);
- }
-
- public void setUserAccess(String aaiMethod, String... httpMethods) {
- for (String httpMethod : httpMethods) {
- this.addUserAccess(aaiMethod, httpMethod);
- }
- }
-
- private void addUserAccess(String aaiMethod, String httpMethod) {
- Set<String> httpMethods = new HashSet<>();
- if (this.aaiFunctionToHttpMethod.containsKey(aaiMethod)) {
- httpMethods = this.aaiFunctionToHttpMethod.get(aaiMethod);
- }
- httpMethods.add(httpMethod);
- this.aaiFunctionToHttpMethod.put(aaiMethod, httpMethods);
- }
-
- public boolean hasAccess(String aaiMethod, String httpMethod) {
- return this.aaiFunctionToHttpMethod.getOrDefault(aaiMethod, Collections.emptySet()).contains(httpMethod);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/auth/exceptions/AAIUnrecognizedFunctionException.java b/aai-core/src/main/java/org/onap/aai/auth/exceptions/AAIUnrecognizedFunctionException.java
deleted file mode 100644
index 1410b445..00000000
--- a/aai-core/src/main/java/org/onap/aai/auth/exceptions/AAIUnrecognizedFunctionException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Modifications Copyright © 2018 IBM.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.auth.exceptions;
-
-import org.onap.aai.exceptions.AAIException;
-
-public class AAIUnrecognizedFunctionException extends AAIException {
-
- private static final String AAI_3012 = "AAI_3012";
- private static final long serialVersionUID = 3297064867724071290L;
-
- public AAIUnrecognizedFunctionException() {
- }
-
- public AAIUnrecognizedFunctionException(String message) {
- super(AAI_3012, message);
- }
-
- public AAIUnrecognizedFunctionException(Throwable cause) {
- super(AAI_3012, cause);
- }
-
- public AAIUnrecognizedFunctionException(String message, Throwable cause) {
- super(AAI_3012, cause, message);
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java b/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java
index 6ea67b90..69560ec1 100644
--- a/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java
+++ b/aai-core/src/main/java/org/onap/aai/concurrent/AaiCallable.java
@@ -44,7 +44,9 @@ public abstract class AaiCallable<T> implements Callable<T> {
* The call method
*/
public T call() throws Exception {
- MDC.setContextMap(mdcCopy);
+ if ( mdcCopy != null ) {
+ MDC.setContextMap(mdcCopy);
+ }
return process();
}
diff --git a/aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java b/aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java
index 9f8bbc45..24e7ec5a 100644
--- a/aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java
+++ b/aai-core/src/main/java/org/onap/aai/config/AuthorizationConfiguration.java
@@ -20,7 +20,7 @@
package org.onap.aai.config;
-import org.onap.aai.auth.AAIAuthCore;
+import org.onap.aai.aaf.auth.AAIAuthCore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/aai-core/src/main/java/org/onap/aai/logging/CustomLogPatternLayoutEncoder.java b/aai-core/src/main/java/org/onap/aai/config/XmlFormatTransformerConfiguration.java
index 010d828b..0c83c2b3 100644
--- a/aai-core/src/main/java/org/onap/aai/logging/CustomLogPatternLayoutEncoder.java
+++ b/aai-core/src/main/java/org/onap/aai/config/XmlFormatTransformerConfiguration.java
@@ -17,24 +17,17 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+package org.onap.aai.config;
-package org.onap.aai.logging;
+import org.onap.aai.transforms.XmlFormatTransformer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
-import ch.qos.logback.access.PatternLayout;
+@Configuration
+public class XmlFormatTransformerConfiguration {
-public class CustomLogPatternLayoutEncoder extends ch.qos.logback.access.PatternLayoutEncoder {
-
- /**
- * @{inheritDoc}
- */
- @Override
- public void start() {
- PatternLayout patternLayout = new CustomLogPatternLayout();
- patternLayout.setContext(context);
- patternLayout.setPattern(getPattern());
- patternLayout.start();
- this.layout = patternLayout;
- super.start();
+ @Bean
+ public XmlFormatTransformer xmlFormatTransformer(){
+ return new XmlFormatTransformer();
}
-
}
diff --git a/aai-core/src/main/java/org/onap/aai/db/props/AAIProperties.java b/aai-core/src/main/java/org/onap/aai/db/props/AAIProperties.java
index a0f6d77e..7dbc3a1d 100644
--- a/aai-core/src/main/java/org/onap/aai/db/props/AAIProperties.java
+++ b/aai-core/src/main/java/org/onap/aai/db/props/AAIProperties.java
@@ -32,9 +32,15 @@ public class AAIProperties {
public static final String RESOURCE_VERSION = "resource-version";
public static final String AAI_URI = "aai-uri";
public static final Integer MAXIMUM_DEPTH = 10000;
+ public static final Integer MINIMUM_DEPTH = 0;
public static final String LINKED = "linked";
public static final String DB_ALIAS_SUFFIX = "-local";
public static final String AAI_UUID = "aai-uuid";
+ public static final String START_TS = "start-ts";
+ public static final String END_TS = "end-ts";
+ public static final String END_SOT = "end-source-of-truth";
+ public static final String START_TX_ID = "start-tx-id";
+ public static final String END_TX_ID = "end-tx-id";
private AAIProperties() {
diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java b/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java
index fdc8e814..d3dfd150 100644
--- a/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java
+++ b/aai-core/src/main/java/org/onap/aai/dbgen/GraphSONPartialReader.java
@@ -20,8 +20,8 @@
package org.onap.aai.dbgen;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@@ -77,7 +77,7 @@ public final class GraphSONPartialReader implements GraphReader {
private boolean unwrapAdjacencyList = false;
private final GraphSONReader reader;
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(InMemoryGraph.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryGraph.class);
final TypeReference<Map<String, Object>> mapTypeReference = new TypeReference<Map<String, Object>>() {};
diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java
index bfd1f55b..d253f876 100644
--- a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java
+++ b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator.java
@@ -20,8 +20,8 @@
package org.onap.aai.dbgen;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.collect.Multimap;
import java.util.HashMap;
@@ -49,7 +49,7 @@ import org.onap.aai.util.AAIConfig;
public class SchemaGenerator {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SchemaGenerator.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(SchemaGenerator.class);
/**
* Load schema into JanusGraph.
diff --git a/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java
new file mode 100644
index 00000000..0f88de24
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/dbgen/SchemaGenerator4Hist.java
@@ -0,0 +1,238 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.dbgen;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.collect.Multimap;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.janusgraph.core.Cardinality;
+import org.janusgraph.core.JanusGraph;
+import org.janusgraph.core.Multiplicity;
+import org.janusgraph.core.PropertyKey;
+import org.janusgraph.core.schema.JanusGraphManagement;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.edges.EdgeIngestor;
+import org.onap.aai.edges.EdgeRule;
+import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderUtil;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.schema.enums.PropertyMetadata;
+import org.onap.aai.util.AAIConfig;
+
+import java.util.*;
+
+import static org.onap.aai.db.props.AAIProperties.*;
+
+public class SchemaGenerator4Hist {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SchemaGenerator4Hist.class);
+
+ /**
+ * Load schema into JanusGraph.
+ *
+ * @param graph
+ * the graph
+ * @param graphMgmt
+ * the graph mgmt
+ */
+ public static void loadSchemaIntoJanusGraph(final JanusGraph graph, final JanusGraphManagement graphMgmt,
+ String backend) {
+
+ try {
+ AAIConfig.init();
+ } catch (Exception ex) {
+ LOGGER.error(" ERROR - Could not run AAIConfig.init(). " + LogFormatTools.getStackTop(ex));
+ // System.out.println(" ERROR - Could not run AAIConfig.init(). ");
+ System.exit(1);
+ }
+
+ // NOTE - JanusGraph 0.5.3 doesn't keep a list of legal node Labels.
+ // They are only used when a vertex is actually being created.
+ // JanusGraph 1.1 will keep track (we think).
+
+ // Use EdgeRules to make sure edgeLabels are defined in the db. NOTE:
+ // the multiplicty used here is
+ // always "MULTI". This is not the same as our internal "Many2Many",
+ // "One2One", "One2Many" or "Many2One"
+ // We use the same edge-label for edges between many different types of
+ // nodes and our internal
+ // multiplicty definitions depends on which two types of nodes are being
+ // connected.
+
+ Multimap<String, EdgeRule> edges = null;
+ Set<String> labels = new HashSet<>();
+
+ EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class);
+
+ try {
+ edges = edgeIngestor.getAllCurrentRules();
+ } catch (EdgeRuleNotFoundException e) {
+ LOGGER.error("Unable to find all rules {}", LogFormatTools.getStackTop(e));
+ }
+
+ for (EdgeRule rule : edges.values()) {
+ labels.add(rule.getLabel());
+ }
+
+ for (String label : labels) {
+ if (graphMgmt.containsRelationType(label)) {
+ String dmsg = " EdgeLabel [" + label + "] already existed. ";
+ LOGGER.debug(dmsg);
+ } else {
+ String dmsg = "Making EdgeLabel: [" + label + "]";
+ LOGGER.debug(dmsg);
+ graphMgmt.makeEdgeLabel(label).multiplicity(Multiplicity.valueOf("MULTI")).make();
+ }
+ }
+
+ Loader loader = LoaderUtil.getLatestVersion();
+
+ Map<String, Introspector> objs = loader.getAllObjects();
+ Map<String, PropertyKey> seenProps = new HashMap<>();
+
+ for (Introspector obj : objs.values()) {
+ for (String propName : obj.getProperties()) {
+ String dbPropName = propName;
+ Optional<String> alias = obj.getPropertyMetadata(propName, PropertyMetadata.DB_ALIAS);
+ if (alias.isPresent()) {
+ dbPropName = alias.get();
+ }
+ if (graphMgmt.containsRelationType(dbPropName)) {
+ String dmsg = " PropertyKey [" + dbPropName + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else {
+ Class<?> type = obj.getClass(propName);
+ Cardinality cardinality = Cardinality.LIST;
+ boolean process = false;
+ if (obj.isListType(propName) && obj.isSimpleGenericType(propName)) {
+ // NOTE - For history - All properties have cardinality = LIST
+ // It is assumed that there is special processing in the Resources MS
+ // for History to turn what used to be SET (referred to as isListType
+ // above) will be stored in our db as a single String. And that
+ // single string will have Cardinality = LIST so we can track its
+ // history.
+ //cardinality = Cardinality.SET;
+ type = obj.getGenericTypeClass(propName);
+ process = true;
+ } else if (obj.isSimpleType(propName)) {
+ process = true;
+ }
+
+ if (process) {
+
+ String imsg = " Creating PropertyKey: [" + dbPropName + "], [" + type.getSimpleName() + "], ["
+ + cardinality + "]";
+ LOGGER.info(imsg);
+ PropertyKey propK;
+ if (!seenProps.containsKey(dbPropName)) {
+ propK = graphMgmt.makePropertyKey(dbPropName).dataType(type).cardinality(cardinality)
+ .make();
+ seenProps.put(dbPropName, propK);
+ } else {
+ propK = seenProps.get(dbPropName);
+ }
+ if (graphMgmt.containsGraphIndex(dbPropName)) {
+ String dmsg = " Index [" + dbPropName + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else {
+ if (obj.getIndexedProperties().contains(propName)) {
+ // NOTE - for History we never add a unique index - just a regular index
+ imsg = "Add index for PropertyKey: [" + dbPropName + "]";
+ LOGGER.info(imsg);
+ graphMgmt.buildIndex(dbPropName, Vertex.class).addKey(propK).buildCompositeIndex();
+ } else {
+ imsg = "No index needed/added for PropertyKey: [" + dbPropName + "]";
+ LOGGER.info(imsg);
+ }
+ }
+ }
+ }
+ }
+ }// Done processing all properties defined in the OXM
+
+ // Add the 3 new History properties are in the DB
+ // They are all Cardinality=Single since instance of a Node, Edge or Property can
+ // only have one of them. That is, a Property can show up many times in a
+ // node, but each instance of that property will only have a single start-ts,
+ // end-ts, end-source-of-truth. Same goes for a node or edge itself.
+ if (graphMgmt.containsRelationType(END_SOT)) {
+ String dmsg = "PropertyKey [" + END_SOT + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else if (!seenProps.containsKey(END_SOT) ) {
+ String imsg = " Creating PropertyKey: [" + END_SOT + "], [String], [SINGLE]";
+ LOGGER.info(imsg);
+ graphMgmt.makePropertyKey(END_SOT).dataType(String.class)
+ .cardinality(Cardinality.SINGLE).make();
+ }
+
+ if (graphMgmt.containsRelationType(START_TS)) {
+ String dmsg = " PropertyKey [" + START_TS + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else if (!seenProps.containsKey(START_TS) ) {
+ String imsg = " Creating PropertyKey: [" + START_TS + "], [Long], [SINGLE]";
+ LOGGER.info(imsg);
+ graphMgmt.makePropertyKey(START_TS).dataType(Long.class)
+ .cardinality(Cardinality.SINGLE).make();
+ }
+
+ if (graphMgmt.containsRelationType(END_TS)) {
+ String dmsg = "PropertyKey [" + END_TS + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else if (!seenProps.containsKey(END_TS) ) {
+ String imsg = " Creating PropertyKey: [" + END_TS + "], [Long], [SINGLE]";
+ LOGGER.info(imsg);
+ graphMgmt.makePropertyKey(END_TS).dataType(Long.class)
+ .cardinality(Cardinality.SINGLE).make();
+ }
+
+ if (graphMgmt.containsRelationType(START_TX_ID)) {
+ String dmsg = "PropertyKey [" + START_TX_ID + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else if (!seenProps.containsKey(START_TX_ID) ) {
+ String imsg = " Creating PropertyKey: [" + START_TX_ID + "], [String], [SINGLE]";
+ LOGGER.info(imsg);
+ graphMgmt.makePropertyKey(START_TX_ID).dataType(String.class)
+ .cardinality(Cardinality.SINGLE).make();
+ }
+
+ if (graphMgmt.containsRelationType(END_TX_ID)) {
+ String dmsg = "PropertyKey [" + END_TX_ID + "] already existed in the DB. ";
+ LOGGER.debug(dmsg);
+ } else if (!seenProps.containsKey(END_TX_ID) ) {
+ String imsg = " Creating PropertyKey: [" + END_TX_ID + "], [String], [SINGLE]";
+ LOGGER.info(imsg);
+ graphMgmt.makePropertyKey(END_TX_ID).dataType(String.class)
+ .cardinality(Cardinality.SINGLE).make();
+ }
+
+ String imsg = "-- About to call graphMgmt commit";
+ LOGGER.info(imsg);
+ graphMgmt.commit();
+ if (backend != null) {
+ LOGGER.info("Successfully loaded the schema to " + backend);
+ }
+
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java
index ca4e02f0..5bb4b656 100644
--- a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java
+++ b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraph.java
@@ -22,13 +22,8 @@
package org.onap.aai.dbmap;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import org.apache.commons.configuration.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -36,10 +31,15 @@ import org.apache.tinkerpop.gremlin.structure.io.IoCore;
import org.janusgraph.core.JanusGraph;
import org.janusgraph.core.JanusGraphFactory;
import org.janusgraph.core.schema.JanusGraphManagement;
+import org.onap.aai.config.SpringContextAware;
import org.onap.aai.dbgen.SchemaGenerator;
+import org.onap.aai.dbgen.SchemaGenerator4Hist;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.util.AAIConstants;
+import java.io.FileNotFoundException;
+import java.util.Properties;
+
/**
* Database Mapping class which acts as the middle man between the REST
* interface objects and JanusGraph DB objects. This class provides methods to commit
@@ -48,16 +48,13 @@ import org.onap.aai.util.AAIConstants;
* object to load, commit/rollback and shutdown for each request. The data model
* rules such as keys/required properties are handled by calling DBMeth methods
* which are driven by a specification file in json.
- *
- *
+ *
+ *
*/
public class AAIGraph {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(AAIGraph.class);
- protected static final String COMPONENT = "aaidbmap";
- protected Map<String, JanusGraph> graphs = new HashMap<>();
- private static final String REALTIME_DB = "realtime";
- private static final String CACHED_DB = "cached";
+ private static final Logger logger = LoggerFactory.getLogger(AAIGraph.class);
+ protected JanusGraph graph;
private static boolean isInit = false;
/**
@@ -67,15 +64,10 @@ public class AAIGraph {
try {
String serviceName = System.getProperty("aai.service.name", "NA");
String rtConfig = System.getProperty("realtime.db.config");
- String cachedConfig = System.getProperty("cached.db.config");
if (rtConfig == null) {
rtConfig = AAIConstants.REALTIME_DB_CONFIG;
}
- if (cachedConfig == null) {
- cachedConfig = AAIConstants.CACHED_DB_CONFIG;
- }
- this.loadGraph(REALTIME_DB, rtConfig, serviceName);
- this.loadGraph(CACHED_DB, cachedConfig, serviceName);
+ this.loadGraph(rtConfig, serviceName);
} catch (Exception e) {
throw new RuntimeException("Failed to instantiate graphs", e);
}
@@ -103,18 +95,17 @@ public class AAIGraph {
return isInit;
}
- private void loadGraph(final String name, final String configPath, final String serviceName)
- throws AAIException, ConfigurationException {
+ private void loadGraph(String configPath, String serviceName) throws Exception {
// Graph being opened by JanusGraphFactory is being placed in hashmap to be used later
// These graphs shouldn't be closed until the application shutdown
try {
- final PropertiesConfiguration propertiesConfiguration =
- new AAIGraphConfig.Builder(configPath).forService(serviceName).withGraphType(name).buildConfiguration();
- final JanusGraph graph = JanusGraphFactory.open(propertiesConfiguration);
+ PropertiesConfiguration propertiesConfiguration = new AAIGraphConfig.Builder(configPath)
+ .forService(serviceName).withGraphType("realtime").buildConfiguration();
+ graph = JanusGraphFactory.open(propertiesConfiguration);
- final Properties graphProps = new Properties();
+ Properties graphProps = new Properties();
propertiesConfiguration.getKeys()
- .forEachRemaining(k -> graphProps.setProperty(k, propertiesConfiguration.getString(k)));
+ .forEachRemaining(k -> graphProps.setProperty(k, propertiesConfiguration.getString(k)));
if ("inmemory".equals(graphProps.get("storage.backend"))) {
// Load the propertyKeys, indexes and edge-Labels into the DB
@@ -126,13 +117,12 @@ public class AAIGraph {
throw new AAIException("AAI_5102");
}
- graphs.put(name, graph);
- } catch (final FileNotFoundException fnfe) {
- throw new AAIException("AAI_4001");
+ } catch (FileNotFoundException e) {
+ throw new AAIException("AAI_4001", e);
}
}
- private void loadSnapShotToInMemoryGraph(final JanusGraph graph, final Properties graphProps) {
+ private void loadSnapShotToInMemoryGraph(JanusGraph graph, Properties graphProps) {
if (logger.isDebugEnabled()) {
logger.debug("Load Snapshot to InMemory Graph");
}
@@ -141,12 +131,12 @@ public class AAIGraph {
if ("true".equals(value)) {
try (Graph transaction = graph.newTransaction()) {
String location = System.getProperty("snapshot.location");
- logAndPrint(logger, "Loading snapshot to inmemory graph.");
+ logAndPrint("Loading snapshot to inmemory graph.");
transaction.io(IoCore.graphson()).readGraph(location);
transaction.tx().commit();
- logAndPrint(logger, "Snapshot loaded to inmemory graph.");
+ logAndPrint("Snapshot loaded to inmemory graph.");
} catch (Exception e) {
- logAndPrint(logger, "ERROR: Could not load datasnapshot to in memory graph. \n"
+ logAndPrint("ERROR: Could not load datasnapshot to in memory graph. \n"
+ ExceptionUtils.getFullStackTrace(e));
throw new RuntimeException(e);
}
@@ -154,19 +144,25 @@ public class AAIGraph {
}
}
- private void loadSchema(final JanusGraph graph) {
+ private void loadSchema(JanusGraph graph) {
// Load the propertyKeys, indexes and edge-Labels into the DB
JanusGraphManagement graphMgt = graph.openManagement();
System.out.println("-- loading schema into JanusGraph");
- SchemaGenerator.loadSchemaIntoJanusGraph(graph, graphMgt, "inmemory");
+ if ("true".equals(SpringContextAware.getApplicationContext().getEnvironment().getProperty("history.enabled", "false"))) {
+ SchemaGenerator4Hist.loadSchemaIntoJanusGraph(graph, graphMgt, "inmemory");
+ } else {
+ SchemaGenerator.loadSchemaIntoJanusGraph(graph, graphMgt, "inmemory");
+ }
}
/**
* Close all of the graph connections made in the instance.
*/
public void graphShutdown() {
- graphs.values().stream().filter(JanusGraph::isOpen).forEach(JanusGraph::close);
+ if (graph != null && graph.isOpen()) {
+ graph.close();
+ }
}
/**
@@ -175,30 +171,10 @@ public class AAIGraph {
* @return the graph
*/
public JanusGraph getGraph() {
- return graphs.get(REALTIME_DB);
- }
-
- public void graphShutdown(final DBConnectionType connectionType) {
-
- graphs.get(this.getGraphName(connectionType)).close();
- }
-
- public JanusGraph getGraph(final DBConnectionType connectionType) {
- return graphs.get(this.getGraphName(connectionType));
- }
-
- private String getGraphName(final DBConnectionType connectionType) {
- String graphName = "";
- if (DBConnectionType.CACHED.equals(connectionType)) {
- graphName = this.CACHED_DB;
- } else if (DBConnectionType.REALTIME.equals(connectionType)) {
- graphName = this.REALTIME_DB;
- }
-
- return graphName;
+ return graph;
}
- private void logAndPrint(final EELFLogger logger, final String msg) {
+ private void logAndPrint(String msg) {
System.out.println(msg);
logger.info(msg);
}
diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java
index d2f81610..ea939b32 100644
--- a/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java
+++ b/aai-core/src/main/java/org/onap/aai/dbmap/AAIGraphConfig.java
@@ -22,8 +22,8 @@ package org.onap.aai.dbmap;
import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.*;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
@@ -46,7 +46,7 @@ import org.janusgraph.diskstorage.configuration.backend.CommonsConfiguration;
*/
public class AAIGraphConfig {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(AAIGraphConfig.class);
+ private static final Logger logger = LoggerFactory.getLogger(AAIGraphConfig.class);
private AAIGraphConfig() {
};
diff --git a/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java b/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java
index 54986f37..d017b7e9 100644
--- a/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java
+++ b/aai-core/src/main/java/org/onap/aai/dbmap/InMemoryGraph.java
@@ -20,12 +20,15 @@
package org.onap.aai.dbmap;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.tinkerpop.gremlin.structure.io.IoCore;
import org.janusgraph.core.JanusGraph;
import org.janusgraph.core.JanusGraphFactory;
@@ -33,52 +36,56 @@ import org.janusgraph.core.JanusGraphTransaction;
import org.janusgraph.core.schema.JanusGraphManagement;
import org.onap.aai.dbgen.GraphSONPartialIO;
import org.onap.aai.dbgen.SchemaGenerator;
+import org.onap.aai.logging.LogFormatTools;
public class InMemoryGraph {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(InMemoryGraph.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryGraph.class);
private JanusGraph graph = null;
- public InMemoryGraph(final Builder builder) throws IOException {
+ public InMemoryGraph(Builder builder) throws IOException {
/*
* Create a In-memory graph
*/
- try (final InputStream is = new FileInputStream(builder.propertyFile);) {
+ InputStream is = new FileInputStream(builder.propertyFile);
+ try {
graph = JanusGraphFactory.open(builder.propertyFile);
- final Properties graphProps = new Properties();
+ Properties graphProps = new Properties();
graphProps.load(is);
- final JanusGraphManagement graphMgt = graph.openManagement();
+ JanusGraphManagement graphMgt = graph.openManagement();
if (builder.isSchemaEnabled) {
LOGGER.info("Schema Enabled");
SchemaGenerator.loadSchemaIntoJanusGraph(graph, graphMgt, graphProps.getProperty("storage.backend"));
}
- try (final JanusGraphTransaction transaction = graph.newTransaction();) {
- LOGGER.info("Loading snapshot");
- if (builder.isPartialGraph) {
- if ((builder.graphsonLocation != null) && (builder.graphsonLocation.length() > 0)) {
- transaction.io(GraphSONPartialIO.build()).readGraph(builder.graphsonLocation);
- } else {
- transaction.io(GraphSONPartialIO.build()).reader().create().readGraph(builder.seqInputStream,
+ JanusGraphTransaction transaction = graph.newTransaction();
+ LOGGER.info("Loading snapshot");
+ if (builder.isPartialGraph) {
+ if ((builder.graphsonLocation != null) && (builder.graphsonLocation.length() > 0)) {
+ transaction.io(GraphSONPartialIO.build()).readGraph(builder.graphsonLocation);
+ } else {
+ transaction.io(GraphSONPartialIO.build()).reader().create().readGraph(builder.seqInputStream,
graph);
- }
+ }
+ } else {
+ if ((builder.graphsonLocation != null) && (builder.graphsonLocation.length() > 0)) {
+ transaction.io(IoCore.graphson()).readGraph(builder.graphsonLocation);
} else {
- if ((builder.graphsonLocation != null) && (builder.graphsonLocation.length() > 0)) {
- transaction.io(IoCore.graphson()).readGraph(builder.graphsonLocation);
- } else {
- transaction.io(IoCore.graphson()).reader().create().readGraph(builder.seqInputStream, graph);
- }
+ transaction.io(IoCore.graphson()).reader().create().readGraph(builder.seqInputStream, graph);
}
- transaction.commit();
- } catch (final IOException e) {
- LOGGER.error("ERROR: Could not load datasnapshot to in memory graph. \n", e);
- throw new IllegalStateException("Could not load datasnapshot to in memory graph");
}
+ transaction.commit();
- } catch (final IOException e) {
- LOGGER.error("ERROR: Could not load datasnapshot to in memory graph. \n", e);
+ } catch (Exception e) {
+ // TODO : Changesysout to logger
+ e.printStackTrace();
+ LOGGER.error("ERROR: Could not load datasnapshot to in memory graph. \n" + LogFormatTools.getStackTop(e));
throw new IllegalStateException("Could not load datasnapshot to in memory graph");
+
+ } finally {
+ is.close();
}
+
}
public static class Builder {
diff --git a/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSConsumer.java b/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSConsumer.java
index 44ff599f..b3a8773e 100644
--- a/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSConsumer.java
+++ b/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSConsumer.java
@@ -22,43 +22,45 @@
package org.onap.aai.dmaap;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.util.Objects;
-import java.util.UUID;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.TextMessage;
-
-import org.apache.log4j.MDC;
import org.json.JSONException;
import org.json.JSONObject;
-import org.onap.aai.logging.LogFormatTools;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.LoggingContext.LoggingField;
-import org.onap.aai.logging.LoggingContext.StatusCode;
+import org.onap.aai.aailog.logs.AaiDmaapMetricLog;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.AaiElsErrorCode;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestTemplate;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.TextMessage;
+import java.util.Map;
+import java.util.Objects;
+
public class AAIDmaapEventJMSConsumer implements MessageListener {
private static final String EVENT_TOPIC = "event-topic";
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIDmaapEventJMSConsumer.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(AAIDmaapEventJMSConsumer.class);
private RestTemplate restTemplate;
private HttpHeaders httpHeaders;
private Environment environment;
+ private Map<String, String> mdcCopy;
+
public AAIDmaapEventJMSConsumer(Environment environment, RestTemplate restTemplate, HttpHeaders httpHeaders) {
+ super();
+ mdcCopy = MDC.getCopyOfContextMap();
Objects.nonNull(environment);
Objects.nonNull(restTemplate);
Objects.nonNull(httpHeaders);
@@ -76,41 +78,47 @@ public class AAIDmaapEventJMSConsumer implements MessageListener {
String jsmMessageTxt = "";
String aaiEvent = "";
+ JSONObject aaiEventHeader;
+ JSONObject joPayload;
+ String transactionId = "";
+ String serviceName = "";
String eventName = "";
- LoggingContext.save();
- LoggingContext.init();
+ String aaiElsErrorCode = AaiElsErrorCode.SUCCESS;
+ String errorDescription = "";
+
+ if ( mdcCopy != null ) {
+ MDC.setContextMap(mdcCopy);
+ }
+
if (message instanceof TextMessage) {
+ AaiDmaapMetricLog metricLog = new AaiDmaapMetricLog();
try {
jsmMessageTxt = ((TextMessage) message).getText();
JSONObject jo = new JSONObject(jsmMessageTxt);
-
if (jo.has("aaiEventPayload")) {
- aaiEvent = jo.getJSONObject("aaiEventPayload").toString();
+ joPayload = jo.getJSONObject("aaiEventPayload");
+ aaiEvent = joPayload.toString();
} else {
return;
}
- if (jo.getString("transId") != null) {
- LoggingContext.requestId(jo.getString("transId"));
- } else {
- final UUID generatedRequestUuid = UUID.randomUUID();
- LoggingContext.requestId(generatedRequestUuid.toString());
- }
- if (jo.getString("fromAppId") != null) {
- LoggingContext.partnerName(jo.getString("fromAppId"));
- }
- if (jo.getString(EVENT_TOPIC) != null) {
- eventName = jo.getString(EVENT_TOPIC);
+ if (jo.getString("event-topic") != null) {
+ eventName = jo.getString("event-topic");
}
-
- LoggingContext.targetEntity("DMAAP");
- if (jo.getString(EVENT_TOPIC) != null) {
- eventName = jo.getString(EVENT_TOPIC);
- LoggingContext.targetServiceName(eventName);
+ if (joPayload.has("event-header")) {
+ try {
+ aaiEventHeader = joPayload.getJSONObject("event-header");
+ if (aaiEventHeader.has("id")) {
+ transactionId = aaiEventHeader.get("id").toString();
+ }
+ if (aaiEventHeader.has("entity-link")) {
+ serviceName = aaiEventHeader.get("entity-link").toString();
+ }
+ }
+ catch (JSONException jexc) {
+ // ignore, this is just used for logging
+ }
}
- LoggingContext.serviceName("AAI");
- LoggingContext.statusCode(StatusCode.COMPLETE);
- LoggingContext.responseCode(LoggingContext.SUCCESS);
- LOGGER.info(eventName + "|" + aaiEvent);
+ metricLog.pre(eventName, aaiEvent, transactionId, serviceName);
HttpEntity httpEntity = new HttpEntity(aaiEvent, httpHeaders);
@@ -121,21 +129,20 @@ public class AAIDmaapEventJMSConsumer implements MessageListener {
if ("AAI-EVENT".equals(eventName)) {
restTemplate.exchange(baseUrl + endpoint, HttpMethod.POST, httpEntity, String.class);
} else {
- LoggingContext.statusCode(StatusCode.ERROR);
LOGGER.error(eventName + "|Event Topic invalid.");
}
} catch (JMSException | JSONException e) {
- LoggingContext.statusCode(StatusCode.ERROR);
- LoggingContext.responseCode(LoggingContext.DATA_ERROR);
- LOGGER.error("AAI_7350 Error parsing aaievent jsm message for sending to dmaap. {} {}", jsmMessageTxt,
- LogFormatTools.getStackTop(e));
+ aaiElsErrorCode = AaiElsErrorCode.DATA_ERROR;
+ errorDescription = e.getMessage();
+ ErrorLogHelper.logException(new AAIException("AAI_7350"));
} catch (Exception e) {
- LoggingContext.statusCode(StatusCode.ERROR);
- LoggingContext.responseCode(LoggingContext.AVAILABILITY_TIMEOUT_ERROR);
- LOGGER.error("AAI_7350 Error sending message to dmaap. {} {}", jsmMessageTxt,
- LogFormatTools.getStackTop(e));
+ aaiElsErrorCode = AaiElsErrorCode.AVAILABILITY_TIMEOUT_ERROR;
+ errorDescription = e.getMessage();
+ ErrorLogHelper.logException(new AAIException("AAI_7304", jsmMessageTxt));
+ }
+ finally {
+ metricLog.post(aaiElsErrorCode, errorDescription);
}
}
-
}
}
diff --git a/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSProducer.java b/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSProducer.java
index 4036b907..eb0d1658 100644
--- a/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSProducer.java
+++ b/aai-core/src/main/java/org/onap/aai/dmaap/AAIDmaapEventJMSProducer.java
@@ -50,4 +50,12 @@ public class AAIDmaapEventJMSProducer implements MessageProducer {
ccf.destroy();
}
}
+
+ public void sendMessageToDefaultDestination(String msg) {
+ if (jmsTemplate != null) {
+ jmsTemplate.convertAndSend(msg);
+ CachingConnectionFactory ccf = (CachingConnectionFactory) this.jmsTemplate.getConnectionFactory();
+ ccf.destroy();
+ }
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/dmaap/MessageProducer.java b/aai-core/src/main/java/org/onap/aai/dmaap/MessageProducer.java
index 9b17d881..1df64b69 100644
--- a/aai-core/src/main/java/org/onap/aai/dmaap/MessageProducer.java
+++ b/aai-core/src/main/java/org/onap/aai/dmaap/MessageProducer.java
@@ -25,4 +25,5 @@ import org.json.JSONObject;
public interface MessageProducer {
void sendMessageToDefaultDestination(JSONObject finalJson);
+ void sendMessageToDefaultDestination(String msg);
}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/model/AAIResources.java b/aai-core/src/main/java/org/onap/aai/domain/model/AAIResources.java
index 4e5f0392..413faf62 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/model/AAIResources.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/model/AAIResources.java
@@ -20,10 +20,10 @@
package org.onap.aai.domain.model;
-import java.util.HashMap;
-
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import java.util.HashMap;
+
public class AAIResources {
private DynamicJAXBContext jaxbContext;
diff --git a/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java b/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java
index d8b9b997..1e6307cc 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/notificationEvent/NotificationEvent.java
@@ -18,30 +18,25 @@
* ============LICENSE_END=========================================================
*/
//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2016.01.06 at 05:38:00 PM EST
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2016.01.06 at 05:38:00 PM EST
//
package org.onap.aai.domain.notificationEvent;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAnyElement;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
import org.w3c.dom.Element;
+import javax.xml.bind.annotation.*;
+
/**
* <p>
* Java class for anonymous complex type.
- *
+ *
* <p>
* The following schema fragment specifies the expected content contained within this class.
- *
+ *
* <pre>
* &lt;complexType>
* &lt;complexContent>
@@ -77,8 +72,8 @@ import org.w3c.dom.Element;
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
- *
- *
+ *
+ *
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"cambriaPartition", "eventHeader", "entity"})
@@ -94,11 +89,11 @@ public class NotificationEvent {
/**
* Gets the value of the eventHeader property.
- *
+ *
* @return
* possible object is
* {@link EventHeader }
- *
+ *
*/
public EventHeader getEventHeader() {
return eventHeader;
@@ -106,11 +101,11 @@ public class NotificationEvent {
/**
* Sets the value of the eventHeader property.
- *
+ *
* @param value
* allowed object is
* {@link EventHeader }
- *
+ *
*/
public void setEventHeader(EventHeader value) {
this.eventHeader = value;
@@ -118,12 +113,12 @@ public class NotificationEvent {
/**
* Gets the value of the any property.
- *
+ *
* @return
* possible object is
* {@link Object }
* {@link Element }
- *
+ *
*/
public Object getEntity() {
return entity;
@@ -131,12 +126,12 @@ public class NotificationEvent {
/**
* Sets the value of the any property.
- *
+ *
* @param value
* allowed object is
* {@link Object }
* {@link Element }
- *
+ *
*/
public void setEntity(Object value) {
this.entity = value;
@@ -144,11 +139,11 @@ public class NotificationEvent {
/**
* Gets the value of the cambriaPartition property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getCambriaPartition() {
return cambriaPartition;
@@ -156,11 +151,11 @@ public class NotificationEvent {
/**
* Sets the value of the cambriaPartition property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setCambriaPartition(String value) {
this.cambriaPartition = value;
@@ -169,10 +164,10 @@ public class NotificationEvent {
/**
* <p>
* Java class for anonymous complex type.
- *
+ *
* <p>
* The following schema fragment specifies the expected content contained within this class.
- *
+ *
* <pre>
* &lt;complexType>
* &lt;complexContent>
@@ -196,8 +191,8 @@ public class NotificationEvent {
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
- *
- *
+ *
+ *
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
@@ -235,11 +230,11 @@ public class NotificationEvent {
/**
* Gets the value of the id property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getId() {
return id;
@@ -247,11 +242,11 @@ public class NotificationEvent {
/**
* Sets the value of the id property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setId(String value) {
this.id = value;
@@ -259,11 +254,11 @@ public class NotificationEvent {
/**
* Gets the value of the timestamp property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getTimestamp() {
return timestamp;
@@ -271,11 +266,11 @@ public class NotificationEvent {
/**
* Sets the value of the timestamp property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setTimestamp(String value) {
this.timestamp = value;
@@ -283,11 +278,11 @@ public class NotificationEvent {
/**
* Gets the value of the sourceName property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getSourceName() {
return sourceName;
@@ -295,11 +290,11 @@ public class NotificationEvent {
/**
* Sets the value of the sourceName property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setSourceName(String value) {
this.sourceName = value;
@@ -307,11 +302,11 @@ public class NotificationEvent {
/**
* Gets the value of the domain property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getDomain() {
return domain;
@@ -319,11 +314,11 @@ public class NotificationEvent {
/**
* Sets the value of the domain property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setDomain(String value) {
this.domain = value;
@@ -331,11 +326,11 @@ public class NotificationEvent {
/**
* Gets the value of the sequenceNumber property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getSequenceNumber() {
return sequenceNumber;
@@ -343,11 +338,11 @@ public class NotificationEvent {
/**
* Sets the value of the sequenceNumber property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setSequenceNumber(String value) {
this.sequenceNumber = value;
@@ -355,11 +350,11 @@ public class NotificationEvent {
/**
* Gets the value of the severity property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getSeverity() {
return severity;
@@ -367,11 +362,11 @@ public class NotificationEvent {
/**
* Sets the value of the severity property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setSeverity(String value) {
this.severity = value;
@@ -379,11 +374,11 @@ public class NotificationEvent {
/**
* Gets the value of the eventType property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getEventType() {
return eventType;
@@ -391,11 +386,11 @@ public class NotificationEvent {
/**
* Sets the value of the eventType property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setEventType(String value) {
this.eventType = value;
@@ -403,11 +398,11 @@ public class NotificationEvent {
/**
* Gets the value of the version property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getVersion() {
return version;
@@ -415,11 +410,11 @@ public class NotificationEvent {
/**
* Sets the value of the version property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setVersion(String value) {
this.version = value;
@@ -427,11 +422,11 @@ public class NotificationEvent {
/**
* Gets the value of the action property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getAction() {
return action;
@@ -439,11 +434,11 @@ public class NotificationEvent {
/**
* Sets the value of the action property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setAction(String value) {
this.action = value;
@@ -451,11 +446,11 @@ public class NotificationEvent {
/**
* Gets the value of the entityType property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getEntityType() {
return entityType;
@@ -463,11 +458,11 @@ public class NotificationEvent {
/**
* Sets the value of the entityType property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setEntityType(String value) {
this.entityType = value;
@@ -475,11 +470,11 @@ public class NotificationEvent {
/**
* Gets the value of the topEntityType property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getTopEntityType() {
return topEntityType;
@@ -487,11 +482,11 @@ public class NotificationEvent {
/**
* Sets the value of the topEntityType property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setTopEntityType(String value) {
this.topEntityType = value;
@@ -499,11 +494,11 @@ public class NotificationEvent {
/**
* Gets the value of the entityLink property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getEntityLink() {
return entityLink;
@@ -511,11 +506,11 @@ public class NotificationEvent {
/**
* Sets the value of the entityLink property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setEntityLink(String value) {
this.entityLink = value;
@@ -523,11 +518,11 @@ public class NotificationEvent {
/**
* Gets the value of the status property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getStatus() {
return status;
@@ -535,11 +530,11 @@ public class NotificationEvent {
/**
* Sets the value of the status property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setStatus(String value) {
this.status = value;
diff --git a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessage.java b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessage.java
index 6cd82eef..53311990 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessage.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessage.java
@@ -20,11 +20,7 @@
package org.onap.aai.domain.responseMessage;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
diff --git a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageData.java b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageData.java
index 76b73642..c48f1ed8 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageData.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageData.java
@@ -23,22 +23,16 @@
package org.onap.aai.domain.responseMessage;
//
-//This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-//See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-//Any modifications to this file will be lost upon recompilation of the source schema.
-//Generated on: 2015.09.11 at 11:53:27 AM EDT
+//This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
+//See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+//Any modifications to this file will be lost upon recompilation of the source schema.
+//Generated on: 2015.09.11 at 11:53:27 AM EDT
//
+import javax.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAnyElement;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"aaiResponseMessageDatum", "any"})
@XmlRootElement(name = "aai-response-message-data", namespace = "http://org.onap.aai.inventory")
diff --git a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageDatum.java b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageDatum.java
index 90c6e280..a8adffde 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageDatum.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessageDatum.java
@@ -20,11 +20,7 @@
package org.onap.aai.domain.responseMessage;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"aaiResponseMessageDatumKey", "aaiResponseMessageDatumValue",
diff --git a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessages.java b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessages.java
index 09bf30e3..8263e58d 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessages.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/responseMessage/AAIResponseMessages.java
@@ -21,29 +21,23 @@
package org.onap.aai.domain.responseMessage;
//
-//This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-//See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-//Any modifications to this file will be lost upon recompilation of the source schema.
-//Generated on: 2015.09.11 at 11:53:27 AM EDT
+//This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
+//See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+//Any modifications to this file will be lost upon recompilation of the source schema.
+//Generated on: 2015.09.11 at 11:53:27 AM EDT
//
+import javax.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAnyElement;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
/**
* <p>
* Java class for anonymous complex type.
- *
+ *
* <p>
* The following schema fragment specifies the expected content contained within this class.
- *
+ *
* <pre>
* &lt;complexType>
* &lt;complexContent>
@@ -77,8 +71,8 @@ import javax.xml.bind.annotation.XmlType;
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
- *
- *
+ *
+ *
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"aaiResponseMessage", "any"})
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/Fault.java b/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/Fault.java
deleted file mode 100644
index 55e45b64..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/Fault.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.02.11 at 04:54:39 PM EST
-//
-
-package org.onap.aai.domain.restPolicyException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-/**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="requestError">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="policyException">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {"requestError"})
-@XmlRootElement(name = "Fault")
-public class Fault {
-
- @XmlElement(required = true)
- protected RequestError requestError;
-
- /**
- * Gets the value of the requestError property.
- *
- * @return
- * possible object is
- * {@link RequestError }
- *
- */
- public RequestError getRequestError() {
- return requestError;
- }
-
- /**
- * Sets the value of the requestError property.
- *
- * @param value
- * allowed object is
- * {@link RequestError }
- *
- */
- public void setRequestError(RequestError value) {
- this.requestError = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="policyException">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"policyException"})
- public static class RequestError {
-
- @XmlElement(required = true)
- protected PolicyException policyException;
-
- /**
- * Gets the value of the policyException property.
- *
- * @return
- * possible object is
- * {@link PolicyException }
- *
- */
- public PolicyException getPolicyException() {
- return policyException;
- }
-
- /**
- * Sets the value of the policyException property.
- *
- * @param value
- * allowed object is
- * {@link PolicyException }
- *
- */
- public void setPolicyException(PolicyException value) {
- this.policyException = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"messageId", "text", "variables"})
- public static class PolicyException {
-
- @XmlElement(required = true)
- protected String messageId;
- @XmlElement(required = true)
- protected String text;
- @XmlElement(required = true)
- protected Variables variables;
-
- /**
- * Gets the value of the messageId property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getMessageId() {
- return messageId;
- }
-
- /**
- * Sets the value of the messageId property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setMessageId(String value) {
- this.messageId = value;
- }
-
- /**
- * Gets the value of the text property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getText() {
- return text;
- }
-
- /**
- * Sets the value of the text property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setText(String value) {
- this.text = value;
- }
-
- /**
- * Gets the value of the variables property.
- *
- * @return
- * possible object is
- * {@link Variables }
- *
- */
- public Variables getVariables() {
- return variables;
- }
-
- /**
- * Sets the value of the variables property.
- *
- * @param value
- * allowed object is
- * {@link Variables }
- *
- */
- public void setVariables(Variables value) {
- this.variables = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"variable"})
- public static class Variables {
-
- protected List<String> variable;
-
- /**
- * Gets the value of the variable property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the variable property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- *
- * <pre>
- * getVariable().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link String }
- *
- * @return the variable
- */
- public List<String> getVariable() {
- if (variable == null) {
- variable = new ArrayList<String>();
- }
- return this.variable;
- }
-
- }
-
- }
-
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/ObjectFactory.java b/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/ObjectFactory.java
deleted file mode 100644
index f85fe748..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/ObjectFactory.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.02.11 at 04:54:39 PM EST
-//
-
-package org.onap.aai.domain.restPolicyException;
-
-import javax.xml.bind.annotation.XmlRegistry;
-
-/**
- * This object contains factory methods for each
- * Java content interface and Java element interface
- * generated in the org.onap.aai.domain.restPolicyException package.
- * <p>
- * An ObjectFactory allows you to programatically
- * construct new instances of the Java representation
- * for XML content. The Java representation of XML
- * content can consist of schema derived interfaces
- * and classes representing the binding of schema
- * type definitions, element declarations and model
- * groups. Factory methods for each of these are
- * provided in this class.
- *
- */
-@XmlRegistry
-public class ObjectFactory {
-
- /**
- * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package:
- * org.onap.aai.domain.restPolicyException
- *
- */
- public ObjectFactory() {
- }
-
- /**
- * Create an instance of {@link Fault }.
- *
- * @return the fault
- */
- public Fault createFault() {
- return new Fault();
- }
-
- /**
- * Create an instance of {@link Fault.RequestError }
- *
- * @return the request error
- */
- public Fault.RequestError createFaultRequestError() {
- return new Fault.RequestError();
- }
-
- /**
- * Create an instance of {@link Fault.RequestError.PolicyException }
- *
- * @return the policy exception
- */
- public Fault.RequestError.PolicyException createFaultRequestErrorPolicyException() {
- return new Fault.RequestError.PolicyException();
- }
-
- /**
- * Create an instance of {@link Fault.RequestError.PolicyException.Variables }
- *
- * @return the variables
- */
- public Fault.RequestError.PolicyException.Variables createFaultRequestErrorPolicyExceptionVariables() {
- return new Fault.RequestError.PolicyException.Variables();
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/PolicyException.java b/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/PolicyException.java
deleted file mode 100644
index 1aa2673a..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/PolicyException.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.domain.restPolicyException;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Generated;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Generated("org.jsonschema2pojo")
-@JsonPropertyOrder({"messageId", "text", "variables"})
-public class PolicyException {
-
- @JsonProperty("messageId")
- private String messageId;
- @JsonProperty("text")
- private String text;
- @JsonProperty("variables")
- private List<String> variables = new ArrayList<String>();
- @JsonIgnore
- private Map<String, Object> additionalProperties = new HashMap<String, Object>();
-
- /**
- * Gets the message id.
- *
- * @return The messageId
- */
- @JsonProperty("messageId")
- public String getMessageId() {
- return messageId;
- }
-
- /**
- * Sets the message id.
- *
- * @param messageId The messageId
- */
- @JsonProperty("messageId")
- public void setMessageId(String messageId) {
- this.messageId = messageId;
- }
-
- /**
- * Gets the text.
- *
- * @return The text
- */
- @JsonProperty("text")
- public String getText() {
- return text;
- }
-
- /**
- * Sets the text.
- *
- * @param text The text
- */
- @JsonProperty("text")
- public void setText(String text) {
- this.text = text;
- }
-
- /**
- * Gets the variables.
- *
- * @return The variables
- */
- @JsonProperty("variables")
- public List<String> getVariables() {
- return variables;
- }
-
- /**
- * Sets the variables.
- *
- * @param variables The variables
- */
- @JsonProperty("variables")
- public void setVariables(List<String> variables) {
- this.variables = variables;
- }
-
- /**
- * Gets the additional properties.
- *
- * @return the additional properties
- */
- @JsonAnyGetter
- public Map<String, Object> getAdditionalProperties() {
- return this.additionalProperties;
- }
-
- /**
- * Sets the additional property.
- *
- * @param name the name
- * @param value the value
- */
- @JsonAnySetter
- public void setAdditionalProperty(String name, Object value) {
- this.additionalProperties.put(name, value);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RESTResponse.java b/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RESTResponse.java
deleted file mode 100644
index 262ca855..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RESTResponse.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.domain.restPolicyException;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.annotation.Generated;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Generated("org.jsonschema2pojo")
-@JsonPropertyOrder({"requestError"})
-public class RESTResponse {
-
- @JsonProperty("requestError")
- private RequestError requestError;
- @JsonIgnore
- private Map<String, Object> additionalProperties = new HashMap<String, Object>();
-
- /**
- * Gets the request error.
- *
- * @return The requestError
- */
- @JsonProperty("requestError")
- public RequestError getRequestError() {
- return requestError;
- }
-
- /**
- * Sets the request error.
- *
- * @param requestError The requestError
- */
- @JsonProperty("requestError")
- public void setRequestError(RequestError requestError) {
- this.requestError = requestError;
- }
-
- /**
- * Gets the additional properties.
- *
- * @return the additional properties
- */
- @JsonAnyGetter
- public Map<String, Object> getAdditionalProperties() {
- return this.additionalProperties;
- }
-
- /**
- * Sets the additional property.
- *
- * @param name the name
- * @param value the value
- */
- @JsonAnySetter
- public void setAdditionalProperty(String name, Object value) {
- this.additionalProperties.put(name, value);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RequestError.java b/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RequestError.java
deleted file mode 100644
index 54580de7..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restPolicyException/RequestError.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.domain.restPolicyException;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.annotation.Generated;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Generated("org.jsonschema2pojo")
-@JsonPropertyOrder({"policyException"})
-public class RequestError {
-
- @JsonProperty("policyException")
- private PolicyException policyException;
- @JsonIgnore
- private Map<String, Object> additionalProperties = new HashMap<String, Object>();
-
- /**
- * Gets the policy exception.
- *
- * @return The policyException
- */
- @JsonProperty("policyException")
- public PolicyException getPolicyException() {
- return policyException;
- }
-
- /**
- * Sets the policy exception.
- *
- * @param policyException The policyException
- */
- @JsonProperty("policyException")
- public void setPolicyException(PolicyException policyException) {
- this.policyException = policyException;
- }
-
- /**
- * Gets the additional properties.
- *
- * @return the additional properties
- */
- @JsonAnyGetter
- public Map<String, Object> getAdditionalProperties() {
- return this.additionalProperties;
- }
-
- /**
- * Sets the additional property.
- *
- * @param name the name
- * @param value the value
- */
- @JsonAnySetter
- public void setAdditionalProperty(String name, Object value) {
- this.additionalProperties.put(name, value);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/Info.java b/aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/Info.java
deleted file mode 100644
index 789fe926..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/Info.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.10.28 at 05:53:17 PM EDT
-//
-
-package org.onap.aai.domain.restResponseInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-/**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="responseMessages" minOccurs="0">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="responseMessage" maxOccurs="unbounded" minOccurs="0">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {"responseMessages"})
-@XmlRootElement(name = "Info")
-public class Info {
-
- protected ResponseMessages responseMessages;
-
- /**
- * Gets the value of the responseMessages property.
- *
- * @return
- * possible object is
- * {@link ResponseMessages }
- *
- */
- public ResponseMessages getResponseMessages() {
- return responseMessages;
- }
-
- /**
- * Sets the value of the responseMessages property.
- *
- * @param value
- * allowed object is
- * {@link ResponseMessages }
- *
- */
- public void setResponseMessages(ResponseMessages value) {
- this.responseMessages = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="responseMessage" maxOccurs="unbounded" minOccurs="0">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"responseMessage"})
- public static class ResponseMessages {
-
- protected List<ResponseMessage> responseMessage;
-
- /**
- * Gets the value of the responseMessage property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the responseMessage property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- *
- * <pre>
- * getResponseMessage().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link ResponseMessage }
- *
- * @return the response message
- */
- public List<ResponseMessage> getResponseMessage() {
- if (responseMessage == null) {
- responseMessage = new ArrayList<ResponseMessage>();
- }
- return this.responseMessage;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"messageId", "text", "variables"})
- public static class ResponseMessage {
-
- @XmlElement(required = true)
- protected String messageId;
- @XmlElement(required = true)
- protected String text;
- @XmlElement(required = true)
- protected Variables variables;
-
- /**
- * Gets the value of the messageId property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getMessageId() {
- return messageId;
- }
-
- /**
- * Sets the value of the messageId property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setMessageId(String value) {
- this.messageId = value;
- }
-
- /**
- * Gets the value of the text property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getText() {
- return text;
- }
-
- /**
- * Sets the value of the text property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setText(String value) {
- this.text = value;
- }
-
- /**
- * Gets the value of the variables property.
- *
- * @return
- * possible object is
- * {@link Variables }
- *
- */
- public Variables getVariables() {
- return variables;
- }
-
- /**
- * Sets the value of the variables property.
- *
- * @param value
- * allowed object is
- * {@link Variables }
- *
- */
- public void setVariables(Variables value) {
- this.variables = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"variable"})
- public static class Variables {
-
- protected List<String> variable;
-
- /**
- * Gets the value of the variable property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the variable property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- *
- * <pre>
- * getVariable().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link String }
- *
- * @return the variable
- */
- public List<String> getVariable() {
- if (variable == null) {
- variable = new ArrayList<String>();
- }
- return this.variable;
- }
-
- }
-
- }
-
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/ObjectFactory.java b/aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/ObjectFactory.java
deleted file mode 100644
index 4efafb23..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restResponseInfo/ObjectFactory.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.10.28 at 05:53:17 PM EDT
-//
-
-package org.onap.aai.domain.restResponseInfo;
-
-import javax.xml.bind.annotation.XmlRegistry;
-
-/**
- * This object contains factory methods for each
- * Java content interface and Java element interface
- * generated in the org.onap.aai.domain.restResponseInfo package.
- * <p>
- * An ObjectFactory allows you to programatically
- * construct new instances of the Java representation
- * for XML content. The Java representation of XML
- * content can consist of schema derived interfaces
- * and classes representing the binding of schema
- * type definitions, element declarations and model
- * groups. Factory methods for each of these are
- * provided in this class.
- *
- */
-@XmlRegistry
-public class ObjectFactory {
-
- /**
- * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package:
- * org.onap.aai.domain.restResponseInfo
- *
- */
- public ObjectFactory() {
- }
-
- /**
- * Create an instance of {@link Info }.
- *
- * @return the info
- */
- public Info createInfo() {
- return new Info();
- }
-
- /**
- * Create an instance of {@link Info.ResponseMessages }
- *
- * @return the response messages
- */
- public Info.ResponseMessages createInfoResponseMessages() {
- return new Info.ResponseMessages();
- }
-
- /**
- * Create an instance of {@link Info.ResponseMessages.ResponseMessage }
- *
- * @return the response message
- */
- public Info.ResponseMessages.ResponseMessage createInfoResponseMessagesResponseMessage() {
- return new Info.ResponseMessages.ResponseMessage();
- }
-
- /**
- * Create an instance of {@link Info.ResponseMessages.ResponseMessage.Variables }
- *
- * @return the variables
- */
- public Info.ResponseMessages.ResponseMessage.Variables createInfoResponseMessagesResponseMessageVariables() {
- return new Info.ResponseMessages.ResponseMessage.Variables();
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/Fault.java b/aai-core/src/main/java/org/onap/aai/domain/restServiceException/Fault.java
deleted file mode 100644
index 3efa13c3..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/Fault.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.02.11 at 04:54:29 PM EST
-//
-
-package org.onap.aai.domain.restServiceException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-/**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="requestError">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="serviceException">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "", propOrder = {"requestError"})
-@XmlRootElement(name = "Fault")
-public class Fault {
-
- @XmlElement(required = true)
- protected RequestError requestError;
-
- /**
- * Gets the value of the requestError property.
- *
- * @return
- * possible object is
- * {@link RequestError }
- *
- */
- public RequestError getRequestError() {
- return requestError;
- }
-
- /**
- * Sets the value of the requestError property.
- *
- * @param value
- * allowed object is
- * {@link RequestError }
- *
- */
- public void setRequestError(RequestError value) {
- this.requestError = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="serviceException">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"serviceException"})
- public static class RequestError {
-
- @XmlElement(required = true)
- protected ServiceException serviceException;
-
- /**
- * Gets the value of the serviceException property.
- *
- * @return
- * possible object is
- * {@link ServiceException }
- *
- */
- public ServiceException getServiceException() {
- return serviceException;
- }
-
- /**
- * Sets the value of the serviceException property.
- *
- * @param value
- * allowed object is
- * {@link ServiceException }
- *
- */
- public void setServiceException(ServiceException value) {
- this.serviceException = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="messageId" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="text" type="{http://www.w3.org/2001/XMLSchema}string"/>
- * &lt;element name="variables">
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * &lt;/element>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"messageId", "text", "variables"})
- public static class ServiceException {
-
- @XmlElement(required = true)
- protected String messageId;
- @XmlElement(required = true)
- protected String text;
- @XmlElement(required = true)
- protected Variables variables;
-
- /**
- * Gets the value of the messageId property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getMessageId() {
- return messageId;
- }
-
- /**
- * Sets the value of the messageId property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setMessageId(String value) {
- this.messageId = value;
- }
-
- /**
- * Gets the value of the text property.
- *
- * @return
- * possible object is
- * {@link String }
- *
- */
- public String getText() {
- return text;
- }
-
- /**
- * Sets the value of the text property.
- *
- * @param value
- * allowed object is
- * {@link String }
- *
- */
- public void setText(String value) {
- this.text = value;
- }
-
- /**
- * Gets the value of the variables property.
- *
- * @return
- * possible object is
- * {@link Variables }
- *
- */
- public Variables getVariables() {
- return variables;
- }
-
- /**
- * Sets the value of the variables property.
- *
- * @param value
- * allowed object is
- * {@link Variables }
- *
- */
- public void setVariables(Variables value) {
- this.variables = value;
- }
-
- /**
- * <p>
- * Java class for anonymous complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within this class.
- *
- * <pre>
- * &lt;complexType>
- * &lt;complexContent>
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- * &lt;sequence>
- * &lt;element name="variable" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
- * &lt;/sequence>
- * &lt;/restriction>
- * &lt;/complexContent>
- * &lt;/complexType>
- * </pre>
- *
- *
- */
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "", propOrder = {"variable"})
- public static class Variables {
-
- protected List<String> variable;
-
- /**
- * Gets the value of the variable property.
- *
- * <p>
- * This accessor method returns a reference to the live list,
- * not a snapshot. Therefore any modification you make to the
- * returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the variable property.
- *
- * <p>
- * For example, to add a new item, do as follows:
- *
- * <pre>
- * getVariable().add(newItem);
- * </pre>
- *
- *
- * <p>
- * Objects of the following type(s) are allowed in the list
- * {@link String }
- *
- * @return the variable
- */
- public List<String> getVariable() {
- if (variable == null) {
- variable = new ArrayList<String>();
- }
- return this.variable;
- }
-
- }
-
- }
-
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/ObjectFactory.java b/aai-core/src/main/java/org/onap/aai/domain/restServiceException/ObjectFactory.java
deleted file mode 100644
index 95eb2cba..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/ObjectFactory.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.02.11 at 04:54:29 PM EST
-//
-
-package org.onap.aai.domain.restServiceException;
-
-import javax.xml.bind.annotation.XmlRegistry;
-
-/**
- * This object contains factory methods for each
- * Java content interface and Java element interface
- * generated in the org.onap.aai.domain.restServiceException package.
- * <p>
- * An ObjectFactory allows you to programatically
- * construct new instances of the Java representation
- * for XML content. The Java representation of XML
- * content can consist of schema derived interfaces
- * and classes representing the binding of schema
- * type definitions, element declarations and model
- * groups. Factory methods for each of these are
- * provided in this class.
- *
- */
-@XmlRegistry
-public class ObjectFactory {
-
- /**
- * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package:
- * org.onap.aai.domain.restServiceException
- *
- */
- public ObjectFactory() {
- }
-
- /**
- * Create an instance of {@link Fault }.
- *
- * @return the fault
- */
- public Fault createFault() {
- return new Fault();
- }
-
- /**
- * Create an instance of {@link Fault.RequestError }
- *
- * @return the request error
- */
- public Fault.RequestError createFaultRequestError() {
- return new Fault.RequestError();
- }
-
- /**
- * Create an instance of {@link Fault.RequestError.ServiceException }
- *
- * @return the service exception
- */
- public Fault.RequestError.ServiceException createFaultRequestErrorServiceException() {
- return new Fault.RequestError.ServiceException();
- }
-
- /**
- * Create an instance of {@link Fault.RequestError.ServiceException.Variables }
- *
- * @return the variables
- */
- public Fault.RequestError.ServiceException.Variables createFaultRequestErrorServiceExceptionVariables() {
- return new Fault.RequestError.ServiceException.Variables();
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/RESTResponse.java b/aai-core/src/main/java/org/onap/aai/domain/restServiceException/RESTResponse.java
deleted file mode 100644
index 09178937..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/RESTResponse.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.domain.restServiceException;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.annotation.Generated;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Generated("org.jsonschema2pojo")
-@JsonPropertyOrder({"requestError"})
-public class RESTResponse {
-
- @JsonProperty("requestError")
- private RequestError requestError;
- @JsonIgnore
- private Map<String, Object> additionalProperties = new HashMap<String, Object>();
-
- /**
- * Gets the request error.
- *
- * @return The requestError
- */
- @JsonProperty("requestError")
- public RequestError getRequestError() {
- return requestError;
- }
-
- /**
- * Sets the request error.
- *
- * @param requestError The requestError
- */
- @JsonProperty("requestError")
- public void setRequestError(RequestError requestError) {
- this.requestError = requestError;
- }
-
- /**
- * Gets the additional properties.
- *
- * @return the additional properties
- */
- @JsonAnyGetter
- public Map<String, Object> getAdditionalProperties() {
- return this.additionalProperties;
- }
-
- /**
- * Sets the additional property.
- *
- * @param name the name
- * @param value the value
- */
- @JsonAnySetter
- public void setAdditionalProperty(String name, Object value) {
- this.additionalProperties.put(name, value);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/RequestError.java b/aai-core/src/main/java/org/onap/aai/domain/restServiceException/RequestError.java
deleted file mode 100644
index 38320218..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/RequestError.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.domain.restServiceException;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.annotation.Generated;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Generated("org.jsonschema2pojo")
-@JsonPropertyOrder({"serviceException"})
-public class RequestError {
-
- @JsonProperty("serviceException")
- private ServiceException serviceException;
- @JsonIgnore
- private Map<String, Object> additionalProperties = new HashMap<String, Object>();
-
- /**
- * Gets the service exception.
- *
- * @return The serviceException
- */
- @JsonProperty("serviceException")
- public ServiceException getServiceException() {
- return serviceException;
- }
-
- /**
- * Sets the service exception.
- *
- * @param serviceException The serviceException
- */
- @JsonProperty("serviceException")
- public void setServiceException(ServiceException serviceException) {
- this.serviceException = serviceException;
- }
-
- /**
- * Gets the additional properties.
- *
- * @return the additional properties
- */
- @JsonAnyGetter
- public Map<String, Object> getAdditionalProperties() {
- return this.additionalProperties;
- }
-
- /**
- * Sets the additional property.
- *
- * @param name the name
- * @param value the value
- */
- @JsonAnySetter
- public void setAdditionalProperty(String name, Object value) {
- this.additionalProperties.put(name, value);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/ServiceException.java b/aai-core/src/main/java/org/onap/aai/domain/restServiceException/ServiceException.java
deleted file mode 100644
index ec658ce3..00000000
--- a/aai-core/src/main/java/org/onap/aai/domain/restServiceException/ServiceException.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.domain.restServiceException;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Generated;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@Generated("org.jsonschema2pojo")
-@JsonPropertyOrder({"messageId", "text", "variables"})
-public class ServiceException {
-
- @JsonProperty("messageId")
- private String messageId;
- @JsonProperty("text")
- private String text;
- @JsonProperty("variables")
- private List<String> variables = new ArrayList<String>();
- @JsonIgnore
- private Map<String, Object> additionalProperties = new HashMap<String, Object>();
-
- /**
- * Gets the message id.
- *
- * @return The messageId
- */
- @JsonProperty("messageId")
- public String getMessageId() {
- return messageId;
- }
-
- /**
- * Sets the message id.
- *
- * @param messageId The messageId
- */
- @JsonProperty("messageId")
- public void setMessageId(String messageId) {
- this.messageId = messageId;
- }
-
- /**
- * Gets the text.
- *
- * @return The text
- */
- @JsonProperty("text")
- public String getText() {
- return text;
- }
-
- /**
- * Sets the text.
- *
- * @param text The text
- */
- @JsonProperty("text")
- public void setText(String text) {
- this.text = text;
- }
-
- /**
- * Gets the variables.
- *
- * @return The variables
- */
- @JsonProperty("variables")
- public List<String> getVariables() {
- return variables;
- }
-
- /**
- * Sets the variables.
- *
- * @param variables The variables
- */
- @JsonProperty("variables")
- public void setVariables(List<String> variables) {
- this.variables = variables;
- }
-
- /**
- * Gets the additional properties.
- *
- * @return the additional properties
- */
- @JsonAnyGetter
- public Map<String, Object> getAdditionalProperties() {
- return this.additionalProperties;
- }
-
- /**
- * Sets the additional property.
- *
- * @param name the name
- * @param value the value
- */
- @JsonAnySetter
- public void setAdditionalProperty(String name, Object value) {
- this.additionalProperties.put(name, value);
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntries.java b/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntries.java
index 7f02cb53..e81b3e3c 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntries.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntries.java
@@ -18,29 +18,28 @@
* ============LICENSE_END=========================================================
*/
//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2015.03.20 at 09:46:47 AM CDT
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Any modifications to this file will be lost upon recompilation of the source schema.
+// Generated on: 2015.03.20 at 09:46:47 AM CDT
//
package org.onap.aai.domain.translog;
-import java.util.ArrayList;
-import java.util.List;
-
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
+import java.util.ArrayList;
+import java.util.List;
/**
* <p>
* Java class for anonymous complex type.
- *
+ *
* <p>
* The following schema fragment specifies the expected content contained within this class.
- *
+ *
* <pre>
* &lt;complexType>
* &lt;complexContent>
@@ -102,8 +101,8 @@ import javax.xml.bind.annotation.XmlType;
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
- *
- *
+ *
+ *
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"transactionLogEntries"})
diff --git a/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntry.java b/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntry.java
index 2ce485be..16c773ae 100644
--- a/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntry.java
+++ b/aai-core/src/main/java/org/onap/aai/domain/translog/TransactionLogEntry.java
@@ -20,14 +20,10 @@
package org.onap.aai.domain.translog;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
import org.eclipse.persistence.oxm.annotations.XmlCDATA;
+import javax.xml.bind.annotation.*;
+
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "",
@@ -70,11 +66,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the transcationLogEntryId property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getTransactionLogEntryId() {
return transactionLogEntryId;
@@ -82,11 +78,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the transactionLogEntryId property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setTransactionLogEntryId(String value) {
this.transactionLogEntryId = value;
@@ -94,11 +90,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the status property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getStatus() {
return status;
@@ -106,11 +102,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the status property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setStatus(String value) {
this.status = value;
@@ -118,11 +114,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the rqstDate property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getRqstDate() {
@@ -131,11 +127,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the rqstDate property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setRqstDate(String value) {
this.rqstDate = value;
@@ -143,11 +139,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the respDate property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getRespDate() {
@@ -156,11 +152,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the respDate property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setRespDate(String value) {
this.respDate = value;
@@ -168,11 +164,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the sourceId property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getSourceId() {
return sourceId;
@@ -180,11 +176,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the sourceId property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setSourceId(String value) {
this.sourceId = value;
@@ -192,11 +188,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the resourceId property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getResourceId() {
return resourceId;
@@ -204,11 +200,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the resourceId property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setResourceId(String value) {
this.resourceId = value;
@@ -216,11 +212,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the resourceType property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getResourceType() {
return resourceType;
@@ -228,11 +224,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the resourceType property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setResourceType(String value) {
this.resourceType = value;
@@ -240,11 +236,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the rqstBuf property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getRqstBuf() {
return rqstBuf;
@@ -252,11 +248,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the rqstBuf property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
@XmlCDATA
public void setRqstBuf(String value) {
@@ -265,11 +261,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the respBuf property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getrespBuf() {
return respBuf;
@@ -277,11 +273,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the respBuf property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
@XmlCDATA
public void setrespBuf(String value) {
@@ -290,11 +286,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the notificationPayload property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getNotificationPayload() {
return notificationPayload;
@@ -302,11 +298,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the notificationPayload property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
@XmlCDATA
public void setNotificationPayload(String value) {
@@ -315,11 +311,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the notificationId property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getNotificationId() {
return notificationId;
@@ -327,11 +323,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the notificationId property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setNotificationId(String value) {
this.notificationId = value;
@@ -339,11 +335,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the notificationId property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getNotificationStatus() {
return notificationStatus;
@@ -351,11 +347,11 @@ public class TransactionLogEntry {
/**
* Sets the value of the notificationId property.
- *
+ *
* @param value
* allowed object is
* {@link String }
- *
+ *
*/
public void setNotificationStatus(String value) {
this.notificationStatus = value;
@@ -363,11 +359,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the notificationTopic property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getNotificationTopic() {
return notificationTopic;
@@ -384,11 +380,11 @@ public class TransactionLogEntry {
/**
* Gets the value of the notificationEntityLink property.
- *
+ *
* @return
* possible object is
* {@link String }
- *
+ *
*/
public String getNotificationEntityLink() {
return notificationEntityLink;
diff --git a/aai-core/src/main/java/org/onap/aai/exceptions/AAIException.java b/aai-core/src/main/java/org/onap/aai/exceptions/AAIException.java
deleted file mode 100644
index 320d5630..00000000
--- a/aai-core/src/main/java/org/onap/aai/exceptions/AAIException.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Modifications Copyright © 2018 IBM.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.exceptions;
-
-import java.util.Collection;
-import java.util.LinkedList;
-
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.ErrorObject;
-import org.onap.aai.logging.ErrorObjectNotFoundException;
-
-public class AAIException extends Exception {
-
- private static final String UPDATE_ERROR_PROPERTIES_BEFORE_USING_THIS_EXCEPTION_CODE =
- " - update error.properties before using this exception code";
- private static final String FAILED_TO_INSTANTIATE_AAI_EXCEPTION_WITH_CODE =
- "Failed to instantiate AAIException with code=";
- public static final String DEFAULT_EXCEPTION_CODE = "AAI_4000";
- private static final long serialVersionUID = 1L;
-
- private final String code;
- private final ErrorObject errorObject;
- private final Collection<String> templateVars;
-
- /**
- * Instantiates a new AAI exception.
- */
- public AAIException() {
- super();
- this.code = DEFAULT_EXCEPTION_CODE;
- this.templateVars = new LinkedList<>();
-
- try {
- this.errorObject = ErrorLogHelper.getErrorObject(getCode());
- } catch (ErrorObjectNotFoundException e) {
- throw new RuntimeException(FAILED_TO_INSTANTIATE_AAI_EXCEPTION_WITH_CODE + getCode()
- + UPDATE_ERROR_PROPERTIES_BEFORE_USING_THIS_EXCEPTION_CODE);
- }
- }
-
- /**
- * Instantiates a new AAI exception.
- *
- * @param code the code
- */
- public AAIException(String code) {
- super();
-
- this.code = code;
- this.templateVars = new LinkedList<>();
-
- try {
- this.errorObject = ErrorLogHelper.getErrorObject(getCode());
- } catch (ErrorObjectNotFoundException e) {
- throw new RuntimeException(FAILED_TO_INSTANTIATE_AAI_EXCEPTION_WITH_CODE + getCode()
- + UPDATE_ERROR_PROPERTIES_BEFORE_USING_THIS_EXCEPTION_CODE);
- }
- }
-
- /**
- * Instantiates a new AAI exception.
- *
- * @param code the code
- * @param details the details
- */
- public AAIException(String code, String details) {
- super(details);
-
- this.code = code;
- this.templateVars = new LinkedList<>();
-
- try {
- this.errorObject = ErrorLogHelper.getErrorObject(getCode());
- errorObject.setDetails(details);
- } catch (ErrorObjectNotFoundException e) {
- throw new RuntimeException(FAILED_TO_INSTANTIATE_AAI_EXCEPTION_WITH_CODE + getCode()
- + UPDATE_ERROR_PROPERTIES_BEFORE_USING_THIS_EXCEPTION_CODE);
- }
- }
-
- /**
- * Instantiates a new AAI exception.
- *
- * @param code the code
- * @param cause the cause
- */
- public AAIException(String code, Throwable cause) {
- super(cause);
-
- this.code = code;
- this.templateVars = new LinkedList<>();
-
- try {
- this.errorObject = ErrorLogHelper.getErrorObject(getCode());
- } catch (ErrorObjectNotFoundException e) {
- throw new RuntimeException(FAILED_TO_INSTANTIATE_AAI_EXCEPTION_WITH_CODE + getCode()
- + UPDATE_ERROR_PROPERTIES_BEFORE_USING_THIS_EXCEPTION_CODE);
- }
- }
-
- /**
- * Instantiates a new AAI exception.
- *
- * @param code the code
- * @param cause the cause
- * @param details the details
- */
- public AAIException(String code, Throwable cause, String details) {
- super(details, cause);
-
- this.code = code;
- this.templateVars = new LinkedList<>();
-
- try {
- this.errorObject = ErrorLogHelper.getErrorObject(getCode());
- } catch (ErrorObjectNotFoundException e) {
- throw new RuntimeException(FAILED_TO_INSTANTIATE_AAI_EXCEPTION_WITH_CODE + getCode()
- + UPDATE_ERROR_PROPERTIES_BEFORE_USING_THIS_EXCEPTION_CODE);
- }
- }
-
- public String getCode() {
- return code;
- }
-
- public ErrorObject getErrorObject() {
- return errorObject;
- }
-
- public Collection<String> getTemplateVars() {
- return templateVars;
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/exceptions/AAIExceptionWithInfo.java b/aai-core/src/main/java/org/onap/aai/exceptions/AAIExceptionWithInfo.java
deleted file mode 100644
index e7f2901e..00000000
--- a/aai-core/src/main/java/org/onap/aai/exceptions/AAIExceptionWithInfo.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.exceptions;
-
-import java.util.HashMap;
-
-public class AAIExceptionWithInfo extends AAIException {
-
- HashMap<String, Object> infoHash;
- String info;
-
- /**
- * Instantiates a new AAI exception with info.
- *
- * @param infoHash the info hash
- * @param info the info
- */
- public AAIExceptionWithInfo(HashMap<String, Object> infoHash, String info) {
- super();
- setInfoHash(infoHash);
- setInfo(info);
- }
-
- /**
- * Instantiates a new AAI exception with info.
- *
- * @param code the code
- * @param infoHash the info hash
- * @param info the info
- */
- public AAIExceptionWithInfo(String code, HashMap<String, Object> infoHash, String info) {
- super(code);
- setInfoHash(infoHash);
- setInfo(info);
- }
-
- /**
- * Instantiates a new AAI exception with info.
- *
- * @param code the code
- * @param details the details
- * @param infoHash the info hash
- * @param info the info
- */
- public AAIExceptionWithInfo(String code, String details, HashMap<String, Object> infoHash, String info) {
- super(code, details);
- setInfoHash(infoHash);
- setInfo(info);
- }
-
- /**
- * Instantiates a new AAI exception with info.
- *
- * @param code the code
- * @param cause the cause
- * @param infoHash the info hash
- * @param info the info
- */
- public AAIExceptionWithInfo(String code, Throwable cause, HashMap<String, Object> infoHash, String info) {
- super(code, cause);
- setInfoHash(infoHash);
- setInfo(info);
- }
-
- /**
- * Instantiates a new AAI exception with info.
- *
- * @param code the code
- * @param cause the cause
- * @param details the details
- * @param infoHash the info hash
- * @param info the info
- */
- public AAIExceptionWithInfo(String code, Throwable cause, String details, HashMap<String, Object> infoHash,
- String info) {
- super(code, cause, details);
- setInfoHash(infoHash);
- setInfo(info);
- }
-
- /**
- * Gets the info hash.
- *
- * @return the info hash
- */
- public HashMap<String, Object> getInfoHash() {
- return infoHash;
- }
-
- /**
- * Sets the info hash.
- *
- * @param infoHash the info hash
- */
- public void setInfoHash(HashMap<String, Object> infoHash) {
- this.infoHash = infoHash;
- }
-
- /**
- * Gets the info.
- *
- * @return the info
- */
- public String getInfo() {
- return info;
- }
-
- /**
- * Sets the info.
- *
- * @param info the new info
- */
- public void setInfo(String info) {
- this.info = info;
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/extensions/ExtensionController.java b/aai-core/src/main/java/org/onap/aai/extensions/ExtensionController.java
index 13c2de94..ec28858e 100644
--- a/aai-core/src/main/java/org/onap/aai/extensions/ExtensionController.java
+++ b/aai-core/src/main/java/org/onap/aai/extensions/ExtensionController.java
@@ -20,8 +20,8 @@
package org.onap.aai.extensions;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
@@ -30,7 +30,7 @@ import org.onap.aai.util.AAIConfig;
public class ExtensionController {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ExtensionController.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionController.class);
/**
* Run extension.
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java b/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java
index 11e6233f..53f2a2cd 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/Introspector.java
@@ -20,15 +20,9 @@
package org.onap.aai.introspection;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.CaseFormat;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.*;
-import java.util.stream.Collectors;
-
import org.apache.commons.lang.ClassUtils;
import org.eclipse.persistence.exceptions.DynamicException;
import org.onap.aai.config.SpringContextAware;
@@ -43,9 +37,14 @@ import org.onap.aai.schema.enums.PropertyMetadata;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.workarounds.NamingExceptions;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.stream.Collectors;
+
public abstract class Introspector implements Cloneable {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(Introspector.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(Introspector.class);
protected String className;
protected String uriChain = "";
@@ -54,6 +53,7 @@ public abstract class Introspector implements Cloneable {
private Set<String> uniqueProperties = null;
private Set<String> indexedProperties = null;
private Set<String> allKeys = null;
+ private Set<String> dslStartNodeProperties = null;
protected CaseFormatStore caseFormatStore = null;
protected NodeIngestor nodeIngestor;
@@ -177,7 +177,7 @@ public abstract class Introspector implements Cloneable {
if (obj != null) {
try {
- if (!nameClass.isAssignableFrom(obj.getClass())) {
+ if (!obj.getClass().getName().equals(nameClass.getName())) {
if (nameClass.isPrimitive()) {
nameClass = ClassUtils.primitiveToWrapper(nameClass);
result = nameClass.getConstructor(String.class).newInstance(obj.toString());
@@ -229,15 +229,8 @@ public abstract class Introspector implements Cloneable {
public Set<String> getProperties(PropertyPredicate<Introspector, String> p) {
final Set<String> temp = new LinkedHashSet<>();
- this.getProperties().stream().filter(item -> {
- return p.test(this, item);
- }).forEach(item -> {
- temp.add(item);
- });
- final Set<String> result = Collections.unmodifiableSet(temp);
-
- return result;
-
+ this.getProperties().stream().filter(item -> p.test(this, item)).forEach(temp::add);
+ return Collections.unmodifiableSet(temp);
}
public Set<String> getSimpleProperties(PropertyPredicate<Introspector, String> p) {
@@ -301,6 +294,31 @@ public abstract class Introspector implements Cloneable {
return result;
}
+ public Set<String> getDslStartNodeProperties() {
+ Set<String> result = null;
+
+ if (this.dslStartNodeProperties == null) {
+ /*
+ * The dslStartNodeProperties will have keys by default
+ * If dslStartNodeProps exist in the oxm use it
+ * if not use the indexedProps
+ */
+ result = new LinkedHashSet<>(this.getKeys());
+
+ String dslKeys = this.getMetadata(ObjectMetadata.DSL_START_NODE_PROPS);
+ String indexedKeys = this.getMetadata(ObjectMetadata.INDEXED_PROPS);
+ if (dslKeys != null) {
+ Arrays.stream(dslKeys.split(",")).forEach(result::add);
+ }
+ else if(indexedKeys != null){
+ Arrays.stream(indexedKeys.split(",")).forEach(result::add);
+ }
+ this.dslStartNodeProperties = Collections.unmodifiableSet(result);
+ }
+ result = this.dslStartNodeProperties;
+ return result;
+ }
+
public Set<String> getUniqueProperties() {
Set<String> result = null;
if (this.uniqueProperties == null) {
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/IntrospectorWalker.java b/aai-core/src/main/java/org/onap/aai/introspection/IntrospectorWalker.java
index aa5ae156..93a48290 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/IntrospectorWalker.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/IntrospectorWalker.java
@@ -20,8 +20,8 @@
package org.onap.aai.introspection;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -34,7 +34,7 @@ import org.onap.aai.logging.LogFormatTools;
public class IntrospectorWalker {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(IntrospectorWalker.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(IntrospectorWalker.class);
private Wanderer w = null;
private Set<String> blacklist = null;
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/JSONStrategy.java b/aai-core/src/main/java/org/onap/aai/introspection/JSONStrategy.java
index e628d5a4..55580dc3 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/JSONStrategy.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/JSONStrategy.java
@@ -26,7 +26,6 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.onap.aai.schema.enums.ObjectMetadata;
import org.onap.aai.schema.enums.PropertyMetadata;
@@ -150,7 +149,7 @@ public class JSONStrategy extends Introspector {
Object resultObject = null;
Class<?> resultClass = null;
resultObject = this.getValue(name);
- if (resultObject instanceof JSONArray) {
+ if (resultObject.getClass().getName().equals("org.json.simple.JSONArray")) {
resultClass = ((List) resultObject).get(0).getClass();
}
@@ -274,10 +273,10 @@ public class JSONStrategy extends Introspector {
/*
* @Override
* public String findEdgeName(String parent, String child) {
- *
+ *
* // Always has for now
* return "has";
- *
+ *
* }
*/
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java b/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java
index 02254a8b..7471c745 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/MoxyLoader.java
@@ -20,8 +20,8 @@
package org.onap.aai.introspection;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.CaseFormat;
import com.google.common.collect.ImmutableMap;
@@ -52,7 +52,7 @@ import org.onap.aai.workarounds.NamingExceptions;
public class MoxyLoader extends Loader {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(MoxyLoader.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MoxyLoader.class);
private DynamicJAXBContext jaxbContext = null;
private Map<String, Introspector> allObjs = null;
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/MoxyStrategy.java b/aai-core/src/main/java/org/onap/aai/introspection/MoxyStrategy.java
index 15311638..57e41081 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/MoxyStrategy.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/MoxyStrategy.java
@@ -20,8 +20,8 @@
package org.onap.aai.introspection;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.CaseFormat;
import com.google.common.base.Joiner;
@@ -54,7 +54,7 @@ import org.springframework.web.util.UriUtils;
public class MoxyStrategy extends Introspector {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(MoxyStrategy.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MoxyStrategy.class);
private DynamicEntity internalObject = null;
private DynamicType internalType = null;
private DynamicJAXBContext jaxbContext = null;
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/generator/CreateExample.java b/aai-core/src/main/java/org/onap/aai/introspection/generator/CreateExample.java
index 73f0a346..8288fd68 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/generator/CreateExample.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/generator/CreateExample.java
@@ -20,17 +20,17 @@
package org.onap.aai.introspection.generator;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.*;
+
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.introspection.*;
-
public class CreateExample implements Wanderer {
private SecureRandom rand = new SecureRandom();
- private final long range = 100000000L;
+ private static final long range = 100000000L;
private Loader loader = null;
private Introspector result = null;
private String objectName = null;
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/DataCopy.java b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/DataCopy.java
index 6a6ee4c1..0994f023 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/DataCopy.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/DataCopy.java
@@ -20,17 +20,6 @@
package org.onap.aai.introspection.sideeffect;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.ws.rs.core.MultivaluedMap;
-
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
@@ -42,6 +31,16 @@ import org.onap.aai.schema.enums.PropertyMetadata;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import javax.ws.rs.core.MultivaluedMap;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+
public class DataCopy extends SideEffect {
public DataCopy(Introspector obj, Vertex self, TransactionalGraphEngine dbEngine, DBSerializer serializer) {
@@ -69,14 +68,12 @@ public class DataCopy extends SideEffect {
} else {
if (results.isEmpty()) {
throw new AAIException("AAI_6114", "object located at " + uri + " not found");
- } else if (results.size() > 1) {
+ } else {
throw new AAIMultiplePropertiesException(
"multiple values of " + entry.getKey() + " found when searching " + uri);
}
}
- } else {
- // skip processing because no required properties were specified
- }
+ } //else skip processing because no required properties were specified
}
@Override
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/PrivateEdge.java b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/PrivateEdge.java
index f4f0bfac..06586317 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/PrivateEdge.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/PrivateEdge.java
@@ -21,15 +21,6 @@
package org.onap.aai.introspection.sideeffect;
import com.google.common.collect.Multimap;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.*;
-import java.util.Map.Entry;
-
-import javax.ws.rs.core.MultivaluedMap;
-
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
@@ -42,7 +33,10 @@ import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.edges.exceptions.AmbiguousRuleChoiceException;
import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.introspection.*;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
import org.onap.aai.introspection.sideeffect.exceptions.AAIMultiplePropertiesException;
import org.onap.aai.parsers.query.QueryParser;
import org.onap.aai.restcore.util.URITools;
@@ -52,6 +46,13 @@ import org.onap.aai.serialization.db.EdgeSerializer;
import org.onap.aai.serialization.db.exceptions.EdgeMultiplicityException;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import javax.ws.rs.core.MultivaluedMap;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.Map.Entry;
+
public class PrivateEdge extends SideEffect {
public PrivateEdge(Introspector obj, Vertex self, TransactionalGraphEngine dbEngine, DBSerializer serializer) {
@@ -111,40 +112,38 @@ public class PrivateEdge extends SideEffect {
throw new EdgeMultiplicityException(message);
}
- for (Entry<String, EdgeRule> edgeEntry : edgeRulesMap.entries()) {
- EdgeRule edgeRule = edgeIngestor.getRule(edgeQuery);
- Iterator<Edge> edges = self.edges(edgeRule.getDirection(), edgeRule.getLabel().toString());
- if (edges.hasNext()) {
- Edge edge = edges.next();
- EdgeStatus status = checkStatus(obj, self);
- switch (status) {
- case CREATED:
- edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self,
- otherVertex, edgeRule.getLabel());
- break;
- case MODIFIED:
- edge.remove();
- edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self,
- otherVertex, edgeRule.getLabel());
- break;
- case REMOVED:
- edge.remove();
- break;
- case UNCHANGED:
- break;
- }
- } else {
- edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self,
- otherVertex, edgeRule.getLabel());
+ EdgeRule edgeRule = edgeIngestor.getRule(edgeQuery);
+ Iterator<Edge> edges = self.edges(edgeRule.getDirection(), edgeRule.getLabel());
+ if (edges.hasNext()) {
+ Edge edge = edges.next();
+ EdgeStatus status = checkStatus(obj, self);
+ switch (status) {
+ case CREATED:
+ edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self,
+ otherVertex, edgeRule.getLabel());
+ break;
+ case MODIFIED:
+ edge.remove();
+ edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self,
+ otherVertex, edgeRule.getLabel());
+ break;
+ case REMOVED:
+ edge.remove();
+ break;
+ case UNCHANGED:
+ break;
}
+ } else {
+ edgeSerializer.addPrivateEdge(this.dbEngine.asAdmin().getTraversalSource(), self,
+ otherVertex, edgeRule.getLabel());
}
}
} else {
if (results.isEmpty()) {
throw new AAIException("AAI_6114", "object located at " + uri + " not found");
- } else if (results.size() > 1) {
+ } else {
throw new AAIMultiplePropertiesException(
- "multiple values of " + entry.getKey() + " found when searching " + uri);
+ "multiple values of " + entry.getKey() + " found when searching " + uri);
}
}
}
@@ -159,7 +158,7 @@ public class PrivateEdge extends SideEffect {
for (String key : templateKeys) {
String currentObjValue = obj.getValue(key);
Map<PropertyMetadata, String> map = obj.getPropertyMetadata(key);
- String oldVertexValue = null;
+ String oldVertexValue;
if (map.containsKey(PropertyMetadata.DB_ALIAS)) {
oldVertexValue = self.<String>property(key + AAIProperties.DB_ALIAS_SUFFIX).orElse(null);
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java
index d86c18a0..a71ffa4e 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffect.java
@@ -20,8 +20,8 @@
package org.onap.aai.introspection.sideeffect;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
@@ -46,7 +46,7 @@ import org.onap.aai.setup.SchemaVersions;
public abstract class SideEffect {
protected static final Pattern template = Pattern.compile("\\{(.*?)\\}");
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(SideEffect.class);
+ private static final Logger logger = LoggerFactory.getLogger(SideEffect.class);
protected final Introspector obj;
protected final TransactionalGraphEngine dbEngine;
diff --git a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffectRunner.java b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffectRunner.java
index ffd9a8c8..8bc83156 100644
--- a/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffectRunner.java
+++ b/aai-core/src/main/java/org/onap/aai/introspection/sideeffect/SideEffectRunner.java
@@ -20,8 +20,8 @@
package org.onap.aai.introspection.sideeffect;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
diff --git a/aai-core/src/main/java/org/onap/aai/logging/CNName.java b/aai-core/src/main/java/org/onap/aai/logging/CNName.java
deleted file mode 100644
index 5337afe3..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/CNName.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import static java.util.Base64.getDecoder;
-
-import ch.qos.logback.access.pattern.AccessConverter;
-import ch.qos.logback.access.spi.IAccessEvent;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.security.cert.X509Certificate;
-
-import javax.security.auth.x500.X500Principal;
-import javax.servlet.http.HttpServletRequest;
-
-public class CNName extends AccessConverter {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(CNName.class);
-
- /**
- * Converts access events to String response codes
- *
- * @param accessEvent the IAccessEvent
- */
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_HEADER_CONV";
- }
-
- String cipherSuite = (String) accessEvent.getRequest().getAttribute("javax.servlet.request.cipher_suite");
- String authUser = null;
- if (cipherSuite != null) {
- try {
- X509Certificate certChain[] = (X509Certificate[]) accessEvent.getRequest()
- .getAttribute("javax.servlet.request.X509Certificate");
- if (certChain == null || certChain.length == 0) {
-
- HttpServletRequest request = accessEvent.getRequest();
-
- String authorization = request.getHeader("Authorization");
-
- // Set the auth user to "-" so if the authorization header is not found
- // Or if the decoded basic auth credentials are not found in the format required
- // it should return "-"
- // If the decoded string is in the right format, find the index of ":"
- // Then get the substring of the starting point to the colon not including the colon
-
- authUser = "-";
-
- if (authorization != null && authorization.startsWith("Basic ")) {
- String credentials = authorization.replace("Basic ", "");
- byte[] userCredentials = getDecoder().decode(credentials.getBytes("utf-8"));
- credentials = new String(userCredentials);
-
- int codePoint = credentials.indexOf(':');
-
- if (codePoint != -1) {
- authUser = credentials.substring(0, codePoint);
- }
-
- }
-
- return authUser;
-
- } else {
- X509Certificate clientCert = certChain[0];
- X500Principal subjectDN = clientCert.getSubjectX500Principal();
- authUser = subjectDN.toString();
- return authUser;
- }
- } catch (Exception e) {
- LOGGER.error(e.getMessage(), e);
- return "-";
- }
- } else {
- return "-";
- }
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/DME2RestFlag.java b/aai-core/src/main/java/org/onap/aai/logging/DME2RestFlag.java
deleted file mode 100644
index 768c095b..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/DME2RestFlag.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.access.pattern.AccessConverter;
-import ch.qos.logback.access.spi.IAccessEvent;
-
-public class DME2RestFlag extends AccessConverter {
-
- /**
- * @{inheritDoc}
- */
- @Override
- public String convert(IAccessEvent accessEvent) {
- if (!isStarted()) {
- return "INACTIVE_HEADER_CONV";
- }
-
- String flag = "-";
-
- if (accessEvent.getRequestParameter("envContext").length > 0
- && !accessEvent.getRequestParameter("envContext")[0].isEmpty()
- && !accessEvent.getRequestParameter("envContext")[0].equals("-")
- && accessEvent.getRequestParameter("routeOffer").length > 0
- && !accessEvent.getRequestParameter("routeOffer")[0].isEmpty()
- && !accessEvent.getRequestParameter("routeOffer")[0].equals("-")
- && accessEvent.getRequestParameter("version").length > 0
- && !accessEvent.getRequestParameter("version")[0].isEmpty()
- && !accessEvent.getRequestParameter("version")[0].equals("-")) {
- flag = "DME2";
- } else {
- flag = "REST";
- }
-
- return flag;
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompElapsedTime.java b/aai-core/src/main/java/org/onap/aai/logging/EcompElapsedTime.java
deleted file mode 100644
index 66d27868..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompElapsedTime.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public class EcompElapsedTime extends ClassicConverter {
-
- private static final String DEFAULT_ELAPSED_TIME_FORMAT = "%d";
-
- private String ELAPSED_TIME_FORMAT;
-
- @Override
- public void start() {
- ELAPSED_TIME_FORMAT = getFirstOption();
- }
-
- @Override
- public String convert(ILoggingEvent event) {
- final long end = event.getTimeStamp();
-
- if (!event.getMDCPropertyMap().containsKey(LoggingField.START_TIME.toString())) {
- return format(0);
- } else if (event.getMDCPropertyMap().containsKey(LoggingField.ELAPSED_TIME.toString())) {
- return format(Integer.parseInt(event.getMDCPropertyMap().get(LoggingField.ELAPSED_TIME.toString())));
- }
-
- final long start =
- LogFormatTools.toTimestamp(event.getMDCPropertyMap().get(LoggingField.START_TIME.toString()));
-
- return format(end - start);
- }
-
- private String format(long elapsedTime) {
- if (ELAPSED_TIME_FORMAT == null) {
- return format(DEFAULT_ELAPSED_TIME_FORMAT, elapsedTime);
- }
-
- return format(ELAPSED_TIME_FORMAT, elapsedTime);
- }
-
- private String format(String format, long elapsedTime) {
- return String.format(format, elapsedTime);
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompEncoder.java b/aai-core/src/main/java/org/onap/aai/logging/EcompEncoder.java
deleted file mode 100644
index 88587297..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompEncoder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-
-public class EcompEncoder extends PatternLayoutEncoder {
-
- @Override
- public void start() {
- PatternLayout patternLayout = new EcompPatternLayout();
- patternLayout.setContext(context);
- patternLayout.setPattern(getPattern());
- patternLayout.setOutputPatternAsHeader(outputPatternAsHeader);
- patternLayout.start();
- this.layout = patternLayout;
- super.start();
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompErrorCategory.java b/aai-core/src/main/java/org/onap/aai/logging/EcompErrorCategory.java
deleted file mode 100644
index 452fcd08..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompErrorCategory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-public class EcompErrorCategory extends ClassicConverter {
-
- @Override
- public String convert(ILoggingEvent event) {
-
- final Level lev = event.getLevel();
- final String defaultCategory = "WARN";
-
- if ((Level.WARN).equals(lev)) {
- return (defaultCategory);
- } else if ((Level.ERROR).equals(lev)) {
- return ("ERROR");
- }
- return (defaultCategory);
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompPatternLayout.java b/aai-core/src/main/java/org/onap/aai/logging/EcompPatternLayout.java
deleted file mode 100644
index 43c147a0..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompPatternLayout.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.PatternLayout;
-
-public class EcompPatternLayout extends PatternLayout {
- static {
- PatternLayout.defaultConverterMap.put("ecompStartTime", EcompStartTime.class.getName());
- PatternLayout.defaultConverterMap.put("ecompElapsedTime", EcompElapsedTime.class.getName());
- PatternLayout.defaultConverterMap.put("eelfClassOfCaller", EelfClassOfCaller.class.getName());
- PatternLayout.defaultConverterMap.put("ecompErrorCategory", EcompErrorCategory.class.getName());
- PatternLayout.defaultConverterMap.put("ecompResponseCode", EcompResponseCode.class.getName());
- PatternLayout.defaultConverterMap.put("ecompResponseDescription", EcompResponseDescription.class.getName());
- PatternLayout.defaultConverterMap.put("ecompStatusCode", EcompStatusCode.class.getName());
- PatternLayout.defaultConverterMap.put("ecompServiceName", EcompServiceName.class.getName());
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompResponseCode.java b/aai-core/src/main/java/org/onap/aai/logging/EcompResponseCode.java
deleted file mode 100644
index 1dc59b4e..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompResponseCode.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public class EcompResponseCode extends ClassicConverter {
-
- @Override
- public String convert(ILoggingEvent event) {
-
- if (!event.getMDCPropertyMap().containsKey(LoggingField.RESPONSE_CODE.toString())) {
- // if response code is not set, return "unknown" (900)
- return LoggingContext.UNKNOWN_ERROR;
- }
- return event.getMDCPropertyMap().get(LoggingField.RESPONSE_CODE.toString());
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompResponseDescription.java b/aai-core/src/main/java/org/onap/aai/logging/EcompResponseDescription.java
deleted file mode 100644
index b72cc100..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompResponseDescription.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public class EcompResponseDescription extends ClassicConverter {
- public static final String DEFAULT_DESCRIPTION = "Unknown response/error description";
-
- @Override
- public String convert(ILoggingEvent event) {
-
- if (!event.getMDCPropertyMap().containsKey(LoggingField.RESPONSE_DESCRIPTION.toString())) {
- return (DEFAULT_DESCRIPTION);
- }
- // Replace pipes and new lines
- String currentDesc = event.getMDCPropertyMap().get(LoggingField.RESPONSE_DESCRIPTION.toString());
- if ((currentDesc == null) || (currentDesc.length() == 0)) {
- return (DEFAULT_DESCRIPTION);
- }
- currentDesc = currentDesc.replaceAll("\\|", "!");
- currentDesc = currentDesc.replaceAll("[\\r\\n]+", "^");
- return event.getMDCPropertyMap().get(currentDesc);
- }
-}
-
-
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompServiceName.java b/aai-core/src/main/java/org/onap/aai/logging/EcompServiceName.java
deleted file mode 100644
index 10d7a211..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompServiceName.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public class EcompServiceName extends ClassicConverter {
- @Override
- public String convert(ILoggingEvent event) {
- if (!event.getMDCPropertyMap().containsKey(LoggingField.SERVICE_NAME.toString())) {
- return "AAI";
- }
- return event.getMDCPropertyMap().get(LoggingField.SERVICE_NAME.toString());
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompStartTime.java b/aai-core/src/main/java/org/onap/aai/logging/EcompStartTime.java
deleted file mode 100644
index 8f015414..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompStartTime.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public class EcompStartTime extends ClassicConverter {
-
- @Override
- public String convert(ILoggingEvent event) {
-
- if (!event.getMDCPropertyMap().containsKey(LoggingField.START_TIME.toString())) {
- return LogFormatTools.toDate(event.getTimeStamp());
- }
-
- return event.getMDCPropertyMap().get(LoggingField.START_TIME.toString());
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EcompStatusCode.java b/aai-core/src/main/java/org/onap/aai/logging/EcompStatusCode.java
deleted file mode 100644
index 4319bbbd..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EcompStatusCode.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.ClassicConverter;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public class EcompStatusCode extends ClassicConverter {
- @Override
- public String convert(ILoggingEvent event) {
- if (!event.getMDCPropertyMap().containsKey(LoggingField.STATUS_CODE.toString())) {
- return LoggingContext.StatusCode.COMPLETE.toString();
- }
- return event.getMDCPropertyMap().get(LoggingField.STATUS_CODE.toString());
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/EelfClassOfCaller.java b/aai-core/src/main/java/org/onap/aai/logging/EelfClassOfCaller.java
deleted file mode 100644
index dc9bc2c2..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/EelfClassOfCaller.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import ch.qos.logback.classic.pattern.NamedConverter;
-import ch.qos.logback.classic.spi.CallerData;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-
-public class EelfClassOfCaller extends NamedConverter {
- protected String getFullyQualifiedName(ILoggingEvent event) {
-
- StackTraceElement[] cda = event.getCallerData();
-
- // If using the EELFLogger, it "hides" the calling class because it wraps the logging calls
- // Without this, you'd only ever see "EELF SLF4jWrapper" when using the
- // %C pattern converter
- if (cda != null && cda.length > 2) {
- return cda[2].getClassName();
- } else if (cda != null && cda.length > 0) {
- return cda[0].getClassName();
- } else {
- return CallerData.NA;
- }
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/ErrorLogHelper.java b/aai-core/src/main/java/org/onap/aai/logging/ErrorLogHelper.java
deleted file mode 100644
index 01327606..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/ErrorLogHelper.java
+++ /dev/null
@@ -1,633 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-
-import javax.ws.rs.core.MediaType;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-
-import org.apache.commons.lang.StringUtils;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.logging.LoggingContext.StatusCode;
-import org.onap.aai.util.AAIConfig;
-import org.onap.aai.util.AAIConstants;
-import org.onap.aai.util.MapperUtil;
-import org.slf4j.MDC;
-
-/**
- *
- * This classes loads the application error properties file
- * and provides a method that returns an ErrorObject
- *
- */
-
-public class ErrorLogHelper {
-
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ErrorLogHelper.class);
- private static final HashMap<String, ErrorObject> ERROR_OBJECTS = new HashMap<String, ErrorObject>();
-
- static {
- try {
- loadProperties();
- } catch (IOException e) {
- throw new RuntimeException("Failed to load error.properties file", e);
- } catch (ErrorObjectFormatException e) {
- throw new RuntimeException("Failed to parse error.properties file", e);
- }
- }
-
- /**
- * Load properties.
- *
- * @throws ErrorObjectFormatException
- * @throws Exception the exception
- */
- public static void loadProperties() throws IOException, ErrorObjectFormatException {
- final String filePath = AAIConstants.AAI_HOME_ETC_APP_PROPERTIES + "error.properties";
- final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
- final Properties properties = new Properties();
-
- if (is != null) {
- properties.load(is);
- } else {
- try (final FileInputStream fis = new FileInputStream(filePath)) {
- properties.load(fis);
- }
- }
-
- for (Entry<Object, Object> entry : properties.entrySet()) {
- final String key = (String) entry.getKey();
- final String value = (String) entry.getValue();
- final String[] errorProperties = value.split(":");
-
- if (errorProperties.length != 7)
- throw new ErrorObjectFormatException();
-
- final ErrorObject errorObject = new ErrorObject();
-
- errorObject.setDisposition(errorProperties[0].trim());
- errorObject.setCategory(errorProperties[1].trim());
- errorObject.setSeverity(errorProperties[2].trim());
- errorObject.setErrorCode(errorProperties[3].trim());
- errorObject.setHTTPResponseCode(errorProperties[4].trim());
- errorObject.setRESTErrorCode(errorProperties[5].trim());
- errorObject.setErrorText(errorProperties[6].trim());
-
- ERROR_OBJECTS.put(key, errorObject);
- }
- }
-
- /**
- * Logs a known A&AI exception (i.e. one that can be found in error.properties)
- *
- * @param key The key for the error in the error.properties file
- * @throws IOException
- * @throws ErrorObjectNotFoundException
- * @throws ErrorObjectFormatException
- */
- public static ErrorObject getErrorObject(String code) throws ErrorObjectNotFoundException {
-
- if (code == null)
- throw new IllegalArgumentException("Key cannot be null");
-
- final ErrorObject errorObject = ERROR_OBJECTS.get(code);
-
- if (errorObject == null) {
- LOGGER.warn("Unknown AAIException with code=" + code + ". Using default AAIException");
- return ERROR_OBJECTS.get(AAIException.DEFAULT_EXCEPTION_CODE);
- }
-
- return errorObject;
- }
-
- /**
- * Determines whether category is policy or not. If policy (1), this is a POL error, else it's a SVC error.
- * The AAIRESTException may contain a different ErrorObject than that created with the REST error key.
- * This allows lower level exception detail to be returned to the client to help troubleshoot the problem.
- * If no error object is embedded in the AAIException, one will be created using the error object from the
- * AAIException.
- *
- * @param are must have a restError value whose numeric value must match what should be returned in the REST API
- * @param variables optional list of variables to flesh out text in error string
- * @return appropriately formatted JSON response per the REST API spec.
- * @throws ErrorObjectFormatException
- * @throws ErrorObjectNotFoundException
- * @throws IOException
- * @deprecated
- */
- public static String getRESTAPIErrorResponse(AAIException are, ArrayList<String> variables) {
- List<MediaType> acceptHeaders = new ArrayList<MediaType>();
- acceptHeaders.add(MediaType.APPLICATION_JSON_TYPE);
-
- return getRESTAPIErrorResponse(acceptHeaders, are, variables);
- }
-
- /**
- * Determines whether category is policy or not. If policy (1), this is a POL error, else it's a SVC error.
- * The AAIRESTException may contain a different ErrorObject than that created with the REST error key.
- * This allows lower level exception detail to be returned to the client to help troubleshoot the problem.
- * If no error object is embedded in the AAIException, one will be created using the error object from the
- * AAIException.
- *
- * @param acceptHeadersOrig the accept headers orig
- * @param are must have a restError value whose numeric value must match what should be returned in the REST API
- * @param variables optional list of variables to flesh out text in error string
- * @return appropriately formatted JSON response per the REST API spec.
- * @throws ErrorObjectFormatException
- * @throws ErrorObjectNotFoundException
- * @throws IOException
- */
- public static String getRESTAPIErrorResponse(List<MediaType> acceptHeadersOrig, AAIException are,
- ArrayList<String> variables) {
-
- StringBuilder text = new StringBuilder();
- String response = null;
-
- List<MediaType> acceptHeaders = new ArrayList<MediaType>();
- // we might have an exception but no accept header, so we'll set default to JSON
- boolean foundValidAcceptHeader = false;
- for (MediaType mt : acceptHeadersOrig) {
- if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt) || MediaType.APPLICATION_JSON_TYPE.isCompatible(mt)) {
- acceptHeaders.add(mt);
- foundValidAcceptHeader = true;
- }
- }
- if (foundValidAcceptHeader == false) {
- // override the exception, client needs to set an appropriate Accept header
- are = new AAIException("AAI_4014");
- acceptHeaders.add(MediaType.APPLICATION_JSON_TYPE);
- }
-
- final ErrorObject eo = are.getErrorObject();
-
- int restErrorCode = Integer.parseInt(eo.getRESTErrorCode());
-
- ErrorObject restErrorObject;
-
- try {
- restErrorObject = ErrorLogHelper.getErrorObject("AAI_" + restErrorCode);
- } catch (ErrorObjectNotFoundException e) {
- LOGGER.warn("Failed to find related error object AAI_" + restErrorCode + " for error object "
- + eo.getErrorCode() + "; using AAI_" + restErrorCode);
- restErrorObject = eo;
- }
-
- text.append(restErrorObject.getErrorText());
-
- // We want to always append the (msg=%n) (ec=%n+1) to the text, but have to find value of n
- // This assumes that the variables in the ArrayList, which might be more than are needed to flesh out the
- // error, are ordered based on the error string.
- int localDataIndex = StringUtils.countMatches(restErrorObject.getErrorText(), "%");
- text.append(" (msg=%").append(localDataIndex + 1).append(") (ec=%").append(localDataIndex + 2).append(")");
-
- if (variables == null) {
- variables = new ArrayList<String>();
- }
-
- if (variables.size() < localDataIndex) {
- ErrorLogHelper.logError("AAI_4011", "data missing for rest error");
- while (variables.size() < localDataIndex) {
- variables.add("null");
- }
- }
-
- // This will put the error code and error text into the right positions
- if (are.getMessage() == null || are.getMessage().length() == 0) {
- variables.add(localDataIndex++, eo.getErrorText());
- } else {
- variables.add(localDataIndex++, eo.getErrorText() + ":" + are.getMessage());
- }
- variables.add(localDataIndex, eo.getErrorCodeString());
-
- for (MediaType mediaType : acceptHeaders) {
- if (MediaType.APPLICATION_XML_TYPE.isCompatible(mediaType)) {
- JAXBContext context = null;
- try {
- if (eo.getCategory().equals("1")) {
-
- context = JAXBContext.newInstance(org.onap.aai.domain.restPolicyException.Fault.class);
- Marshaller m = context.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
-
- org.onap.aai.domain.restPolicyException.ObjectFactory factory =
- new org.onap.aai.domain.restPolicyException.ObjectFactory();
- org.onap.aai.domain.restPolicyException.Fault fault = factory.createFault();
- org.onap.aai.domain.restPolicyException.Fault.RequestError requestError =
- factory.createFaultRequestError();
- org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException policyException =
- factory.createFaultRequestErrorPolicyException();
- org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException.Variables polvariables =
- factory.createFaultRequestErrorPolicyExceptionVariables();
-
- policyException.setMessageId("POL" + eo.getRESTErrorCode());
- policyException.setText(text.toString());
- for (int i = 0; i < variables.size(); i++) {
- polvariables.getVariable().add(variables.get(i));
- }
- policyException.setVariables(polvariables);
- requestError.setPolicyException(policyException);
- fault.setRequestError(requestError);
-
- StringWriter sw = new StringWriter();
- m.marshal(fault, sw);
-
- response = sw.toString();
-
- } else {
-
- context = JAXBContext.newInstance(org.onap.aai.domain.restServiceException.Fault.class);
- Marshaller m = context.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
-
- org.onap.aai.domain.restServiceException.ObjectFactory factory =
- new org.onap.aai.domain.restServiceException.ObjectFactory();
- org.onap.aai.domain.restServiceException.Fault fault = factory.createFault();
- org.onap.aai.domain.restServiceException.Fault.RequestError requestError =
- factory.createFaultRequestError();
- org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException serviceException =
- factory.createFaultRequestErrorServiceException();
- org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException.Variables svcvariables =
- factory.createFaultRequestErrorServiceExceptionVariables();
- serviceException.setMessageId("SVC" + eo.getRESTErrorCode());
- serviceException.setText(text.toString());
- for (int i = 0; i < variables.size(); i++) {
- svcvariables.getVariable().add(variables.get(i));
- }
- serviceException.setVariables(svcvariables);
- requestError.setServiceException(serviceException);
- fault.setRequestError(requestError);
-
- StringWriter sw = new StringWriter();
- m.marshal(fault, sw);
-
- response = sw.toString();
-
- }
- } catch (Exception ex) {
- LOGGER.error(
- "We were unable to create a rest exception to return on an API because of a parsing error "
- + ex.getMessage());
- }
- } else {
- try {
- if (eo.getCategory().equals("1")) {
- org.onap.aai.domain.restPolicyException.RESTResponse restresp =
- new org.onap.aai.domain.restPolicyException.RESTResponse();
- org.onap.aai.domain.restPolicyException.RequestError reqerr =
- new org.onap.aai.domain.restPolicyException.RequestError();
- org.onap.aai.domain.restPolicyException.PolicyException polexc =
- new org.onap.aai.domain.restPolicyException.PolicyException();
- polexc.setMessageId("POL" + eo.getRESTErrorCode());
- polexc.setText(text.toString());
- polexc.setVariables(variables);
- reqerr.setPolicyException(polexc);
- restresp.setRequestError(reqerr);
- response = (MapperUtil.writeAsJSONString((Object) restresp));
-
- } else {
- org.onap.aai.domain.restServiceException.RESTResponse restresp =
- new org.onap.aai.domain.restServiceException.RESTResponse();
- org.onap.aai.domain.restServiceException.RequestError reqerr =
- new org.onap.aai.domain.restServiceException.RequestError();
- org.onap.aai.domain.restServiceException.ServiceException svcexc =
- new org.onap.aai.domain.restServiceException.ServiceException();
- svcexc.setMessageId("SVC" + eo.getRESTErrorCode());
- svcexc.setText(text.toString());
- svcexc.setVariables(variables);
- reqerr.setServiceException(svcexc);
- restresp.setRequestError(reqerr);
- response = (MapperUtil.writeAsJSONString((Object) restresp));
- }
- } catch (AAIException ex) {
- LOGGER.error(
- "We were unable to create a rest exception to return on an API because of a parsing error "
- + ex.getMessage());
- }
- }
- }
-
- return response;
- }
-
- /**
- * Gets the RESTAPI error response with logging.
- *
- * @param acceptHeadersOrig the accept headers orig
- * @param are the are
- * @param variables the variables
- * @param logline the logline
- * @return the RESTAPI error response with logging
- * @throws ErrorObjectFormatException
- * @throws ErrorObjectNotFoundException
- * @throws IOException
- */
- public static String getRESTAPIErrorResponseWithLogging(List<MediaType> acceptHeadersOrig, AAIException are,
- ArrayList<String> variables) {
- String response = ErrorLogHelper.getRESTAPIErrorResponse(acceptHeadersOrig, are, variables);
-
- LOGGER.error(are.getMessage() + " " + LogFormatTools.getStackTop(are));
-
- return response;
- }
-
- /**
- * Gets the RESTAPI info response.
- *
- * @param acceptHeaders the accept headers
- * @param areList the are list
- * @return the RESTAPI info response
- * @throws ErrorObjectFormatException
- * @throws ErrorObjectNotFoundException
- * @throws IOException
- */
- public static Object getRESTAPIInfoResponse(List<MediaType> acceptHeaders,
- HashMap<AAIException, ArrayList<String>> areList) {
-
- Object respObj = null;
-
- org.onap.aai.domain.restResponseInfo.ObjectFactory factory =
- new org.onap.aai.domain.restResponseInfo.ObjectFactory();
- org.onap.aai.domain.restResponseInfo.Info info = factory.createInfo();
- org.onap.aai.domain.restResponseInfo.Info.ResponseMessages responseMessages =
- factory.createInfoResponseMessages();
- Iterator<Entry<AAIException, ArrayList<String>>> it = areList.entrySet().iterator();
-
- while (it.hasNext()) {
- Entry<AAIException, ArrayList<String>> pair = (Entry<AAIException, ArrayList<String>>) it.next();
- AAIException are = pair.getKey();
- ArrayList<String> variables = pair.getValue();
-
- StringBuilder text = new StringBuilder();
-
- ErrorObject eo = are.getErrorObject();
-
- int restErrorCode = Integer.parseInt(eo.getRESTErrorCode());
- ErrorObject restErrorObject;
- try {
- restErrorObject = ErrorLogHelper.getErrorObject("AAI_" + String.format("%04d", restErrorCode));
- } catch (ErrorObjectNotFoundException e) {
- restErrorObject = eo;
- }
- text.append(restErrorObject.getErrorText());
-
- // We want to always append the (msg=%n) (ec=%n+1) to the text, but have to find value of n
- // This assumes that the variables in the ArrayList, which might be more than are needed to flesh out the
- // error, are ordered based on the error string.
- int localDataIndex = StringUtils.countMatches(restErrorObject.getErrorText(), "%");
- text.append(" (msg=%").append(localDataIndex + 1).append(") (rc=%").append(localDataIndex + 2).append(")");
-
- if (variables == null) {
- variables = new ArrayList<String>();
- }
-
- if (variables.size() < localDataIndex) {
- ErrorLogHelper.logError("AAI_4011", "data missing for rest error");
- while (variables.size() < localDataIndex) {
- variables.add("null");
- }
- }
-
- // This will put the error code and error text into the right positions
- if (are.getMessage() == null) {
- variables.add(localDataIndex++, eo.getErrorText());
- } else {
- variables.add(localDataIndex++, eo.getErrorText() + ":" + are.getMessage());
- }
- variables.add(localDataIndex, eo.getErrorCodeString());
-
- try {
- org.onap.aai.domain.restResponseInfo.Info.ResponseMessages.ResponseMessage responseMessage =
- factory.createInfoResponseMessagesResponseMessage();
- org.onap.aai.domain.restResponseInfo.Info.ResponseMessages.ResponseMessage.Variables infovariables =
- factory.createInfoResponseMessagesResponseMessageVariables();
-
- responseMessage.setMessageId("INF" + eo.getRESTErrorCode());
- responseMessage.setText(text.toString());
- for (int i = 0; i < variables.size(); i++) {
- infovariables.getVariable().add(variables.get(i));
- }
-
- responseMessage.setVariables(infovariables);
- responseMessages.getResponseMessage().add(responseMessage);
-
- } catch (Exception ex) {
- LOGGER.error("We were unable to create a rest exception to return on an API because of a parsing error "
- + ex.getMessage());
- }
- }
-
- info.setResponseMessages(responseMessages);
- respObj = (Object) info;
-
- return respObj;
- }
-
- /**
- * Determines whether category is policy or not. If policy (1), this is a POL error, else it's a SVC error.
- * The AAIRESTException may contain a different ErrorObject than that created with the REST error key.
- * This allows lower level exception detail to be returned to the client to help troubleshoot the problem.
- * If no error object is embedded in the AAIException, one will be created using the error object from the
- * AAIException.
- *
- * @param are must have a restError value whose numeric value must match what should be returned in the REST API
- * @param variables optional list of variables to flesh out text in error string
- * @return appropriately formatted JSON response per the REST API spec.
- * @throws ErrorObjectFormatException
- * @throws ErrorObjectNotFoundException
- * @throws IOException
- */
- public static String getRESTAPIPolicyErrorResponseXML(AAIException are, ArrayList<String> variables) {
-
- StringBuilder text = new StringBuilder();
- String response = null;
- JAXBContext context = null;
-
- ErrorObject eo = are.getErrorObject();
-
- int restErrorCode = Integer.parseInt(eo.getRESTErrorCode());
- ErrorObject restErrorObject;
- try {
- restErrorObject = ErrorLogHelper.getErrorObject("AAI_" + restErrorCode);
- } catch (ErrorObjectNotFoundException e) {
- restErrorObject = eo;
- }
-
- text.append(restErrorObject.getErrorText());
-
- // We want to always append the (msg=%n) (ec=%n+1) to the text, but have to find value of n
- // This assumes that the variables in the ArrayList, which might be more than are needed to flesh out the
- // error, are ordered based on the error string.
- int localDataIndex = StringUtils.countMatches(restErrorObject.getErrorText(), "%");
- text.append(" (msg=%").append(localDataIndex + 1).append(") (ec=%").append(localDataIndex + 2).append(")");
-
- if (variables == null) {
- variables = new ArrayList<String>();
- }
-
- if (variables.size() < localDataIndex) {
- ErrorLogHelper.logError("AAI_4011", "data missing for rest error");
- while (variables.size() < localDataIndex) {
- variables.add("null");
- }
- }
-
- // This will put the error code and error text into the right positions
- if (are.getMessage() == null) {
- variables.add(localDataIndex++, eo.getErrorText());
- } else {
- variables.add(localDataIndex++, eo.getErrorText() + ":" + are.getMessage());
- }
- variables.add(localDataIndex, eo.getErrorCodeString());
-
- try {
- if (eo.getCategory().equals("1")) {
-
- context = JAXBContext.newInstance(org.onap.aai.domain.restPolicyException.Fault.class);
- Marshaller m = context.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
-
- org.onap.aai.domain.restPolicyException.ObjectFactory factory =
- new org.onap.aai.domain.restPolicyException.ObjectFactory();
- org.onap.aai.domain.restPolicyException.Fault fault = factory.createFault();
- org.onap.aai.domain.restPolicyException.Fault.RequestError requestError =
- factory.createFaultRequestError();
- org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException policyException =
- factory.createFaultRequestErrorPolicyException();
- org.onap.aai.domain.restPolicyException.Fault.RequestError.PolicyException.Variables polvariables =
- factory.createFaultRequestErrorPolicyExceptionVariables();
-
- policyException.setMessageId("POL" + eo.getRESTErrorCode());
- policyException.setText(text.toString());
- for (int i = 0; i < variables.size(); i++) {
- polvariables.getVariable().add(variables.get(i));
- }
- policyException.setVariables(polvariables);
- requestError.setPolicyException(policyException);
- fault.setRequestError(requestError);
-
- StringWriter sw = new StringWriter();
- m.marshal(fault, sw);
-
- response = sw.toString();
-
- } else {
-
- context = JAXBContext.newInstance(org.onap.aai.domain.restServiceException.Fault.class);
- Marshaller m = context.createMarshaller();
- m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
-
- org.onap.aai.domain.restServiceException.ObjectFactory factory =
- new org.onap.aai.domain.restServiceException.ObjectFactory();
- org.onap.aai.domain.restServiceException.Fault fault = factory.createFault();
- org.onap.aai.domain.restServiceException.Fault.RequestError requestError =
- factory.createFaultRequestError();
- org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException serviceException =
- factory.createFaultRequestErrorServiceException();
- org.onap.aai.domain.restServiceException.Fault.RequestError.ServiceException.Variables svcvariables =
- factory.createFaultRequestErrorServiceExceptionVariables();
- serviceException.setMessageId("POL" + eo.getRESTErrorCode());
- serviceException.setText(text.toString());
- for (int i = 0; i < variables.size(); i++) {
- svcvariables.getVariable().add(variables.get(i));
- }
- serviceException.setVariables(svcvariables);
- requestError.setServiceException(serviceException);
- fault.setRequestError(requestError);
-
- StringWriter sw = new StringWriter();
- m.marshal(fault, sw);
-
- response = sw.toString();
-
- }
- } catch (Exception ex) {
- LOGGER.error("We were unable to create a rest exception to return on an API because of a parsing error "
- + ex.getMessage());
- }
- return response;
- }
-
- public static void logException(AAIException e) {
- final ErrorObject errorObject = e.getErrorObject();
-
- // MDC.put("severity", errorObject.getSeverity()); //TODO Use LoggingContext.severity(int severity)
- String severityCode = errorObject.getSeverityCode(errorObject.getSeverity());
-
- if (!AAIConfig.isEmpty(severityCode)) {
- int sevCode = Integer.parseInt(severityCode);
- if (sevCode > 0 && sevCode <= 3) {
- LoggingContext.severity(sevCode);
- }
- }
- String stackTrace = "";
- try {
- stackTrace = LogFormatTools.getStackTop(e);
- } catch (Exception a) {
- // ignore
- }
- final String errorMessage = new StringBuilder().append(errorObject.getErrorText()).append(":")
- .append(errorObject.getRESTErrorCode()).append(":").append(errorObject.getHTTPResponseCode())
- .append(":").append(e.getMessage()).toString().replaceAll("\\n", "^");
-
- LoggingContext.responseCode(Integer.toString(errorObject.getHTTPResponseCode().getStatusCode()));
- LoggingContext.responseDescription(errorMessage);
- LoggingContext.statusCode(StatusCode.ERROR);
-
- final String details =
- new StringBuilder().append(errorObject.getErrorCodeString()).append(" ").append(stackTrace).toString();
-
- if (errorObject.getSeverity().equalsIgnoreCase("WARN"))
- LOGGER.warn(details);
- else if (errorObject.getSeverity().equalsIgnoreCase("ERROR"))
- LOGGER.error(details);
- else if (errorObject.getSeverity().equalsIgnoreCase("FATAL"))
- LOGGER.error(details);
- else if (errorObject.getSeverity().equals("INFO"))
- LOGGER.info(details);
- }
-
- public static void logError(String code) {
- logError(code, "");
- }
-
- public static void logError(String code, String message) {
- logException(new AAIException(code, message));
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/ErrorObject.java b/aai-core/src/main/java/org/onap/aai/logging/ErrorObject.java
deleted file mode 100644
index 6048c18b..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/ErrorObject.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import javax.ws.rs.core.Response.Status;
-
-/**
- *
- * Contains the definition of all error message fields to be mapped from the Error
- * properties file
- *
- */
-public class ErrorObject {
-
- private String disposition;
- private String category;
- private String severity;
- private Status httpResponseCode = Status.INTERNAL_SERVER_ERROR; // default
- private String restErrorCode = "3002";
- private String errorCode;
- private String errorText;
- private String details;
-
- /**
- * Instantiates a new error object.
- */
- public ErrorObject() {
- super();
- }
-
- /**
- * Creates an error object with the default HTTP Error Code (Status.INTERNAL_SERVER_ERROR)
- *
- * @param disposition the disposition
- * @param category the category
- * @param severity the severity
- * @param httpResponseCode the http response code
- * @param restErrorCode the rest error code
- * @param errorCode the error code
- * @param errorText the error text
- */
- public ErrorObject(String disposition, String category, String severity, Integer httpResponseCode,
- String restErrorCode, String errorCode, String errorText) {
- super();
- this.setDisposition(disposition);
- this.setCategory(category);
- this.severity = severity;
- this.setHTTPResponseCode(httpResponseCode);
- this.setRESTErrorCode(restErrorCode);
- this.setErrorCode(errorCode);
- this.setErrorText(errorText);
- }
-
- // OLD STARTS HERE
-
- /**
- * Instantiates a new error object.
- *
- * @param severity the severity
- * @param errorCode the error code
- * @param errorText the error text
- * @param disposition the disposition
- * @param category the category
- */
- public ErrorObject(String severity, String errorCode, String errorText, String disposition, String category) {
- this(severity, Status.INTERNAL_SERVER_ERROR, errorCode, errorText, disposition, category);
- }
-
- /**
- * Instantiates a new error object.
- *
- * @param severity the severity
- * @param httpResponseCode the http response code
- * @param errorCode the error code
- * @param errorText the error text
- * @param disposition the disposition
- * @param category the category
- */
- public ErrorObject(String severity, Integer httpResponseCode, String errorCode, String errorText,
- String disposition, String category) {
- super();
- this.severity = severity;
- this.setHTTPResponseCode(httpResponseCode);
- this.setErrorCode(errorCode);
- this.setErrorText(errorText);
- this.setDisposition(disposition);
- this.setCategory(category);
- }
-
- /**
- * Instantiates a new error object.
- *
- * @param severity the severity
- * @param httpResponseCode the http response code
- * @param errorCode the error code
- * @param errorText the error text
- * @param disposition the disposition
- * @param category the category
- */
- public ErrorObject(String severity, Status httpResponseCode, String errorCode, String errorText, String disposition,
- String category) {
- super();
- this.severity = severity;
- this.setHTTPResponseCode(httpResponseCode);
- this.setErrorCode(errorCode);
- this.setErrorText(errorText);
- this.setDisposition(disposition);
- this.setCategory(category);
- }
-
- /**
- * Gets the disposition.
- *
- * @return the disposition
- */
- public String getDisposition() {
- return disposition;
- }
-
- /**
- * Sets the disposition.
- *
- * @param disposition the new disposition
- */
- public void setDisposition(String disposition) {
- this.disposition = disposition;
- }
-
- /**
- * Gets the category.
- *
- * @return the category
- */
- public String getCategory() {
- return category;
- }
-
- /**
- * Sets the category.
- *
- * @param category the new category
- */
- public void setCategory(String category) {
- this.category = category;
- }
-
- /**
- * Gets the severity.
- *
- * @return the severity
- */
- public String getSeverity() {
- return severity;
- }
-
- /**
- * Sets the severity.
- *
- * @param severity the new severity
- */
- public void setSeverity(String severity) {
- this.severity = severity;
- }
-
- /**
- * Gets the error code.
- *
- * @return the error code
- */
- public String getErrorCode() {
- return errorCode;
- }
-
- /**
- * Sets the error code.
- *
- * @param errorCode the new error code
- */
- public void setErrorCode(String errorCode) {
- this.errorCode = errorCode;
- }
-
- /**
- * Gets the HTTP response code.
- *
- * @return the HTTP response code
- */
- public Status getHTTPResponseCode() {
- return httpResponseCode;
- }
-
- /**
- * Sets the HTTP response code.
- *
- * @param httpResponseCode the new HTTP response code
- */
- public void setHTTPResponseCode(Integer httpResponseCode) {
- this.httpResponseCode = Status.fromStatusCode(httpResponseCode);
- if (this.httpResponseCode == null) {
- throw new IllegalArgumentException(
- "setHTTPResponseCode was passed an invalid Integer value, fix error.properties or your code "
- + httpResponseCode);
- }
- }
-
- /**
- * Sets the HTTP response code.
- *
- * @param httpResponseCode the new HTTP response code
- */
- public void setHTTPResponseCode(String httpResponseCode) {
- this.httpResponseCode = Status.fromStatusCode(Integer.valueOf(httpResponseCode));
- if (this.httpResponseCode == null) {
- throw new IllegalArgumentException(
- "setHTTPResponseCode was passed an invalid String value, fix error.properties or your code "
- + httpResponseCode);
- }
- }
-
- /**
- * Sets the REST error code.
- *
- * @param restErrorCode the new REST error code
- */
- public void setRESTErrorCode(String restErrorCode) {
- this.restErrorCode = restErrorCode;
- }
-
- /**
- * Gets the REST error code.
- *
- * @return the REST error code
- */
- public String getRESTErrorCode() {
- return this.restErrorCode;
- }
-
- /**
- * Sets the HTTP response code.
- *
- * @param httpResponseCode the new HTTP response code
- */
- public void setHTTPResponseCode(Status httpResponseCode) {
- this.httpResponseCode = httpResponseCode;
- if (this.httpResponseCode == null) {
- throw new IllegalArgumentException(
- "setHTTPResponseCode was passed an invalid String value, fix error.properties or your code "
- + httpResponseCode);
- }
- }
-
- /**
- * Gets the error text.
- *
- * @return the error text
- */
- public String getErrorText() {
- return errorText;
- }
-
- /**
- * Sets the error text.
- *
- * @param errorText the new error text
- */
- public void setErrorText(String errorText) {
- this.errorText = errorText;
- }
-
- /**
- * Gets the details.
- *
- * @return the details
- */
- public String getDetails() {
- return details;
- }
-
- /**
- * Sets the details.
- *
- * @param details the new details
- */
- public void setDetails(String details) {
- this.details = details == null ? "" : details;
- }
-
- /**
- * Gets the error code string. This is also the string
- * configured in Nagios to alert on
- *
- * @return the error code string
- */
- // Get the X.Y.Z representation of the error code
- public String getErrorCodeString() {
- String prefix = null;
- switch (disposition) {
- default:
- prefix = "";
- break;
- case "5":
- prefix = "ERR.";
- break;
- }
- return prefix + disposition + "." + category + "." + errorCode;
- }
-
- /**
- * Gets the severity Code. This is also the string
- * configured in Nagios to alert on
- *
- * @return the severity
- */
- // Get the numerical value of severity
- public String getSeverityCode(String severity) {
- String severityCode = "";
- switch (severity) {
- case "WARN":
- severityCode = "1";
- break;
- case "ERROR":
- severityCode = "2";
- break;
- case "FATAL":
- severityCode = "3";
- break;
- }
- return severityCode;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "ErrorObject [errorCode=" + errorCode + ", errorText=" + errorText + ", restErrorCode=" + restErrorCode
- + ", httpResponseCode=" + httpResponseCode + ", severity=" + severity + ", disposition=" + disposition
- + ", category=" + category + "]";
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/ErrorObjectNotFoundException.java b/aai-core/src/main/java/org/onap/aai/logging/ErrorObjectNotFoundException.java
deleted file mode 100644
index 3daf7137..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/ErrorObjectNotFoundException.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-public class ErrorObjectNotFoundException extends Exception {
-
- private static final long serialVersionUID = 4115316781400786740L;
-
- public ErrorObjectNotFoundException() {
- // TODO Auto-generated constructor stub
- }
-
- public ErrorObjectNotFoundException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- public ErrorObjectNotFoundException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
- public ErrorObjectNotFoundException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
- public ErrorObjectNotFoundException(String message, Throwable cause, boolean enableSuppression,
- boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- // TODO Auto-generated constructor stub
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/LogFormatTools.java b/aai-core/src/main/java/org/onap/aai/logging/LogFormatTools.java
deleted file mode 100644
index 804801f1..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/LogFormatTools.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.util.AAIConfig;
-import org.onap.aai.util.AAIConstants;
-
-public class LogFormatTools {
-
- private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
- private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DATE_FORMAT).withZone(ZoneOffset.UTC);
-
- public static String getCurrentDateTime() {
- return DTF.format(ZonedDateTime.now());
- }
-
- public static String toDate(long timestamp) {
- return DTF.format(Instant.ofEpochMilli(timestamp));
- }
-
- public static long toTimestamp(String date) {
- return ZonedDateTime.parse(date, DTF).toInstant().toEpochMilli();
- }
-
- /**
- * Gets the stack top.
- *
- * @param e the e
- * @return the stack top
- * @throws NumberFormatException the number format exception
- * @throws AAIException the AAI exception
- */
- public static String getStackTop(Throwable e) {
- // StringBuilder is more efficient than StringBuffer and should only
- // StringBuffer is only supposed to be used if multiple threads are modifying
- // the same object and since this object is created locally not necessary
- StringBuilder stackMessage = new StringBuilder();
- int maxStackTraceEntries = 10;
- try {
- maxStackTraceEntries = Integer.valueOf(AAIConfig.get(AAIConstants.LOGGING_MAX_STACK_TRACE_ENTRIES));
- } catch (AAIException a) {
- // ignore, use default
- } catch (NumberFormatException n) {
- // ignore, use default
- }
- if (e != null) {
- Throwable rootCause = ExceptionUtils.getRootCause(e);
- if (rootCause != null) {
- stackMessage.append("root cause=" + ExceptionUtils.getRootCause(e));
- StackTraceElement[] elements = rootCause.getStackTrace();
- int i = 0;
- for (StackTraceElement element : elements) {
- if (i < maxStackTraceEntries) {
- stackMessage.append(" ClassName- ");
- stackMessage.append(element.getClassName());
- stackMessage.append(" :LineNumber- ");
- stackMessage.append(element.getLineNumber());
- stackMessage.append(" :MethodName- ");
- stackMessage.append(element.getMethodName());
- }
- i++;
- }
- } else if (e.getCause() != null) {
- stackMessage.append("cause=" + e.getCause());
- StackTraceElement[] elements = e.getCause().getStackTrace();
- int i = 0;
- for (StackTraceElement element : elements) {
- if (i < maxStackTraceEntries) {
- stackMessage.append(" ClassName- ");
- stackMessage.append(element.getClassName());
- stackMessage.append(" :LineNumber- ");
- stackMessage.append(element.getLineNumber());
- stackMessage.append(" :MethodName- ");
- stackMessage.append(element.getMethodName());
- }
- i++;
- }
- } else if (e.getStackTrace() != null) {
- stackMessage.append("ex=" + e.toString());
- StackTraceElement[] elements = e.getStackTrace();
- int i = 0;
- for (StackTraceElement element : elements) {
- if (i < maxStackTraceEntries) {
- stackMessage.append(" ClassName- ");
- stackMessage.append(element.getClassName());
- stackMessage.append(" :LineNumber- ");
- stackMessage.append(element.getLineNumber());
- stackMessage.append(" :MethodName- ");
- stackMessage.append(element.getMethodName());
- }
- i++;
- }
- }
- }
- return stackMessage.toString();
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/LoggingContext.java b/aai-core/src/main/java/org/onap/aai/logging/LoggingContext.java
deleted file mode 100644
index 5630fd10..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/LoggingContext.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.slf4j.MDC;
-
-public class LoggingContext {
-
- public enum StatusCode {
- COMPLETE, ERROR
- }
-
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(LoggingContext.class);
-
- private static final String PREVIOUS_CONTEXTS_KEY = "_PREVIOUS_CONTEXTS";
-
- // Response codes from Logging Guidelines
- public static final String SUCCESS = "0";
- public static final String PERMISSION_ERROR = "100";
- public static final String AVAILABILITY_TIMEOUT_ERROR = "200";
- public static final String DATA_ERROR = "300";
- public static final String SCHEMA_ERROR = "400";
- public static final String BUSINESS_PROCESS_ERROR = "500";
- public static final String UNKNOWN_ERROR = "900";
-
- protected static final Map<String, String> responseMap = new HashMap();
-
- static {
- responseMap.put(SUCCESS, "Success");
- responseMap.put(UNKNOWN_ERROR, "Unknown error");
- }
-
- // Specific Log Event Fields
- public enum LoggingField {
- START_TIME("startTime"), REQUEST_ID("requestId"), SERVICE_INSTANCE_ID("serviceInstanceId"), SERVER_NAME(
- "serverName"), SERVICE_NAME("serviceName"), PARTNER_NAME("partnerName"), STATUS_CODE(
- "statusCode"), RESPONSE_CODE("responseCode"), RESPONSE_DESCRIPTION(
- "responseDescription"), INSTANCE_UUID("instanceUUID"), SEVERITY(
- "severity"), SERVER_IP_ADDRESS(
- "serverIpAddress"), ELAPSED_TIME("elapsedTime"), SERVER(
- "server"), CLIENT_IP_ADDRESS("clientIpAddress"), UNUSED(
- "unused"), PROCESS_KEY("processKey"), CUSTOM_FIELD_1(
- "customField1"), CUSTOM_FIELD_2(
- "customField2"), CUSTOM_FIELD_3(
- "customField3"), CUSTOM_FIELD_4(
- "customField4"),
-
- // Specific Metric Log Event Fields
- TARGET_ENTITY("targetEntity"), TARGET_SERVICE_NAME("targetServiceName"),
- // A&AI Specific Log Event Fields
- COMPONENT("component"), STOP_WATCH_START("stopWatchStart");
-
- private final String text;
-
- private LoggingField(final String text) {
- this.text = text;
- }
-
- @Override
- public String toString() {
- return text;
- }
- }
-
- public static void init() {
- LoggingContext.clear();
- LoggingContext.startTime();
- LoggingContext.server();
- LoggingContext.serverIpAddress();
- }
-
- public static void startTime() {
- MDC.put(LoggingField.START_TIME.toString(), LogFormatTools.getCurrentDateTime());
- }
-
- public static UUID requestId() {
- final String sUuid = MDC.get(LoggingField.REQUEST_ID.toString());
-
- if (sUuid == null)
- return null;
-
- return UUID.fromString(sUuid);
- }
-
- public static void requestId(UUID requestId) {
- MDC.put(LoggingField.REQUEST_ID.toString(), requestId.toString());
- }
-
- public static void requestId(String requestId) {
- try {
- if (requestId.contains(":")) {
- String[] uuidParts = requestId.split(":");
- requestId = uuidParts[0];
- }
- MDC.put(LoggingField.REQUEST_ID.toString(), UUID.fromString(requestId).toString());
- } catch (IllegalArgumentException e) {
- final UUID generatedRequestUuid = UUID.randomUUID();
- MDC.put(LoggingField.REQUEST_ID.toString(), generatedRequestUuid.toString());
- LoggingContext.save();
- // set response code to 0 since we don't know what the outcome of this request is yet
- String responseCode = LoggingContext.DATA_ERROR;
- LoggingContext.responseCode(responseCode);
- LoggingContext.responseDescription("Unable to use UUID " + requestId + " (Not formatted properly) ");
- LoggingContext.statusCode(StatusCode.ERROR);
-
- LOGGER.warn("Using generated UUID=" + generatedRequestUuid);
- LoggingContext.restore();
-
- }
- }
-
- public static void serviceInstanceId(String serviceInstanceId) {
- MDC.put(LoggingField.SERVICE_INSTANCE_ID.toString(), serviceInstanceId);
- }
-
- public static void serverName(String serverName) {
- MDC.put(LoggingField.SERVER_NAME.toString(), serverName);
- }
-
- public static void serviceName(String serviceName) {
- MDC.put(LoggingField.SERVICE_NAME.toString(), serviceName);
- }
-
- public static void partnerName(String partnerName) {
- MDC.put(LoggingField.PARTNER_NAME.toString(), partnerName);
- }
-
- public static void statusCode(StatusCode statusCode) {
- MDC.put(LoggingField.STATUS_CODE.toString(), statusCode.toString());
- }
-
- public static String responseCode() {
- return MDC.get(LoggingField.RESPONSE_CODE.toString());
- }
-
- public static void responseCode(String responseCode) {
- MDC.put(LoggingField.RESPONSE_CODE.toString(), responseCode);
- }
-
- public static void responseDescription(String responseDescription) {
- MDC.put(LoggingField.RESPONSE_DESCRIPTION.toString(), responseDescription);
- }
-
- public static Object instanceUuid() {
- return UUID.fromString(MDC.get(LoggingField.INSTANCE_UUID.toString()));
- }
-
- public static void instanceUuid(UUID instanceUuid) {
- MDC.put(LoggingField.INSTANCE_UUID.toString(), instanceUuid.toString());
- }
-
- public static void severity(int severity) {
- MDC.put(LoggingField.SEVERITY.toString(), String.valueOf(severity));
- }
-
- public static void successStatusFields() {
- responseCode(SUCCESS);
- statusCode(StatusCode.COMPLETE);
- responseDescription("Success");
- }
-
- private static void serverIpAddress() {
- try {
- MDC.put(LoggingField.SERVER_IP_ADDRESS.toString(), InetAddress.getLocalHost().getHostAddress());
- } catch (UnknownHostException e) {
- LOGGER.warn("Unable to resolve server IP address - will not be displayed in logged events");
- }
- }
-
- public static void elapsedTime(long elapsedTime, TimeUnit timeUnit) {
- MDC.put(LoggingField.ELAPSED_TIME.toString(),
- String.valueOf(TimeUnit.MILLISECONDS.convert(elapsedTime, timeUnit)));
- }
-
- private static void server() {
- try {
- MDC.put(LoggingField.SERVER.toString(), InetAddress.getLocalHost().getCanonicalHostName());
- } catch (UnknownHostException e) {
- LOGGER.warn("Unable to resolve server IP address - hostname will not be displayed in logged events");
- }
- }
-
- public static void clientIpAddress(InetAddress clientIpAddress) {
- MDC.put(LoggingField.CLIENT_IP_ADDRESS.toString(), clientIpAddress.getHostAddress());
- }
-
- public static void clientIpAddress(String clientIpAddress) {
- try {
- MDC.put(LoggingField.CLIENT_IP_ADDRESS.toString(), InetAddress.getByName(clientIpAddress).getHostAddress());
- } catch (UnknownHostException e) {
- // Ignore, will not be thrown since InetAddress.getByName(String) only
- // checks the validity of the passed in string
- }
- }
-
- public static void unused(String unused) {
- LOGGER.warn("Using field '" + LoggingField.UNUSED + "' (seems like this should go unused...)");
- MDC.put(LoggingField.UNUSED.toString(), unused);
- }
-
- public static void processKey(String processKey) {
- MDC.put(LoggingField.PROCESS_KEY.toString(), processKey);
- }
-
- public static String customField1() {
- return MDC.get(LoggingField.CUSTOM_FIELD_1.toString());
- }
-
- public static void customField1(String customField1) {
- MDC.put(LoggingField.CUSTOM_FIELD_1.toString(), customField1);
- }
-
- public static void customField2(String customField2) {
- MDC.put(LoggingField.CUSTOM_FIELD_2.toString(), customField2);
- }
-
- public static void customField3(String customField3) {
- MDC.put(LoggingField.CUSTOM_FIELD_3.toString(), customField3);
- }
-
- public static void customField4(String customField4) {
- MDC.put(LoggingField.CUSTOM_FIELD_4.toString(), customField4);
- }
-
- public static void component(String component) {
- MDC.put(LoggingField.COMPONENT.toString(), component);
- }
-
- public static void targetEntity(String targetEntity) {
- MDC.put(LoggingField.TARGET_ENTITY.toString(), targetEntity);
- }
-
- public static void targetServiceName(String targetServiceName) {
- MDC.put(LoggingField.TARGET_SERVICE_NAME.toString(), targetServiceName);
- }
-
- public static boolean isStopWatchStarted() {
- final String rawStopWatchStart = MDC.get(LoggingField.STOP_WATCH_START.toString());
- return rawStopWatchStart != null;
- }
-
- public static void stopWatchStart() {
- MDC.put(LoggingField.STOP_WATCH_START.toString(), String.valueOf(System.nanoTime()));
- }
-
- public static double stopWatchStop() {
- final long stopWatchEnd = System.nanoTime();
- final String rawStopWatchStart = MDC.get(LoggingField.STOP_WATCH_START.toString());
-
- if (rawStopWatchStart == null)
- throw new StopWatchNotStartedException();
-
- final Long stopWatchStart = Long.valueOf(rawStopWatchStart);
-
- MDC.remove(LoggingField.STOP_WATCH_START.toString());
-
- final double elapsedTimeMillis = (stopWatchEnd - stopWatchStart) / 1000.0 / 1000.0;
-
- LoggingContext.elapsedTime((long) elapsedTimeMillis, TimeUnit.MILLISECONDS);
-
- return elapsedTimeMillis;
- }
-
- public static void put(String key, String value) {
- MDC.put(key, value);
- }
-
- public static void clear() {
- MDC.clear();
- }
-
- public static void remove(String key) {
- MDC.remove(key);
- }
-
- public static void save() {
- final JSONObject context = new JSONObject();
-
- for (LoggingField field : LoggingField.values()) {
- if (field == LoggingField.ELAPSED_TIME)
- continue;
-
- try {
- context.put(field.toString(), MDC.get(field.toString()));
- } catch (JSONException e) {
- // Ignore - only occurs when the key is null (which can't happen)
- // or the value is invalid (everything is converted to a string
- // before it get put() to the MDC)
- }
- }
-
- final String rawJsonArray = MDC.get(PREVIOUS_CONTEXTS_KEY);
-
- if (rawJsonArray == null) {
- final JSONArray stack = new JSONArray().put(context);
-
- MDC.put(PREVIOUS_CONTEXTS_KEY, stack.toString());
- } else {
- try {
- final JSONArray stack = new JSONArray(rawJsonArray).put(context);
-
- MDC.put(PREVIOUS_CONTEXTS_KEY, stack.toString());
- } catch (JSONException e) {
- // Ignore
- }
- }
- }
-
- public static void restore() {
-
- final String rawPreviousContexts = MDC.get(PREVIOUS_CONTEXTS_KEY);
-
- if (rawPreviousContexts == null) {
- throw new LoggingContextNotExistsException();
- }
-
- try {
- final JSONArray previousContexts = new JSONArray(rawPreviousContexts);
- final JSONObject previousContext = previousContexts.getJSONObject(previousContexts.length() - 1);
-
- @SuppressWarnings("unchecked")
- final Iterator<String> keys = previousContext.keys();
- boolean foundElapsedTime = false;
- while (keys.hasNext()) {
- final String key = keys.next();
- if (LoggingField.ELAPSED_TIME.toString().equals(key)) {
- foundElapsedTime = true;
- }
- try {
- MDC.put(key, previousContext.getString(key));
- } catch (JSONException e) {
- // Ignore, only occurs when the key is null (cannot happen)
- // or the value is invalid (they are all strings)
- }
- }
- if (!foundElapsedTime) {
- MDC.remove(LoggingField.ELAPSED_TIME.toString());
- }
- MDC.put(PREVIOUS_CONTEXTS_KEY, removeLast(previousContexts).toString());
- } catch (JSONException e) {
- // Ignore, the previousContext is serialized from a JSONObject
- }
- }
-
- public static void restoreIfPossible() {
- try {
- restore();
- } catch (LoggingContextNotExistsException e) {
- // Ignore
- }
- }
-
- /**
- * AJSC declares an ancient version of org.json:json in one of the parent POMs of this project.
- * I tried to update our version of that library in our POM, but it's ignored because of the way
- * AJSC has organized their <dependencies>. Had they put it into the <dependencyManagement> section,
- * this method would not be necessary.
- */
- private static JSONArray removeLast(JSONArray previousContexts) {
- final JSONArray result = new JSONArray();
-
- for (int i = 0; i < previousContexts.length() - 1; i++) {
- try {
- result.put(previousContexts.getJSONObject(i));
- } catch (JSONException e) {
- // Ignore - not possible
- }
- }
-
- return result;
- }
-
- public static Map<String, String> getCopy() {
- final Map<String, String> copy = new HashMap<>();
-
- for (LoggingField field : LoggingField.values()) {
- final String value = MDC.get(field.toString());
-
- if (value != null)
- copy.put(field.toString(), value);
- }
-
- return copy;
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/StopWatch.java b/aai-core/src/main/java/org/onap/aai/logging/StopWatch.java
deleted file mode 100644
index 0d93827f..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/StopWatch.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-import org.onap.aai.logging.LoggingContext.LoggingField;
-
-public final class StopWatch {
-
- private StopWatch() {
- }
-
- public static void start() {
- LoggingContext.stopWatchStart();
- }
-
- public static double stop() {
- return LoggingContext.stopWatchStop();
- }
-
- public static void conditionalStart() {
- if (LoggingContext.isStopWatchStarted()) {
- return;
- }
- start();
- }
-
- public static double stopIfStarted() {
- if (LoggingContext.isStopWatchStarted()) {
- return (stop());
- }
- return (0);
- }
-
- public static void clear() {
- LoggingContext.remove(LoggingField.STOP_WATCH_START.toString());
- LoggingContext.remove(LoggingField.ELAPSED_TIME.toString());
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/StopWatchNotStartedException.java b/aai-core/src/main/java/org/onap/aai/logging/StopWatchNotStartedException.java
deleted file mode 100644
index e4819c5c..00000000
--- a/aai-core/src/main/java/org/onap/aai/logging/StopWatchNotStartedException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.logging;
-
-public class StopWatchNotStartedException extends RuntimeException {
-
- private static final long serialVersionUID = -4540164295822859408L;
-
- public StopWatchNotStartedException() {
- super();
- }
-
- public StopWatchNotStartedException(String message) {
- super(message);
- }
-
- public StopWatchNotStartedException(Throwable cause) {
- super(cause);
- }
-
- public StopWatchNotStartedException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/parsers/query/LegacyQueryParser.java b/aai-core/src/main/java/org/onap/aai/parsers/query/LegacyQueryParser.java
index c9412733..ca735357 100644
--- a/aai-core/src/main/java/org/onap/aai/parsers/query/LegacyQueryParser.java
+++ b/aai-core/src/main/java/org/onap/aai/parsers/query/LegacyQueryParser.java
@@ -20,8 +20,8 @@
package org.onap.aai.parsers.query;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URI;
@@ -49,7 +49,7 @@ import org.onap.aai.schema.enums.PropertyMetadata;
*/
public class LegacyQueryParser extends QueryParser implements Parsable {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(LegacyQueryParser.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(LegacyQueryParser.class);
private Introspector previous = null;
diff --git a/aai-core/src/main/java/org/onap/aai/parsers/query/RelationshipQueryParser.java b/aai-core/src/main/java/org/onap/aai/parsers/query/RelationshipQueryParser.java
index 0958a81e..e1319802 100644
--- a/aai-core/src/main/java/org/onap/aai/parsers/query/RelationshipQueryParser.java
+++ b/aai-core/src/main/java/org/onap/aai/parsers/query/RelationshipQueryParser.java
@@ -20,8 +20,8 @@
package org.onap.aai.parsers.query;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
@@ -41,7 +41,7 @@ import org.springframework.context.ApplicationContext;
*/
public class RelationshipQueryParser extends LegacyQueryParser {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(RelationshipQueryParser.class);
+ private static final Logger logger = LoggerFactory.getLogger(RelationshipQueryParser.class);
private Introspector relationship = null;
diff --git a/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java b/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java
index 0b072b88..0ee22f50 100644
--- a/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java
+++ b/aai-core/src/main/java/org/onap/aai/parsers/relationship/RelationshipToURI.java
@@ -20,8 +20,8 @@
package org.onap.aai.parsers.relationship;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URI;
@@ -57,7 +57,7 @@ import org.springframework.context.ApplicationContext;
*/
public class RelationshipToURI {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(RelationshipToURI.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(RelationshipToURI.class);
private Introspector relationship = null;
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/Validation.java b/aai-core/src/main/java/org/onap/aai/prevalidation/Validation.java
new file mode 100644
index 00000000..d420c558
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/Validation.java
@@ -0,0 +1,92 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.prevalidation;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+import java.util.Objects;
+
+public class Validation {
+
+ @SerializedName("validationId")
+ private String validationId;
+
+ @SerializedName("action")
+ private String action;
+
+ @SerializedName("violations")
+ private List<Violation> violations;
+
+ public String getValidationId() {
+ return validationId;
+ }
+
+ public void setValidationId(String validationId) {
+ this.validationId = validationId;
+ }
+
+ public List<Violation> getViolations() {
+ return violations;
+ }
+
+ public void setViolations(List<Violation> violations) {
+ this.violations = violations;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Validation that = (Validation) o;
+ return Objects.equals(validationId, that.validationId) &&
+ Objects.equals(action, that.action) &&
+ Objects.equals(violations, that.violations);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(validationId, action, violations);
+ }
+
+ @Override
+ public String toString() {
+ return "Validation{" +
+ "validationId='" + validationId + '\'' +
+ ", action='" + action + '\'' +
+ ", violations=" + violations +
+ '}';
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java
new file mode 100644
index 00000000..36569dd0
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationConfiguration.java
@@ -0,0 +1,51 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.prevalidation;
+
+import org.onap.aai.restclient.RestClient;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+@Profile("pre-validation")
+@Configuration
+public class ValidationConfiguration {
+
+ @Bean(name = "validationRestClient")
+ @ConditionalOnProperty(name = "validation.service.client", havingValue = "two-way-ssl", matchIfMissing = true)
+ public RestClient validationRestClientTwoWaySSL() {
+ return new ValidationServiceRestClient();
+ }
+
+ @Bean(name = "validationRestClient")
+ @ConditionalOnProperty(name = "validation.service.client", havingValue = "no-auth")
+ public RestClient validationRestClientNoAuth() {
+ return new ValidationServiceNoAuthClient();
+ }
+
+ @Bean(name = "validationRestClient")
+ @ConditionalOnProperty(name = "validation.service.client", havingValue = "one-way-ssl")
+ public RestClient validationRestClientOneWaySSL() {
+ return new ValidationServiceOneWayClient();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java
new file mode 100644
index 00000000..78083ecb
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationService.java
@@ -0,0 +1,299 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.prevalidation;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.rest.ueb.NotificationEvent;
+import org.onap.aai.restclient.RestClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Profile;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * <b>ValidationService</b> routes all the writes to the database
+ * excluding deletes for now to the validation service to verify
+ * that the request is an valid one before committing to the database
+ */
+@Service
+@Profile("pre-validation")
+public class ValidationService {
+
+ /**
+ * Error indicating that the service trying to connect is down
+ */
+ static final String CONNECTION_REFUSED_STRING =
+ "Connection refused to the validation microservice due to service unreachable";
+
+ /**
+ * Error indicating that the server is unable to reach the port
+ * Could be server related connectivity issue
+ */
+ static final String CONNECTION_TIMEOUT_STRING =
+ "Connection timeout to the validation microservice as this could " +
+ "indicate the server is unable to reach port, " +
+ "please check on server by running: nc -w10 -z -v ${VALIDATION_HOST} ${VALIDATION_PORT}";
+
+ /**
+ * Error indicating that the request exceeded the allowed time
+ *
+ * Note: This means that the service could be active its
+ * just taking some time to process our request
+ */
+ static final String REQUEST_TIMEOUT_STRING =
+ "Request to validation service took longer than the currently set timeout";
+
+ static final String VALIDATION_ENDPOINT = "/v1/app/validate";
+ static final String VALIDATION_HEALTH_ENDPOINT = "/v1/core/core-service/info";
+
+ private static final String ENTITY_TYPE = "entity-type";
+ private static final String ACTION = "action";
+ private static final String SOURCE_NAME = "source-name";
+
+ private static final String DELETE = "DELETE";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ValidationService.class);
+
+ private final RestClient validationRestClient;
+
+ private final String appName;
+
+ private final Set<String> validationNodeTypes;
+
+ private List<Pattern> exclusionList;
+
+ private final Gson gson;
+
+ @Autowired
+ public ValidationService(
+ @Qualifier("validationRestClient") RestClient validationRestClient,
+ @Value("${spring.application.name}") String appName,
+ @Value("${validation.service.node-types}") String validationNodes,
+ @Value("${validation.service.exclusion-regexes}") String exclusionRegexes
+ ){
+ this.validationRestClient = validationRestClient;
+ this.appName = appName;
+
+ this.validationNodeTypes = Arrays
+ .stream(validationNodes.split(","))
+ .collect(Collectors.toSet());
+
+ if(exclusionRegexes == null || exclusionRegexes.isEmpty()){
+ this.exclusionList = new ArrayList<>();
+ } else {
+ this.exclusionList = Arrays
+ .stream(exclusionRegexes.split(","))
+ .map(Pattern::compile)
+ .collect(Collectors.toList());
+ }
+ this.gson = new Gson();
+ LOGGER.info("Successfully initialized the pre validation service");
+ }
+
+ @PostConstruct
+ public void initialize() throws AAIException {
+
+ Map<String, String> httpHeaders = new HashMap<>();
+
+ httpHeaders.put("X-FromAppId", appName);
+ httpHeaders.put("X-TransactionID", UUID.randomUUID().toString());
+ httpHeaders.put("Content-Type", "application/json");
+
+ ResponseEntity<String> healthCheckResponse = null;
+
+ try {
+
+ healthCheckResponse = validationRestClient.execute(
+ VALIDATION_HEALTH_ENDPOINT,
+ HttpMethod.GET,
+ httpHeaders,
+ null
+ );
+
+ } catch(Exception ex){
+ AAIException validationException = new AAIException("AAI_4021", ex);
+ throw validationException;
+ }
+
+ if(!isSuccess(healthCheckResponse)){
+ throw new AAIException("AAI_4021");
+ }
+
+ LOGGER.info("Successfully connected to the validation service endpoint");
+ }
+
+ public boolean shouldValidate(String nodeType){
+ return this.validationNodeTypes.contains(nodeType);
+ }
+
+ public void validate(List<NotificationEvent> notificationEvents) throws AAIException {
+
+ if(notificationEvents == null || notificationEvents.isEmpty()){
+ return;
+ }
+
+ {
+ // Get the first notification and if the source of that notification
+ // is in one of the regexes then we skip sending it to validation
+ NotificationEvent notification = notificationEvents.get(0);
+ Introspector eventHeader = notification.getEventHeader();
+ if(eventHeader != null){
+ String source = eventHeader.getValue(SOURCE_NAME);
+ for(Pattern pattern: exclusionList){
+ if(pattern.matcher(source).matches()){
+ return;
+ }
+ }
+ }
+
+ }
+
+ for (NotificationEvent event : notificationEvents) {
+
+ Introspector eventHeader = event.getEventHeader();
+
+ if(eventHeader == null){
+ // Should I skip processing the request and let it continue
+ // or fail the request and cause client impact
+ continue;
+ }
+
+ String entityType = eventHeader.getValue(ENTITY_TYPE);
+ String action = eventHeader.getValue(ACTION);
+
+ /**
+ * Skipping the delete events for now
+ * Note: Might revisit this later when validation supports DELETE events
+ */
+ if(DELETE.equalsIgnoreCase(action)){
+ continue;
+ }
+
+ if (this.shouldValidate(entityType)) {
+ List<String> violations = this.preValidate(event.getNotificationEvent());
+ if(!violations.isEmpty()){
+ AAIException aaiException = new AAIException("AAI_4019");
+ aaiException.getTemplateVars().addAll(violations);
+ throw aaiException;
+ }
+ }
+ }
+ }
+
+ List<String> preValidate(String body) throws AAIException {
+
+ Map<String, String> httpHeaders = new HashMap<>();
+
+ httpHeaders.put("X-FromAppId", appName);
+ httpHeaders.put("X-TransactionID", UUID.randomUUID().toString());
+ httpHeaders.put("Content-Type", "application/json");
+
+ List<String> violations = new ArrayList<>();
+ ResponseEntity responseEntity;
+ try {
+
+ responseEntity = validationRestClient.execute(
+ VALIDATION_ENDPOINT,
+ HttpMethod.POST,
+ httpHeaders,
+ body
+ );
+
+ if(isSuccess(responseEntity)){
+ LOGGER.debug("Validation Service returned following response status code {} and body {}", responseEntity.getStatusCodeValue(), responseEntity.getBody());
+ } else {
+ Validation validation = null;
+ try {
+ validation = gson.fromJson(responseEntity.getBody().toString(), Validation.class);
+ } catch(JsonSyntaxException jsonException){
+ LOGGER.warn("Unable to convert the response body {}", jsonException.getMessage());
+ }
+
+ if(validation == null){
+ LOGGER.debug(
+ "Validation Service following status code {} with body {}",
+ responseEntity.getStatusCodeValue(),
+ responseEntity.getBody()
+ );
+ } else {
+ violations.addAll(extractViolations(validation));
+ }
+ }
+ } catch(Exception e){
+ // If the exception cause is client side timeout
+ // then proceed as if it passed validation
+ // resources microservice shouldn't be blocked because of validation service
+ // is taking too long or if the validation service is down
+ // Any other exception it should block the request from passing?
+ if(e.getCause() instanceof SocketTimeoutException){
+ LOGGER.error(REQUEST_TIMEOUT_STRING, e.getCause());
+ } else if(e.getCause() instanceof ConnectException){
+ LOGGER.error(CONNECTION_REFUSED_STRING, e.getCause());
+ } else if(e.getCause() instanceof ConnectTimeoutException){
+ LOGGER.error(CONNECTION_TIMEOUT_STRING, e.getCause());
+ } else {
+ LOGGER.error("Unknown exception thrown please investigate", e.getCause());
+ }
+ }
+ return violations;
+ }
+
+ boolean isSuccess(ResponseEntity responseEntity){
+ return responseEntity != null && responseEntity.getStatusCode().is2xxSuccessful();
+ }
+
+ List<String> extractViolations(Validation validation) {
+
+ List<String> errorMessages = new ArrayList<>();
+
+ if(validation == null){
+ return errorMessages;
+ }
+
+ List<Violation> violations = validation.getViolations();
+
+ if (violations != null && !violations.isEmpty()) {
+ for (Violation violation : validation.getViolations()) {
+ LOGGER.info(violation.getErrorMessage());
+ errorMessages.add(violation.getErrorMessage());
+ }
+ }
+
+ return errorMessages;
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceNoAuthClient.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceNoAuthClient.java
new file mode 100644
index 00000000..d373ae78
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceNoAuthClient.java
@@ -0,0 +1,79 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-19 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.prevalidation;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.onap.aai.restclient.NoAuthRestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.util.MultiValueMap;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+public class ValidationServiceNoAuthClient extends NoAuthRestClient {
+
+ private static Logger logger = LoggerFactory.getLogger(ValidationServiceNoAuthClient.class);
+
+ @Value("${validation.service.base.url}")
+ private String baseUrl;
+
+ @Value("${validation.service.timeout-in-milliseconds}")
+ private Integer timeout;
+
+ @Override
+ protected HttpComponentsClientHttpRequestFactory getHttpRequestFactory() throws Exception {
+ HttpComponentsClientHttpRequestFactory requestFactory = super.getHttpRequestFactory();
+ requestFactory.setConnectionRequestTimeout(timeout);
+ requestFactory.setReadTimeout(timeout);
+ requestFactory.setConnectTimeout(timeout);
+ return requestFactory;
+ }
+
+ @Override
+ public String getBaseUrl() {
+ return baseUrl;
+ }
+
+ @Override
+ public MultiValueMap<String, String> getHeaders(Map<String, String> headers) {
+ HttpHeaders httpHeaders = new HttpHeaders();
+
+ String defaultAccept = headers.getOrDefault(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
+ String defaultContentType =
+ headers.getOrDefault(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString());
+
+ if (headers.isEmpty()) {
+ httpHeaders.setAccept(Collections.singletonList(MediaType.parseMediaType(defaultAccept)));
+ httpHeaders.setContentType(MediaType.parseMediaType(defaultContentType));
+ }
+
+ httpHeaders.add("X-FromAppId", appName);
+ httpHeaders.add("X-TransactionId", UUID.randomUUID().toString());
+ headers.forEach(httpHeaders::add);
+ return httpHeaders;
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceOneWayClient.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceOneWayClient.java
new file mode 100644
index 00000000..40efd469
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceOneWayClient.java
@@ -0,0 +1,92 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-19 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.prevalidation;
+
+import org.onap.aai.restclient.OneWaySSLRestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.util.MultiValueMap;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+public class ValidationServiceOneWayClient extends OneWaySSLRestClient {
+
+ @Value("${validation.service.base.url}")
+ private String baseUrl;
+
+ @Value("${validation.service.ssl.trust-store}")
+ private String truststorePath;
+
+ @Value("${validation.service.ssl.trust-store-password}")
+ private String truststorePassword;
+
+ @Value("${validation.service.timeout-in-milliseconds}")
+ private Integer timeout;
+
+ @Override
+ public String getBaseUrl() {
+ return baseUrl;
+ }
+
+ @Override
+ protected String getTruststorePath() {
+ return truststorePath;
+ }
+
+ @Override
+ protected char[] getTruststorePassword() {
+ return truststorePassword.toCharArray();
+ }
+
+ @Override
+ protected HttpComponentsClientHttpRequestFactory getHttpRequestFactory() throws Exception {
+ HttpComponentsClientHttpRequestFactory requestFactory = super.getHttpRequestFactory();
+ requestFactory.setConnectionRequestTimeout(timeout);
+ requestFactory.setReadTimeout(timeout);
+ requestFactory.setConnectTimeout(timeout);
+ return requestFactory;
+ }
+
+ @Override
+ public MultiValueMap<String, String> getHeaders(Map<String, String> headers) {
+ HttpHeaders httpHeaders = new HttpHeaders();
+
+ String defaultAccept = headers.getOrDefault(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
+ String defaultContentType =
+ headers.getOrDefault(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString());
+
+ if (headers.isEmpty()) {
+ httpHeaders.setAccept(Collections.singletonList(MediaType.parseMediaType(defaultAccept)));
+ httpHeaders.setContentType(MediaType.parseMediaType(defaultContentType));
+ }
+
+ httpHeaders.add("X-FromAppId", appName);
+ httpHeaders.add("X-TransactionId", UUID.randomUUID().toString());
+ httpHeaders.add("X-TransactionId", appName);
+ headers.forEach(httpHeaders::add);
+ return httpHeaders;
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceRestClient.java b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceRestClient.java
new file mode 100644
index 00000000..8674272e
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/ValidationServiceRestClient.java
@@ -0,0 +1,108 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.prevalidation;
+
+import org.onap.aai.restclient.TwoWaySSLRestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.util.MultiValueMap;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+public class ValidationServiceRestClient extends TwoWaySSLRestClient {
+
+ @Value("${validation.service.base.url}")
+ private String baseUrl;
+
+ @Value("${validation.service.ssl.key-store}")
+ private String keystorePath;
+
+ @Value("${validation.service.ssl.trust-store}")
+ private String truststorePath;
+
+ @Value("${validation.service.ssl.key-store-password}")
+ private String keystorePassword;
+
+ @Value("${validation.service.ssl.trust-store-password}")
+ private String truststorePassword;
+
+ @Value("${validation.service.timeout-in-milliseconds}")
+ private Integer timeout;
+
+ @Override
+ public String getBaseUrl() {
+ return baseUrl;
+ }
+
+ @Override
+ protected String getKeystorePath() {
+ return keystorePath;
+ }
+
+ @Override
+ protected String getTruststorePath() {
+ return truststorePath;
+ }
+
+ @Override
+ protected char[] getKeystorePassword() {
+ return keystorePassword.toCharArray();
+ }
+
+ @Override
+ protected char[] getTruststorePassword() {
+ return truststorePassword.toCharArray();
+ }
+
+ protected HttpComponentsClientHttpRequestFactory getHttpRequestFactory() throws Exception {
+ HttpComponentsClientHttpRequestFactory requestFactory = super.getHttpRequestFactory();
+ requestFactory.setConnectionRequestTimeout(timeout);
+ requestFactory.setReadTimeout(timeout);
+ requestFactory.setConnectTimeout(timeout);
+ return requestFactory;
+ }
+
+ @Override
+ public MultiValueMap<String, String> getHeaders(Map<String, String> headers) {
+ HttpHeaders httpHeaders = new HttpHeaders();
+
+ String defaultAccept = headers.getOrDefault(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString());
+ String defaultContentType =
+ headers.getOrDefault(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString());
+
+ if (headers.isEmpty()) {
+ httpHeaders.setAccept(Collections.singletonList(MediaType.parseMediaType(defaultAccept)));
+ httpHeaders.setContentType(MediaType.parseMediaType(defaultContentType));
+ }
+
+ httpHeaders.add("X-FromAppId", appName);
+ httpHeaders.add("X-TransactionId", UUID.randomUUID().toString());
+ headers.forEach(httpHeaders::add);
+ return httpHeaders;
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/prevalidation/Violation.java b/aai-core/src/main/java/org/onap/aai/prevalidation/Violation.java
new file mode 100644
index 00000000..e5472a7c
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/prevalidation/Violation.java
@@ -0,0 +1,128 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-19 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.prevalidation;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Objects;
+
+public class Violation {
+
+ @SerializedName("violationId")
+ private String violationId;
+
+ @SerializedName("modelName")
+ private String modelName;
+
+ @SerializedName("category")
+ private String category;
+
+ @SerializedName("severity")
+ private String severity;
+
+ @SerializedName("violationType")
+ private String violationType;
+
+ @SerializedName("errorMessage")
+ private String errorMessage;
+
+ public String getViolationId() {
+ return violationId;
+ }
+
+ public void setViolationId(String violationId) {
+ this.violationId = violationId;
+ }
+
+ public String getModelName() {
+ return modelName;
+ }
+
+ public void setModelName(String modelName) {
+ this.modelName = modelName;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getSeverity() {
+ return severity;
+ }
+
+ public void setSeverity(String severity) {
+ this.severity = severity;
+ }
+
+ public String getViolationType() {
+ return violationType;
+ }
+
+ public void setViolationType(String violationType) {
+ this.violationType = violationType;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ @Override
+ public String toString() {
+ return "Violation{" +
+ "violationId='" + violationId + '\'' +
+ ", modelName='" + modelName + '\'' +
+ ", category='" + category + '\'' +
+ ", severity='" + severity + '\'' +
+ ", violationType='" + violationType + '\'' +
+ ", errorMessage='" + errorMessage + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Violation violation = (Violation) o;
+ return Objects.equals(violationId, violation.violationId) &&
+ Objects.equals(modelName, violation.modelName) &&
+ Objects.equals(category, violation.category) &&
+ Objects.equals(severity, violation.severity) &&
+ Objects.equals(violationType, violation.violationType) &&
+ Objects.equals(errorMessage, violation.errorMessage);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(violationId, modelName, category, severity, violationType, errorMessage);
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java
index 272a2c21..1dc3f1d6 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java
@@ -64,7 +64,6 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
public GraphTraversalBuilder(Loader loader, GraphTraversalSource source) {
super(loader, source);
-
traversal = (GraphTraversal<Vertex, E>) __.<E>start();
}
@@ -73,7 +72,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
* Instantiates a new graph traversal builder.
*
* @param loader the loader
- * @param start the start
+ * @param start the start
*/
public GraphTraversalBuilder(Loader loader, GraphTraversalSource source, Vertex start) {
super(loader, source, start);
@@ -89,12 +88,33 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
public QueryBuilder<Vertex> getVerticesByProperty(String key, Object value) {
// correct value call because the index is registered as an Integer
- traversal.has(key, this.correctObjectType(value));
-
+ this.vertexHas(key, this.correctObjectType(value));
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
+ @Override
+ protected void vertexHas(String key, Object value) {
+ traversal.has(key, value);
+ }
+
+ @Override
+ protected void vertexHasNot(String key) {
+ traversal.hasNot(key);
+ }
+
+ @Override
+ protected void vertexHas(String key) {
+ traversal.has(key);
+ }
+
+ //TODO: Remove this once we test this - at this point i dont thib this is required
+ //because predicare is an object
+ /*@Override
+ protected void vertexHas(final String key, final P<?> predicate) {
+ traversal.has(key, predicate);
+ }*/
+
/**
* @{inheritDoc}
*/
@@ -107,7 +127,21 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
correctedValues.add(this.correctObjectType(item));
}
- traversal.has(key, P.within(correctedValues));
+ this.vertexHas(key, P.within(correctedValues));
+ stepIndex++;
+ return (QueryBuilder<Vertex>) this;
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ public QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value) {
+ ArrayList<String> values = new ArrayList<>(Arrays.asList(value.split(",")));
+ int size = values.size();
+ for (int i = 0; i < size; i++) {
+ values.set(i, values.get(i).trim());
+ }
+ this.vertexHas(key, P.within(values));
stepIndex++;
return (QueryBuilder<Vertex>) this;
@@ -120,7 +154,8 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
public QueryBuilder<Vertex> getVerticesStartsWithProperty(String key, Object value) {
// correct value call because the index is registered as an Integer
- traversal.has(key, org.janusgraph.core.attribute.Text.textPrefix(value));
+ //TODO Check if this needs to be in QB and add these as internal
+ this.vertexHas(key, org.janusgraph.core.attribute.Text.textPrefix(value));
stepIndex++;
return (QueryBuilder<Vertex>) this;
@@ -131,8 +166,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getVerticesByProperty(String key) {
-
- traversal.has(key);
+ this.vertexHas(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -142,8 +176,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key) {
-
- traversal.hasNot(key);
+ this.vertexHasNot(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -155,8 +188,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value) {
// correct value call because the index is registered as an Integer
- traversal.has(key, P.neq(this.correctObjectType(value)));
-
+ this.vertexHas(key, P.neq(this.correctObjectType(value)));
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -173,16 +205,14 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
correctedValues.add(this.correctObjectType(item));
}
- traversal.has(key, P.without(correctedValues));
-
+ this.vertexHas(key, P.without(correctedValues));
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@Override
public QueryBuilder<Vertex> getVerticesGreaterThanProperty(final String key, Object value) {
-
- traversal.has(key, P.gte(this.correctObjectType(value)));
+ this.vertexHas(key, P.gte(this.correctObjectType(value)));
stepIndex++;
return (QueryBuilder<Vertex>) this;
@@ -190,8 +220,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
@Override
public QueryBuilder<Vertex> getVerticesLessThanProperty(final String key, Object value) {
-
- traversal.has(key, P.lte(this.correctObjectType(value)));
+ this.vertexHas(key, P.lte(this.correctObjectType(value)));
stepIndex++;
return (QueryBuilder<Vertex>) this;
@@ -214,7 +243,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) {
for (Map.Entry<String, String> es : map.entrySet()) {
- traversal.has(es.getKey(), es.getValue());
+ this.vertexHas(es.getKey(), es.getValue());
stepIndex++;
}
traversal.has(AAIProperties.NODE_TYPE, type);
@@ -234,7 +263,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
bValue = (Boolean) value;
}
- traversal.has(key, bValue);
+ this.vertexHas(key, bValue);
stepIndex++;
}
return (QueryBuilder<Vertex>) this;
@@ -257,9 +286,9 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
if (val != null) {
// this is because the index is registered as an Integer
if (val.getClass().equals(Long.class)) {
- traversal.has(key, new Integer(val.toString()));
+ this.vertexHas(key, new Integer(val.toString()));
} else {
- traversal.has(key, val);
+ this.vertexHas(key, val);
}
stepIndex++;
}
@@ -290,9 +319,9 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
// this is because the index is registered as an Integer
if (val.getClass().equals(Long.class)) {
- traversal.has(prop, new Integer(val.toString()));
+ this.vertexHas(prop, new Integer(val.toString()));
} else {
- traversal.has(prop, val);
+ this.vertexHas(prop, val);
}
stepIndex++;
}
@@ -326,7 +355,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Introspector parent, Introspector child)
- throws AAIException {
+ throws AAIException {
createTraversal(type, parent, child, false);
return (QueryBuilder<Vertex>) this;
@@ -334,13 +363,13 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
@Override
public QueryBuilder<Vertex> createPrivateEdgeTraversal(EdgeType type, Introspector parent, Introspector child)
- throws AAIException {
+ throws AAIException {
this.createTraversal(type, parent, child, true);
return (QueryBuilder<Vertex>) this;
}
private void createTraversal(EdgeType type, Introspector parent, Introspector child, boolean isPrivateEdge)
- throws AAIException {
+ throws AAIException {
String isAbstractType = parent.getMetadata(ObjectMetadata.ABSTRACT);
if ("true".equals(isAbstractType)) {
markParentBoundary();
@@ -352,18 +381,17 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
/**
- *
* @{inheritDoc}
*/
@Override
public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in,
- List<String> labels) throws AAIException {
+ List<String> labels) throws AAIException {
this.edgeQueryToVertex(type, out, in, labels);
return (QueryBuilder<Vertex>) this;
}
private Traversal<Vertex, Vertex>[] handleAbstractEdge(EdgeType type, Introspector abstractParent,
- Introspector child, boolean isPrivateEdge) throws AAIException {
+ Introspector child, boolean isPrivateEdge) throws AAIException {
String childName = child.getDbName();
String inheritorMetadata = abstractParent.getMetadata(ObjectMetadata.INHERITORS);
String[] inheritors = inheritorMetadata.split(",");
@@ -399,7 +427,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
innerTraversal.in(inLabels.toArray(new String[inLabels.size()]));
} else {
innerTraversal.union(__.out(outLabels.toArray(new String[outLabels.size()])),
- __.in(inLabels.toArray(new String[inLabels.size()])));
+ __.in(inLabels.toArray(new String[inLabels.size()])));
}
innerTraversal.has(AAIProperties.NODE_TYPE, childName);
@@ -411,7 +439,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
public QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType,
- List<String> labels) throws AAIException {
+ List<String> labels) throws AAIException {
Introspector outObj = loader.introspectorFromName(outNodeType);
Introspector inObj = loader.introspectorFromName(inNodeType);
this.edgeQuery(type, outObj, inObj, labels);
@@ -556,6 +584,23 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
return this;
}
+ @Override
+ public QueryBuilder<E> valueMap() {
+ this.traversal.valueMap();
+ stepIndex++;
+
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> valueMap(String... names) {
+ this.traversal.valueMap(names);
+ stepIndex++;
+
+ return this;
+ }
+
+
/**
* {@inheritDoc}
*/
@@ -649,12 +694,12 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
* Edge query.
*
* @param outObj the out type
- * @param inObj the in type
+ * @param inObj the in type
* @throws NoEdgeRuleFoundException
* @throws AAIException
*/
private void edgeQueryToVertex(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels)
- throws AAIException {
+ throws AAIException {
String outType = outObj.getDbName();
String inType = inObj.getDbName();
@@ -686,7 +731,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
}
if (rules.isEmpty()) {
throw new NoEdgeRuleFoundException(
- "No edge rules found for " + outType + " and " + inType + " of type " + type.toString());
+ "No edge rules found for " + outType + " and " + inType + " of type " + type.toString());
}
}
@@ -711,7 +756,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
traversal.in(inLabels.toArray(new String[inLabels.size()]));
} else {
traversal.union(__.out(outLabels.toArray(new String[outLabels.size()])),
- __.in(inLabels.toArray(new String[inLabels.size()])));
+ __.in(inLabels.toArray(new String[inLabels.size()])));
}
stepIndex++;
@@ -724,12 +769,12 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
* Edge query.
*
* @param outObj the out type
- * @param inObj the in type
+ * @param inObj the in type
* @throws NoEdgeRuleFoundException
* @throws AAIException
*/
private void edgeQuery(EdgeType type, Introspector outObj, Introspector inObj, List<String> labels)
- throws AAIException {
+ throws AAIException {
String outType = outObj.getDbName();
String inType = inObj.getDbName();
@@ -777,7 +822,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
traversal.inE(inLabels.toArray(new String[inLabels.size()]));
} else {
traversal.union(__.outE(outLabels.toArray(new String[outLabels.size()])),
- __.inE(inLabels.toArray(new String[inLabels.size()])));
+ __.inE(inLabels.toArray(new String[inLabels.size()])));
}
}
@@ -902,4 +947,5 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> {
return (QueryBuilder<Edge>) this;
}
+
}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
index 98da0766..fcfeb268 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java
@@ -22,6 +22,8 @@
package org.onap.aai.query.builder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
@@ -54,10 +56,14 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
private static final String ARGUMENT2 = "#!#argument#!#";
private static final String HAS = ".has('";
+ private static final String SINGLE_QUOTE = "'";
+ private static final String ESCAPE_SINGLE_QUOTE = "\\'";
private GremlinGroovyShell gremlinGroovy = new GremlinGroovyShell();
private GraphTraversal<?, ?> completeTraversal = null;
protected List<String> list = null;
+ private static final Logger LOGGER = LoggerFactory.getLogger(QueryBuilder.class);
+
/**
* Instantiates a new gremlin query builder.
*
@@ -79,6 +85,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
list = new ArrayList<>();
}
+
@Override
public QueryBuilder<Vertex> exactMatchQuery(Introspector obj) {
// TODO not implemented because this is implementation is no longer used
@@ -87,6 +94,22 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
return (QueryBuilder<Vertex>) this;
}
+ @Override
+ protected void vertexHas(String key, Object value) {
+ list.add(HAS + key + "', " + value + ")");
+ }
+
+ @Override
+ protected void vertexHasNot(String key) {
+ list.add(".hasNot('" + key + "')");
+
+ }
+
+ @Override
+ protected void vertexHas(String key) {
+ list.add(HAS + key + "')");
+ }
+
/**
* @{inheritDoc}
*/
@@ -95,11 +118,16 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
String term = "";
if (value != null && !(value instanceof String)) {
+ String valueString = value.toString();
+ if (valueString.indexOf('\'') != -1) {
+ value = valueString.replace(SINGLE_QUOTE, ESCAPE_SINGLE_QUOTE);
+ }
+ LOGGER.trace("Inside getVerticesByProperty(): key = {}, value = {}", key, value);
term = value.toString();
} else {
term = "'" + value + "'";
}
- list.add(HAS + key + "', " + term + ")");
+ this.vertexHas(key, term);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -109,7 +137,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, Object value) {
- list.add(HAS + key + "', " + value + ")");
+ this.vertexHas(key, value);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -125,7 +153,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
bValue = (Boolean) value;
}
- list.add(HAS + key + "', " + bValue + ")");
+ this.vertexHas(key, bValue);
stepIndex++;
}
return (QueryBuilder<Vertex>) this;
@@ -148,7 +176,31 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
}
String argument = Joiner.on(",").join(arguments);
predicate = predicate.replace(ARGUMENT2, argument);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
+ stepIndex++;
+ return (QueryBuilder<Vertex>) this;
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value) {
+ ArrayList<String> arguments = new ArrayList<>(Arrays.asList(value.split(",")));
+ //add the single quotes
+ for (int i = 0; i < arguments.size(); i++) {
+ if(arguments.get(i) != null && !arguments.get(i).startsWith("'")
+ && !arguments.get(i).endsWith("'")) {
+ arguments.set(i,"'" + arguments.get(i).trim() + "'");
+ }
+ else {
+ arguments.set(i, arguments.get(i).trim());
+ }
+ }
+ String predicate = "P.within(#!#argument#!#)";
+ String argument = Joiner.on(",").join(arguments);
+ predicate = predicate.replace(ARGUMENT2, argument);
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -158,8 +210,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getVerticesByProperty(String key) {
-
- list.add(HAS + key + "')");
+ this.vertexHas(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -169,8 +220,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getVerticesExcludeByProperty(String key) {
-
- list.add(".hasNot('" + key + "')");
+ this.vertexHasNot(key);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -180,7 +230,6 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
*/
@Override
public QueryBuilder<Vertex> getVerticesStartsWithProperty(String key, Object value) {
-
String term = "";
String predicate = "org.janusgraph.core.attribute.Text.textPrefix(#!#argument#!#)";
if (value != null && !(value instanceof String)) {
@@ -189,7 +238,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
term = "'" + value + "'";
}
predicate = predicate.replace(ARGUMENT2, term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -208,7 +257,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
term = "'" + value + "'";
}
predicate = predicate.replace(ARGUMENT2, term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -230,7 +279,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
}
String argument = Joiner.on(",").join(arguments);
predicate = predicate.replace(ARGUMENT2, argument);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -245,7 +294,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
term = "'" + value + "'";
}
predicate = predicate.replace("#!#argument1#!#", term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -260,7 +309,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
term = "'" + value + "'";
}
predicate = predicate.replace("#!#argument1#!#", term);
- list.add(HAS + key + "', " + predicate + ")");
+ this.vertexHas(key, predicate);
stepIndex++;
return (QueryBuilder<Vertex>) this;
}
@@ -281,6 +330,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
public QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map) {
for (Map.Entry<String, String> es : map.entrySet()) {
+ //TODO what is this and where is it used - need to check
list.add(HAS + es.getKey() + "', '" + es.getValue() + "')");
stepIndex++;
}
@@ -594,6 +644,20 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
}
@Override
+ public QueryBuilder<E> fold() {
+ this.list.add(".fold()");
+ stepIndex++;
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> id() {
+ this.list.add(".id()");
+ stepIndex++;
+ return this;
+ }
+
+ @Override
public QueryBuilder<E> dedup() {
this.list.add(".dedup()");
stepIndex++;
@@ -656,6 +720,31 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
return this;
}
+
+ @Override
+ public QueryBuilder<E> valueMap() {
+ this.list.add(".valueMap()");
+ stepIndex++;
+
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> valueMap(String... names) {
+ String stepString = ".valueMap('";
+ for (int i = 0; i < names.length; i++) {
+ stepString = stepString + names[i] + "'";
+ if (i != (names.length - 1)) {
+ stepString = stepString + ",'";
+ }
+ }
+ stepString = stepString + ")";
+ this.list.add(stepString);
+ stepIndex++;
+
+ return this;
+ }
+
/**
* {@inheritDoc}
@@ -853,4 +942,9 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> {
return (QueryBuilder<Edge>) this;
}
+ /*
+ * This is required for the subgraphstrategies to work
+ */
+
+
}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinTraversal.java b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinTraversal.java
index 710db480..9cd35ab9 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinTraversal.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinTraversal.java
@@ -61,6 +61,7 @@ public class GremlinTraversal<E> extends GremlinQueryBuilder<E> {
this.factory = new TraversalStrategy(this.loader, this);
}
+
protected GremlinTraversal(List<String> traversal, Loader loader, GraphTraversalSource source,
GremlinQueryBuilder<E> gtb) {
super(loader, source);
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/HistoryGremlinTraversal.java b/aai-core/src/main/java/org/onap/aai/query/builder/HistoryGremlinTraversal.java
new file mode 100644
index 00000000..5b14995c
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/HistoryGremlinTraversal.java
@@ -0,0 +1,170 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.query.builder;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.parsers.query.QueryParser;
+import org.onap.aai.parsers.query.TraversalStrategy;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The Class GremlinTraversal.
+ */
+public class HistoryGremlinTraversal<E> extends GremlinTraversal<E> {
+
+ /**
+ * Instantiates a new gremlin traversal.
+ *
+ * @param loader the loader
+ */
+ public HistoryGremlinTraversal(Loader loader, GraphTraversalSource source) {
+ super(loader, source);
+ }
+
+ /**
+ * Instantiates a new gremlin traversal.
+ *
+ * @param loader the loader
+ * @param start the start
+ */
+ public HistoryGremlinTraversal(Loader loader, GraphTraversalSource source, Vertex start) {
+ super(loader, source, start);
+ }
+
+
+ protected HistoryGremlinTraversal(List<String> traversal, Loader loader, GraphTraversalSource source,
+ GremlinQueryBuilder<E> gtb) {
+ super(traversal, loader, source, gtb);
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryParser createQueryFromURI(URI uri) throws UnsupportedEncodingException, AAIException {
+ return factory.buildURIParser(uri);
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryParser createQueryFromRelationship(Introspector relationship)
+ throws UnsupportedEncodingException, AAIException {
+ return factory.buildRelationshipParser(relationship);
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryParser createQueryFromURI(URI uri, MultivaluedMap<String, String> queryParams)
+ throws UnsupportedEncodingException, AAIException {
+ return factory.buildURIParser(uri, queryParams);
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryParser createQueryFromObjectName(String objName) {
+ return factory.buildObjectNameParser(objName);
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryBuilder<E> newInstance(Vertex start) {
+ return new HistoryGremlinTraversal<>(loader, source, start);
+ }
+
+ /**
+ * @{inheritDoc}
+ */
+ @Override
+ public QueryBuilder<E> newInstance() {
+ return new HistoryGremlinTraversal<>(loader, source);
+ }
+
+ @Override
+ protected QueryBuilder<E> cloneQueryAtStep(int index) {
+
+ int idx = index;
+
+ if (idx == 0) {
+ idx = stepIndex;
+ }
+
+ List<String> newList = new ArrayList<>();
+ for (int i = 0; i < idx; i++) {
+ newList.add(this.list.get(i));
+ }
+
+ return new HistoryGremlinTraversal<>(newList, loader, source, this);
+ }
+
+ @Override
+ protected void vertexHas(String key, Object value) {
+ super.vertexHas(key, value);
+ touchHistoryProperties(key, value);
+ }
+
+ @Override
+ protected void vertexHasNot(String key) {
+ super.vertexHasNot(key);
+ touchHistoryProperties(key);
+
+ }
+
+ @Override
+ protected void vertexHas(String key) {
+ super.vertexHas(key);
+ touchHistoryProperties(key);
+ }
+
+ /*
+ * This is required for the subgraphstrategies to work
+ */
+ private void touchHistoryProperties(String key){
+ if(key != null && !key.isEmpty() && !key.equals(AAIProperties.NODE_TYPE)) {
+ list.add(".where(__.properties('" + key + "'))");
+ }
+
+ }
+
+ private void touchHistoryProperties(String key, Object value) {
+ if(key != null && !key.isEmpty() && !key.equals(AAIProperties.NODE_TYPE)) {
+ list.add(".where(__.properties('" + key + "').hasValue(" + value + "))");
+ }
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/HistoryTraversalURIOptimizedQuery.java b/aai-core/src/main/java/org/onap/aai/query/builder/HistoryTraversalURIOptimizedQuery.java
new file mode 100644
index 00000000..aeb5cd19
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/HistoryTraversalURIOptimizedQuery.java
@@ -0,0 +1,93 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.query.builder;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.schema.enums.ObjectMetadata;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class HistoryTraversalURIOptimizedQuery<E> extends TraversalURIOptimizedQuery {
+
+ protected Map<Integer, String> stepToAaiUri = new HashMap<>();
+
+ public HistoryTraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source) {
+ super(loader, source);
+ }
+
+ public HistoryTraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source, Vertex start) {
+ super(loader, source, start);
+ }
+
+ protected HistoryTraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source,
+ GraphTraversalBuilder gtb) {
+ super(traversal, loader, source, gtb);
+ }
+
+ protected HistoryTraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source,
+ GraphTraversalBuilder gtb, Map<Integer, String> stepToAaiUri) {
+ super(traversal, loader, source, gtb, stepToAaiUri);
+ }
+
+ @Override
+ protected void vertexHas(String key, Object value) {
+ super.vertexHas(key, value);
+ touchHistoryProperties(key, value);
+ }
+
+ @Override
+ protected void vertexHasNot(String key) {
+ super.vertexHasNot(key);
+ touchHistoryProperties(key);
+ }
+
+ @Override
+ protected void vertexHas(String key) {
+ super.vertexHas(key);
+ touchHistoryProperties(key);
+ }
+
+ private void touchHistoryProperties(String key){
+ if(key != null && !key.isEmpty() && !key.equals(AAIProperties.NODE_TYPE)) {
+ traversal.where(__.properties(key));
+ }
+ }
+
+ private void touchHistoryProperties(String key, Object value){
+ if(key != null && !key.isEmpty() && !key.equals(AAIProperties.NODE_TYPE)) {
+ traversal.where(__.properties(key).hasValue(value));
+ }
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java
index a214811c..007f9798 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java
@@ -20,14 +20,6 @@
package org.onap.aai.query.builder;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.MultivaluedMap;
-
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
@@ -42,11 +34,17 @@ import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
-import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.parsers.query.QueryParser;
import org.onap.aai.parsers.query.QueryParserStrategy;
import org.springframework.context.ApplicationContext;
+import javax.ws.rs.core.MultivaluedMap;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
/**
* The Class QueryBuilder.
*/
@@ -113,9 +111,21 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
*/
public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, Object value);
+
+ /**
+ * Gets the edges by property.
+ *
+ * @param key the key
+ * @param value the value
+ * @return the vertices by property
+ */
+ public QueryBuilder<Edge> getEdgesByProperty(String key, Object value) {
+ return this.has(key, value.toString());
+ }
+
/**
* filters by all the values for this property
- *
+ *
* @param key
* @param values
* @return vertices that match these values
@@ -126,7 +136,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* filters by all the values for this property
- *
+ *
* @param key
* @param values
* @return vertices that match these values
@@ -134,10 +144,18 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, List<?> values);
/**
+ * filters by all the values for this property
+ *
+ * @param key
+ * @param value in comma delimited string format
+ * @return vertices that match these values
+ */
+ public abstract QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value);
+
+ /**
* Gets the vertices that have this property key.
*
* @param key the key
- * @param value the value
* @return the vertices by property
*/
public abstract QueryBuilder<Vertex> getVerticesByProperty(String key);
@@ -146,14 +164,13 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
* Gets the vertices that do not have this property key.
*
* @param key the key
- * @param value the value
* @return the vertices by property
*/
public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key);
/**
* filters by elements that start with the value for this property
- *
+ *
* @param key
* @param value
* @return vertices that match these values
@@ -171,7 +188,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* filters by all the values for this property and excludes the vertices
- *
+ *
* @param key
* @param values
* @return vertices that match these values
@@ -182,7 +199,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* filters by all the values for this property and excludes the vertices
- *
+ *
* @param key
* @param values
* @return vertices that match these values
@@ -191,18 +208,18 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* filters by all the values greater than for this property
- *
+ *
* @param key
- * @param values
+ * @param value
* @return vertices that match these values
*/
public abstract QueryBuilder<Vertex> getVerticesGreaterThanProperty(String key, Object value);
/**
* filters by all the values less than for this property
- *
+ *
* @param key
- * @param values
+ * @param value
* @return vertices that match these values
*/
@@ -334,7 +351,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
*
- * @param MissingOptionalParameter
+ * @param edgeType
* @param outNodeType
* @param inNodeType
* @return
@@ -348,6 +365,22 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
return this.createEdgeTraversal(outNodeType, inNodeType);
}
+ /**
+ *
+ * @param edgeType
+ * @param outNodeType
+ * @param inNodeType
+ * @return
+ * @throws AAIException
+ */
+ public QueryBuilder<Vertex> createEdgeTraversalWithLabels(MissingOptionalParameter edgeType, String outNodeType,
+ String inNodeType, List<String> labels) throws AAIException {
+ /*
+ * When no optional parameter edgetype is sent get all edges between the 2 nodetypes
+ */
+ return this.createEdgeTraversalWithLabels(outNodeType, inNodeType, labels);
+ }
+
public QueryBuilder<Vertex> createEdgeTraversal(String outNodeType, String inNodeType) throws AAIException {
Introspector out = loader.introspectorFromName(outNodeType);
@@ -380,6 +413,38 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
return queryBuilder;
}
+ public QueryBuilder<Vertex> createEdgeTraversalWithLabels(String outNodeType, String inNodeType, List<String> labels) throws AAIException {
+
+ Introspector out = loader.introspectorFromName(outNodeType);
+ Introspector in = loader.introspectorFromName(inNodeType);
+
+ QueryBuilder<Vertex> cousinBuilder = null;
+ QueryBuilder<Vertex> treeBuilder = null;
+ QueryBuilder<Vertex> queryBuilder = null;
+
+ try {
+ cousinBuilder = this.newInstance().createEdgeTraversalWithLabels(EdgeType.COUSIN, out, in, labels);
+ } catch (AAIException e) {
+ }
+
+ if (cousinBuilder != null) {
+ try {
+ treeBuilder = this.newInstance().createEdgeTraversalWithLabels(EdgeType.TREE, out, in, labels);
+ } catch (AAIException e) {
+ }
+ if (treeBuilder != null) {
+ queryBuilder = this.union(new QueryBuilder[] {cousinBuilder, treeBuilder});
+ } else {
+ queryBuilder = this.union(new QueryBuilder[] {cousinBuilder});
+ }
+ } else {
+ treeBuilder = this.newInstance().createEdgeTraversalWithLabels(EdgeType.TREE, out, in, labels);
+ queryBuilder = this.union(new QueryBuilder[] {treeBuilder});
+ }
+
+ return queryBuilder;
+ }
+
public QueryBuilder<Vertex> createPrivateEdgeTraversal(EdgeType type, String outNodeType, String inNodeType)
throws AAIException {
Introspector out = loader.introspectorFromName(outNodeType);
@@ -415,6 +480,43 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
public abstract QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in,
List<String> labels) throws AAIException;
+
+ /**
+ * This method and it's overloaded counterpart are conditional statements.
+ * This method creates an edge traversal step if an optional property is present
+ * This is necessary in cases such as "if the Optional Property 1 is sent,
+ * find all Nodes of type A with edges to Nodes of type B with property 1,
+ * otherwise, simply find all nodes of type A".
+ * @param type
+ * @param outNodeType
+ * @param inNodeType
+ * @param value
+ * @return
+ * @throws AAIException
+ */
+ public QueryBuilder<Vertex> createEdgeTraversalIfParameterIsPresent(EdgeType type, String outNodeType, String inNodeType,
+ Object value) throws AAIException {
+ return this.createEdgeTraversal(type, outNodeType, inNodeType);
+ }
+
+ /**
+ * This method and it's overloaded counterpart are conditional statements.
+ * This method skips an edge traversal step if there is an optional property missing.
+ * This is necessary in cases such as "if the Optional Property 1 is sent,
+ * find all Nodes of type A with edges to Nodes of type B with property 1,
+ * otherwise, simply find all nodes of type A".
+ * @param type
+ * @param outNodeType
+ * @param inNodeType
+ * @param value
+ * @return
+ * @throws AAIException
+ */
+ public QueryBuilder<Vertex> createEdgeTraversalIfParameterIsPresent(EdgeType type, String outNodeType, String inNodeType,
+ MissingOptionalParameter value) throws AAIException {
+ return (QueryBuilder<Vertex>) this;
+ }
+
/**
*
* @param type
@@ -467,7 +569,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* Creates a queryparser from a given object name.
- *
+ *
* @param objName - name of the object type as it appears in the database
* @return
*/
@@ -538,7 +640,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* uses all fields in the introspector to create a query
- *
+ *
* @param obj
* @return
*/
@@ -547,7 +649,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* lets you join any number of QueryBuilders
* <b>be careful about starting with a union it will not use indexes</b>
- *
+ *
* @param builder
* @return
*/
@@ -563,6 +665,10 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
public abstract QueryBuilder<E> unfold();
+ public abstract QueryBuilder<E> fold();
+
+ public abstract QueryBuilder<E> id();
+
public abstract QueryBuilder<E> dedup();
public abstract QueryBuilder<E> emit();
@@ -591,6 +697,10 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
public abstract QueryBuilder<E> by(String name);
+ public abstract QueryBuilder<E> valueMap();
+
+ public abstract QueryBuilder<E> valueMap(String... names);
+
public abstract QueryBuilder<E> both();
public abstract QueryBuilder<Tree> tree();
@@ -598,7 +708,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* Used to prevent the traversal from repeating its path through the graph.
* See http://tinkerpop.apache.org/docs/3.0.1-incubating/#simplepath-step for more info.
- *
+ *
* @return a QueryBuilder with the simplePath step appended to its traversal
*/
public abstract QueryBuilder<E> simplePath();
@@ -617,7 +727,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* Used to skip step if there is an optional property missing.
- *
+ *
* @param key
* @param value
* @return
@@ -629,7 +739,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* TODO the edge direction is hardcoded here, make it more generic
* Returns the parent edge of the vertex
- *
+ *
* @return
*/
public QueryBuilder<Edge> getParentEdge() {
@@ -640,7 +750,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
/**
* TODO the edge direction is hardcoded here, make it more generic
* Returns the parent vertex of the vertex
- *
+ *
* @return
*/
public QueryBuilder<Vertex> getParentVertex() {
@@ -672,4 +782,13 @@ public abstract class QueryBuilder<E> implements Iterator<E> {
public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, MissingOptionalParameter value) {
return getVerticesByProperty(key, value);
}
+
+ protected abstract void vertexHas(String key, Object value) ;
+
+ protected abstract void vertexHasNot(String key);
+
+ protected abstract void vertexHas(String key);
+
+ //TODO: This probably is not required but need to test
+ // protected abstract void vertexHas(final String key, final P<?> predicate);
}
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/TraversalQuery.java b/aai-core/src/main/java/org/onap/aai/query/builder/TraversalQuery.java
index cf99fd10..579c3571 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/TraversalQuery.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/TraversalQuery.java
@@ -30,7 +30,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
@@ -47,6 +46,7 @@ public class TraversalQuery<E> extends GraphTraversalBuilder<E> {
*
* @param loader the loader
*/
+
public TraversalQuery(Loader loader, GraphTraversalSource source) {
super(loader, source);
this.factory = new TraversalStrategy(this.loader, this);
@@ -125,6 +125,16 @@ public class TraversalQuery<E> extends GraphTraversalBuilder<E> {
}
@Override
+ public QueryBuilder<E> fold() {
+ return this;
+ }
+
+ @Override
+ public QueryBuilder<E> id() {
+ return this;
+ }
+
+ @Override
protected QueryBuilder<E> cloneQueryAtStep(int index) {
GraphTraversal.Admin<Vertex, E> cloneAdmin = getCloneAdmin(index);
return new TraversalQuery<>(cloneAdmin, loader, source, this);
diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java b/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java
index 91d2d084..0e2a9cad 100644
--- a/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java
+++ b/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java
@@ -145,7 +145,6 @@ public class TraversalURIOptimizedQuery<E> extends TraversalQuery {
}
return shouldOptimize;
-
}
private Optional<String> getStepUriFromIntrospector(Introspector obj) {
@@ -166,7 +165,7 @@ public class TraversalURIOptimizedQuery<E> extends TraversalQuery {
return Optional.of(uri);
}
- private int getLastURIStepKey() {
+ protected int getLastURIStepKey() {
return stepToAaiUri.keySet().stream().mapToInt(Integer::intValue).max().getAsInt();
}
diff --git a/aai-core/src/main/java/org/onap/aai/rest/db/DBRequest.java b/aai-core/src/main/java/org/onap/aai/rest/db/DBRequest.java
index 1f94fbe2..e25a9062 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/db/DBRequest.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/db/DBRequest.java
@@ -26,6 +26,7 @@ import java.util.Optional;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriInfo;
+import org.onap.aai.aailog.logs.DBRequestWrapper;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.MarshallerProperties;
import org.onap.aai.parsers.query.QueryParser;
@@ -34,7 +35,7 @@ import org.onap.aai.restcore.HttpMethod;
/**
* The Class DBRequest.
*/
-public class DBRequest {
+public class DBRequest implements DBRequestWrapper {
private final QueryParser parser;
diff --git a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
index 61fc33a4..86d7e1b7 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/db/HttpEntry.java
@@ -20,57 +20,24 @@
package org.onap.aai.rest.db;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jsonpatch.JsonPatchException;
import com.github.fge.jsonpatch.mergepatch.JsonMergePatch;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriBuilder;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.janusgraph.core.JanusGraphException;
import org.javatuples.Pair;
-import org.json.JSONException;
-import org.json.JSONObject;
+import org.onap.aai.aailog.logs.AaiDBMetricLog;
import org.onap.aai.db.props.AAIProperties;
-import org.onap.aai.dbmap.DBConnectionType;
-import org.onap.aai.domain.responseMessage.AAIResponseMessage;
-import org.onap.aai.domain.responseMessage.AAIResponseMessageDatum;
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.extensions.AAIExtensionMap;
-import org.onap.aai.extensions.ExtensionController;
import org.onap.aai.introspection.*;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.LoggingContext;
import org.onap.aai.nodes.NodeIngestor;
import org.onap.aai.parsers.query.QueryParser;
-import org.onap.aai.parsers.uri.URIToExtensionInformation;
-import org.onap.aai.parsers.uri.URIToObject;
+import org.onap.aai.prevalidation.ValidationService;
import org.onap.aai.rest.ueb.UEBNotification;
import org.onap.aai.restcore.HttpMethod;
import org.onap.aai.schema.enums.ObjectMetadata;
@@ -84,17 +51,31 @@ import org.onap.aai.serialization.queryformats.FormatFactory;
import org.onap.aai.serialization.queryformats.Formatter;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
+import org.onap.aai.transforms.XmlFormatTransformer;
import org.onap.aai.util.AAIConfig;
+import org.onap.aai.util.AAIConstants;
+import org.onap.aai.util.delta.DeltaEvents;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
+
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.Status;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.stream.Collectors;
/**
* The Class HttpEntry.
*/
public class HttpEntry {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(HttpEntry.class);
- private static final String TARGET_ENTITY = "DB";
+ private static final Logger LOGGER = LoggerFactory.getLogger(HttpEntry.class);
private ModelType introspectorFactoryType;
@@ -125,8 +106,24 @@ public class HttpEntry {
@Value("${schema.uri.base.path}")
private String basePath;
+ @Value("${delta.events.enabled:false}")
+ private boolean isDeltaEventsEnabled;
+
+ @Autowired
+ private XmlFormatTransformer xmlFormatTransformer;
+
+ /**
+ * Inject the validation service if the profile pre-valiation is enabled,
+ * Otherwise this variable will be set to null and thats why required=false
+ * so that it can continue even if pre validation isn't enabled
+ */
+ @Autowired(required = false)
+ private ValidationService validationService;
+
private UEBNotification notification;
+ private int notificationDepth;
+
/**
* Instantiates a new http entry.
*
@@ -138,23 +135,45 @@ public class HttpEntry {
this.queryStyle = queryStyle;
}
- public HttpEntry setHttpEntryProperties(SchemaVersion version, DBConnectionType connectionType) {
+ public HttpEntry setHttpEntryProperties(SchemaVersion version) {
this.version = version;
this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
- this.dbEngine = new JanusGraphDBEngine(queryStyle, connectionType, loader);
+ this.dbEngine = new JanusGraphDBEngine(queryStyle, loader);
getDbEngine().startTransaction();
this.notification = new UEBNotification(loader, loaderFactory, schemaVersions);
+ if("true".equals(AAIConfig.get("aai.notification.depth.all.enabled", "true"))){
+ this.notificationDepth = AAIProperties.MAXIMUM_DEPTH;
+ } else {
+ this.notificationDepth = AAIProperties.MINIMUM_DEPTH;
+ }
return this;
}
- public HttpEntry setHttpEntryProperties(SchemaVersion version, DBConnectionType connectionType,
- UEBNotification notification) {
+ public HttpEntry setHttpEntryProperties(SchemaVersion version, UEBNotification notification) {
this.version = version;
this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
- this.dbEngine = new JanusGraphDBEngine(queryStyle, connectionType, loader);
+ this.dbEngine = new JanusGraphDBEngine(queryStyle, loader);
this.notification = notification;
+
+ if("true".equals(AAIConfig.get("aai.notification.depth.all.enabled", "true"))){
+ this.notificationDepth = AAIProperties.MAXIMUM_DEPTH;
+ } else {
+ this.notificationDepth = AAIProperties.MINIMUM_DEPTH;
+ }
+ // start transaction on creation
+ getDbEngine().startTransaction();
+ return this;
+ }
+
+ public HttpEntry setHttpEntryProperties(SchemaVersion version, UEBNotification notification, int notificationDepth) {
+ this.version = version;
+ this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
+ this.dbEngine = new JanusGraphDBEngine(queryStyle, loader);
+
+ this.notification = notification;
+ this.notificationDepth = notificationDepth;
// start transaction on creation
getDbEngine().startTransaction();
return this;
@@ -222,7 +241,7 @@ public class HttpEntry {
/**
* Returns the pagination size
- *
+ *
* @return integer of the size of results to be returned when paginated
*/
public int getPaginationBucket() {
@@ -231,7 +250,7 @@ public class HttpEntry {
/**
* Setter for the pagination bucket variable which stores in this object the size of results to return
- *
+ *
* @param pb
*/
public void setPaginationBucket(int pb) {
@@ -240,7 +259,7 @@ public class HttpEntry {
/**
* Getter to return the pagination index requested by the user when requesting paginated results
- *
+ *
* @return
*/
public int getPaginationIndex() {
@@ -250,7 +269,7 @@ public class HttpEntry {
/**
* Sets the pagination index that was passed in by the user, to determine which index or results to retrieve when
* paginated
- *
+ *
* @param pi
*/
public void setPaginationIndex(int pi) {
@@ -262,7 +281,7 @@ public class HttpEntry {
/**
* Sets the total vertices variables and calculates the amount of pages based on size and total vertices
- *
+ *
* @param totalVertices
* @param paginationBucketSize
*/
@@ -293,7 +312,7 @@ public class HttpEntry {
/**
* Process.
- *
+ *
* @param requests the requests
* @param sourceOfTruth the source of truth
*
@@ -303,41 +322,44 @@ public class HttpEntry {
public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth,
boolean enableResourceVersion) throws AAIException {
- DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
- String methodName = "process";
+ DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, notificationDepth);
Response response;
- Introspector obj = null;
- QueryParser query = null;
- URI uri = null;
+ Introspector obj;
+ QueryParser query;
+ URI uri;
String transactionId = null;
- int depth = AAIProperties.MAXIMUM_DEPTH;
+ int depth;
Format format = null;
List<Pair<URI, Response>> responses = new ArrayList<>();
- MultivaluedMap<String, String> params = null;
- HttpMethod method = null;
- String uriTemp = "";
- Boolean success = true;
+ MultivaluedMap<String, String> params;
+ HttpMethod method;
+ String uriTemp;
+ boolean success = true;
QueryEngine queryEngine = dbEngine.getQueryEngine();
- int maxRetries = 10;
- int retry = 0;
+ Set<Vertex> mainVertexesToNotifyOn = new LinkedHashSet<>();
+
+ AaiDBMetricLog metricLog = new AaiDBMetricLog(AAIConstants.AAI_RESOURCES_MS);
+
+ String outputMediaType = null;
+
+ if(requests != null && !requests.isEmpty()){
+ HttpHeaders headers = requests.get(0).getHeaders();
+ outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
+ }
- LoggingContext.save();
for (DBRequest request : requests) {
response = null;
Status status = Status.NOT_FOUND;
method = request.getMethod();
+ metricLog.pre(request);
try {
try {
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName + " " + method);
-
obj = request.getIntrospector();
query = request.getParser();
transactionId = request.getTransactionId();
uriTemp = request.getUri().getRawPath().replaceFirst("^v\\d+/", "");
uri = UriBuilder.fromPath(uriTemp).build();
- LoggingContext.startTime();
List<Vertex> vertTemp;
List<Vertex> vertices;
if (this.isPaginated()) {
@@ -348,8 +370,9 @@ public class HttpEntry {
} else {
vertices = query.getQueryBuilder().toList();
}
- boolean isNewVertex = false;
- String outputMediaType = getMediaType(request.getHeaders().getAcceptableMediaTypes());
+ boolean isNewVertex;
+ HttpHeaders headers = request.getHeaders();
+ outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
String result = null;
params = request.getInfo().getQueryParameters(false);
depth = setDepth(obj, params.getFirst("depth"));
@@ -369,15 +392,14 @@ public class HttpEntry {
if (vertices.size() > 1 && processSingle
&& !(method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP))) {
if (method.equals(HttpMethod.DELETE)) {
- LoggingContext.restoreIfPossible();
+
throw new AAIException("AAI_6138");
} else {
- LoggingContext.restoreIfPossible();
throw new AAIException("AAI_6137");
}
}
if (method.equals(HttpMethod.PUT)) {
- String resourceVersion = (String) obj.getValue("resource-version");
+ String resourceVersion = obj.getValue(AAIProperties.RESOURCE_VERSION);
if (vertices.isEmpty()) {
if (enableResourceVersion) {
serializer.verifyResourceVersion("create", query.getResultType(), "",
@@ -387,7 +409,7 @@ public class HttpEntry {
} else {
if (enableResourceVersion) {
serializer.verifyResourceVersion("update", query.getResultType(),
- vertices.get(0).<String>property("resource-version").orElse(null),
+ vertices.get(0).<String>property(AAIProperties.RESOURCE_VERSION).orElse(null),
resourceVersion, obj.getURI());
}
isNewVertex = false;
@@ -404,6 +426,22 @@ public class HttpEntry {
if (!isNewVertex) {
v = vertices.get(0);
}
+
+ /*
+ * This skip-related-to query parameter is used to determine if the relationships object will omit the related-to-property
+ * If a GET is sent to resources without a format, if format=resource, or if format=resource_and_url with this param set to false
+ * then behavior will be keep the related-to properties. By default, set to true.
+ * Otherwise, for any other case, when the skip-related-to parameter exists, has value=true, or some unfamiliar input (e.g. skip-related-to=bogusvalue), the value is true.
+ */
+ boolean isSkipRelatedTo = true;
+ if (params.containsKey("skip-related-to")) {
+ String skipRelatedTo = params.getFirst("skip-related-to");
+ isSkipRelatedTo = !(skipRelatedTo != null && skipRelatedTo.equals("false"));
+ } else {
+ // if skip-related-to param is missing, then default it to false;
+ isSkipRelatedTo = false;
+ }
+
HashMap<String, Introspector> relatedObjects = new HashMap<>();
String nodeOnly = params.getFirst("nodes-only");
boolean isNodeOnly = nodeOnly != null;
@@ -412,12 +450,7 @@ public class HttpEntry {
if (format == null) {
obj = this.getObjectFromDb(vertices, serializer, query, obj, request.getUri(),
- depth, isNodeOnly, cleanUp);
-
- LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(),
- TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
+ depth, isNodeOnly, cleanUp, isSkipRelatedTo);
if (obj != null) {
status = Status.OK;
@@ -436,6 +469,14 @@ public class HttpEntry {
Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex)
.collect(Collectors.toList())).toString();
+
+ if(outputMediaType == null){
+ outputMediaType = MediaType.APPLICATION_JSON;
+ }
+
+ if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(outputMediaType))){
+ result = xmlFormatTransformer.transform(result);
+ }
status = Status.OK;
}
@@ -443,12 +484,7 @@ public class HttpEntry {
case GET_RELATIONSHIP:
if (format == null) {
obj = this.getRelationshipObjectFromDb(vertices, serializer, query,
- request.getInfo().getRequestUri());
-
- LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(),
- TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
+ request.getInfo().getRequestUri(), isSkipRelatedTo);
if (obj != null) {
status = Status.OK;
@@ -471,49 +507,50 @@ public class HttpEntry {
Formatter formatter = ff.get(format, params);
result = formatter.output(vertices.stream().map(vertex -> (Object) vertex)
.collect(Collectors.toList())).toString();
+
+ if(outputMediaType == null){
+ outputMediaType = MediaType.APPLICATION_JSON;
+ }
+
+ if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(outputMediaType))){
+ result = xmlFormatTransformer.transform(result);
+ }
status = Status.OK;
}
break;
case PUT:
- response = this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request,
- sourceOfTruth, version, loader, obj, uri, true);
if (isNewVertex) {
v = serializer.createNewVertex(obj);
}
serializer.serializeToDb(obj, v, query, uri.getRawPath(), requestContext);
- this.invokeExtension(dbEngine, this.dbEngine.tx(), HttpMethod.PUT, request,
- sourceOfTruth, version, loader, obj, uri, false);
status = Status.OK;
if (isNewVertex) {
status = Status.CREATED;
}
- obj = serializer.getLatestVersionView(v);
- if (query.isDependent()) {
- relatedObjects =
- this.getRelatedObjects(serializer, queryEngine, v, obj, this.loader);
+
+ mainVertexesToNotifyOn.add(v);
+ if (notificationDepth == AAIProperties.MINIMUM_DEPTH) {
+ Map<String, Pair<Introspector, LinkedHashMap<String,Introspector>>> allImpliedDeleteObjs = serializer.getImpliedDeleteUriObjectPair();
+
+ for(Map.Entry<String, Pair<Introspector, LinkedHashMap<String,Introspector>>> entry: allImpliedDeleteObjs.entrySet()){
+ // The format is purposefully %s/%s%s due to the fact
+ // that every aai-uri will have a slash at the beginning
+ // If that assumption isn't true, then its best to change this code
+ String curUri = String.format("%s/%s%s", basePath , version , entry.getKey());
+ Introspector curObj = entry.getValue().getValue0();
+ HashMap<String, Introspector> curObjRelated = entry.getValue().getValue1();
+ notification.createNotificationEvent(transactionId, sourceOfTruth, Status.NO_CONTENT, URI.create(curUri), curObj, curObjRelated, basePath);
+ }
}
- LoggingContext.elapsedTime(
- (long) serializer.getDBTimeMsecs() + (long) queryEngine.getDBTimeMsecs(),
- TimeUnit.MILLISECONDS);
- LOGGER.info("Completed ");
- LoggingContext.restoreIfPossible();
- notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj,
- relatedObjects, basePath);
break;
case PUT_EDGE:
serializer.touchStandardVertexProperties(v, false);
- this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth,
- version, loader, obj, uri, true);
- serializer.createEdge(obj, v);
-
- LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
+ Vertex relatedVertex = serializer.createEdge(obj, v);
status = Status.OK;
- notification.createNotificationEvent(transactionId, sourceOfTruth, status,
- new URI(uri.toString().replace("/relationship-list/relationship", "")),
- serializer.getLatestVersionView(v), relatedObjects, basePath);
+
+ mainVertexesToNotifyOn.add(v);
+ serializer.addVertexToEdgeVertexes(relatedVertex);
break;
case MERGE_PATCH:
Introspector existingObj = loader.introspectorFromName(obj.getDbName());
@@ -536,37 +573,23 @@ public class HttpEntry {
JsonNode completed = patch.apply(existingNode);
String patched = mapper.writeValueAsString(completed);
Introspector patchedObj = loader.unmarshal(existingObj.getName(), patched);
- if (relationshipList == null) {
+ if (relationshipList == null && patchedObj.hasProperty("relationship-list")) {
// if the caller didn't touch the relationship-list, we shouldn't either
patchedObj.setValue("relationship-list", null);
}
serializer.serializeToDb(patchedObj, v, query, uri.getRawPath(), requestContext);
status = Status.OK;
- patchedObj = serializer.getLatestVersionView(v);
- if (query.isDependent()) {
- relatedObjects = this.getRelatedObjects(serializer, queryEngine, v, patchedObj,
- this.loader);
- }
- LoggingContext.elapsedTime(
- (long) serializer.getDBTimeMsecs() + (long) queryEngine.getDBTimeMsecs(),
- TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
- notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri,
- patchedObj, relatedObjects, basePath);
+ mainVertexesToNotifyOn.add(v);
} catch (IOException | JsonPatchException e) {
-
- LOGGER.info("Caught exception: " + e.getMessage());
- LoggingContext.restoreIfPossible();
throw new AAIException("AAI_3000", "could not perform patch operation");
}
break;
case DELETE:
- String resourceVersion = params.getFirst("resource-version");
- obj = serializer.getLatestVersionView(v);
+ String resourceVersion = params.getFirst(AAIProperties.RESOURCE_VERSION);
+ obj = serializer.getLatestVersionView(v, notificationDepth);
if (query.isDependent()) {
relatedObjects =
- this.getRelatedObjects(serializer, queryEngine, v, obj, this.loader);
+ serializer.getRelatedObjects(queryEngine, v, obj, this.loader);
}
/*
* Find all Delete-other-vertex vertices and create structure for notify
@@ -576,7 +599,7 @@ public class HttpEntry {
*/
List<Vertex> deletableVertices = dbEngine.getQueryEngine().findDeletable(v);
- Long vId = (Long) v.id();
+ Object vId = v.id();
/*
* I am assuming vertexId cant be null
@@ -595,17 +618,7 @@ public class HttpEntry {
this.buildRelatedObjects(serializer, queryEngine, deleteObjects);
}
- this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth,
- version, loader, obj, uri, true);
serializer.delete(v, deletableVertices, resourceVersion, enableResourceVersion);
- this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth,
- version, loader, obj, uri, false);
-
- LoggingContext.elapsedTime(
- (long) serializer.getDBTimeMsecs() + (long) queryEngine.getDBTimeMsecs(),
- TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
status = Status.NO_CONTENT;
notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj,
relatedObjects, basePath);
@@ -618,19 +631,16 @@ public class HttpEntry {
this.buildNotificationEvent(sourceOfTruth, status, transactionId, notification,
deleteObjects, uriMap, deleteRelatedObjects, basePath);
}
-
break;
case DELETE_EDGE:
serializer.touchStandardVertexProperties(v, false);
- serializer.deleteEdge(obj, v);
+ Optional<Vertex> otherV = serializer.deleteEdge(obj, v);
- LoggingContext.elapsedTime((long) serializer.getDBTimeMsecs(), TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
status = Status.NO_CONTENT;
- notification.createNotificationEvent(transactionId, sourceOfTruth, Status.OK,
- new URI(uri.toString().replace("/relationship-list/relationship", "")),
- serializer.getLatestVersionView(v), relatedObjects, basePath);
+ if (otherV.isPresent()) {
+ mainVertexesToNotifyOn.add(v);
+ serializer.addVertexToEdgeVertexes(otherV.get());
+ }
break;
default:
break;
@@ -659,21 +669,14 @@ public class HttpEntry {
}
} else if (response == null) {
response = Response.status(status).type(outputMediaType).build();
- } else {
- // response already set to something
- }
+ } // else, response already set to something
+
Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
responses.add(pairedResp);
} catch (JanusGraphException e) {
this.dbEngine.rollback();
-
- LOGGER.info("Caught exception: " + e.getMessage());
- LoggingContext.restoreIfPossible();
throw new AAIException("AAI_6134", e);
}
- if (retry == maxRetries) {
- throw new AAIException("AAI_6134");
- }
} catch (AAIException e) {
success = false;
ArrayList<String> templateVars = new ArrayList<>();
@@ -683,31 +686,123 @@ public class HttpEntry {
ErrorLogHelper.logException(e);
response = Response.status(e.getErrorObject().getHTTPResponseCode()).entity(ErrorLogHelper
.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), e, templateVars))
+ .type(outputMediaType)
.build();
Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
responses.add(pairedResp);
- continue;
} catch (Exception e) {
success = false;
- e.printStackTrace();
AAIException ex = new AAIException("AAI_4000", e);
- ArrayList<String> templateVars = new ArrayList<String>();
+ ArrayList<String> templateVars = new ArrayList<>();
templateVars.add(request.getMethod().toString()); // GET, PUT, etc
- templateVars.add(request.getUri().getPath().toString());
+ templateVars.add(request.getUri().getPath());
ErrorLogHelper.logException(ex);
response = Response.status(ex.getErrorObject().getHTTPResponseCode()).entity(ErrorLogHelper
.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), ex, templateVars))
+ .type(outputMediaType)
.build();
Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
responses.add(pairedResp);
- continue;
+ }
+ finally {
+ if (response != null) {
+ metricLog.post(request, response);
+ }
}
}
- notification.triggerEvents();
+
+ if (success) {
+ generateEvents(sourceOfTruth, serializer, transactionId, queryEngine, mainVertexesToNotifyOn);
+ } else {
+ notification.clearEvents();
+ }
+
return Pair.with(success, responses);
}
/**
+ * Generate notification events for the resulting db requests.
+ */
+ private void generateEvents(String sourceOfTruth, DBSerializer serializer, String transactionId, QueryEngine queryEngine, Set<Vertex> mainVertexesToNotifyOn) throws AAIException {
+ if (notificationDepth == AAIProperties.MINIMUM_DEPTH) {
+ serializer.getUpdatedVertexes().entrySet().stream().filter(Map.Entry::getValue).map(Map.Entry::getKey).forEach(mainVertexesToNotifyOn::add);
+ }
+ Set<Vertex> edgeVertexes = serializer.touchStandardVertexPropertiesForEdges().stream()
+ .filter(v -> !mainVertexesToNotifyOn.contains(v)).collect(Collectors.toSet());
+ try {
+ createNotificationEvents(mainVertexesToNotifyOn, sourceOfTruth, serializer, transactionId, queryEngine, notificationDepth);
+ if("true".equals(AAIConfig.get("aai.notification.both.sides.enabled", "true"))){
+ createNotificationEvents(edgeVertexes, sourceOfTruth, serializer, transactionId, queryEngine, AAIProperties.MINIMUM_DEPTH);
+ }
+ } catch (UnsupportedEncodingException e) {
+ LOGGER.warn("Encountered exception generating events", e);
+ }
+
+ // Since @Autowired required is set to false, we need to do a null check
+ // for the existence of the validationService since its only enabled if profile is enabled
+ if(validationService != null){
+ validationService.validate(notification.getEvents());
+ }
+ notification.triggerEvents();
+ if (isDeltaEventsEnabled) {
+ try {
+ DeltaEvents deltaEvents = new DeltaEvents(transactionId, sourceOfTruth, version.toString(), serializer.getObjectDeltas());
+ deltaEvents.triggerEvents();
+ } catch (Exception e) {
+ LOGGER.error("Error sending Delta Events", e);
+ }
+ }
+ }
+
+ /**
+ * Generate notification events for provided set of vertexes at the specified depth
+ */
+ private void createNotificationEvents(Set<Vertex> vertexesToNotifyOn, String sourceOfTruth, DBSerializer serializer,
+ String transactionId, QueryEngine queryEngine, int eventDepth) throws AAIException, UnsupportedEncodingException {
+ for(Vertex vertex : vertexesToNotifyOn){
+ if (canGenerateEvent(vertex)) {
+ boolean isCurVertexNew = vertex.value(AAIProperties.CREATED_TS).equals(vertex.value(AAIProperties.LAST_MOD_TS));
+ Status curObjStatus = (isCurVertexNew) ? Status.CREATED : Status.OK;
+
+ Introspector curObj = serializer.getLatestVersionView(vertex, eventDepth);
+ String aaiUri = vertex.<String>property(AAIProperties.AAI_URI).value();
+ String uri = String.format("%s/%s%s", basePath, version, aaiUri);
+ HashMap<String, Introspector> curRelatedObjs = new HashMap<>();
+ if (!curObj.isTopLevel()) {
+ curRelatedObjs = serializer.getRelatedObjects(queryEngine, vertex, curObj, this.loader);
+ }
+ notification.createNotificationEvent(transactionId, sourceOfTruth, curObjStatus, URI.create(uri), curObj, curRelatedObjs, basePath);
+ }
+ }
+ }
+
+ /**
+ * Verifies that vertex has needed properties to generate on
+ * @param vertex Vertex to be verified
+ * @return <code>true</code> if vertex has necessary properties and exists
+ */
+ private boolean canGenerateEvent(Vertex vertex) {
+ boolean canGenerate = true;
+ try {
+ if(!vertex.property(AAIProperties.AAI_URI).isPresent()){
+ LOGGER.debug("Encountered an vertex {} with missing aai-uri", vertex.id());
+ canGenerate = false;
+ } else if(!vertex.property(AAIProperties.CREATED_TS).isPresent() || !vertex.property(AAIProperties.LAST_MOD_TS).isPresent()){
+ LOGGER.debug("Encountered an vertex {} with missing timestamp", vertex.id());
+ canGenerate = false;
+ }
+ } catch (IllegalStateException e) {
+ if (e.getMessage().contains(" was removed")) {
+ LOGGER.warn("Attempted to generate event for non existent vertex", e);
+ } else {
+ LOGGER.warn("Encountered exception generating events", e);
+ }
+ canGenerate = false;
+ }
+ return canGenerate;
+ }
+
+ /**
* Gets the media type.
*
* @param mediaTypeList the media type list
@@ -760,7 +855,6 @@ public class HttpEntry {
return serializer.dbToObject(results, obj, depth, nodeOnly, cleanUp);
}
-
/**
* Gets the object from db.
*
@@ -770,6 +864,7 @@ public class HttpEntry {
* @param uri the uri
* @param depth the depth
* @param cleanUp the clean up
+ * @param isSkipRelatedTo include related to flag
* @return the object from db
* @throws AAIException the AAI exception
* @throws IllegalAccessException the illegal access exception
@@ -783,9 +878,11 @@ public class HttpEntry {
* @throws AAIUnknownObjectException
* @throws URISyntaxException
*/
- private Introspector getRelationshipObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query,
- URI uri) throws AAIException, IllegalArgumentException, SecurityException, UnsupportedEncodingException,
- AAIUnknownObjectException {
+ private Introspector getObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query,
+ Introspector obj, URI uri, int depth, boolean nodeOnly, String cleanUp, boolean isSkipRelatedTo)
+ throws AAIException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
+ SecurityException, InstantiationException, NoSuchMethodException, UnsupportedEncodingException,
+ AAIUnknownObjectException, URISyntaxException {
// nothing found
if (results.isEmpty()) {
@@ -793,104 +890,45 @@ public class HttpEntry {
throw new AAIException("AAI_6114", msg);
}
- if (results.size() > 1) {
- throw new AAIException("AAI_6148", uri.getPath());
- }
+ return serializer.dbToObject(results, obj, depth, nodeOnly, cleanUp, isSkipRelatedTo);
- Vertex v = results.get(0);
- return serializer.dbToRelationshipObject(v);
}
/**
- * Invoke extension.
+ * Gets the object from db.
*
- * @param dbEngine the db engine
- * @param g the g
- * @param httpMethod the http method
- * @param fromAppId the from app id
- * @param apiVersion the api version
- * @param loader the loader
- * @param obj the obj
+ * @param serializer the serializer
+ * @param query the query
* @param uri the uri
- * @param isPreprocess the is preprocess
- * @return the response
+ * @return the object from db
+ * @throws AAIException the AAI exception
+ * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws SecurityException the security exception
+ * @throws InstantiationException the instantiation exception
+ * @throws NoSuchMethodException the no such method exception
* @throws UnsupportedEncodingException the unsupported encoding exception
- * @throws AAIException the AAI exception
- */
- private Response invokeExtension(TransactionalGraphEngine dbEngine, Graph g, HttpMethod httpMethod,
- DBRequest request, String fromAppId, SchemaVersion apiVersion, Loader loader, Introspector obj, URI uri,
- boolean isPreprocess) throws IllegalArgumentException, UnsupportedEncodingException, AAIException {
- AAIExtensionMap aaiExtMap = new AAIExtensionMap();
- // ModelInjestor injestor = ModelInjestor.getInstance();
- Response response = null;
- URIToExtensionInformation extensionInformation = new URIToExtensionInformation(loader, uri);
- aaiExtMap.setHttpEntry(this);
- aaiExtMap.setDbRequest(request);
- aaiExtMap.setTransId(request.getTransactionId());
- aaiExtMap.setFromAppId(fromAppId);
- aaiExtMap.setGraph(g);
- aaiExtMap.setApiVersion(apiVersion.toString());
- aaiExtMap.setObjectFromRequest(obj);
- aaiExtMap.setObjectFromRequestType(obj.getJavaClassName());
- aaiExtMap.setObjectFromResponse(obj);
- aaiExtMap.setObjectFromResponseType(obj.getJavaClassName());
- aaiExtMap.setJaxbContext(nodeIngestor.getContextForVersion(apiVersion));
- aaiExtMap.setUri(uri.getRawPath());
- aaiExtMap.setTransactionalGraphEngine(dbEngine);
- aaiExtMap.setLoader(loader);
- aaiExtMap.setNamespace(extensionInformation.getNamespace());
-
- ExtensionController ext = new ExtensionController();
- ext.runExtension(aaiExtMap.getApiVersion(), extensionInformation.getNamespace(),
- extensionInformation.getTopObject(), extensionInformation.getMethodName(httpMethod, isPreprocess),
- aaiExtMap, isPreprocess);
-
- if (aaiExtMap.getPrecheckAddedList().size() > 0) {
- response = notifyOnSkeletonCreation(aaiExtMap, obj, request.getHeaders());
- }
-
- return response;
- }
-
- /**
- * Notify on skeleton creation.
- *
- * @param aaiExtMap the aai ext map
- * @param input the input
- * @param headers the headers
- * @return the response
+ * @throws MalformedURLException the malformed URL exception
+ * @throws AAIUnknownObjectException
+ * @throws URISyntaxException
*/
- // Legacy support
- private Response notifyOnSkeletonCreation(AAIExtensionMap aaiExtMap, Introspector input, HttpHeaders headers) {
- Response response = null;
- HashMap<AAIException, ArrayList<String>> exceptionList = new HashMap<AAIException, ArrayList<String>>();
-
- StringBuilder keyString = new StringBuilder();
+ private Introspector getRelationshipObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query,
+ URI uri, boolean isSkipRelatedTo) throws AAIException, IllegalArgumentException, SecurityException, UnsupportedEncodingException,
+ AAIUnknownObjectException {
- Set<String> resourceKeys = input.getKeys();
- for (String key : resourceKeys) {
- keyString.append(key).append("=").append(input.getValue(key).toString()).append(" ");
+ // nothing found
+ if (results.isEmpty()) {
+ String msg = createNotFoundMessage(query.getResultType(), uri);
+ throw new AAIException("AAI_6114", msg);
}
- for (AAIResponseMessage msg : aaiExtMap.getPrecheckResponseMessages().getAAIResponseMessage()) {
- ArrayList<String> templateVars = new ArrayList<>();
-
- templateVars.add("PUT " + input.getDbName());
- templateVars.add(keyString.toString());
- List<String> keys = new ArrayList<>();
- templateVars.add(msg.getAaiResponseMessageResourceType());
- for (AAIResponseMessageDatum dat : msg.getAaiResponseMessageData().getAAIResponseMessageDatum()) {
- keys.add(dat.getAaiResponseMessageDatumKey() + "=" + dat.getAaiResponseMessageDatumValue());
- }
- templateVars.add(StringUtils.join(keys, ", "));
- exceptionList.put(new AAIException("AAI_0004", msg.getAaiResponseMessageResourceType()), templateVars);
+ if (results.size() > 1) {
+ throw new AAIException("AAI_6148", uri.getPath());
}
- response = Response.status(Status.ACCEPTED)
- .entity(ErrorLogHelper.getRESTAPIInfoResponse(headers.getAcceptableMediaTypes(), exceptionList))
- .build();
- return response;
+ Vertex v = results.get(0);
+ return serializer.dbToRelationshipObject(v, isSkipRelatedTo);
}
/**
@@ -901,10 +939,7 @@ public class HttpEntry {
* @return the string
*/
private String createNotFoundMessage(String resultType, URI uri) {
-
- String msg = "No Node of type " + resultType + " found at: " + uri.getPath();
-
- return msg;
+ return "No Node of type " + resultType + " found at: " + uri.getPath();
}
/**
@@ -915,11 +950,8 @@ public class HttpEntry {
* @return the string
*/
private String createRelationshipNotFoundMessage(String resultType, URI uri) {
-
- String msg = "No relationship found of type " + resultType + " at the given URI: " + uri.getPath()
+ return "No relationship found of type " + resultType + " at the given URI: " + uri.getPath()
+ "/relationship-list";
-
- return msg;
}
/**
@@ -933,16 +965,13 @@ public class HttpEntry {
int depth = AAIProperties.MAXIMUM_DEPTH;
String getAllRandomStr = AAIConfig.get("aai.rest.getall.depthparam", "");
- if (depthParam != null && getAllRandomStr != null && !getAllRandomStr.isEmpty()
- && getAllRandomStr.equals(depthParam)) {
+ if (getAllRandomStr != null && !getAllRandomStr.isEmpty() && getAllRandomStr.equals(depthParam)) {
return depth;
}
if (depthParam == null) {
if (this.version.compareTo(schemaVersions.getDepthVersion()) >= 0) {
depth = 0;
- } else {
- depth = AAIProperties.MAXIMUM_DEPTH;
}
} else {
if (!depthParam.isEmpty() && !"all".equals(depthParam)) {
@@ -973,184 +1002,14 @@ public class HttpEntry {
return depth;
}
- /**
- * Checks if is modification method.
- *
- * @param method the method
- * @return true, if is modification method
- */
- private boolean isModificationMethod(HttpMethod method) {
- boolean result = false;
-
- if (method.equals(HttpMethod.PUT) || method.equals(HttpMethod.PUT_EDGE) || method.equals(HttpMethod.DELETE_EDGE)
- || method.equals(HttpMethod.MERGE_PATCH)) {
- result = true;
- }
-
- return result;
-
- }
-
- /**
- * Given an uri, introspector object and loader object
- * it will check if the obj is top level object if it is,
- * it will return immediately returning the uri passed in
- * If it isn't, it will go through, get the uriTemplate
- * from the introspector object and get the count of "/"s
- * and remove that part of the uri using substring
- * and keep doing that until the current object is top level
- * Also added the max depth just so worst case scenario
- * Then keep adding aai-uri to the list include the aai-uri passed in
- * Convert that list into an array and return it
- * <p>
- *
- * Example:
- *
- * <blockquote>
- * aai-uri ->
- * /cloud-infrastructure/cloud-regions/cloud-region/cloud-owner/cloud-region-id/tenants/tenant/tenant1/vservers/vserver/v1
- *
- * Given the uriTemplate vserver -> /vservers/vserver/{vserver-id}
- * it converts to /vservers/vserver
- *
- * lastIndexOf /vservers/vserver in
- * /cloud-infrastructure/cloud-regions/cloud-region/cloud-owner/cloud-region-id/tenants/tenant/tenant1/vservers/vserver/v1
- * ^
- * |
- * |
- * lastIndexOf
- * Use substring to get the string from 0 to that lastIndexOf
- * aai-uri -> /cloud-infrastructure/cloud-regions/cloud-region/cloud-owner/cloud-region-id/tenants/tenant/tenant1
- *
- * From this new aai-uri, generate a introspector from the URITOObject class
- * and keep doing this until you
- *
- * </blockquote>
- *
- * @param aaiUri - aai-uri of the vertex representating the unique id of a given vertex
- * @param obj - introspector object of the given starting vertex
- * @param loader - Type of loader which will always be MoxyLoader to support model driven
- * @return an array of strings which can be used to get the vertexes of parent and grand parents from a given vertex
- * @throws UnsupportedEncodingException
- * @throws AAIException
- */
- String[] convertIntrospectorToUriList(String aaiUri, Introspector obj, Loader loader)
- throws UnsupportedEncodingException, AAIException {
-
- List<String> uriList = new ArrayList<>();
- String template = StringUtils.EMPTY;
- String truncatedUri = aaiUri;
- int depth = AAIProperties.MAXIMUM_DEPTH;
- uriList.add(truncatedUri);
-
- while (depth >= 0 && !obj.isTopLevel()) {
- template = obj.getMetadata(ObjectMetadata.URI_TEMPLATE);
-
- if (template == null) {
- LOGGER.warn("Unable to find the uriTemplate for the object {}", obj.getDbName());
- return null;
- }
-
- int templateCount = StringUtils.countMatches(template, "/");
- int truncatedUriCount = StringUtils.countMatches(truncatedUri, "/");
-
- if (templateCount > truncatedUriCount) {
- LOGGER.warn("Template uri {} contains more slashes than truncatedUri {}", template, truncatedUri);
- return null;
- }
-
- int cutIndex = StringUtils.ordinalIndexOf(truncatedUri, "/", truncatedUriCount - templateCount + 1);
- truncatedUri = StringUtils.substring(truncatedUri, 0, cutIndex);
- uriList.add(truncatedUri);
- obj = new URIToObject(loader, UriBuilder.fromPath(truncatedUri).build()).getEntity();
- depth--;
- }
-
- return uriList.toArray(new String[uriList.size()]);
- }
-
- /**
- *
- * @param serializer
- * @param queryEngine
- * @param v
- * @param obj
- * @param loader
- * @return
- * @throws IllegalAccessException
- * @throws IllegalArgumentException
- * @throws InvocationTargetException
- * @throws SecurityException
- * @throws InstantiationException
- * @throws NoSuchMethodException
- * @throws UnsupportedEncodingException
- * @throws AAIException
- * @throws URISyntaxException
- */
- private HashMap<String, Introspector> getRelatedObjects(DBSerializer serializer, QueryEngine queryEngine, Vertex v,
- Introspector obj, Loader loader) throws IllegalAccessException, IllegalArgumentException,
- InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException,
- UnsupportedEncodingException, AAIException, URISyntaxException {
-
- HashMap<String, Introspector> relatedVertices = new HashMap<>();
- VertexProperty aaiUriProperty = v.property(AAIProperties.AAI_URI);
-
- if (!aaiUriProperty.isPresent()) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("For the given vertex {}, it seems aai-uri is not present so not getting related objects",
- v.id().toString());
- } else {
- LOGGER.info(
- "It seems aai-uri is not present in vertex, so not getting related objects, for more info enable debug log");
- }
- return relatedVertices;
- }
-
- String aaiUri = aaiUriProperty.value().toString();
-
- if (!obj.isTopLevel()) {
- String[] uriList = convertIntrospectorToUriList(aaiUri, obj, loader);
- List<Vertex> vertexChain = null;
- // If the uriList is null then there is something wrong with converting the uri
- // into a list of aai-uris so falling back to the old mechanism for finding parents
- if (uriList == null) {
- LOGGER.info(
- "Falling back to the old mechanism due to unable to convert aai-uri to list of uris but this is not optimal");
- vertexChain = queryEngine.findParents(v);
- } else {
- vertexChain = queryEngine.findParents(uriList);
- }
- for (Vertex vertex : vertexChain) {
- try {
- final Introspector vertexObj = serializer.getVertexProperties(vertex);
- relatedVertices.put(vertexObj.getObjectId(), vertexObj);
- } catch (AAIUnknownObjectException e) {
- LOGGER.warn("Unable to get vertex properties, partial list of related vertices returned");
- }
- }
- } else {
- try {
- final Introspector vertexObj = serializer.getVertexProperties(v);
- relatedVertices.put(vertexObj.getObjectId(), vertexObj);
- } catch (AAIUnknownObjectException e) {
- LOGGER.warn("Unable to get vertex properties, partial list of related vertices returned");
- }
- }
-
- return relatedVertices;
- }
-
private Map<Vertex, Introspector> buildIntrospectorObjects(DBSerializer serializer, Iterable<Vertex> vertices) {
Map<Vertex, Introspector> deleteObjectMap = new HashMap<>();
for (Vertex vertex : vertices) {
try {
- // deleteObjectMap.computeIfAbsent(vertex, s ->
- // serializer.getLatestVersionView(vertex));
- Introspector deleteObj = serializer.getLatestVersionView(vertex);
+ Introspector deleteObj = serializer.getLatestVersionView(vertex, notificationDepth);
deleteObjectMap.put(vertex, deleteObj);
} catch (UnsupportedEncodingException | AAIException e) {
LOGGER.warn("Unable to get Introspctor Objects, Just continue");
- continue;
}
}
@@ -1170,7 +1029,6 @@ public class HttpEntry {
}
} catch (UnsupportedEncodingException e) {
LOGGER.warn("Unable to get URIs, Just continue");
- continue;
}
}
@@ -1186,15 +1044,13 @@ public class HttpEntry {
for (Map.Entry<Vertex, Introspector> entry : introSpector.entrySet()) {
try {
HashMap<String, Introspector> relatedObjects =
- this.getRelatedObjects(serializer, queryEngine, entry.getKey(), entry.getValue(), this.loader);
+ serializer.getRelatedObjects(queryEngine, entry.getKey(), entry.getValue(), this.loader);
if (null != entry.getValue()) {
relatedObjectsMap.put(entry.getValue().getObjectId(), relatedObjects);
}
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException
- | InstantiationException | NoSuchMethodException | UnsupportedEncodingException | AAIException
- | URISyntaxException e) {
+ } catch (IllegalArgumentException | SecurityException
+ | UnsupportedEncodingException | AAIException e) {
LOGGER.warn("Unable to get realted Objects, Just continue");
- continue;
}
}
@@ -1208,10 +1064,8 @@ public class HttpEntry {
Map<String, HashMap<String, Introspector>> deleteRelatedObjects, String basePath) {
for (Map.Entry<Vertex, Introspector> entry : deleteObjects.entrySet()) {
try {
- String vertexObjectId = "";
-
if (null != entry.getValue()) {
- vertexObjectId = entry.getValue().getObjectId();
+ String vertexObjectId = entry.getValue().getObjectId();
if (uriMap.containsKey(vertexObjectId) && deleteRelatedObjects.containsKey(vertexObjectId)) {
notification.createNotificationEvent(transactionId, sourceOfTruth, status,
@@ -1227,12 +1081,38 @@ public class HttpEntry {
}
public void setPaginationParameters(String resultIndex, String resultSize) {
- if (resultIndex != null && resultIndex != "-1" && resultSize != null && resultSize != "-1") {
+ if (resultIndex != null && !"-1".equals(resultIndex) && resultSize != null && !"-1".equals(resultSize)) {
this.setPaginationIndex(Integer.parseInt(resultIndex));
this.setPaginationBucket(Integer.parseInt(resultSize));
}
}
+ public List<Object> getPaginatedVertexListForAggregateFormat(List<Object> aggregateVertexList) throws AAIException {
+ List<Object> finalList = new Vector<>();
+ if (this.isPaginated()) {
+ if (aggregateVertexList != null && !aggregateVertexList.isEmpty()) {
+ int listSize = aggregateVertexList.size();
+ if (listSize == 1) {
+ List<Object> vertexList = (List<Object>) aggregateVertexList.get(0);
+ this.setTotalsForPaging(vertexList.size(), this.getPaginationBucket());
+ int startIndex = (this.getPaginationIndex() - 1) * this.getPaginationBucket();
+ int endIndex = Math.min((this.getPaginationBucket() * this.getPaginationIndex()), vertexList.size());
+ if (startIndex > endIndex) {
+ throw new AAIException("AAI_6150",
+ " ResultIndex is not appropriate for the result set, Needs to be <= " + endIndex);
+ }
+ finalList.add(new ArrayList<Object>());
+ for (int i = startIndex; i < endIndex; i++) {
+ ((ArrayList<Object>) finalList.get(0)).add(((ArrayList<Object>) aggregateVertexList.get(0)).get(i));
+ }
+ return finalList;
+ }
+ }
+ }
+ // If the list size is greater than 1 or if pagination is not needed, return the original list.
+ return aggregateVertexList;
+ }
+
public List<Object> getPaginatedVertexList(List<Object> vertexList) throws AAIException {
List<Object> vertices;
if (this.isPaginated()) {
diff --git a/aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java b/aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java
index 61beb8d0..14e554cd 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/ueb/NotificationEvent.java
@@ -63,10 +63,13 @@ public class NotificationEvent {
StoreNotificationEvent sne = new StoreNotificationEvent(transactionId, sourceOfTruth);
- sne.storeEvent(loader, eventHeader, obj);
+ sne.storeEventAndSendToJms(loader, eventHeader, obj);
}
+ public String getNotificationEvent() throws AAIException {
+ return new StoreNotificationEvent(transactionId, sourceOfTruth).storeEventOnly(loader, eventHeader, obj);
+ }
/**
* Gets the notification version.
*
diff --git a/aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java b/aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java
index b189c050..28a644a9 100644
--- a/aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java
+++ b/aai-core/src/main/java/org/onap/aai/rest/ueb/UEBNotification.java
@@ -20,22 +20,13 @@
package org.onap.aai.rest.ueb;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import javax.ws.rs.core.Response.Status;
-
-import org.onap.aai.config.SpringContextAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.introspection.exceptions.AAIUnmarshallingException;
import org.onap.aai.logging.LogFormatTools;
@@ -43,15 +34,20 @@ import org.onap.aai.parsers.uri.URIToObject;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
+import javax.ws.rs.core.Response.Status;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.*;
+
/**
* The Class UEBNotification.
*/
public class UEBNotification {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(UEBNotification.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(UEBNotification.class);
private Loader currentVersionLoader = null;
- protected List<NotificationEvent> events = null;
+ protected Map<String, NotificationEvent> events = null;
private SchemaVersion notificationVersion = null;
/**
@@ -60,13 +56,27 @@ public class UEBNotification {
* @param loader the loader
*/
public UEBNotification(Loader loader, LoaderFactory loaderFactory, SchemaVersions schemaVersions) {
- events = new ArrayList<>();
+ events = new LinkedHashMap<>();
SchemaVersion defaultVersion = schemaVersions.getDefaultVersion();
currentVersionLoader = loaderFactory.createLoaderForVersion(loader.getModelType(), defaultVersion);
notificationVersion = defaultVersion;
}
/**
+ * Instantiates a new UEB notification.
+ *
+ * @param modelType - Model type
+ * @param loaderFactory - the loader factory
+ * @param schemaVersions the schema versions bean
+ */
+ public UEBNotification(ModelType modelType, LoaderFactory loaderFactory, SchemaVersions schemaVersions) {
+ events = new LinkedHashMap<>();
+ SchemaVersion defaultVersion = schemaVersions.getDefaultVersion();
+ currentVersionLoader = loaderFactory.createLoaderForVersion(modelType, defaultVersion);
+ notificationVersion = defaultVersion;
+ }
+
+ /**
* Creates the notification event.
*
* @param transactionId the X-TransactionId
@@ -97,7 +107,6 @@ public class UEBNotification {
Introspector eventHeader = currentVersionLoader.introspectorFromName("notification-event-header");
URIToObject parser = new URIToObject(currentVersionLoader, uri, relatedObjects);
- String entityLink = "";
if ((basePath != null) && (!basePath.isEmpty())) {
if (!(basePath.startsWith("/"))) {
basePath = "/" + basePath;
@@ -113,10 +122,12 @@ public class UEBNotification {
}
}
- if (uri.toString().startsWith("/")) {
- entityLink = basePath + notificationVersion + uri;
+ String uriStr = getUri(uri.toString(), basePath);
+ String entityLink;
+ if (uriStr.startsWith("/")) {
+ entityLink = basePath + notificationVersion + uriStr;
} else {
- entityLink = basePath + notificationVersion + "/" + uri;
+ entityLink = basePath + notificationVersion + "/" + uriStr;
}
eventHeader.setValue("entity-link", entityLink);
@@ -166,7 +177,7 @@ public class UEBNotification {
}
final NotificationEvent event =
new NotificationEvent(currentVersionLoader, eventHeader, eventObject, transactionId, sourceOfTruth);
- events.add(event);
+ events.put(uri.toString(), event);
} catch (AAIUnknownObjectException e) {
throw new RuntimeException("Fatal error - notification-event-header object not found!");
} catch (AAIUnmarshallingException e) {
@@ -181,14 +192,41 @@ public class UEBNotification {
* @throws AAIException the AAI exception
*/
public void triggerEvents() throws AAIException {
- for (NotificationEvent event : events) {
+ for (NotificationEvent event : events.values()) {
event.trigger();
}
- events.clear();
+ clearEvents();
}
public List<NotificationEvent> getEvents() {
+ return new ArrayList<>(this.events.values());
+ }
+ public Map<String, NotificationEvent> getEventsMap() {
return this.events;
}
+ private String getUri(String uri, String basePath) {
+ if (uri == null || uri.isEmpty()) {
+ return uri;
+ } else if (uri.charAt(0) != '/') {
+ uri = '/' + uri;
+ }
+
+ if ((basePath != null) && (!basePath.isEmpty())) {
+ if (!(basePath.startsWith("/"))) {
+ basePath = "/" + basePath;
+ }
+ if (!(basePath.endsWith("/"))) {
+ basePath = basePath + "/";
+ }
+ }
+
+ LOGGER.trace("Notification header uri base path:'{}', uri:'{}'", basePath, uri);
+
+ return uri.replaceAll("^" + basePath + "v\\d+", "");
+ }
+
+ public void clearEvents() {
+ events.clear();
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/RESTAPI.java b/aai-core/src/main/java/org/onap/aai/restcore/RESTAPI.java
index ae102a83..2b1256ba 100644
--- a/aai-core/src/main/java/org/onap/aai/restcore/RESTAPI.java
+++ b/aai-core/src/main/java/org/onap/aai/restcore/RESTAPI.java
@@ -20,64 +20,47 @@
package org.onap.aai.restcore;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import com.google.common.base.Joiner;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.onap.aai.db.props.AAIProperties;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
-import org.onap.aai.introspection.tools.CreateUUID;
-import org.onap.aai.introspection.tools.DefaultFields;
-import org.onap.aai.introspection.tools.InjectKeysFromURI;
-import org.onap.aai.introspection.tools.IntrospectorValidator;
-import org.onap.aai.introspection.tools.Issue;
-import org.onap.aai.introspection.tools.RemoveNonVisibleProperty;
+import org.onap.aai.introspection.tools.*;
import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.LoggingContext;
import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.FormatDate;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.*;
+
/**
* Base class for AAI REST API classes.
* Provides method to validate header information
* TODO should authenticate caller and authorize them for the API they are calling
* TODO should store the transaction
*
- *
+ *
*/
public class RESTAPI {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(RESTAPI.class);
-
- protected final String COMPONENT = "aairest";
+ private static final Logger LOGGER = LoggerFactory.getLogger(RESTAPI.class);
/**
* The Enum Action.
*/
public enum Action {
GET, PUT, POST, DELETE
- };
+ }
/**
* Gets the from app id.
@@ -101,8 +84,6 @@ public class RESTAPI {
throw new AAIException("AAI_4009");
}
- LoggingContext.partnerName(fromAppId);
-
return fromAppId;
}
@@ -128,8 +109,6 @@ public class RESTAPI {
throw new AAIException("AAI_4010");
}
- LoggingContext.requestId(transId);
-
return transId;
}
@@ -173,7 +152,7 @@ public class RESTAPI {
int depth = AAIProperties.MAXIMUM_DEPTH; // default
if (depthParam != null && depthParam.length() > 0 && !depthParam.equals("all")) {
try {
- depth = Integer.valueOf(depthParam);
+ depth = Integer.parseInt(depthParam);
} catch (Exception e) {
throw new AAIException("AAI_4016");
}
@@ -192,9 +171,9 @@ public class RESTAPI {
*/
protected Response consumerExceptionResponseGenerator(HttpHeaders headers, UriInfo info, HttpMethod templateAction,
AAIException e) {
- ArrayList<String> templateVars = new ArrayList<String>();
+ ArrayList<String> templateVars = new ArrayList<>();
templateVars.add(templateAction.toString()); // GET, PUT, etc
- templateVars.add(info.getPath().toString());
+ templateVars.add(info.getPath());
templateVars.addAll(e.getTemplateVars());
ErrorLogHelper.logException(e);
@@ -236,7 +215,7 @@ public class RESTAPI {
messages.add(issue.getDetail());
}
}
- String errors = Joiner.on(",").join(messages);
+ String errors = String.join(",", messages);
throw new AAIException("AAI_3000", errors);
}
// check that key in payload and key in request uri are the same
@@ -249,22 +228,6 @@ public class RESTAPI {
}
}
- protected DBConnectionType determineConnectionType(String fromAppId, String realTime) throws AAIException {
- if (fromAppId == null) {
- throw new AAIException("AAI_4009", "X-FromAppId is not set");
- }
-
- DBConnectionType type = DBConnectionType.REALTIME;
- boolean isRealTimeClient = AAIConfig.get("aai.realtime.clients", "").contains(fromAppId);
- if (isRealTimeClient || realTime != null) {
- type = DBConnectionType.REALTIME;
- } else {
- type = DBConnectionType.CACHED;
- }
-
- return type;
- }
-
/**
* Gets the input media type.
*
@@ -272,10 +235,7 @@ public class RESTAPI {
* @return the input media type
*/
protected String getInputMediaType(MediaType mediaType) {
- String result = mediaType.getType() + "/" + mediaType.getSubtype();
-
- return result;
-
+ return mediaType.getType() + "/" + mediaType.getSubtype();
}
/**
@@ -288,25 +248,23 @@ public class RESTAPI {
* @throws AAIException
*/
- public int getTimeoutLimit(String sot, String appTimeouts, String defaultTimeout) throws AAIException {
+ public int getTimeoutLimit(String sot, String appTimeouts, String defaultTimeout) {
String[] ignoreAppIds = (appTimeouts).split("\\|");
int appLimit = Integer.parseInt(defaultTimeout);
- final Map<String, Integer> m = new HashMap<String, Integer>();
- if (ignoreAppIds != null) {
- for (int i = 0; i < ignoreAppIds.length; i++) {
- String[] vals = ignoreAppIds[i].split(",");
- m.put(vals[0], Integer.parseInt(vals[1]));
- }
- if (m.get(sot) != null) {
- appLimit = m.get(sot);
- }
+ final Map<String, Integer> m = new HashMap<>();
+ for (int i = 0; i < ignoreAppIds.length; i++) {
+ String[] vals = ignoreAppIds[i].split(",");
+ m.put(vals[0], Integer.parseInt(vals[1]));
+ }
+ if (m.get(sot) != null) {
+ appLimit = m.get(sot);
}
return appLimit;
}
/**
* Returns whether time out is enabled
- *
+ *
* @param sot
* @param isEnabled
* @param appTimeouts
@@ -314,9 +272,8 @@ public class RESTAPI {
* @return boolean of whether the timeout is enabled
* @throws AAIException
*/
- public boolean isTimeoutEnabled(String sot, String isEnabled, String appTimeouts, String defaultTimeout)
- throws AAIException {
- Boolean isTimeoutEnabled = Boolean.parseBoolean(isEnabled);
+ public boolean isTimeoutEnabled(String sot, String isEnabled, String appTimeouts, String defaultTimeout) {
+ boolean isTimeoutEnabled = Boolean.parseBoolean(isEnabled);
int ata = -1;
if (isTimeoutEnabled) {
ata = getTimeoutLimit(sot, appTimeouts, defaultTimeout);
@@ -326,7 +283,7 @@ public class RESTAPI {
/**
* Executes the process thread and watches the future for the timeout
- *
+ *
* @param handler
* @param sourceOfTruth
* @param appTimeoutLimit
@@ -358,7 +315,7 @@ public class RESTAPI {
/**
* runner sets up the timer logic and invokes it
- *
+ *
* @param toe
* @param tba
* @param tdl
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/search/AAIAbstractGroovyShell.java b/aai-core/src/main/java/org/onap/aai/restcore/search/AAIAbstractGroovyShell.java
index b521a617..13f3f05e 100644
--- a/aai-core/src/main/java/org/onap/aai/restcore/search/AAIAbstractGroovyShell.java
+++ b/aai-core/src/main/java/org/onap/aai/restcore/search/AAIAbstractGroovyShell.java
@@ -28,13 +28,20 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.PropertyExpression;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.setup.SchemaVersions;
public abstract class AAIAbstractGroovyShell {
@@ -76,4 +83,20 @@ public abstract class AAIAbstractGroovyShell {
* @return result of graph traversal
*/
public abstract GraphTraversal<?, ?> executeTraversal(String traversal, Map<String, Object> params);
+
+ /**
+ *
+ * @param engine
+ * @param traversal
+ * @param params
+ * @return result of graph traversal
+ */
+ public abstract String executeTraversal(TransactionalGraphEngine engine, String traversal,
+ Map<String, Object> params, QueryStyle style, GraphTraversalSource source);
+
+ protected Loader getLoader(){
+ SchemaVersions schemaVersions = (SchemaVersions) SpringContextAware.getBean("schemaVersions");
+ return SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY,
+ schemaVersions.getDefaultVersion());
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java b/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java
index 2b39af43..85e47223 100644
--- a/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java
+++ b/aai-core/src/main/java/org/onap/aai/restcore/search/GremlinGroovyShell.java
@@ -26,6 +26,8 @@ import groovy.lang.Script;
import java.util.Map;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
/**
@@ -57,4 +59,9 @@ public class GremlinGroovyShell extends AAIAbstractGroovyShell {
public String executeTraversal(TransactionalGraphEngine engine, String traversal, Map<String, Object> params) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String executeTraversal(TransactionalGraphEngine engine, String traversal, Map<String, Object> params, QueryStyle style, GraphTraversalSource source) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java b/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java
index ba6acb66..fbaa7465 100644
--- a/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java
+++ b/aai-core/src/main/java/org/onap/aai/restcore/search/GroovyQueryBuilder.java
@@ -26,6 +26,7 @@ import groovy.lang.Script;
import java.util.Map;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.config.SpringContextAware;
import org.onap.aai.introspection.Loader;
@@ -53,11 +54,8 @@ public class GroovyQueryBuilder extends AAIAbstractGroovyShell {
@Override
public String executeTraversal(TransactionalGraphEngine engine, String traversal, Map<String, Object> params) {
QueryBuilder<Vertex> builder = engine.getQueryBuilder(QueryStyle.GREMLIN_TRAVERSAL);
- SchemaVersions schemaVersions = (SchemaVersions) SpringContextAware.getBean("schemaVersions");
- Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY,
- schemaVersions.getDefaultVersion());
- builder.changeLoader(loader);
+ builder.changeLoader(getLoader());
Binding binding = new Binding(params);
binding.setVariable("builder", builder);
Script script = shell.parse(traversal);
@@ -74,4 +72,17 @@ public class GroovyQueryBuilder extends AAIAbstractGroovyShell {
public GraphTraversal<?, ?> executeTraversal(String traversal, Map<String, Object> params) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String executeTraversal(TransactionalGraphEngine engine, String traversal, Map<String, Object> params, QueryStyle style, GraphTraversalSource traversalSource) {
+ QueryBuilder<Vertex> builder = engine.getQueryBuilder(style, traversalSource);
+ builder.changeLoader(getLoader());
+ Binding binding = new Binding(params);
+ binding.setVariable("builder", builder);
+ Script script = shell.parse(traversal);
+ script.setBinding(binding);
+ script.run();
+
+ return builder.getQuery();
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/restcore/util/URITools.java b/aai-core/src/main/java/org/onap/aai/restcore/util/URITools.java
index c3211fbe..a757d3db 100644
--- a/aai-core/src/main/java/org/onap/aai/restcore/util/URITools.java
+++ b/aai-core/src/main/java/org/onap/aai/restcore/util/URITools.java
@@ -47,22 +47,26 @@ public class URITools {
MultivaluedMap<String, String> result = new MultivaluedHashMap<>();
String queryParams = uri.getRawQuery();
if (queryParams != null) {
- String[] sections = queryParams.split("&");
- String[] query = null;
- String key, value = "";
- for (String section : sections) {
- query = section.split("=");
- key = UriUtils.decode(query[0], "UTF-8");
- if (query[1] != null) {
- query[1] = query[1].replaceAll("\\+", "%20");
+ try {
+ String[] sections = queryParams.split("&");
+ String[] query = null;
+ String key, value = "";
+ for (String section : sections) {
+ query = section.split("=");
+ key = UriUtils.decode(query[0], "UTF-8");
+ if (query[1] != null) {
+ query[1] = query[1].replaceAll("\\+", "%20");
+ }
+ value = UriUtils.decode(query[1], "UTF-8");
+ if (result.containsKey(key)) {
+ result.add(key, value);
+ } else {
+ result.putSingle(key, value);
+ }
}
- value = UriUtils.decode(query[1], "UTF-8");
- if (result.containsKey(key)) {
- result.add(key, value);
- } else {
- result.putSingle(key, value);
- }
- }
+ } catch (UnsupportedEncodingException e) {
+
+ }
}
return result;
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java b/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
index 3996c07d..14fb8cb5 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/db/DBSerializer.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,29 +17,13 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-
package org.onap.aai.serialization.db;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.CaseFormat;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.*;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.ws.rs.core.UriBuilder;
-
-import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Direction;
@@ -47,14 +31,13 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.janusgraph.core.SchemaViolationException;
-import org.javatuples.Triplet;
+import org.javatuples.Pair;
import org.onap.aai.concurrent.AaiCallable;
import org.onap.aai.config.SpringContextAware;
import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.edges.EdgeRule;
import org.onap.aai.edges.EdgeRuleQuery;
-import org.onap.aai.edges.TypeAlphabetizer;
import org.onap.aai.edges.enums.AAIDirection;
import org.onap.aai.edges.enums.EdgeField;
import org.onap.aai.edges.enums.EdgeProperty;
@@ -67,10 +50,11 @@ import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.introspection.sideeffect.*;
import org.onap.aai.logging.ErrorLogHelper;
import org.onap.aai.logging.LogFormatTools;
-import org.onap.aai.logging.LoggingContext;
import org.onap.aai.logging.StopWatch;
import org.onap.aai.parsers.query.QueryParser;
+import org.onap.aai.parsers.relationship.RelationshipToURI;
import org.onap.aai.parsers.uri.URIParser;
+import org.onap.aai.parsers.uri.URIToObject;
import org.onap.aai.parsers.uri.URIToRelationshipObject;
import org.onap.aai.query.builder.QueryBuilder;
import org.onap.aai.schema.enums.ObjectMetadata;
@@ -83,16 +67,32 @@ import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.AAIConstants;
+import org.onap.aai.util.delta.*;
import org.onap.aai.workarounds.NamingExceptions;
import org.springframework.context.ApplicationContext;
-public class DBSerializer {
-
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DBSerializer.class);
+import javax.ws.rs.core.UriBuilder;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
- private static final String IMPLICIT_DELETE = "Implicit DELETE";
+public class DBSerializer {
- private static final String MISSING_REQUIRED_NODE_PROPERTY = "Vertex missing required aai-node-type property";
+ private static final Logger LOGGER = LoggerFactory.getLogger(DBSerializer.class);
+ private static final String RELATIONSHIP_LABEL = "relationship-label";
+ private static final String RELATIONSHIP = "relationship";
+ public static final String FALSE = "false";
+ public static final String AAI_6145 = "AAI_6145";
+ public static final String AAI_6129 = "AAI_6129";
private final TransactionalGraphEngine engine;
private final String sourceOfTruth;
@@ -108,6 +108,12 @@ public class DBSerializer {
private SchemaVersions schemaVersions;
private Set<String> namedPropNodes;
+ private Map<String, ObjectDelta> objectDeltas = new LinkedHashMap<>();
+ private Map<Vertex, Boolean> updatedVertexes = new LinkedHashMap<>();
+ private Set<Vertex> edgeVertexes = new LinkedHashSet<>();
+ private Map<String, Pair<Introspector, LinkedHashMap<String, Introspector>>> impliedDeleteUriObjectPair = new LinkedHashMap<>();
+ private int notificationDepth;
+ private boolean isDeltaEventsEnabled;
/**
* Instantiates a new DB serializer.
@@ -124,15 +130,39 @@ public class DBSerializer {
this.sourceOfTruth = sourceOfTruth;
this.introspectionType = introspectionType;
this.schemaVersions = (SchemaVersions) SpringContextAware.getBean("schemaVersions");
- SchemaVersion LATEST = schemaVersions.getDefaultVersion();
+ SchemaVersion latestVersion = schemaVersions.getDefaultVersion();
this.latestLoader =
- SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, LATEST);
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, latestVersion);
this.version = version;
this.loader =
SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, version);
this.namedPropNodes = this.latestLoader.getNamedPropNodes();
this.baseURL = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE);
this.currentTimeMillis = System.currentTimeMillis();
+ // If creating the DBSerializer the old way then set the notification depth to maximum
+ this.notificationDepth = AAIProperties.MAXIMUM_DEPTH;
+ initBeans();
+ }
+
+ public DBSerializer(SchemaVersion version,
+ TransactionalGraphEngine engine,
+ ModelType introspectionType,
+ String sourceOfTruth,
+ int notificationDepth) throws AAIException {
+ this.engine = engine;
+ this.sourceOfTruth = sourceOfTruth;
+ this.introspectionType = introspectionType;
+ this.schemaVersions = (SchemaVersions) SpringContextAware.getBean("schemaVersions");
+ SchemaVersion latestVersion = schemaVersions.getDefaultVersion();
+ this.latestLoader =
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, latestVersion);
+ this.version = version;
+ this.loader =
+ SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(introspectionType, version);
+ this.namedPropNodes = this.latestLoader.getNamedPropNodes();
+ this.baseURL = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE);
+ this.currentTimeMillis = System.currentTimeMillis();
+ this.notificationDepth = notificationDepth;
initBeans();
}
@@ -143,10 +173,7 @@ public class DBSerializer {
setEdgeIngestor(ei);
EdgeSerializer es = ctx.getBean(EdgeSerializer.class);
setEdgeSerializer(es);
- }
-
- private void backupESInit() {
- setEdgeSerializer(new EdgeSerializer(this.edgeRules));
+ isDeltaEventsEnabled = Boolean.parseBoolean(SpringContextAware.getApplicationContext().getEnvironment().getProperty("delta.events.enabled", FALSE));
}
public void setEdgeSerializer(EdgeSerializer edgeSer) {
@@ -165,31 +192,95 @@ public class DBSerializer {
return this.edgeRules;
}
+ public Map<Vertex, Boolean> getUpdatedVertexes() {
+ return updatedVertexes;
+ }
+
+ public Map<String, Pair<Introspector, LinkedHashMap<String, Introspector>>> getImpliedDeleteUriObjectPair(){
+ return impliedDeleteUriObjectPair;
+ }
+
/**
* Touch standard vertex properties.
- *
- * @param v the v
+ * @param v the v
* @param isNewVertex the is new vertex
*/
public void touchStandardVertexProperties(Vertex v, boolean isNewVertex) {
String timeNowInSec = Long.toString(currentTimeMillis);
-
if (isNewVertex) {
+ String uuid = UUID.randomUUID().toString();
v.property(AAIProperties.SOURCE_OF_TRUTH, this.sourceOfTruth);
- v.property(AAIProperties.CREATED_TS, timeNowInSec);
- v.property(AAIProperties.AAI_UUID, UUID.randomUUID().toString());
+ v.property(AAIProperties.CREATED_TS, currentTimeMillis);
+ v.property(AAIProperties.AAI_UUID, uuid);
+ v.property(AAIProperties.RESOURCE_VERSION, timeNowInSec);
+ v.property(AAIProperties.LAST_MOD_TS, currentTimeMillis);
+ v.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, this.sourceOfTruth);
+ } else {
+ if(isDeltaEventsEnabled) {
+ standardVertexPropsDeltas(v, timeNowInSec);
+ }
+ v.property(AAIProperties.RESOURCE_VERSION, timeNowInSec);
+ v.property(AAIProperties.LAST_MOD_TS, currentTimeMillis);
+ v.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, this.sourceOfTruth);
}
- v.property(AAIProperties.RESOURCE_VERSION, timeNowInSec);
- v.property(AAIProperties.LAST_MOD_TS, timeNowInSec);
- v.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, this.sourceOfTruth);
+ }
+ private void standardVertexPropsDeltas(Vertex v, String timeNowInSec) {
+ String uri = v.property(AAIProperties.AAI_URI).value().toString();
+ long createdTs = (Long) v.property(AAIProperties.CREATED_TS).value();
+ DeltaAction objDeltaAction = createdTs == currentTimeMillis ? DeltaAction.CREATE : DeltaAction.UPDATE;
+ if (getObjectDeltas().containsKey(uri)) {
+ getObjectDeltas().get(uri).setAction(objDeltaAction);
+ }
+
+ addPropDelta(uri, AAIProperties.AAI_UUID, PropertyDeltaFactory.getDelta(DeltaAction.STATIC, v.property(AAIProperties.AAI_UUID).value()), objDeltaAction);
+ addPropDelta(uri, AAIProperties.NODE_TYPE, PropertyDeltaFactory.getDelta(DeltaAction.STATIC, v.property(AAIProperties.NODE_TYPE).value()), objDeltaAction);
+ addPropDelta(uri, AAIProperties.SOURCE_OF_TRUTH, PropertyDeltaFactory.getDelta(DeltaAction.STATIC, v.property(AAIProperties.SOURCE_OF_TRUTH).value()), objDeltaAction);
+ addPropDelta(uri, AAIProperties.CREATED_TS, PropertyDeltaFactory.getDelta(DeltaAction.STATIC, v.property(AAIProperties.CREATED_TS).value()), objDeltaAction);
+
+ if (objDeltaAction.equals(DeltaAction.UPDATE)) {
+ addPropDelta(
+ uri,
+ AAIProperties.RESOURCE_VERSION,
+ PropertyDeltaFactory.getDelta(objDeltaAction, timeNowInSec, v.property(AAIProperties.RESOURCE_VERSION).value()),
+ objDeltaAction
+ );
+ addPropDelta(
+ uri,
+ AAIProperties.LAST_MOD_TS,
+ PropertyDeltaFactory.getDelta(objDeltaAction, currentTimeMillis, v.property(AAIProperties.LAST_MOD_TS).value()),
+ objDeltaAction
+ );
+ addPropDelta(
+ uri,
+ AAIProperties.LAST_MOD_SOURCE_OF_TRUTH,
+ PropertyDeltaFactory.getDelta(objDeltaAction, this.sourceOfTruth, v.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH).value()),
+ objDeltaAction
+ );
+ } else {
+ addPropDelta(uri, AAIProperties.RESOURCE_VERSION, PropertyDeltaFactory.getDelta(objDeltaAction, v.property(AAIProperties.RESOURCE_VERSION).value()), objDeltaAction);
+ addPropDelta(uri, AAIProperties.LAST_MOD_TS, PropertyDeltaFactory.getDelta(objDeltaAction, v.property(AAIProperties.LAST_MOD_TS).value()), objDeltaAction);
+ addPropDelta(uri, AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, PropertyDeltaFactory.getDelta(objDeltaAction, v.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH).value()), objDeltaAction);
+ }
}
- private void touchStandardVertexProperties(String nodeType, Vertex v, boolean isNewVertex) {
+ public Map<String, ObjectDelta> getObjectDeltas() {return objectDeltas;}
+
+ private void addPropDelta(String uri, String prop, PropertyDelta delta, DeltaAction objDeltaAction) {
+ ObjectDelta objectDelta = this.objectDeltas.getOrDefault(uri, new ObjectDelta(uri, objDeltaAction, this.sourceOfTruth, this.currentTimeMillis));
+ objectDelta.addPropertyDelta(prop, delta);
+ objectDeltas.put(uri, objectDelta);
+ }
+ private void addRelationshipDelta(String uri, RelationshipDelta delta, DeltaAction objDeltaAction) {
+ ObjectDelta objectDelta = this.objectDeltas.getOrDefault(uri, new ObjectDelta(uri, objDeltaAction, this.sourceOfTruth, this.currentTimeMillis));
+ objectDelta.addRelationshipDelta(delta);
+ objectDeltas.put(uri, objectDelta);
+ }
+
+ private void touchStandardVertexProperties(String nodeType, Vertex v, boolean isNewVertex) {
v.property(AAIProperties.NODE_TYPE, nodeType);
touchStandardVertexProperties(v, isNewVertex);
-
}
/**
@@ -197,14 +288,12 @@ public class DBSerializer {
*
* @param wrappedObject the wrapped object
* @return the vertex
- * @throws UnsupportedEncodingException the unsupported encoding exception
- * @throws AAIException the AAI exception
*/
public Vertex createNewVertex(Introspector wrappedObject) {
Vertex v;
try {
StopWatch.conditionalStart();
- v = this.engine.tx().addVertex();
+ v = this.engine.tx().addVertex(wrappedObject.getDbName());
touchStandardVertexProperties(wrappedObject.getDbName(), v, true);
} finally {
dbTimeMsecs += StopWatch.stopIfStarted();
@@ -227,7 +316,7 @@ public class DBSerializer {
if (className.lastIndexOf('.') == -1) {
return className;
}
- returnValue = className.substring(className.lastIndexOf('.') + 1, className.length());
+ returnValue = className.substring(className.lastIndexOf('.') + 1);
return returnValue;
}
@@ -240,15 +329,9 @@ public class DBSerializer {
* @param uriQuery the uri query
* @param identifier the identifier
* @throws SecurityException the security exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws InstantiationException the instantiation exception
- * @throws InterruptedException the interrupted exception
- * @throws NoSuchMethodException the no such method exception
* @throws AAIException the AAI exception
* @throws UnsupportedEncodingException the unsupported encoding exception
- * @throws AAIUnknownObjectException
*/
public void serializeToDb(Introspector obj, Vertex v, QueryParser uriQuery, String identifier,
String requestContext) throws AAIException, UnsupportedEncodingException {
@@ -284,8 +367,6 @@ public class DBSerializer {
if (isTopLevel) {
addUriIfNeeded(v, obj.getURI());
}
-
- processObject(obj, v, requestContext);
if (!isTopLevel) {
URI uri = this.getURIForVertex(v);
URIParser parser = new URIParser(this.loader, uri);
@@ -293,6 +374,7 @@ public class DBSerializer {
addUriIfNeeded(v, uri.toString());
}
}
+ processObject(obj, v, requestContext);
} catch (SchemaViolationException e) {
throw new AAIException("AAI_6117", e);
} finally {
@@ -302,7 +384,7 @@ public class DBSerializer {
private void addUriIfNeeded(Vertex v, String uri) {
VertexProperty<String> uriProp = v.property(AAIProperties.AAI_URI);
- if (!uriProp.isPresent() || (uriProp.isPresent() && !uriProp.value().equals(uri))) {
+ if (!uriProp.isPresent() || !uriProp.value().equals(uri)) {
v.property(AAIProperties.AAI_URI, uri);
}
}
@@ -310,43 +392,42 @@ public class DBSerializer {
/**
* Process object.
*
- * @param <T> the generic type
* @param obj the obj
* @param v the v
* @return the list
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws InstantiationException the instantiation exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws AAIException the AAI exception
* @throws UnsupportedEncodingException the unsupported encoding exception
- * @throws AAIUnknownObjectException
*/
/*
* Helper method for reflectToDb
* Handles all the property setting
*/
- private <T> List<Vertex> processObject(Introspector obj, Vertex v, String requestContext)
+ private List<Vertex> processObject(Introspector obj, Vertex v, String requestContext)
throws UnsupportedEncodingException, AAIException {
Set<String> properties = new LinkedHashSet<>(obj.getProperties());
properties.remove(AAIProperties.RESOURCE_VERSION);
List<Vertex> dependentVertexes = new ArrayList<>();
List<Vertex> processedVertexes = new ArrayList<>();
- boolean isComplexType = false;
- boolean isListType = false;
- if (!obj.isContainer()) {
- this.touchStandardVertexProperties(v, false);
+
+ boolean isComplexType ;
+ boolean isListType;
+
+ // If the notification depth is set to maximum
+ // this is the behavior of the expected clients
+ if(notificationDepth == AAIProperties.MAXIMUM_DEPTH) {
+ if (!obj.isContainer()) {
+ this.touchStandardVertexProperties(v, false);
+ }
}
this.executePreSideEffects(obj, v);
for (String property : properties) {
- Object value = null;
final String propertyType;
propertyType = obj.getType(property);
isComplexType = obj.isComplexType(property);
isListType = obj.isListType(property);
- value = obj.getValue(property);
+ Object value = obj.getValue(property);
if (!(isComplexType || isListType)) {
boolean canModify = this.canModify(obj, property, requestContext);
@@ -362,16 +443,28 @@ public class DBSerializer {
// they are populated dynamically on GETs
continue;
}
+ Object oldValue = v.property(dbProperty).orElse(null);
+ String uri = getURIForVertex(v).toString();
if (value != null) {
- if (!value.equals(v.property(dbProperty).orElse(null))) {
+ if (!value.equals(oldValue)) {
if (propertyType.toLowerCase().contains(".long")) {
v.property(dbProperty, new Integer(((Long) value).toString()));
} else {
v.property(dbProperty, value);
}
+ if (isDeltaEventsEnabled) {
+ createDeltaProperty(uri, value, dbProperty, oldValue);
+ }
+ this.updatedVertexes.putIfAbsent(v, false);
}
} else {
- v.property(dbProperty).remove();
+ if (oldValue != null) {
+ v.property(dbProperty).remove();
+ if (isDeltaEventsEnabled) {
+ addPropDelta(uri, dbProperty, PropertyDeltaFactory.getDelta(DeltaAction.DELETE, oldValue), DeltaAction.UPDATE);
+ }
+ this.updatedVertexes.putIfAbsent(v, false);
+ }
}
}
} else if (isListType) {
@@ -386,7 +479,21 @@ public class DBSerializer {
}
} else {
// simple list case
- engine.setListProperty(v, property, list);
+ if (isDeltaEventsEnabled) {
+ String uri = getURIForVertex(v).toString();
+ List<Object> oldVal = engine.getListProperty(v, property);
+ engine.setListProperty(v, property, list);
+ if (list == null || list.isEmpty()) { // property delete scenario, there is no new value
+ if (oldVal != null && !oldVal.isEmpty()) { // and there is an old value
+ addPropDelta(uri, property, PropertyDeltaFactory.getDelta(DeltaAction.DELETE, oldVal), DeltaAction.UPDATE);
+ }
+ } else { // is either a create or update and is handled by the called method
+ createDeltaProperty(uri, list, property, oldVal);
+ }
+ } else {
+ engine.setListProperty(v, property, list);
+ }
+ this.updatedVertexes.putIfAbsent(v, false);
}
} else {
// method.getReturnType() is not 'simple' then create a vertex and edge recursively returning an edge
@@ -427,62 +534,192 @@ public class DBSerializer {
}
this.writeThroughDefaults(v, obj);
/* handle those vertexes not touched */
- for (Vertex toBeRemoved : processedVertexes) {
- dependentVertexes.remove(toBeRemoved);
+ for (Vertex toBeKept : processedVertexes) {
+ dependentVertexes.remove(toBeKept);
}
- // If the dependent vertices are not empty, then with
- // the current behaviour, it should remove the vertices implicitly
- // We are updating the code to properly log which call
- // is doing this so the SE can work with the clients making the call to
- // tell them not to call this API and can hopefully deprecate this
- // functionality in the future releases
- if (!dependentVertexes.isEmpty()) {
+ ImpliedDelete impliedDelete = new ImpliedDelete(engine, this);
+ List<Vertex> impliedDeleteVertices = impliedDelete.execute(v.id(), sourceOfTruth, obj.getName(), dependentVertexes);
+
+ if(notificationDepth == AAIProperties.MINIMUM_DEPTH){
+ for(Vertex curVertex : impliedDeleteVertices){
+ if(!curVertex.property("aai-uri").isPresent()){
+ LOGGER.debug("Encountered an vertex {} with missing aai-uri", curVertex.id());
+ continue;
+ }
+ String curAaiUri = curVertex.<String>property(AAIProperties.AAI_URI).value();
+ Introspector curObj = this.getLatestVersionView(curVertex, notificationDepth);
- LoggingContext.responseDescription(IMPLICIT_DELETE);
+ LinkedHashMap<String, Introspector> curObjRelated = new LinkedHashMap<>();
- // Find all the deletable vertices from the dependent vertices that should be deleted
- // So for each of the following dependent vertices,
- // we will use the edge properties and do the cascade delete
- List<Vertex> impliedDeleteVertices = this.engine.getQueryEngine().findDeletable(dependentVertexes);
- int impliedDeleteCount = impliedDeleteVertices.size();
+ if(!curObj.isTopLevel()){
+ curObjRelated.putAll(this.getRelatedObjects(engine.getQueryEngine(), curVertex, curObj, this.loader));
+ }
- LOGGER.warn(
- "For the vertex with id {}, doing an implicit delete on update will delete total of {} vertexes",
- v.id(), impliedDeleteCount);
+ if(!impliedDeleteUriObjectPair.containsKey(curAaiUri)){
+ impliedDeleteUriObjectPair.put(curAaiUri, new Pair<>(curObj, curObjRelated));
+ }
+ }
+ }
- String impliedDeleteLogEnabled = AAIConfig.get(AAIConstants.AAI_IMPLIED_DELETE_LOG_ENABLED, "true");
+ impliedDelete.delete(impliedDeleteVertices);
- int impliedDeleteLogLimit = AAIConfig.getInt(AAIConstants.AAI_IMPLIED_DELETE_LOG_LIMIT, "-1");
+ // touch svp using vertex list for what changed
+ // if the notification depth is zero
+ if(notificationDepth == AAIProperties.MINIMUM_DEPTH){
+ this.updatedVertexes.entrySet().stream()
+ .filter(e -> !e.getValue())
+ .filter(e -> !edgeVertexes.contains(e.getKey()))
+ .forEach(e -> {
+ this.touchStandardVertexProperties(e.getKey(), false);
+ e.setValue(true);
+ });
+ }
+ this.executePostSideEffects(obj, v);
+ return processedVertexes;
+ }
- if (impliedDeleteLogLimit == -1) {
- impliedDeleteLogLimit = Integer.MAX_VALUE;
- }
+ private void createDeltaProperty(String uri, Object value, String dbProperty, Object oldValue) {
+ if (oldValue == null) {
+ addPropDelta(uri, dbProperty, PropertyDeltaFactory.getDelta(DeltaAction.CREATE, value), DeltaAction.UPDATE);
+ } else {
+ addPropDelta(uri, dbProperty, PropertyDeltaFactory.getDelta(DeltaAction.UPDATE, value, oldValue), DeltaAction.UPDATE);
+ }
+ }
- // If the logging is enabled for implied delete
- // then log the payload in the latest format
- if ("true".equals(impliedDeleteLogEnabled) && impliedDeleteCount <= impliedDeleteLogLimit) {
- for (Vertex vertex : impliedDeleteVertices) {
- Introspector introspector = null;
- try {
- introspector = getLatestVersionView(vertex);
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info("Implied delete object in json format {}", introspector.marshal(false));
- }
- } catch (Exception ex) {
- LOGGER.warn(
- "Encountered an exception during retrieval of vertex properties with vertex-id {} -> {}",
- v.id(), LogFormatTools.getStackTop(ex));
- }
+ public HashMap<String, Introspector> getRelatedObjects(QueryEngine queryEngine, Vertex v,
+ Introspector obj, Loader loader) throws IllegalArgumentException, SecurityException, UnsupportedEncodingException, AAIException {
+
+ HashMap<String, Introspector> relatedVertices = new HashMap<>();
+ VertexProperty aaiUriProperty = v.property(AAIProperties.AAI_URI);
+
+ if (!aaiUriProperty.isPresent()) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("For the given vertex {}, it seems aai-uri is not present so not getting related objects",
+ v.id().toString());
+ } else {
+ LOGGER.info(
+ "It seems aai-uri is not present in vertex, so not getting related objects, for more info enable debug log");
+ }
+ return relatedVertices;
+ }
+
+ String aaiUri = aaiUriProperty.value().toString();
+
+ if (!obj.isTopLevel()) {
+ String[] uriList = convertIntrospectorToUriList(aaiUri, obj, loader);
+ List<Vertex> vertexChain;
+ // If the uriList is null then there is something wrong with converting the uri
+ // into a list of aai-uris so falling back to the old mechanism for finding parents
+ if (uriList == null) {
+ LOGGER.info(
+ "Falling back to the old mechanism due to unable to convert aai-uri to list of uris but this is not optimal");
+ vertexChain = queryEngine.findParents(v);
+ } else if (uriList.length == 1) {
+ // If the uri list is size 1 the only uri in the list is the one represented by v thus no need to query
+ vertexChain = Collections.singletonList(v);
+ } else {
+ // the uriList at element 0 is the node in question and should not be included in the vertex chain lookup.
+ vertexChain = queryEngine.findParents(Arrays.copyOfRange(uriList, 1, uriList.length));
+ // inject v into start of vertexChain
+ vertexChain.add(0, v);
+ }
+ for (Vertex vertex : vertexChain) {
+ try {
+ final Introspector vertexObj = this.getVertexProperties(vertex);
+ relatedVertices.put(vertexObj.getObjectId(), vertexObj);
+ } catch (AAIUnknownObjectException e) {
+ LOGGER.warn("Unable to get vertex properties, partial list of related vertices returned");
}
}
+ } else {
+ try {
+ final Introspector vertexObj = this.getVertexProperties(v);
+ relatedVertices.put(vertexObj.getObjectId(), vertexObj);
+ } catch (AAIUnknownObjectException e) {
+ LOGGER.warn("Unable to get vertex properties, partial list of related vertices returned");
+ }
+ }
+
+ return relatedVertices;
+ }
+
+ /**
+ * Given an uri, introspector object and loader object
+ * it will check if the obj is top level object if it is,
+ * it will return immediately returning the uri passed in
+ * If it isn't, it will go through, get the uriTemplate
+ * from the introspector object and get the count of "/"s
+ * and remove that part of the uri using substring
+ * and keep doing that until the current object is top level
+ * Also added the max depth just so worst case scenario
+ * Then keep adding aai-uri to the list include the aai-uri passed in
+ * Convert that list into an array and return it
+ * <p>
+ *
+ * Example:
+ *
+ * <blockquote>
+ * aai-uri ->
+ * /cloud-infrastructure/cloud-regions/cloud-region/cloud-owner/cloud-region-id/tenants/tenant/tenant1/vservers/vserver/v1
+ *
+ * Given the uriTemplate vserver -> /vservers/vserver/{vserver-id}
+ * it converts to /vservers/vserver
+ *
+ * lastIndexOf /vservers/vserver in
+ * /cloud-infrastructure/cloud-regions/cloud-region/cloud-owner/cloud-region-id/tenants/tenant/tenant1/vservers/vserver/v1
+ * ^
+ * |
+ * |
+ * lastIndexOf
+ * Use substring to get the string from 0 to that lastIndexOf
+ * aai-uri -> /cloud-infrastructure/cloud-regions/cloud-region/cloud-owner/cloud-region-id/tenants/tenant/tenant1
+ *
+ * From this new aai-uri, generate a introspector from the URITOObject class
+ * and keep doing this until you
+ *
+ * </blockquote>
+ *
+ * @param aaiUri - aai-uri of the vertex representating the unique id of a given vertex
+ * @param obj - introspector object of the given starting vertex
+ * @param loader - Type of loader which will always be MoxyLoader to support model driven
+ * @return an array of strings which can be used to get the vertexes of parent and grand parents from a given vertex
+ * @throws UnsupportedEncodingException
+ * @throws AAIException
+ */
+ String[] convertIntrospectorToUriList(String aaiUri, Introspector obj, Loader loader)
+ throws UnsupportedEncodingException, AAIException {
+
+ List<String> uriList = new ArrayList<>();
+ String template;
+ String truncatedUri = aaiUri;
+ int depth = AAIProperties.MAXIMUM_DEPTH;
+ uriList.add(truncatedUri);
+
+ while (depth >= 0 && !obj.isTopLevel()) {
+ template = obj.getMetadata(ObjectMetadata.URI_TEMPLATE);
+
+ if (template == null) {
+ LOGGER.warn("Unable to find the uriTemplate for the object {}", obj.getDbName());
+ return null;
+ }
- // After all the appropriate logging, calling the delete to delete the affected vertices
- this.delete(impliedDeleteVertices);
+ int templateCount = StringUtils.countMatches(template, "/");
+ int truncatedUriCount = StringUtils.countMatches(truncatedUri, "/");
+
+ if (templateCount > truncatedUriCount) {
+ LOGGER.warn("Template uri {} contains more slashes than truncatedUri {}", template, truncatedUri);
+ return null;
+ }
+
+ int cutIndex = StringUtils.ordinalIndexOf(truncatedUri, "/", truncatedUriCount - templateCount + 1);
+ truncatedUri = StringUtils.substring(truncatedUri, 0, cutIndex);
+ uriList.add(truncatedUri);
+ obj = new URIToObject(loader, UriBuilder.fromPath(truncatedUri).build()).getEntity();
+ depth--;
}
- this.executePostSideEffects(obj, v);
- return processedVertexes;
+ return uriList.toArray(new String[0]);
}
/**
@@ -491,9 +728,7 @@ public class DBSerializer {
* @param obj the obj
* @param vertex the vertex
* @throws SecurityException the security exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIException the AAI exception
*/
@@ -517,28 +752,141 @@ public class DBSerializer {
* @throws AAIException the AAI exception
*/
private void processRelationshipList(Introspector wrapped, Vertex v)
- throws UnsupportedEncodingException, AAIException {
+ throws UnsupportedEncodingException, AAIException {
+
+ List<Object> relationships = wrapped.getValue("relationship");
+ String mainUri = getURIForVertex(v).toString();
+ String aNodeType = v.property(AAIProperties.NODE_TYPE).value().toString();
+ EdgeRuleQuery.Builder cousinQueryBuilder = new EdgeRuleQuery.Builder(aNodeType)
+ .edgeType(EdgeType.COUSIN)
+ .version(wrapped.getVersion());
+ EdgeRuleQuery.Builder treeQueryBuilder = new EdgeRuleQuery.Builder(aNodeType)
+ .edgeType(EdgeType.TREE)
+ .version(wrapped.getVersion());
- List<Object> relationships = (List<Object>) wrapped.getValue("relationship");
-
- List<Triplet<Vertex, Vertex, String>> addEdges = new ArrayList<>();
- List<Edge> existingEdges = this.engine.getQueryEngine().findEdgesForVersion(v, wrapped.getLoader());
+ EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class);
+ Set<Pair<String, String>> cousinUriAndLabels = new LinkedHashSet<>();
for (Object relationship : relationships) {
- Edge e = null;
- Vertex cousinVertex = null;
- String label = null;
+
+ String label;
Introspector wrappedRel = IntrospectorFactory.newInstance(this.introspectionType, relationship);
- QueryParser parser = engine.getQueryBuilder().createQueryFromRelationship(wrappedRel);
+ String relUri = urlToUri(new RelationshipToURI(loader, wrappedRel).getUri().toString());
+
+ if (relUri.startsWith("/vnf/")) {
+ QueryParser parser = engine.getQueryBuilder().createQueryFromRelationship(wrappedRel);
+ List<Vertex> results = parser.getQueryBuilder().toList();
+ if (results.isEmpty()) {
+ final AAIException ex = new AAIException(AAI_6129,
+ String.format("Node of type %s. Could not find object at: %s", parser.getResultType(), parser.getUri()));
+ ex.getTemplateVars().add(parser.getResultType());
+ ex.getTemplateVars().add(parser.getUri().toString());
+ throw ex;
+ } else {
+ // still an issue if there's more than one
+ if (results.get(0).property(AAIProperties.AAI_URI).isPresent()) {
+ relUri = results.get(0).value(AAIProperties.AAI_URI);
+ } else {
+ LOGGER.warn("Not processing the vertex {} because its missing required property aai-uri", results.get(0).id());
+ continue;
+ }
+ }
+ }
- if (wrappedRel.hasProperty("relationship-label")) {
- label = wrappedRel.getValue("relationship-label");
+ if (wrappedRel.getValue(RELATIONSHIP_LABEL) != null) {
+ label = wrappedRel.getValue(RELATIONSHIP_LABEL);
+ } else {
+ URIToObject uriToObject = new URIToObject(loader, URI.create(relUri));
+ String bNodeType = uriToObject.getEntityName();
+ EdgeRuleQuery ruleQuery = cousinQueryBuilder.to(bNodeType).build();
+ if (!edgeIngestor.hasRule(ruleQuery)) {
+ EdgeRuleQuery treeQuery = treeQueryBuilder.to(bNodeType).build();
+ if (edgeIngestor.hasRule(treeQuery)) {
+ throw new AAIException(AAI_6145); //attempted to create cousin edge for a parent-child edge rule
+ }
+ throw new AAIException("AAI_6120", String.format(
+ "No EdgeRule found for passed nodeTypes: %s, %s.",
+ aNodeType, bNodeType));
+ } else {
+ try {
+ final List<EdgeRule> rules = new ArrayList<>(edgeIngestor.getRules(ruleQuery).values());
+ if (rules.size() == 1) {
+ label = rules.get(0).getLabel();
+ } else {
+ Optional<EdgeRule> defaultRule = rules.stream().filter(EdgeRule::isDefault).findFirst();
+ if (defaultRule.isPresent()) {
+ label = defaultRule.get().getLabel();
+ } else {
+ throw new AAIException(AAI_6145);
+ }
+ }
+ } catch (EdgeRuleNotFoundException ea) {
+ throw new AAIException(AAI_6145, ea);
+ }
+ }
}
+ cousinUriAndLabels.add(Pair.with(relUri, label));
+ }
+
+ List<Path> paths = this.engine.getQueryEngine().findCousinsAsPath(v);
+ Set<Path> toRemove = new HashSet<>();
+
+
+ // for each path 3 things can happen:
+ // 1. The edge rule that created it is not in this version no action is to be taken on that edge
+ // 2. The edge rule exits in this version it's included in the request the edge is left alone
+ // 3. The edge rule exits in this version and is not included in the request it is marked for removal
+ for (Path path : paths) {
+ if (path.size() < 3) {
+ continue;
+ }
+
+ // Path represents
+ // v ----related-to--> otherV
+ // In the above case,
+ // path objects get(0) returns vertex v
+ // path objects.get(1) returns edge related-to
+ // path objects.get(2) returns vertex otherV
+ Vertex otherV = path.get(2);
+
+ String bUri;
+ if (otherV.property(AAIProperties.AAI_URI).isPresent()) {
+ bUri = otherV.value(AAIProperties.AAI_URI);
+ } else {
+ continue;
+ }
+ String edgeLabel = path.<Edge>get(1).label();
+
+ Pair<String, String> key = Pair.with(bUri, edgeLabel);
+ if (cousinUriAndLabels.contains(key)) {
+ cousinUriAndLabels.remove(key);
+ } else {
+ String bNodeType;
+ if (otherV.property(AAIProperties.NODE_TYPE).isPresent()) {
+ bNodeType = otherV.property(AAIProperties.NODE_TYPE).value().toString();
+ } else {
+ continue;
+ }
+ EdgeRuleQuery ruleQuery = cousinQueryBuilder.to(bNodeType).label(edgeLabel).build();
+ if (edgeIngestor.hasRule(ruleQuery)) {
+ toRemove.add(path);
+ }
+ }
+
+ }
+
+ Set<Pair<Vertex, String>> toBeCreated = new HashSet<>();
+ for (Pair<String, String> cousinUriAndLabel : cousinUriAndLabels) {
+ Edge e;
+ Vertex cousinVertex;
+ String label = cousinUriAndLabel.getValue1();
+ String cousinUri = cousinUriAndLabel.getValue0();
+ QueryParser parser = engine.getQueryBuilder().createQueryFromURI(URI.create(cousinUri));
List<Vertex> results = parser.getQueryBuilder().toList();
if (results.isEmpty()) {
- final AAIException ex = new AAIException("AAI_6129",
- "Node of type " + parser.getResultType() + ". Could not find object at: " + parser.getUri());
+ final AAIException ex = new AAIException(AAI_6129,
+ "Node of type " + parser.getResultType() + ". Could not find object at: " + parser.getUri());
ex.getTemplateVars().add(parser.getResultType());
ex.getTemplateVars().add(parser.getUri().toString());
throw ex;
@@ -553,38 +901,56 @@ public class DBSerializer {
EdgeRuleQuery.Builder baseQ = new EdgeRuleQuery.Builder(vType, cousinType).label(label);
if (!edgeRules.hasRule(baseQ.build())) {
- throw new AAIException("AAI_6120",
- "No EdgeRule found for passed nodeTypes: "
- + v.property(AAIProperties.NODE_TYPE).value().toString() + ", "
- + cousinVertex.property(AAIProperties.NODE_TYPE).value().toString()
- + (label != null ? (" with label " + label) : "") + ".");
+ throw new AAIException("AAI_6120", String.format(
+ "No EdgeRule found for passed nodeTypes: %s, %s%s.",
+ aNodeType, cousinType, label != null ? (" with label " + label) : ""));
} else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.TREE).build())
- && !edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) {
- throw new AAIException("AAI_6145");
+ && !edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) {
+ throw new AAIException(AAI_6145);
}
e = this.getEdgeBetween(EdgeType.COUSIN, v, cousinVertex, label);
if (e == null) {
- addEdges.add(new Triplet<>(v, cousinVertex, label));
- } else {
- existingEdges.remove(e);
+ toBeCreated.add(Pair.with(cousinVertex, label));
}
}
}
- for (Edge edge : existingEdges) {
- edge.remove();
+ for (Path path : toRemove) {
+ if(isDeltaEventsEnabled) {
+ deltaForEdge(mainUri, path.get(1), DeltaAction.DELETE_REL, DeltaAction.UPDATE);
+ }
+ this.updatedVertexes.putIfAbsent(v, false);
+ this.edgeVertexes.add(path.get(2));
+ path.<Edge>get(1).remove();
}
- for (Triplet<Vertex, Vertex, String> triplet : addEdges) {
+
+ for (Pair<Vertex, String> create : toBeCreated) {
try {
- edgeSer.addEdge(this.engine.asAdmin().getTraversalSource(), triplet.getValue0(), triplet.getValue1(),
- triplet.getValue2());
- } catch (NoEdgeRuleFoundException e) {
- throw new AAIException("AAI_6129", e);
+ Edge e = edgeSer.addEdge(this.engine.asAdmin().getTraversalSource(), v, create.getValue0(), create.getValue1());
+ if (isDeltaEventsEnabled) {
+ deltaForEdge(mainUri, e, DeltaAction.CREATE_REL, DeltaAction.UPDATE);
+ }
+ this.updatedVertexes.putIfAbsent(v, false);
+ this.edgeVertexes.add(create.getValue0());
+ } catch (NoEdgeRuleFoundException ex) {
+ throw new AAIException(AAI_6129, ex);
}
}
+ }
+
+ private void deltaForEdge(String mainUri, Edge edge, DeltaAction edgeAction, DeltaAction mainAction) {
+ RelationshipDelta relationshipDelta = new RelationshipDelta(
+ edgeAction,
+ edge.inVertex().property(AAIProperties.AAI_UUID).value().toString(),
+ edge.outVertex().property(AAIProperties.AAI_UUID).value().toString(),
+ edge.inVertex().property(AAIProperties.AAI_URI).value().toString(),
+ edge.outVertex().property(AAIProperties.AAI_URI).value().toString(),
+ edge.label());
+ edge.properties().forEachRemaining(p -> relationshipDelta.addProp(p.key(), p.value().toString()));
+ addRelationshipDelta(mainUri, relationshipDelta, mainAction);
}
/**
@@ -600,11 +966,9 @@ public class DBSerializer {
Set<String> required = latest.getRequiredProperties();
for (String field : required) {
- String defaultValue = null;
- Object vertexProp = null;
- defaultValue = latest.getPropertyMetadata(field).get(PropertyMetadata.DEFAULT_VALUE);
+ String defaultValue = latest.getPropertyMetadata(field).get(PropertyMetadata.DEFAULT_VALUE);
if (defaultValue != null) {
- vertexProp = v.<Object>property(field).orElse(null);
+ Object vertexProp = v.property(field).orElse(null);
if (vertexProp == null) {
v.property(field, defaultValue);
}
@@ -620,11 +984,7 @@ public class DBSerializer {
* @param v the v
* @param dependentObj the dependent obj
* @return the vertex
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws InstantiationException the instantiation exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws AAIException the AAI exception
* @throws UnsupportedEncodingException the unsupported encoding exception
@@ -633,23 +993,21 @@ public class DBSerializer {
private Vertex reflectDependentVertex(Vertex v, Introspector dependentObj, String requestContext)
throws AAIException, UnsupportedEncodingException {
- // QueryParser p = this.engine.getQueryBuilder().createQueryFromURI(obj.getURI());
- // List<Vertex> items = p.getQuery().toList();
QueryBuilder<Vertex> query = this.engine.getQueryBuilder(v);
query.createEdgeTraversal(EdgeType.TREE, v, dependentObj);
query.createKeyQuery(dependentObj);
List<Vertex> items = query.toList();
- Vertex dependentVertex = null;
+ Vertex dependentVertex;
if (items.size() == 1) {
dependentVertex = items.get(0);
this.verifyResourceVersion("update", dependentObj.getDbName(),
dependentVertex.<String>property(AAIProperties.RESOURCE_VERSION).orElse(null),
- (String) dependentObj.getValue(AAIProperties.RESOURCE_VERSION), (String) dependentObj.getURI());
+ dependentObj.getValue(AAIProperties.RESOURCE_VERSION), dependentObj.getURI());
} else {
this.verifyResourceVersion("create", dependentObj.getDbName(), "",
- (String) dependentObj.getValue(AAIProperties.RESOURCE_VERSION), (String) dependentObj.getURI());
+ dependentObj.getValue(AAIProperties.RESOURCE_VERSION), dependentObj.getURI());
dependentVertex = createNewVertex(dependentObj);
}
@@ -664,11 +1022,7 @@ public class DBSerializer {
* @param child the child
* @param obj the obj
* @return the vertex
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws InstantiationException the instantiation exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws AAIException the AAI exception
* @throws UnsupportedEncodingException the unsupported encoding exception
@@ -699,7 +1053,10 @@ public class DBSerializer {
child.property(AAIProperties.LINKED, true);
}
}
- edgeSer.addTreeEdge(this.engine.asAdmin().getTraversalSource(), parent, child);
+ e = edgeSer.addTreeEdge(this.engine.asAdmin().getTraversalSource(), parent, child);
+ if(isDeltaEventsEnabled) {
+ deltaForEdge(child.property(AAIProperties.AAI_URI).value().toString(), e, DeltaAction.CREATE_REL, DeltaAction.CREATE);
+ }
}
return child;
@@ -724,19 +1081,14 @@ public class DBSerializer {
* @param cleanUp the clean up
* @return the introspector
* @throws AAIException the AAI exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
* @throws SecurityException the security exception
- * @throws InstantiationException the instantiation exception
- * @throws NoSuchMethodException the no such method exception
* @throws UnsupportedEncodingException the unsupported encoding exception
- * @throws MalformedURLException the malformed URL exception
* @throws AAIUnknownObjectException
* @throws URISyntaxException
*/
public Introspector dbToObject(List<Vertex> vertices, final Introspector obj, int depth, boolean nodeOnly,
- String cleanUp) throws UnsupportedEncodingException, AAIException {
+ String cleanUp, boolean isSkipRelatedTo) throws UnsupportedEncodingException, AAIException {
final int internalDepth;
if (depth == Integer.MAX_VALUE) {
internalDepth = depth--;
@@ -747,7 +1099,7 @@ public class DBSerializer {
if (vertices.size() > 1 && !obj.isContainer()) {
dbTimeMsecs += StopWatch.stopIfStarted();
throw new AAIException("AAI_6136",
- "query object mismatch: this object cannot hold multiple items." + obj.getDbName());
+ "query object mismatch: this object cannot hold multiple items." + obj.getDbName());
} else if (obj.isContainer()) {
final List getList;
String listProperty = null;
@@ -758,7 +1110,7 @@ public class DBSerializer {
}
}
final String propertyName = listProperty;
- getList = (List) obj.getValue(listProperty);
+ getList = obj.getValue(listProperty);
/*
* This is an experimental multithreading experiment
@@ -768,28 +1120,15 @@ public class DBSerializer {
List<Future<Object>> futures = new ArrayList<>();
- QueryEngine tgEngine = this.engine.getQueryEngine();
for (Vertex v : vertices) {
-
AaiCallable<Object> task = new AaiCallable<Object>() {
@Override
public Object process() throws UnsupportedEncodingException, AAIException {
Set<Vertex> seen = new HashSet<>();
Introspector childObject;
- try {
- childObject = obj.newIntrospectorInstanceOfNestedProperty(propertyName);
- } catch (AAIUnknownObjectException e) {
- throw e;
- }
- try {
- dbToObject(childObject, v, seen, internalDepth, nodeOnly, cleanUp);
- } catch (UnsupportedEncodingException e) {
- throw e;
- } catch (AAIException e) {
- throw e;
- }
+ childObject = obj.newIntrospectorInstanceOfNestedProperty(propertyName);
+ dbToObject(childObject, v, seen, internalDepth, nodeOnly, cleanUp, isSkipRelatedTo);
return childObject.getUnderlyingObject();
- // getList.add(childObject.getUnderlyingObject());
}
};
futures.add(pool.submit(task));
@@ -798,17 +1137,14 @@ public class DBSerializer {
for (Future<Object> future : futures) {
try {
getList.add(future.get());
- } catch (ExecutionException e) {
- dbTimeMsecs += StopWatch.stopIfStarted();
- throw new AAIException("AAI_4000", e);
- } catch (InterruptedException e) {
+ } catch (ExecutionException | InterruptedException e) {
dbTimeMsecs += StopWatch.stopIfStarted();
throw new AAIException("AAI_4000", e);
}
}
} else if (vertices.size() == 1) {
Set<Vertex> seen = new HashSet<>();
- dbToObject(obj, vertices.get(0), seen, depth, nodeOnly, cleanUp);
+ dbToObject(obj, vertices.get(0), seen, depth, nodeOnly, cleanUp, isSkipRelatedTo);
} else {
// obj = null;
}
@@ -820,26 +1156,62 @@ public class DBSerializer {
/**
* Db to object.
*
+ * @param vertices the vertices
+ * @param obj the obj
+ * @param depth the depth
+ * @param cleanUp the clean up
+ * @return the introspector
+ * @throws AAIException the AAI exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws SecurityException the security exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws AAIUnknownObjectException
+ * @throws URISyntaxException
+ */
+ public Introspector dbToObject(List<Vertex> vertices, final Introspector obj, int depth, boolean nodeOnly,
+ String cleanUp) throws UnsupportedEncodingException, AAIException {
+ return dbToObject(vertices, obj, depth, nodeOnly, cleanUp, false);
+ }
+
+ /**
+ * Db to object.
+ *
* @param obj the obj
* @param v the v
* @param seen the seen
* @param depth the depth
* @param cleanUp the clean up
* @return the introspector
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
* @throws SecurityException the security exception
- * @throws InstantiationException the instantiation exception
- * @throws NoSuchMethodException the no such method exception
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIException the AAI exception
- * @throws MalformedURLException the malformed URL exception
* @throws AAIUnknownObjectException
* @throws URISyntaxException
*/
private Introspector dbToObject(Introspector obj, Vertex v, Set<Vertex> seen, int depth, boolean nodeOnly,
String cleanUp) throws AAIException, UnsupportedEncodingException {
+ return dbToObject(obj, v, seen, depth, nodeOnly, cleanUp, false);
+ }
+
+ /**
+ * Db to object.
+ *
+ * @param obj the obj
+ * @param v the v
+ * @param seen the seen
+ * @param depth the depth
+ * @param cleanUp the clean up
+ * @return the introspector
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws SecurityException the security exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws AAIException the AAI exception
+ * @throws AAIUnknownObjectException
+ * @throws URISyntaxException
+ */
+ private Introspector dbToObject(Introspector obj, Vertex v, Set<Vertex> seen, int depth, boolean nodeOnly,
+ String cleanUp, boolean isSkipRelatedTo) throws AAIException, UnsupportedEncodingException {
if (depth < 0) {
return null;
@@ -850,7 +1222,6 @@ public class DBSerializer {
boolean modified = false;
for (String property : obj.getProperties(PropertyPredicates.isVisible())) {
List<Object> getList = null;
- Vertex[] vertices = null;
if (!(obj.isComplexType(property) || obj.isListType(property))) {
this.copySimpleProperty(property, obj, v);
@@ -869,9 +1240,8 @@ public class DBSerializer {
} else if (property.equals("relationship-list") && !nodeOnly) {
/* relationships need to be handled correctly */
Introspector relationshipList = obj.newIntrospectorInstanceOfProperty(property);
- relationshipList = createRelationshipList(v, relationshipList, cleanUp);
+ relationshipList = createRelationshipList(v, relationshipList, cleanUp, isSkipRelatedTo);
if (relationshipList != null) {
- modified = true;
obj.setValue(property, relationshipList.getUnderlyingObject());
modified = true;
}
@@ -890,42 +1260,39 @@ public class DBSerializer {
try {
rule = edgeRules.getRule(
- new EdgeRuleQuery.Builder(vType, childDbName).edgeType(EdgeType.TREE).build());
+ new EdgeRuleQuery.Builder(vType, childDbName).edgeType(EdgeType.TREE).build());
} catch (EdgeRuleNotFoundException e) {
throw new NoEdgeRuleFoundException(e);
} catch (AmbiguousRuleChoiceException e) {
throw new MultipleEdgeRuleFoundException(e);
}
if (!rule.getContains().equals(AAIDirection.NONE.toString())) {
- // vertices = this.queryEngine.findRelatedVertices(v, Direction.OUT, rule.getLabel(),
- // childDbName);
+
Direction ruleDirection = rule.getDirection();
- Iterator<Vertex> itr = v.vertices(ruleDirection, rule.getLabel());
- List<Vertex> verticesList = (List<Vertex>) IteratorUtils.toList(itr);
- itr = verticesList.stream().filter(item -> {
- return item.property(AAIProperties.NODE_TYPE).orElse("").equals(childDbName);
- }).iterator();
- if (itr.hasNext()) {
- getList = (List<Object>) obj.getValue(property);
+ List<Vertex> verticesList = new ArrayList<>();
+ v.vertices(ruleDirection, rule.getLabel()).forEachRemaining(vertex -> {
+ if (vertex.property(AAIProperties.NODE_TYPE).orElse("").equals(childDbName)) {
+ verticesList.add(vertex);
+ }
+ });
+ if (!verticesList.isEmpty()) {
+ getList = obj.getValue(property);
}
int processed = 0;
- int removed = 0;
- while (itr.hasNext()) {
- Vertex childVertex = itr.next();
+ for (Vertex childVertex : verticesList) {
if (!seen.contains(childVertex)) {
Introspector argumentObject = obj.newIntrospectorInstanceOfNestedProperty(property);
Object result =
- dbToObject(argumentObject, childVertex, seen, depth, nodeOnly, cleanUp);
+ dbToObject(argumentObject, childVertex, seen, depth, nodeOnly, cleanUp, isSkipRelatedTo);
if (result != null) {
getList.add(argumentObject.getUnderlyingObject());
}
processed++;
} else {
- removed++;
LOGGER.warn("Cycle found while serializing vertex id={}",
- childVertex.id().toString());
+ childVertex.id().toString());
}
}
if (processed == 0) {
@@ -943,11 +1310,8 @@ public class DBSerializer {
getList.addAll(temp);
modified = true;
}
-
}
-
}
-
}
}
@@ -969,27 +1333,26 @@ public class DBSerializer {
Introspector obj = this.latestLoader.introspectorFromName(nodeType);
Set<Vertex> seen = new HashSet<>();
int depth = 0;
- String cleanUp = "false";
- boolean nodeOnly = true;
StopWatch.conditionalStart();
- this.dbToObject(obj, v, seen, depth, nodeOnly, cleanUp);
+ this.dbToObject(obj, v, seen, depth, false, FALSE);
dbTimeMsecs += StopWatch.stopIfStarted();
return obj;
}
public Introspector getLatestVersionView(Vertex v) throws AAIException, UnsupportedEncodingException {
+ return getLatestVersionView(v, AAIProperties.MAXIMUM_DEPTH);
+ }
+
+ public Introspector getLatestVersionView(Vertex v, int depth) throws AAIException, UnsupportedEncodingException {
String nodeType = v.<String>property(AAIProperties.NODE_TYPE).orElse(null);
if (nodeType == null) {
throw new AAIException("AAI_6143");
}
Introspector obj = this.latestLoader.introspectorFromName(nodeType);
Set<Vertex> seen = new HashSet<>();
- int depth = AAIProperties.MAXIMUM_DEPTH;
- String cleanUp = "false";
- boolean nodeOnly = false;
StopWatch.conditionalStart();
- this.dbToObject(obj, v, seen, depth, nodeOnly, cleanUp);
+ this.dbToObject(obj, v, seen, depth, false, FALSE);
dbTimeMsecs += StopWatch.stopIfStarted();
return obj;
}
@@ -1000,11 +1363,7 @@ public class DBSerializer {
* @param property the property
* @param obj the obj
* @param v the v
- * @throws InstantiationException the instantiation exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
*/
private void copySimpleProperty(String property, Introspector obj, Vertex v) {
@@ -1014,65 +1373,22 @@ public class DBSerializer {
}
}
- /**
- * Load the introspector from the hashmap for the given property key
- *
- * @param property - vertex property
- * @param obj - introspector object representing the vertex
- * @param hashMap - Containing a list of pre-fetched properties for a given vertex
- */
- private void copySimplePropertyFromHashMap(String property, Introspector obj, Map<String, Object> hashMap) {
-
- final Map<PropertyMetadata, String> metadata = obj.getPropertyMetadata(property);
- String dbPropertyName = property;
-
- if (metadata.containsKey(PropertyMetadata.DB_ALIAS)) {
- dbPropertyName = metadata.get(PropertyMetadata.DB_ALIAS);
- }
-
- final Object temp = hashMap.getOrDefault(dbPropertyName, null);
-
- if (temp != null) {
- obj.setValue(property, temp);
- }
- }
-
- /**
- * Simple db to object.
- *
- * @param obj the obj
- * @param v the v
- * @throws InstantiationException the instantiation exception
- * @throws IllegalAccessException the illegal access exception
- * @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws NoSuchMethodException the no such method exception
- * @throws SecurityException the security exception
- */
- private void simpleDbToObject(Introspector obj, Vertex v) {
- for (String key : obj.getProperties()) {
- this.copySimpleProperty(key, obj, v);
- }
- }
-
public Map<String, Object> convertVertexToHashMap(Introspector obj, Vertex v) {
- long startTime = System.currentTimeMillis();
-
Set<String> simpleProperties = obj.getSimpleProperties(PropertyPredicates.isVisible());
String[] simplePropsArray = new String[simpleProperties.size()];
simplePropsArray = simpleProperties.toArray(simplePropsArray);
Map<String, Object> simplePropsHashMap = new HashMap<>(simplePropsArray.length * 2);
- v.properties(simplePropsArray).forEachRemaining((vp) -> simplePropsHashMap.put(vp.key(), vp.value()));
+ v.properties(simplePropsArray).forEachRemaining(vp -> simplePropsHashMap.put(vp.key(), vp.value()));
return simplePropsHashMap;
}
- public Introspector dbToRelationshipObject(Vertex v) throws UnsupportedEncodingException, AAIException {
+ public Introspector dbToRelationshipObject(Vertex v, boolean isSkipRelatedTo) throws UnsupportedEncodingException, AAIException {
Introspector relationshipList = this.latestLoader.introspectorFromName("relationship-list");
- relationshipList = createRelationshipList(v, relationshipList, "false");
+ relationshipList = createRelationshipList(v, relationshipList, FALSE, isSkipRelatedTo);
return relationshipList;
}
@@ -1083,136 +1399,96 @@ public class DBSerializer {
* @param obj the obj
* @param cleanUp the clean up
* @return the object
- * @throws InstantiationException the instantiation exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIException the AAI exception
- * @throws MalformedURLException the malformed URL exception
* @throws URISyntaxException
*/
private Introspector createRelationshipList(Vertex v, Introspector obj, String cleanUp)
throws UnsupportedEncodingException, AAIException {
+ // default boolean value for isSkipRelatedTo is false
+ return createRelationshipList(v, obj, cleanUp, false);
+ }
- String[] cousinRules = new String[0];
-
- try {
- cousinRules = edgeRules.retrieveCachedCousinLabels(obj.getDbName());
- } catch (ExecutionException e) {
- LOGGER.warn("Encountered an execution exception while retrieving labels for the node type {} using cached",
- obj.getDbName(), e);
- }
-
- List<Vertex> cousins = null;
- if (cousinRules != null && cousinRules.length != 0) {
- cousins = this.engine.getQueryEngine().findCousinVertices(v, cousinRules);
- } else {
- cousins = this.engine.getQueryEngine().findCousinVertices(v);
- }
+ /**
+ * Creates the relationship list.
+ *
+ * @param v the v
+ * @param obj the obj
+ * @param cleanUp the clean up
+ * @param isSkipRelatedTo to determine adding related-to-property in response
+ * @return the object
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws SecurityException the security exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws AAIException the AAI exception
+ * @throws URISyntaxException
+ */
+ private Introspector createRelationshipList(Vertex v, Introspector obj, String cleanUp, boolean isSkipRelatedTo)
+ throws UnsupportedEncodingException, AAIException {
- List<Object> relationshipObjList = obj.getValue("relationship");
+ List<Object> relationshipObjList = obj.getValue(RELATIONSHIP);
VertexProperty nodeTypeProperty = v.property(AAIProperties.NODE_TYPE);
if (!nodeTypeProperty.isPresent()) {
- LoggingContext.responseDescription(MISSING_REQUIRED_NODE_PROPERTY);
LOGGER.warn("Not processing the vertex {} because its missing required property aai-node-type", v.id());
- LoggingContext.remove(LoggingContext.LoggingField.RESPONSE_DESCRIPTION.toString());
return null;
}
- String aNodeType = nodeTypeProperty.value().toString();
+ List<Path> paths = this.engine.getQueryEngine().findCousinsAsPath(v);
- TypeAlphabetizer alphabetizer = new TypeAlphabetizer();
+ String aNodeType = v.property(AAIProperties.NODE_TYPE).value().toString();
EdgeIngestor edgeIngestor = SpringContextAware.getBean(EdgeIngestor.class);
- Set<String> keysWithMultipleLabels = edgeIngestor.getMultipleLabelKeys();
-
- // For the given vertex, find all the cousins
- // For each cousin retrieve the node type and then
- // check if the version is greater than the edge label version
- // meaning is the current version equal to greater than the version
- // where we introduced the edge labels into the relationship payload
- // If it is, then we check if the edge key there are multiple labels
- // If there are multiple labels, then we need to go to the database
- // to retrieve the labels between itself and cousin vertex
- // If there is only single label between the edge a and b, then
- // we can retrieve what that is without going to the database
- // from using the edge rules json and get the edge rule out of it
- EdgeRuleQuery.Builder queryBuilder = new EdgeRuleQuery.Builder(aNodeType);
- for (Vertex cousin : cousins) {
- VertexProperty vertexProperty = cousin.property(AAIProperties.NODE_TYPE);
- String bNodeType = null;
- if (vertexProperty.isPresent()) {
- bNodeType = cousin.property(AAIProperties.NODE_TYPE).value().toString();
- } else {
- // If the vertex is missing the aai-node-type
- // Then its either a bad vertex or its in the process
- // of getting deleted so we should ignore these vertexes
- LoggingContext.responseDescription(MISSING_REQUIRED_NODE_PROPERTY);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("For the vertex {}, unable to retrieve the aai-node-type", v.id().toString());
- } else {
- LOGGER.info("Unable to retrieve the aai-node-type for vertex, for more info enable debug log");
- }
- LoggingContext.remove(LoggingContext.LoggingField.RESPONSE_DESCRIPTION.toString());
+
+ EdgeRuleQuery.Builder queryBuilder = new EdgeRuleQuery.Builder(aNodeType)
+ .edgeType(EdgeType.COUSIN)
+ .version(obj.getVersion());
+
+ for (Path path : paths){
+ if(path.size() < 3){
continue;
}
- if (obj.getVersion().compareTo(schemaVersions.getEdgeLabelVersion()) >= 0) {
- String edgeKey = alphabetizer.buildAlphabetizedKey(aNodeType, bNodeType);
- if (keysWithMultipleLabels.contains(edgeKey)) {
- List<String> edgeLabels = this.getEdgeLabelsBetween(EdgeType.COUSIN, v, cousin);
- for (String edgeLabel : edgeLabels) {
- Introspector relationshipObj = obj.newIntrospectorInstanceOfNestedProperty("relationship");
- Object result = processEdgeRelationship(relationshipObj, cousin, cleanUp, edgeLabel);
- if (result != null) {
- relationshipObjList.add(result);
- }
- }
- } else {
- EdgeRule edgeRule = null;
+ // Path represents
+ // v ----related-to--> otherV
+ // In the above case,
+ // path objects get(0) returns vertex v
+ // path objects.get(1) returns edge related-to
+ // path objects.get(2) returns vertex otherV
+ Edge edge = path.get(1);
+ Vertex otherV= path.get(2);
+
+ // TODO: Come back and revisit this code
+ // Create a query based on the a nodetype and b nodetype
+ // which is also a cousin edge and ensure the version
+ // is used properly so for example in order to be backwards
+ // compatible if we had allowed a edge between a and b
+ // in a previous release and we decided to remove it from
+ // the edge rules in the future we can display the edge
+ // only for the older apis and the new apis if the edge rule
+ // is removed will not be seen in the newer version of the API
- // Create a query based on the a nodetype and b nodetype
- // which is also a cousin edge and ensure the version
- // is used properly so for example in order to be backwards
- // compatible if we had allowed a edge between a and b
- // in a previous release and we decided to remove it from
- // the edge rules in the future we can display the edge
- // only for the older apis and the new apis if the edge rule
- // is removed will not be seen in the newer version of the API
+ String bNodeType = null;
+ if (otherV.property(AAIProperties.NODE_TYPE).isPresent()) {
+ bNodeType = otherV.property(AAIProperties.NODE_TYPE).value().toString();
+ } else {
+ continue;
+ }
- EdgeRuleQuery ruleQuery =
- queryBuilder.to(bNodeType).edgeType(EdgeType.COUSIN).version(obj.getVersion()).build();
+ String edgeLabel = edge.label();
+ EdgeRuleQuery ruleQuery = queryBuilder.to(bNodeType).label(edgeLabel).build();
- try {
- edgeRule = edgeIngestor.getRule(ruleQuery);
- } catch (EdgeRuleNotFoundException e) {
- LOGGER.warn(
- "Caught an edge rule not found exception for query {}, {},"
- + " it could be the edge rule is no longer valid for the existing edge in db",
- ruleQuery, LogFormatTools.getStackTop(e));
- continue;
- } catch (AmbiguousRuleChoiceException e) {
- LOGGER.error("Caught an ambiguous rule not found exception for query {}, {}", ruleQuery,
- LogFormatTools.getStackTop(e));
- continue;
- }
+ if(!edgeIngestor.hasRule(ruleQuery)){
+ LOGGER.debug( "Caught an edge rule not found for query {}", ruleQuery);
+ continue;
+ }
- Introspector relationshipObj = obj.newIntrospectorInstanceOfNestedProperty("relationship");
- Object result = processEdgeRelationship(relationshipObj, cousin, cleanUp, edgeRule.getLabel());
- if (result != null) {
- relationshipObjList.add(result);
- }
- }
- } else {
- Introspector relationshipObj = obj.newIntrospectorInstanceOfNestedProperty("relationship");
- Object result = processEdgeRelationship(relationshipObj, cousin, cleanUp, null);
- if (result != null) {
- relationshipObjList.add(result);
- }
+ Introspector relationshipObj = obj.newIntrospectorInstanceOfNestedProperty(RELATIONSHIP);
+ Object result = processEdgeRelationship(relationshipObj, otherV, cleanUp, edgeLabel, isSkipRelatedTo);
+ if (result != null) {
+ relationshipObjList.add(result);
}
}
@@ -1228,23 +1504,17 @@ public class DBSerializer {
* Process edge relationship.
*
* @param relationshipObj the relationship obj
- * @param edge the edge
+ * @param edgeLabel the edge's label
* @param cleanUp the clean up
* @return the object
- * @throws InstantiationException the instantiation exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws UnsupportedEncodingException the unsupported encoding exception
- * @throws AAIException the AAI exception
- * @throws MalformedURLException the malformed URL exception
* @throws AAIUnknownObjectException
* @throws URISyntaxException
*/
private Object processEdgeRelationship(Introspector relationshipObj, Vertex cousin, String cleanUp,
- String edgeLabel) throws UnsupportedEncodingException, AAIUnknownObjectException {
+ String edgeLabel, boolean isSkipRelatedTo) throws UnsupportedEncodingException, AAIUnknownObjectException {
VertexProperty aaiUriProperty = cousin.property("aai-uri");
@@ -1254,8 +1524,8 @@ public class DBSerializer {
URI uri = UriBuilder.fromUri(aaiUriProperty.value().toString()).build();
- URIToRelationshipObject uriParser = null;
- Introspector result = null;
+ URIToRelationshipObject uriParser;
+ Introspector result;
try {
uriParser = new URIToRelationshipObject(relationshipObj.getLoader(), uri, this.baseURL);
result = uriParser.getResult();
@@ -1269,13 +1539,13 @@ public class DBSerializer {
if (cousinVertexNodeType.isPresent()) {
String cousinType = cousinVertexNodeType.value().toString();
- if (namedPropNodes.contains(cousinType)) {
+ if (namedPropNodes.contains(cousinType) && !isSkipRelatedTo) {
this.addRelatedToProperty(result, cousin, cousinType);
}
}
- if (edgeLabel != null && result.hasProperty("relationship-label")) {
- result.setValue("relationship-label", edgeLabel);
+ if (edgeLabel != null && result.hasProperty(RELATIONSHIP_LABEL)) {
+ result.setValue(RELATIONSHIP_LABEL, edgeLabel);
}
return result.getUnderlyingObject();
@@ -1286,11 +1556,7 @@ public class DBSerializer {
*
* @param v the v
* @return the URI for vertex
- * @throws InstantiationException the instantiation exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIUnknownObjectException
@@ -1300,7 +1566,7 @@ public class DBSerializer {
return getURIForVertex(v, false);
}
- public URI getURIForVertex(Vertex v, boolean overwrite) throws UnsupportedEncodingException {
+ public URI getURIForVertex(Vertex v, boolean overwrite) {
URI uri = UriBuilder.fromPath("/unknown-uri").build();
String aaiUri = v.<String>property(AAIProperties.AAI_URI).orElse(null);
@@ -1312,28 +1578,11 @@ public class DBSerializer {
return uri;
}
- /**
- * Gets the URI from list.
- *
- * @param list the list
- * @return the URI from list
- * @throws UnsupportedEncodingException the unsupported encoding exception
- */
- private URI getURIFromList(List<Introspector> list) throws UnsupportedEncodingException {
- String uri = "";
- StringBuilder sb = new StringBuilder();
- for (Introspector i : list) {
- sb.insert(0, i.getURI());
- }
-
- uri = sb.toString();
- return UriBuilder.fromPath(uri).build();
- }
public void addRelatedToProperty(Introspector relationship, Vertex cousinVertex, String cousinType)
throws AAIUnknownObjectException {
- Introspector obj = null;
+ Introspector obj;
try {
obj = this.loader.introspectorFromName(cousinType);
@@ -1360,7 +1609,7 @@ public class DBSerializer {
}
if (!relatedToProperties.isEmpty()) {
- List relatedToList = (List) relationship.getValue("related-to-property");
+ List<Object> relatedToList = relationship.getValue("related-to-property");
for (Introspector introspector : relatedToProperties) {
relatedToList.add(introspector.getUnderlyingObject());
}
@@ -1389,22 +1638,22 @@ public class DBSerializer {
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIException the AAI exception
*/
- public boolean createEdge(Introspector relationship, Vertex inputVertex)
+ public Vertex createEdge(Introspector relationship, Vertex inputVertex)
throws UnsupportedEncodingException, AAIException {
- Vertex relatedVertex = null;
+ Vertex relatedVertex;
StopWatch.conditionalStart();
QueryParser parser = engine.getQueryBuilder().createQueryFromRelationship(relationship);
String label = null;
- if (relationship.hasProperty("relationship-label")) {
- label = relationship.getValue("relationship-label");
+ if (relationship.hasProperty(RELATIONSHIP_LABEL)) {
+ label = relationship.getValue(RELATIONSHIP_LABEL);
}
List<Vertex> results = parser.getQueryBuilder().toList();
if (results.isEmpty()) {
dbTimeMsecs += StopWatch.stopIfStarted();
- AAIException e = new AAIException("AAI_6129",
+ AAIException e = new AAIException(AAI_6129,
"Node of type " + parser.getResultType() + ". Could not find object at: " + parser.getUri());
e.getTemplateVars().add(parser.getResultType());
e.getTemplateVars().add(parser.getUri().toString());
@@ -1420,7 +1669,10 @@ public class DBSerializer {
try {
e = this.getEdgeBetween(EdgeType.COUSIN, inputVertex, relatedVertex, label);
if (e == null) {
- edgeSer.addEdge(this.engine.asAdmin().getTraversalSource(), inputVertex, relatedVertex, label);
+ e = edgeSer.addEdge(this.engine.asAdmin().getTraversalSource(), inputVertex, relatedVertex, label);
+ if(isDeltaEventsEnabled) {
+ deltaForEdge(inputVertex.property(AAIProperties.AAI_URI).value().toString(), e, DeltaAction.CREATE_REL, DeltaAction.UPDATE);
+ }
} else {
// attempted to link two vertexes already linked
}
@@ -1430,7 +1682,7 @@ public class DBSerializer {
}
dbTimeMsecs += StopWatch.stopIfStarted();
- return true;
+ return relatedVertex;
}
/**
@@ -1439,8 +1691,6 @@ public class DBSerializer {
* @param aVertex the out vertex
* @param bVertex the in vertex
* @return the edges between
- * @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
*/
private Edge getEdgeBetweenWithLabel(EdgeType type, Vertex aVertex, Vertex bVertex, EdgeRule edgeRule) {
@@ -1476,42 +1726,11 @@ public class DBSerializer {
}
/**
- * Gets all the edges between of the type.
- *
- * @param aVertex the out vertex
- * @param bVertex the in vertex
- * @return the edges between
- * @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
- */
- private List<Edge> getEdgesBetween(EdgeType type, Vertex aVertex, Vertex bVertex) {
-
- List<Edge> result = new ArrayList<>();
-
- if (bVertex != null) {
- GraphTraversal<Vertex, Edge> findEdgesBetween = null;
- findEdgesBetween = this.engine.asAdmin().getTraversalSource().V(aVertex).bothE();
- if (EdgeType.TREE.equals(type)) {
- findEdgesBetween = findEdgesBetween.not(__.or(__.has(EdgeProperty.CONTAINS.toString(), "NONE"),
- __.has(EdgeField.PRIVATE.toString(), true)));
- } else {
- findEdgesBetween = findEdgesBetween.has(EdgeProperty.CONTAINS.toString(), "NONE")
- .not(__.has(EdgeField.PRIVATE.toString(), true));
- }
- findEdgesBetween = findEdgesBetween.filter(__.otherV().hasId(bVertex.id()));
- result = findEdgesBetween.toList();
- }
-
- return result;
- }
-
- /**
* Gets all the edges string between of the type.
*
* @param aVertex the out vertex
* @param bVertex the in vertex
* @return the edges between
- * @throws AAIException the AAI exception
* @throws NoEdgeRuleFoundException
*/
private List<String> getEdgeLabelsBetween(EdgeType type, Vertex aVertex, Vertex bVertex) {
@@ -1535,30 +1754,6 @@ public class DBSerializer {
}
/**
- * Gets all the edges string between of the type.
- *
- * @param aVertex the out vertex
- * @param bVertex the in vertex
- * @return the edges between
- * @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
- */
- private Long getEdgeLabelsCount(Vertex aVertex, Vertex bVertex) {
-
- Long result = null;
-
- if (bVertex != null) {
- GraphTraversal<Vertex, Edge> findEdgesBetween = null;
- findEdgesBetween = this.engine.asAdmin().getTraversalSource().V(aVertex).bothE();
- findEdgesBetween = findEdgesBetween.has(EdgeProperty.CONTAINS.toString(), "NONE")
- .not(__.has(EdgeField.PRIVATE.toString(), true));
- findEdgesBetween = findEdgesBetween.filter(__.otherV().hasId(bVertex.id()));
- result = findEdgesBetween.count().next();
- }
- return result;
- }
-
- /**
* Gets all the edges between the vertexes with the label and type.
*
* @param aVertex the out vertex
@@ -1628,23 +1823,23 @@ public class DBSerializer {
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIException the AAI exception
*/
- public boolean deleteEdge(Introspector relationship, Vertex inputVertex)
+ public Optional<Vertex> deleteEdge(Introspector relationship, Vertex inputVertex)
throws UnsupportedEncodingException, AAIException {
- Vertex relatedVertex = null;
+ Vertex relatedVertex;
StopWatch.conditionalStart();
QueryParser parser = engine.getQueryBuilder().createQueryFromRelationship(relationship);
List<Vertex> results = parser.getQueryBuilder().toList();
String label = null;
- if (relationship.hasProperty("relationship-label")) {
- label = relationship.getValue("relationship-label");
+ if (relationship.hasProperty(RELATIONSHIP_LABEL)) {
+ label = relationship.getValue(RELATIONSHIP_LABEL);
}
if (results.isEmpty()) {
dbTimeMsecs += StopWatch.stopIfStarted();
- return false;
+ return Optional.empty();
}
relatedVertex = results.get(0);
@@ -1653,29 +1848,19 @@ public class DBSerializer {
edge = this.getEdgeBetween(EdgeType.COUSIN, inputVertex, relatedVertex, label);
} catch (NoEdgeRuleFoundException e) {
dbTimeMsecs += StopWatch.stopIfStarted();
- throw new AAIException("AAI_6129", e);
+ throw new AAIException(AAI_6129, e);
}
if (edge != null) {
+ if(isDeltaEventsEnabled) {
+ String mainUri = inputVertex.property(AAIProperties.AAI_URI).value().toString();
+ deltaForEdge(mainUri, edge, DeltaAction.DELETE_REL, DeltaAction.UPDATE);
+ }
edge.remove();
dbTimeMsecs += StopWatch.stopIfStarted();
- return true;
+ return Optional.of(relatedVertex);
} else {
dbTimeMsecs += StopWatch.stopIfStarted();
- return false;
- }
-
- }
-
- /**
- * Delete items with traversal.
- *
- * @param vertexes the vertexes
- * @throws IllegalStateException the illegal state exception
- */
- public void deleteItemsWithTraversal(List<Vertex> vertexes) throws IllegalStateException {
-
- for (Vertex v : vertexes) {
- deleteWithTraversal(v);
+ return Optional.empty();
}
}
@@ -1688,12 +1873,7 @@ public class DBSerializer {
public void deleteWithTraversal(Vertex startVertex) {
StopWatch.conditionalStart();
List<Vertex> results = this.engine.getQueryEngine().findDeletable(startVertex);
-
- for (Vertex v : results) {
- LOGGER.debug("Removing vertex {} with label {}", v.id(), v.label());
- v.remove();
- }
- dbTimeMsecs += StopWatch.stopIfStarted();
+ this.delete(results);
}
/**
@@ -1720,12 +1900,47 @@ public class DBSerializer {
for (Vertex v : vertices) {
LOGGER.debug("Removing vertex {} with label {}", v.id(), v.label());
+ if(isDeltaEventsEnabled) {
+ deltaForVertexDelete(v);
+ }
+ //add the cousin vertexes of v to have their resource-version updated and notified on.
+ v.edges(Direction.BOTH)
+ .forEachRemaining(e -> {
+ if (e.property(EdgeProperty.CONTAINS.toString()).isPresent()
+ && AAIDirection.NONE.toString().equals(e.<String>value(EdgeProperty.CONTAINS.toString()))) {
+ e.bothVertices().forEachRemaining(cousinV -> {
+ if (!v.equals(cousinV)) {
+ edgeVertexes.add(cousinV);
+ }
+ });
+ }
+ });
+
+ //if somewhere along the way v was added to the sets tracking the what is to be updated/notified on
+ // it should be removed from them as v is to be deleted
+ edgeVertexes.remove(v);
+ updatedVertexes.remove(v);
v.remove();
}
dbTimeMsecs += StopWatch.stopIfStarted();
}
+ private void deltaForVertexDelete(Vertex v) {
+ String aaiUri = v.property(AAIProperties.AAI_URI).value().toString();
+ v.keys().forEach(k -> {
+ List<Object> list = new ArrayList<>();
+ v.properties(k).forEachRemaining(vp -> list.add(vp.value()));
+ if (list.size() == 1) {
+ addPropDelta(aaiUri, k, PropertyDeltaFactory.getDelta(DeltaAction.DELETE, list.get(0)), DeltaAction.DELETE);
+ } else {
+ addPropDelta(aaiUri, k, PropertyDeltaFactory.getDelta(DeltaAction.DELETE, list), DeltaAction.DELETE);
+ }
+
+ });
+ v.edges(Direction.BOTH).forEachRemaining(e -> deltaForEdge(aaiUri, e, DeltaAction.DELETE, DeltaAction.DELETE));
+ }
+
/**
* Delete.
*
@@ -1741,7 +1956,7 @@ public class DBSerializer {
boolean result = verifyDeleteSemantics(v, resourceVersion, enableResourceVersion);
/*
* The reason why I want to call PreventDeleteSemantics second time is to catch the prevent-deletes in a chain
- * These are far-fewer than seeing a prevnt-delete on the vertex to be deleted
+ * These are far-fewer than seeing a prevent-delete on the vertex to be deleted
* So its better to make these in 2 steps
*/
if (result && !deletableVertices.isEmpty()) {
@@ -1756,7 +1971,6 @@ public class DBSerializer {
}
}
-
}
/**
@@ -1782,7 +1996,6 @@ public class DBSerializer {
}
}
-
}
/**
@@ -1795,15 +2008,14 @@ public class DBSerializer {
*/
private boolean verifyDeleteSemantics(Vertex vertex, String resourceVersion, boolean enableResourceVersion)
throws AAIException {
- boolean result = true;
- String nodeType = "";
- String errorDetail = " unknown delete semantic found";
- String aaiExceptionCode = "";
+ boolean result;
+ String nodeType;
nodeType = vertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
- if (enableResourceVersion && !this.verifyResourceVersion("delete", nodeType,
- vertex.<String>property(AAIProperties.RESOURCE_VERSION).orElse(null), resourceVersion, nodeType)) {
+ if (enableResourceVersion) {
+ this.verifyResourceVersion("delete", nodeType,
+ vertex.<String>property(AAIProperties.RESOURCE_VERSION).orElse(null), resourceVersion, nodeType);
}
- List<Vertex> vertices = new ArrayList<Vertex>();
+ List<Vertex> vertices = new ArrayList<>();
vertices.add(vertex);
result = verifyPreventDeleteSemantics(vertices);
@@ -1819,7 +2031,6 @@ public class DBSerializer {
*/
private boolean verifyPreventDeleteSemantics(List<Vertex> vertices) throws AAIException {
boolean result = true;
- String nodeType = "";
String errorDetail = " unknown delete semantic found";
String aaiExceptionCode = "";
@@ -1987,6 +2198,35 @@ public class DBSerializer {
/**
* Db to object With Filters
* This is for a one-time run with Tenant Isloation to only filter relationships
+ *
+ * @param obj the obj
+ * @param v the vertex from the graph
+ * @param depth the depth
+ * @param nodeOnly specify if to exclude relationships or not
+ * @param filterCousinNodes
+ * @return the introspector
+ * @throws AAIException the AAI exception
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws SecurityException the security exception
+ * @throws InstantiationException the instantiation exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ * @throws MalformedURLException the malformed URL exception
+ * @throws AAIUnknownObjectException
+ * @throws URISyntaxException
+ */
+ public Introspector dbToObjectWithFilters(Introspector obj, Vertex v, Set<Vertex> seen, int depth, boolean nodeOnly,
+ List<String> filterCousinNodes, List<String> filterParentNodes)
+ throws AAIException, UnsupportedEncodingException {
+ return dbToObjectWithFilters(obj, v, seen, depth, nodeOnly,
+ filterCousinNodes, filterParentNodes, false);
+ }
+
+ /**
+ * Db to object With Filters
+ * This is for a one-time run with Tenant Isloation to only filter relationships
* TODO: Chnage the original dbToObject to take filter parent/cousins
*
* @param obj the obj
@@ -1994,6 +2234,7 @@ public class DBSerializer {
* @param depth the depth
* @param nodeOnly specify if to exclude relationships or not
* @param filterCousinNodes
+ * @param isSkipRelatedTo determine to incorporated related-to-property data
* @return the introspector
* @throws AAIException the AAI exception
* @throws IllegalAccessException the illegal access exception
@@ -2009,9 +2250,9 @@ public class DBSerializer {
*/
// TODO - See if you can merge the 2 dbToObjectWithFilters
public Introspector dbToObjectWithFilters(Introspector obj, Vertex v, Set<Vertex> seen, int depth, boolean nodeOnly,
- List<String> filterCousinNodes, List<String> filterParentNodes)
+ List<String> filterCousinNodes, List<String> filterParentNodes, boolean isSkipRelatedTo)
throws AAIException, UnsupportedEncodingException {
- String cleanUp = "false";
+ String cleanUp = FALSE;
if (depth < 0) {
return null;
}
@@ -2020,7 +2261,6 @@ public class DBSerializer {
boolean modified = false;
for (String property : obj.getProperties(PropertyPredicates.isVisible())) {
List<Object> getList = null;
- Vertex[] vertices = null;
if (!(obj.isComplexType(property) || obj.isListType(property))) {
this.copySimpleProperty(property, obj, v);
@@ -2032,7 +2272,7 @@ public class DBSerializer {
if (!property.equals("relationship-list") && depth >= 0) {
Introspector argumentObject = obj.newIntrospectorInstanceOfProperty(property);
Object result = dbToObjectWithFilters(argumentObject, v, seen, depth + 1, nodeOnly,
- filterCousinNodes, filterParentNodes);
+ filterCousinNodes, filterParentNodes, isSkipRelatedTo);
if (result != null) {
obj.setValue(property, argumentObject.getUnderlyingObject());
modified = true;
@@ -2041,9 +2281,8 @@ public class DBSerializer {
/* relationships need to be handled correctly */
Introspector relationshipList = obj.newIntrospectorInstanceOfProperty(property);
relationshipList =
- createFilteredRelationshipList(v, relationshipList, cleanUp, filterCousinNodes);
+ createFilteredRelationshipList(v, relationshipList, cleanUp, filterCousinNodes, isSkipRelatedTo);
if (relationshipList != null) {
- modified = true;
obj.setValue(property, relationshipList.getUnderlyingObject());
modified = true;
}
@@ -2060,7 +2299,7 @@ public class DBSerializer {
String vType = v.<String>property(AAIProperties.NODE_TYPE).orElse(null);
EdgeRule rule;
- boolean isthisParentRequired =
+ boolean isThisParentRequired =
filterParentNodes.parallelStream().anyMatch(childDbName::contains);
EdgeRuleQuery q = new EdgeRuleQuery.Builder(vType, childDbName).edgeType(EdgeType.TREE).build();
@@ -2072,34 +2311,30 @@ public class DBSerializer {
} catch (AmbiguousRuleChoiceException e) {
throw new MultipleEdgeRuleFoundException(e);
}
- if (!rule.getContains().equals(AAIDirection.NONE.toString()) && isthisParentRequired) {
- // vertices = this.queryEngine.findRelatedVertices(v, Direction.OUT, rule.getLabel(),
- // childDbName);
+ if (!rule.getContains().equals(AAIDirection.NONE.toString()) && isThisParentRequired) {
Direction ruleDirection = rule.getDirection();
- Iterator<Vertex> itr = v.vertices(ruleDirection, rule.getLabel());
- List<Vertex> verticesList = (List<Vertex>) IteratorUtils.toList(itr);
- itr = verticesList.stream().filter(item -> {
- return item.property(AAIProperties.NODE_TYPE).orElse("").equals(childDbName);
- }).iterator();
- if (itr.hasNext()) {
- getList = (List<Object>) obj.getValue(property);
+ List<Vertex> verticesList = new ArrayList<>();
+ v.vertices(ruleDirection, rule.getLabel()).forEachRemaining(vertex -> {
+ if (vertex.property(AAIProperties.NODE_TYPE).orElse("").equals(childDbName)) {
+ verticesList.add(vertex);
+ }
+ });
+ if (!verticesList.isEmpty()) {
+ getList = obj.getValue(property);
}
int processed = 0;
- int removed = 0;
- while (itr.hasNext()) {
- Vertex childVertex = itr.next();
+ for (Vertex childVertex : verticesList) {
if (!seen.contains(childVertex)) {
Introspector argumentObject = obj.newIntrospectorInstanceOfNestedProperty(property);
Object result = dbToObjectWithFilters(argumentObject, childVertex, seen, depth,
- nodeOnly, filterCousinNodes, filterParentNodes);
+ nodeOnly, filterCousinNodes, filterParentNodes, isSkipRelatedTo);
if (result != null) {
getList.add(argumentObject.getUnderlyingObject());
}
processed++;
} else {
- removed++;
LOGGER.warn("Cycle found while serializing vertex id={}",
childVertex.id().toString());
}
@@ -2115,7 +2350,7 @@ public class DBSerializer {
} else if (obj.isSimpleGenericType(property)) {
List<Object> temp = this.engine.getListProperty(v, property);
if (temp != null) {
- getList = (List<Object>) obj.getValue(property);
+ getList = obj.getValue(property);
getList.addAll(temp);
modified = true;
}
@@ -2143,19 +2378,13 @@ public class DBSerializer {
* @param obj the obj
* @param cleanUp the clean up
* @return the object
- * @throws InstantiationException the instantiation exception
- * @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
- * @throws InvocationTargetException the invocation target exception
- * @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws UnsupportedEncodingException the unsupported encoding exception
* @throws AAIException the AAI exception
- * @throws MalformedURLException the malformed URL exception
- * @throws URISyntaxException
*/
private Introspector createFilteredRelationshipList(Vertex v, Introspector obj, String cleanUp,
- List<String> filterNodes) throws UnsupportedEncodingException, AAIException {
+ List<String> filterNodes, boolean isSkipRelatedTo) throws UnsupportedEncodingException, AAIException {
List<Vertex> allCousins = this.engine.getQueryEngine().findCousinVertices(v);
Iterator<Vertex> cousinVertices = allCousins.stream().filter(item -> {
@@ -2163,14 +2392,14 @@ public class DBSerializer {
return filterNodes.parallelStream().anyMatch(node::contains);
}).iterator();
- List<Vertex> cousins = (List<Vertex>) IteratorUtils.toList(cousinVertices);
+ List<Object> relationshipObjList = obj.getValue(RELATIONSHIP);
- // items.parallelStream().anyMatch(inputStr::contains)
- List<Object> relationshipObjList = obj.getValue("relationship");
+ List<Vertex> cousins = new ArrayList<>();
+ cousinVertices.forEachRemaining(cousins::add);
for (Vertex cousin : cousins) {
- Introspector relationshipObj = obj.newIntrospectorInstanceOfNestedProperty("relationship");
- Object result = processEdgeRelationship(relationshipObj, cousin, cleanUp, null);
+ Introspector relationshipObj = obj.newIntrospectorInstanceOfNestedProperty(RELATIONSHIP);
+ Object result = processEdgeRelationship(relationshipObj, cousin, cleanUp, null, isSkipRelatedTo);
if (result != null) {
relationshipObjList.add(result);
}
@@ -2184,4 +2413,31 @@ public class DBSerializer {
}
}
+ public Set<Vertex> touchStandardVertexPropertiesForEdges() {
+ this.edgeVertexes.forEach(v -> this.touchStandardVertexProperties(v, false));
+ return this.edgeVertexes;
+ }
+
+ public void addVertexToEdgeVertexes(Vertex vertex){
+ this.edgeVertexes.add(vertex);
+ }
+
+ private String urlToUri(String url) {
+ if (url.startsWith("/")) {
+ url = url.substring(1);
+ }
+
+ if (url.endsWith("/")) {
+ url = url.substring(0, url.length() - 1);
+ }
+
+ // TODO - Check if this makes to do for model driven for base uri path
+ url = url.replaceFirst("[a-z][a-z]*/v\\d+/", "");
+ if (url.charAt(0) != '/') {
+ url = '/' + url;
+ }
+
+ return url;
+ }
+
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/GraphSingleton.java b/aai-core/src/main/java/org/onap/aai/serialization/db/GraphSingleton.java
index cb713d56..3a7c6d2d 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/db/GraphSingleton.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/db/GraphSingleton.java
@@ -20,11 +20,10 @@
package org.onap.aai.serialization.db;
-import java.util.concurrent.atomic.AtomicInteger;
-
import org.janusgraph.core.JanusGraph;
import org.onap.aai.dbmap.AAIGraph;
-import org.onap.aai.dbmap.DBConnectionType;
+
+import java.util.concurrent.atomic.AtomicInteger;
/* This class simply calls AAIGraph under the covers for now */
public class GraphSingleton {
@@ -63,7 +62,4 @@ public class GraphSingleton {
return AAIGraph.getInstance().getGraph();
}
- public JanusGraph getTxGraph(DBConnectionType connectionType) {
- return AAIGraph.getInstance().getGraph(connectionType);
- }
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/ImpliedDelete.java b/aai-core/src/main/java/org/onap/aai/serialization/db/ImpliedDelete.java
new file mode 100644
index 00000000..437f1634
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/db/ImpliedDelete.java
@@ -0,0 +1,205 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.serialization.db;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.lang.StringUtils;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.engines.query.QueryEngine;
+import org.onap.aai.util.AAIConfigProxy;
+import org.onap.aai.util.AAIConstants;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * <b>ImpliedDelete</b> class is responsible for deleting children
+ * of a parent vertex if the client explicitly asks to remove them
+ * It will check if they are allowed and based on that information
+ * it will decide whether to proceed with the deletion or
+ * throw an exception back to the requester if they are not allowed
+ *
+ * It implements the AAIProxy Interface and any calls to the
+ * AAIConfig should be using the proxy methods and any new
+ * methods that needs to be invoked should be added there first
+ *
+ * @see org.onap.aai.util.AAIConfigProxy
+ */
+public class ImpliedDelete implements AAIConfigProxy {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ImpliedDelete.class);
+
+ private static final String IMPLICIT_DELETE = "Implicit DELETE";
+ private static final String STAR = "*";
+
+ private TransactionalGraphEngine engine;
+ private DBSerializer serializer;
+
+ public ImpliedDelete(TransactionalGraphEngine engine, DBSerializer serializer){
+ this.engine = engine;
+ this.serializer = serializer;
+ }
+
+ /**
+ * Checks if the user is allowed to execute implied delete
+ * If they are allowed to do the delete, then for all the dependent vertices
+ * it will identify all the deletable vertices to them
+ * and log them based on the following aaiconfig properties:
+ *
+ * aai.implied.delete.log.enabled=true
+ * aai.implied.delete.log.limit=-1
+ *
+ * Above properties are the default assumption of the code if they are not overwritten
+ * So the code will log for every vertex it is about to delete
+ * If there are thousands of vertexes that get implicitly deleted,
+ * its preferable that the operation timeout rather than
+ * someone accidentally deleting thousands of children
+ *
+ * @param id - Identifier of the vertex whose children could be potentially deleted
+ * @param sot - source of truth of who the requester who is making the request
+ * @param objectType - type of the parent object whose children are being deleted
+ * @param dependentVertexes - list of children vertexes
+ * @throws AAIException if the user is not allowed to implicitly delete children
+ */
+ public List<Vertex> execute(Object id, String sot, String objectType, List<Vertex> dependentVertexes) throws AAIException {
+ if(dependentVertexes != null && !dependentVertexes.isEmpty()){
+ // Find all the deletable vertices from the dependent vertices that should be deleted
+ // So for each of the following dependent vertices,
+ // we will use the edge properties and do the cascade delete
+ QueryEngine queryEngine = this.engine.getQueryEngine();
+ List<Vertex> impliedDeleteVertices = queryEngine.findDeletable(dependentVertexes);
+ if(this.allow(sot, objectType)){
+
+ int impliedDeleteCount = impliedDeleteVertices.size();
+
+ LOGGER.warn(
+ "For the vertex with id {}, doing an implicit delete on update will delete total of {} vertexes",
+ id,
+ impliedDeleteCount
+ );
+
+ String impliedDeleteLogEnabled = get(AAIConstants.AAI_IMPLIED_DELETE_LOG_ENABLED, "true");
+
+ int impliedDeleteLogLimit = getInt(AAIConstants.AAI_IMPLIED_DELETE_LOG_LIMIT, "-1");
+
+ if (impliedDeleteLogLimit == -1) {
+ impliedDeleteLogLimit = Integer.MAX_VALUE;
+ }
+
+ // If the logging is enabled for implied delete
+ // then log the payload in the latest format
+ if ("true".equals(impliedDeleteLogEnabled) && impliedDeleteCount <= impliedDeleteLogLimit) {
+ for (Vertex vertex : impliedDeleteVertices) {
+ Introspector introspector = null;
+ try {
+ introspector = serializer.getLatestVersionView(vertex);
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Implied delete object in json format {}", introspector.marshal(false));
+ }
+ } catch (Exception ex) {
+ LOGGER.warn(
+ "Encountered an exception during retrieval of vertex properties with vertex-id {} -> {}",
+ id, LogFormatTools.getStackTop(ex));
+ }
+ }
+ }
+ } else {
+ LOGGER.error("User {} is not allowed to implicit delete on parent object {}", sot, objectType);
+ throw new AAIException("AAI_9109");
+ }
+ return impliedDeleteVertices;
+ } else {
+ // Return null or an empty list back to the user based on input
+ return dependentVertexes;
+ }
+ }
+
+ public void delete(List<Vertex> vertices){
+ // After all the appropriate logging, calling the serializer delete to delete the affected vertices
+ if(vertices != null && !vertices.isEmpty()){
+ serializer.delete(vertices);
+ }
+ }
+
+ /**
+ * Checks the property in the aaiconfig properties
+ * to see if the user is allowed to do implicit delete
+ *
+ * Expecting the aaiconfig.properties to have following type of properties
+ *
+ * <code>
+ * aai.implied.delete.whitelist.sdnc=*
+ * aai.implied.delete.whitelist.sdc='pserver','vserver'
+ * </code>
+ *
+ * So in the above code, the expectation is for any of the following user:
+ *
+ * <ul>
+ * <li>SDC</li>
+ * <li>SDc</li>
+ * <li>Sdc</li>
+ * <li>sDc</li>
+ * <li>SdC</li>
+ * <li>sdC</li>
+ * <li>sdc</li>
+ * </ul>
+ *
+ * They are allowed to delete the children of pserver and vserver by implicit delete
+ *
+ * Note: The reason the property values are placed inside the single quotes is
+ * so if there is an object called volume and there is another object called volume-group
+ * when doing an contains it can falsely allow volume-group children to be implicitly deleted
+ * and the cost of turning the string into an array and then searching if its inside it
+ * or loading into an set which is unnecessary and it could potentially be done for every request
+ *
+ * @param sourceOfTruth - the original requester that the request is coming from,
+ * derived from HTTP Header X-FromAppId
+ * @param parentObjectType - parent object in which they are trying to do the implicit delete against
+ *
+ * @return true - if the requester is allowed to implicit delete against the object type
+ * false - if they are not allowed
+ */
+ private boolean allow(String sourceOfTruth, String parentObjectType){
+ Objects.requireNonNull(sourceOfTruth);
+ Objects.requireNonNull(parentObjectType);
+
+ String propertyName = AAIConstants.AAI_IMPLIED_DELETE_WHITELIST + sourceOfTruth.toLowerCase();
+ String whitelist = get(propertyName, StringUtils.EMPTY);
+
+ if(whitelist.isEmpty()){
+ return false;
+ }
+
+ if(STAR.equals(whitelist)){
+ return true;
+ }
+
+ if(whitelist.contains("'" + parentObjectType + "'")){
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/db/InMemoryGraphSingleton.java b/aai-core/src/main/java/org/onap/aai/serialization/db/InMemoryGraphSingleton.java
index 90f71db5..2ca96b5b 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/db/InMemoryGraphSingleton.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/db/InMemoryGraphSingleton.java
@@ -21,7 +21,6 @@
package org.onap.aai.serialization.db;
import org.janusgraph.core.JanusGraph;
-import org.onap.aai.dbmap.DBConnectionType;
public class InMemoryGraphSingleton extends GraphSingleton {
@@ -51,8 +50,4 @@ public class InMemoryGraphSingleton extends GraphSingleton {
return inMemgraph;
}
- @Override
- public JanusGraph getTxGraph(DBConnectionType connectionType) {
- return inMemgraph;
- }
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/InMemoryDBEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/InMemoryDBEngine.java
index 86c32f4a..66509c97 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/engines/InMemoryDBEngine.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/InMemoryDBEngine.java
@@ -20,23 +20,22 @@
package org.onap.aai.serialization.engines;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.janusgraph.core.JanusGraph;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.introspection.Loader;
import org.onap.aai.query.builder.*;
import org.onap.aai.serialization.db.InMemoryGraphSingleton;
import org.onap.aai.serialization.engines.query.GraphTraversalQueryEngine;
import org.onap.aai.serialization.engines.query.QueryEngine;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
public class InMemoryDBEngine extends TransactionalGraphEngine {
/**
@@ -49,10 +48,8 @@ public class InMemoryDBEngine extends TransactionalGraphEngine {
*/
private JanusGraph graph = null;
- private static final TransactionalGraphEngine.Admin admin = null;
-
- public InMemoryDBEngine(QueryStyle style, DBConnectionType connectionType, Loader loader, JanusGraph graph) {
- super(style, loader, connectionType, InMemoryGraphSingleton.getInstance(graph));
+ public InMemoryDBEngine(QueryStyle style, Loader loader, JanusGraph graph) {
+ super(style, loader, InMemoryGraphSingleton.getInstance(graph));
this.graph = graph;
}
@@ -195,8 +192,7 @@ public class InMemoryDBEngine extends TransactionalGraphEngine {
if (this.tx() == null) {
this.currentTx = graph.newTransaction();
this.currentTraversal = this.tx().traversal();
- this.readOnlyTraversal =
- this.tx().traversal(GraphTraversalSource.build().with(ReadOnlyStrategy.instance()));
+ this.readOnlyTraversal = this.tx().traversal().withStrategies(ReadOnlyStrategy.instance());
}
return currentTx;
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/JanusGraphDBEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/JanusGraphDBEngine.java
index 346cf026..2a4511d0 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/engines/JanusGraphDBEngine.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/JanusGraphDBEngine.java
@@ -20,16 +20,15 @@
package org.onap.aai.serialization.engines;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.introspection.Loader;
import org.onap.aai.serialization.db.JanusGraphSingleton;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
public class JanusGraphDBEngine extends TransactionalGraphEngine {
/**
@@ -38,8 +37,8 @@ public class JanusGraphDBEngine extends TransactionalGraphEngine {
* @param style the style
* @param loader the loader
*/
- public JanusGraphDBEngine(QueryStyle style, DBConnectionType connectionType, Loader loader) {
- super(style, loader, connectionType, JanusGraphSingleton.getInstance());
+ public JanusGraphDBEngine(QueryStyle style, Loader loader) {
+ super(style, loader, JanusGraphSingleton.getInstance());
}
/**
@@ -82,7 +81,7 @@ public class JanusGraphDBEngine extends TransactionalGraphEngine {
@Override
public List<Object> getListProperty(Vertex v, String name) {
- List<Object> result = new ArrayList<Object>();
+ List<Object> result = new ArrayList<>();
Iterator<VertexProperty<Object>> iterator = v.properties(name);
@@ -90,7 +89,7 @@ public class JanusGraphDBEngine extends TransactionalGraphEngine {
result.add(iterator.next().value());
}
- if (result.size() == 0) {
+ if (result.isEmpty()) {
result = null;
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/QueryStyle.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/QueryStyle.java
index c291fbcb..f69e4d34 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/engines/QueryStyle.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/QueryStyle.java
@@ -21,5 +21,5 @@
package org.onap.aai.serialization.engines;
public enum QueryStyle {
- GREMLIN_TRAVERSAL, GREMLIN_UNIQUE, GREMLINPIPELINE_TRAVERSAL, TRAVERSAL, TRAVERSAL_URI
+ GREMLIN_TRAVERSAL, GREMLIN_UNIQUE, GREMLINPIPELINE_TRAVERSAL, TRAVERSAL, TRAVERSAL_URI, HISTORY_TRAVERSAL, HISTORY_GREMLIN_TRAVERSAL
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/TransactionalGraphEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/TransactionalGraphEngine.java
index 731d6c23..b945db05 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/engines/TransactionalGraphEngine.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/TransactionalGraphEngine.java
@@ -20,29 +20,26 @@
package org.onap.aai.serialization.engines;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.janusgraph.core.JanusGraph;
import org.janusgraph.core.schema.JanusGraphManagement;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.introspection.Loader;
import org.onap.aai.query.builder.*;
import org.onap.aai.serialization.db.GraphSingleton;
import org.onap.aai.serialization.engines.query.GraphTraversalQueryEngine;
import org.onap.aai.serialization.engines.query.QueryEngine;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
public abstract class TransactionalGraphEngine {
protected GraphSingleton singleton = null;
- protected QueryEngine queryEngine = null;
protected QueryBuilder<Vertex> queryBuilder = null;
- protected QueryStyle style = null;
- protected final DBConnectionType connectionType;
+ protected QueryStyle style;
protected final Loader loader;
protected Graph currentTx = null;
protected GraphTraversalSource currentTraversal = null;
@@ -55,19 +52,16 @@ public abstract class TransactionalGraphEngine {
* @param style the style
* @param loader the loader
*/
- public TransactionalGraphEngine(QueryStyle style, Loader loader, DBConnectionType connectionType,
- GraphSingleton singleton) {
+ public TransactionalGraphEngine(QueryStyle style, Loader loader, GraphSingleton singleton) {
this.loader = loader;
this.style = style;
this.singleton = singleton;
- this.connectionType = connectionType;
admin = new Admin();
}
public TransactionalGraphEngine(QueryStyle style, Loader loader) {
this.loader = loader;
this.style = style;
- this.connectionType = DBConnectionType.REALTIME;
admin = new Admin();
}
@@ -97,7 +91,7 @@ public abstract class TransactionalGraphEngine {
* @return the graph
*/
private JanusGraph getGraph() {
- return singleton.getTxGraph(this.connectionType);
+ return singleton.getTxGraph();
}
/**
@@ -150,6 +144,10 @@ public abstract class TransactionalGraphEngine {
return getQueryBuilder(this.style, loader);
}
+ public QueryBuilder<Vertex> getQueryBuilder(QueryStyle style, GraphTraversalSource source) {
+ return getQueryBuilder(style, this.loader, source);
+ }
+
public QueryBuilder<Vertex> getQueryBuilder(QueryStyle style, Loader loader) {
if (style.equals(QueryStyle.GREMLIN_TRAVERSAL)) {
return new GremlinTraversal<>(loader, this.asAdmin().getTraversalSource());
@@ -161,7 +159,32 @@ public abstract class TransactionalGraphEngine {
return new TraversalQuery<>(loader, this.asAdmin().getTraversalSource());
} else if (style.equals(QueryStyle.TRAVERSAL_URI)) {
return new TraversalURIOptimizedQuery<>(loader, this.asAdmin().getTraversalSource());
- } else {
+ } else if (style.equals(QueryStyle.HISTORY_TRAVERSAL)) {
+ throw new IllegalArgumentException("History Traversal needs history traversal source");
+ } else if (style.equals(QueryStyle.HISTORY_GREMLIN_TRAVERSAL)) {
+ throw new IllegalArgumentException("History Gremlin Traversal needs history traversal source");
+ }else {
+ throw new IllegalArgumentException("Query Builder type not recognized");
+ }
+ return queryBuilder;
+ }
+
+ public QueryBuilder<Vertex> getQueryBuilder(QueryStyle style, Loader loader, GraphTraversalSource source) {
+ if (style.equals(QueryStyle.GREMLIN_TRAVERSAL)) {
+ return new GremlinTraversal<>(loader, source);
+ } else if (style.equals(QueryStyle.GREMLIN_UNIQUE)) {
+ return new GremlinUnique<>(loader, source);
+ } else if (style.equals(QueryStyle.GREMLINPIPELINE_TRAVERSAL)) {
+ // return new GremlinPipelineTraversal(loader);
+ } else if (style.equals(QueryStyle.TRAVERSAL)) {
+ return new TraversalQuery<>(loader, source);
+ } else if (style.equals(QueryStyle.TRAVERSAL_URI)) {
+ return new TraversalURIOptimizedQuery<>(loader, source);
+ } else if (style.equals(QueryStyle.HISTORY_TRAVERSAL)) {
+ return new HistoryTraversalURIOptimizedQuery<>(loader, source);
+ }else if (style.equals(QueryStyle.HISTORY_GREMLIN_TRAVERSAL)) {
+ return new HistoryGremlinTraversal<>(loader, source);
+ }else {
throw new IllegalArgumentException("Query Builder type not recognized");
}
return queryBuilder;
@@ -202,8 +225,7 @@ public abstract class TransactionalGraphEngine {
if (this.tx() == null) {
this.currentTx = this.getGraph().newTransaction();
this.currentTraversal = this.tx().traversal();
- this.readOnlyTraversal =
- this.tx().traversal(GraphTraversalSource.build().with(ReadOnlyStrategy.instance()));
+ this.readOnlyTraversal =this.tx().traversal().withStrategies(ReadOnlyStrategy.instance());
}
return currentTx;
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java
index e012aef3..376a2798 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java
@@ -20,18 +20,9 @@
package org.onap.aai.serialization.engines.query;
-import static org.onap.aai.edges.enums.AAIDirection.IN;
-import static org.onap.aai.edges.enums.AAIDirection.NONE;
-import static org.onap.aai.edges.enums.AAIDirection.OUT;
-import static org.onap.aai.edges.enums.EdgeField.PRIVATE;
-import static org.onap.aai.edges.enums.EdgeProperty.CONTAINS;
-import static org.onap.aai.edges.enums.EdgeProperty.DELETE_OTHER_V;
-
-import java.util.List;
-import java.util.Set;
-
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
@@ -41,9 +32,19 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.edges.enums.EdgeField;
+import org.onap.aai.edges.enums.EdgeProperty;
import org.onap.aai.introspection.Loader;
import org.onap.aai.logging.StopWatch;
+import java.util.List;
+import java.util.Set;
+
+import static org.onap.aai.edges.enums.AAIDirection.*;
+import static org.onap.aai.edges.enums.EdgeField.PRIVATE;
+import static org.onap.aai.edges.enums.EdgeProperty.CONTAINS;
+import static org.onap.aai.edges.enums.EdgeProperty.DELETE_OTHER_V;
+
/*
* This class needs some big explanation despite its compact size.
* This controls all the queries performed by the CRUD API in A&AI.
@@ -256,6 +257,15 @@ public class GraphTraversalQueryEngine extends QueryEngine {
return pipeline.toList();
}
+ public List<Path> findCousinsAsPath(Vertex start){
+ return this.g.V(start).bothE().where(
+ __.and(
+ __.has(EdgeProperty.CONTAINS.toString(), NONE.toString()),
+ __.not(__.has(EdgeField.PRIVATE.toString(), true))
+ )
+ ).otherV().path().toList();
+ }
+
public double getDBTimeMsecs() {
return (dbTimeMsecs);
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java
index 4f30b564..b250d8f3 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java
@@ -22,6 +22,7 @@ package org.onap.aai.serialization.engines.query;
import java.util.List;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.structure.Direction;
@@ -81,7 +82,7 @@ public abstract class QueryEngine {
/**
* Finds all immediate children of start (no grandchildren or so forth) of the given type
- *
+ *
* @param start - the start vertex
* @param type - the desired aai-node-type
* @return the list of immediate child vertices of given type
@@ -90,7 +91,7 @@ public abstract class QueryEngine {
/**
* Finds all immediate children of start (no grandchildren or so forth)
- *
+ *
* @param start - the start vertex
* @return the list of immediate child vertices
*/
@@ -173,6 +174,8 @@ public abstract class QueryEngine {
*/
public abstract List<Vertex> findCousinVertices(Vertex start, String... labels);
+ public abstract List<Path> findCousinsAsPath(Vertex start);
+
public abstract double getDBTimeMsecs();
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java
new file mode 100644
index 00000000..4c37aaa1
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Aggregate.java
@@ -0,0 +1,313 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.serialization.queryformats;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.gson.*;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.params.AsTree;
+import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.NodesOnly;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class Aggregate extends MultiFormatMapper {
+ private static final Logger LOGGER = LoggerFactory.getLogger(LifecycleFormat.class);
+ protected JsonParser parser = new JsonParser();
+ protected final DBSerializer serializer;
+ protected final Loader loader;
+ protected final UrlBuilder urlBuilder;
+ protected final int depth;
+ protected final boolean nodesOnly;
+
+ protected Aggregate(Builder builder) {
+ this.urlBuilder = builder.getUrlBuilder();
+ this.loader = builder.getLoader();
+ this.serializer = builder.getSerializer();
+ this.depth = builder.getDepth();
+ this.nodesOnly = builder.isNodesOnly();
+ this.isTree = builder.isTree();
+ }
+
+ @Override
+ public Optional<JsonObject> getJsonFromVertex(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException{
+ JsonObject json = new JsonObject();
+ JsonObject outer = new JsonObject();
+ Optional<JsonObject> properties = this.createSelectedPropertiesObject(v,selectedProps);
+ if (properties.isPresent()) {
+ json.add("properties", properties.get());
+ outer.add(this.urlBuilder.pathed(v),json.getAsJsonObject());
+ } else {
+ return Optional.empty();
+ }
+ return Optional.of(outer);
+ }
+
+ @Override
+ public int parallelThreshold() {
+ return 100;
+ }
+
+ public Optional<JsonObject> createPropertiesObject(Vertex v) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+ Iterator<VertexProperty<Object>> iter = v.properties();
+
+ while (iter.hasNext()) {
+ VertexProperty<Object> prop = iter.next();
+ if (prop.value() instanceof String) {
+ json.addProperty(prop.key(), (String) prop.value());
+ } else if (prop.value() instanceof Boolean) {
+ json.addProperty(prop.key(), (Boolean) prop.value());
+ } else if (prop.value() instanceof Number) {
+ json.addProperty(prop.key(), (Number) prop.value());
+ } else if (prop.value() instanceof List) {
+ Gson gson = new Gson();
+ String list = gson.toJson(prop.value());
+
+ json.addProperty(prop.key(), list);
+ } else {
+ // throw exception?
+ return null;
+ }
+ }
+
+ return Optional.of(json);
+ }
+
+ public Optional<JsonObject> createSelectedPropertiesObject(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+ Set<String> propList = null;
+ String nodeType = v.<String>value(AAIProperties.NODE_TYPE);
+ if (selectedProps != null && !selectedProps.isEmpty() && selectedProps.containsKey(nodeType)) {
+ propList = removeSingleQuotesForProperties(selectedProps.get(nodeType));
+ }
+ Iterator<VertexProperty<Object>> iter = v.properties();
+
+ Gson gson = new Gson();
+ while (iter.hasNext()) {
+ VertexProperty<Object> prop = iter.next();
+ if (propList != null && !propList.isEmpty()) {
+ if (propList.contains(prop.label())) {
+ if (prop.value() instanceof String) {
+ json.addProperty(prop.key(), (String) prop.value());
+ } else if (prop.value() instanceof Boolean) {
+ json.addProperty(prop.key(), (Boolean) prop.value());
+ } else if (prop.value() instanceof Number) {
+ json.addProperty(prop.key(), (Number) prop.value());
+ } else if (prop.value() instanceof List) {
+ json.addProperty(prop.key(), gson.toJson(prop.value()));
+ } else {
+ // throw exception?
+ return null;
+ }
+ }
+ } else {
+ return this.createPropertiesObject(v);
+ }
+ }
+
+ return Optional.of(json);
+ }
+
+ private Set<String> removeSingleQuotesForProperties(List<String> props){
+ if (props != null && !props.isEmpty()) {
+ return props.stream().map(
+ e -> e.substring(1, e.length()-1)).collect(Collectors.toSet());
+ } else {
+ return Collections.emptySet();
+ }
+ }
+
+ public JsonArray process(List<Object> queryResults, Map<String, List<String>> properties) {
+ JsonArray body = new JsonArray();
+ Stream<Object> stream;
+ if (queryResults.size() >= this.parallelThreshold()) {
+ stream = queryResults.parallelStream();
+ } else {
+ stream = queryResults.stream();
+ }
+ final boolean isParallel = stream.isParallel();
+
+ stream.map(o -> {
+ try {
+ return this.formatObject(o, properties);
+ } catch (AAIFormatVertexException e) {
+ LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e));
+ } catch (AAIFormatQueryResultFormatNotSupported e) {
+ LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e));
+ }
+
+ return Optional.<JsonObject>empty();
+ }).filter(Optional::isPresent)
+ .map(Optional::get)
+ .forEach(json -> {
+ if (isParallel) {
+ synchronized (body) {
+ body.add(json);
+ }
+ } else {
+ body.add(json);
+ }
+ });
+ return body;
+ }
+
+ @Override
+ public Optional<JsonObject> formatObject(Object input, Map<String, List<String>> properties)
+ throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ JsonObject json = new JsonObject();
+ if (input instanceof ArrayList) {
+ Optional<JsonArray> ja = processInput(input, properties);
+ json.add("results", ja.get());
+ } else {
+ throw new AAIFormatQueryResultFormatNotSupported();
+ }
+ return Optional.of(json);
+ }
+
+ private Optional<JsonArray> processInput(Object input, Map properties) throws AAIFormatVertexException {
+ JsonArray json = new JsonArray();
+ for (Object l : (ArrayList) input) {
+ if (l instanceof ArrayList) {
+ JsonArray inner = new JsonArray();
+ for (Vertex o : (ArrayList<Vertex>) l) {
+ if (o instanceof Vertex) {
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o, properties);
+ if (obj.isPresent()) {
+ inner.add(obj.get());
+ } else {
+ continue;
+ }
+ }
+ }
+ json.add(inner);
+ } else {
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex)l, properties);
+ json.add(obj.get());
+ }
+ }
+ return Optional.of(json);
+ }
+
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
+
+ protected final Loader loader;
+ protected final DBSerializer serializer;
+ protected final UrlBuilder urlBuilder;
+ protected boolean includeUrl = false;
+ protected boolean nodesOnly = false;
+ protected int depth = 1;
+ protected boolean modelDriven = false;
+ private boolean tree = false;
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ }
+
+ protected boolean isTree() { return this.tree; }
+
+ public Builder isTree(Boolean tree) {
+ this.tree = tree;
+ return this;
+ }
+
+ protected Loader getLoader() {
+ return this.loader;
+ }
+
+ protected DBSerializer getSerializer() {
+ return this.serializer;
+ }
+
+ protected UrlBuilder getUrlBuilder() {
+ return this.urlBuilder;
+ }
+
+ public Builder includeUrl() {
+ this.includeUrl = true;
+ return this;
+ }
+
+ public Builder nodesOnly(Boolean nodesOnly) {
+ this.nodesOnly = nodesOnly;
+ return this;
+ }
+
+ public boolean isNodesOnly() {
+ return this.nodesOnly;
+ }
+
+ public Builder depth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+
+ public boolean isIncludeUrl() {
+ return this.includeUrl;
+ }
+
+ public Builder modelDriven() {
+ this.modelDriven = true;
+ return this;
+ }
+
+ public boolean getModelDriven() {
+ return this.modelDriven;
+ }
+
+ public Aggregate build() {
+ return new Aggregate(this);
+ }
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
+
+ JsonObject json = new JsonObject();
+ json.addProperty("url", this.urlBuilder.pathed(v));
+ Optional<JsonObject> properties = this.createPropertiesObject(v);
+ if (properties.isPresent()) {
+ json.add("properties", properties.get());
+ } else {
+ return Optional.empty();
+ }
+ return Optional.of(json);
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ChangesFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ChangesFormat.java
new file mode 100644
index 00000000..bbaed360
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ChangesFormat.java
@@ -0,0 +1,95 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.serialization.queryformats;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+public class ChangesFormat extends MultiFormatMapper {
+
+ private Long startTs = 0L;
+
+ public void startTs(String startTime) {
+ /*
+ * StartTs = truncate time
+ */
+ if (startTime == null || startTime.isEmpty() || "now".equals(startTime) || "0".equals(startTime) || "-1".equals(startTime)){
+ String historyTruncateDays = SpringContextAware.getApplicationContext().getEnvironment().getProperty("history.truncate.window.days", "365");
+ this.startTs = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(Long.parseLong(historyTruncateDays));
+ } else {
+ this.startTs = Long.parseLong(startTime);
+ }
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v) {
+ JsonObject json = new JsonObject();
+ if (!v.properties(AAIProperties.RESOURCE_VERSION).hasNext() ||
+ !v.properties(AAIProperties.NODE_TYPE).hasNext() ||
+ !v.properties(AAIProperties.AAI_URI).hasNext()) {
+ return Optional.empty();
+ }
+ json.addProperty("node-type", v.<String>value(AAIProperties.NODE_TYPE));
+ json.addProperty("uri", v.<String>value(AAIProperties.AAI_URI));
+
+ final Set<Long> changes = new HashSet<>();
+ v.properties(AAIProperties.RESOURCE_VERSION).forEachRemaining(o->
+ o.properties(AAIProperties.START_TS, AAIProperties.END_TS)
+ .forEachRemaining(p -> {
+ Long val = (Long) p.value();
+ if(val >= startTs) {
+ changes.add(val);
+ }
+ }
+ ));
+ v.edges(Direction.BOTH).forEachRemaining(e -> {
+ if(e.property(AAIProperties.START_TS).isPresent() && (Long)e.property(AAIProperties.START_TS).value() >= startTs) {
+ changes.add((Long) e.property(AAIProperties.START_TS).value());
+ }
+ if(e.property(AAIProperties.END_TS).isPresent() && (Long)e.property(AAIProperties.END_TS).value() >= startTs) {
+ changes.add((Long) e.property(AAIProperties.END_TS).value());
+ }
+ });
+
+ List<Long> sortedList = new ArrayList<>(changes);
+ sortedList.sort(Comparator.naturalOrder());
+ JsonArray jsonArray = new JsonArray();
+ sortedList.forEach(jsonArray::add);
+
+ json.add("changes", jsonArray);
+
+ return Optional.of(json);
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Console.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Console.java
index ba20c652..7e230c3a 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Console.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Console.java
@@ -22,8 +22,11 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonObject;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
public class Console implements FormatMapper {
@@ -38,6 +41,13 @@ public class Console implements FormatMapper {
}
@Override
+ public Optional<JsonObject> formatObject(Object o, Map<String, List<String>> properties) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ JsonObject json = new JsonObject();
+ json.addProperty("result", o.toString());
+ return Optional.of(json);
+ }
+
+ @Override
public int parallelThreshold() {
return 100;
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java
index 8ee4e3a4..60a10c51 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Count.java
@@ -23,6 +23,7 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonObject;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -37,8 +38,7 @@ import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexExcepti
public class Count implements FormatMapper {
@Override
- public Optional<JsonObject> formatObject(Object o)
- throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ public Optional<JsonObject> formatObject(Object o) {
@SuppressWarnings("unchecked")
List<Object> list = (List<Object>) o;
@@ -46,12 +46,17 @@ public class Count implements FormatMapper {
list.stream().map(this::getCount).filter(Optional::isPresent).map(Optional::get)
.collect(Collectors.toConcurrentMap(Pair::getValue0, Pair::getValue1, Long::sum))
- .forEach((k, v) -> countResult.addProperty(k, v));
+ .forEach(countResult::addProperty);
return Optional.of(countResult);
}
@Override
+ public Optional<JsonObject> formatObject(Object o, Map<String, List<String>> properties) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ return Optional.empty();
+ }
+
+ @Override
public int parallelThreshold() {
return 20;
}
@@ -72,10 +77,10 @@ public class Count implements FormatMapper {
}
if (pair == null) {
- return Optional.<Pair<String, Long>>empty();
+ return Optional.empty();
}
- return Optional.<Pair<String, Long>>of(pair);
+ return Optional.of(pair);
}
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java
index 8de38117..f471b3c1 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Format.java
@@ -23,7 +23,7 @@ package org.onap.aai.serialization.queryformats;
import org.onap.aai.exceptions.AAIException;
public enum Format {
- graphson, pathed, pathed_resourceversion, id, resource, simple, resource_and_url, console, raw, count, resource_with_sot;
+ graphson, pathed, pathed_resourceversion, id, resource, simple, resource_and_url, console, raw, count, resource_with_sot, state, lifecycle, changes, aggregate;
public static Format getFormat(String format) throws AAIException {
try {
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java
index 854a20f4..0ae0c5fe 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatFactory.java
@@ -20,9 +20,6 @@
package org.onap.aai.serialization.queryformats;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Loader;
import org.onap.aai.serialization.db.DBSerializer;
@@ -31,6 +28,9 @@ import org.onap.aai.serialization.queryformats.utils.QueryParamInjector;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
import org.onap.aai.setup.SchemaVersions;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+
public class FormatFactory {
private final Loader loader;
@@ -47,7 +47,7 @@ public class FormatFactory {
}
public Formatter get(Format format) throws AAIException {
- return get(format, new MultivaluedHashMap<String, String>());
+ return get(format, new MultivaluedHashMap<>());
}
public Formatter get(Format format, MultivaluedMap<String, String> params) throws AAIException {
@@ -59,29 +59,34 @@ public class FormatFactory {
formatter = new Formatter(inject(new GraphSON(), params));
break;
case pathed:
- formatter = new Formatter(inject(new PathedURL(loader, urlBuilder), params));
+ formatter = new Formatter(inject(new PathedURL.Builder(loader, serializer, urlBuilder), params).build(), params);
break;
case pathed_resourceversion:
- formatter = new Formatter(inject(new PathedURL(loader, urlBuilder).includeUrl(), params));
+ formatter = new Formatter(inject(new PathedURL.Builder(loader, serializer, urlBuilder).includeUrl(), params).build(), params);
break;
case id:
- formatter = new Formatter(inject(new IdURL(loader, urlBuilder), params));
+ formatter = new Formatter(inject(new IdURL.Builder(loader, serializer, urlBuilder), params).build(), params);
break;
case resource:
- formatter = new Formatter(inject(new Resource.Builder(loader, serializer, urlBuilder), params).build());
+ formatter = new Formatter(inject(new Resource.Builder(loader, serializer, urlBuilder, params), params).build(), params);
break;
case resource_and_url:
formatter = new Formatter(
- inject(new Resource.Builder(loader, serializer, urlBuilder).includeUrl(), params).build());
+ inject(new Resource.Builder(loader, serializer, urlBuilder, params).includeUrl(), params).build(), params);
break;
case raw:
formatter =
- new Formatter(inject(new RawFormat.Builder(loader, serializer, urlBuilder), params).build());
+ new Formatter(inject(new RawFormat.Builder(loader, serializer, urlBuilder), params).build(), params);
break;
case simple:
formatter = new Formatter(
inject(new RawFormat.Builder(loader, serializer, urlBuilder).depth(0).modelDriven(), params)
- .build());
+ .build(), params);
+ break;
+ case aggregate:
+ formatter = new Formatter(
+ inject(new Aggregate.Builder(loader, serializer, urlBuilder).depth(0).modelDriven(), params)
+ .build(), params);
break;
case console:
formatter = new Formatter(inject(new Console(), params));
@@ -91,7 +96,19 @@ public class FormatFactory {
break;
case resource_with_sot:
formatter = new Formatter(
- inject(new ResourceWithSoT.Builder(loader, serializer, urlBuilder), params).build());
+ inject(new ResourceWithSoT.Builder(loader, serializer, urlBuilder), params).build(), params);
+ break;
+ case changes:
+ formatter =
+ new Formatter(inject(new ChangesFormat(), params));
+ break;
+ case state:
+ formatter =
+ new Formatter(inject(new StateFormat.Builder(loader, serializer, urlBuilder), params).build(format));
+ break;
+ case lifecycle:
+ formatter =
+ new Formatter(inject(new LifecycleFormat.Builder(loader, serializer, urlBuilder), params).build(format));
break;
default:
break;
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java
index 26af2e31..cf967f0f 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/FormatMapper.java
@@ -22,6 +22,8 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonObject;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
@@ -30,6 +32,7 @@ import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexExcepti
public interface FormatMapper {
Optional<JsonObject> formatObject(Object o) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported;
+ Optional<JsonObject> formatObject(Object o, Map<String, List<String>> properties) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported;
int parallelThreshold();
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java
index a19bd3f6..0e15173a 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Formatter.java
@@ -20,46 +20,70 @@
package org.onap.aai.serialization.queryformats;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import org.json.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
-import org.onap.aai.logging.LogFormatTools;
-import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
-import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
-
public class Formatter {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(Formatter.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(Formatter.class);
- protected JsonParser parser = new JsonParser();
protected final FormatMapper format;
+ protected MultivaluedMap<String, String> params;
public Formatter(FormatMapper format) {
this.format = format;
}
- public JsonObject output(List<Object> queryResults) {
+ public Formatter(FormatMapper format, MultivaluedMap<String, String> params) {
+ this.format = format;
+ this.params = params;
+ }
- Stream<Object> stream;
- JsonObject result = new JsonObject();
- JsonArray body = new JsonArray();
+ public JsonObject output(List<Object> queryResults, Map<String, List<String>> properties) {
+
+ final JsonArray body;
if (this.format instanceof Count) {
JsonObject countResult;
+ body = new JsonArray();
try {
countResult = format.formatObject(queryResults).orElseThrow(() -> new AAIFormatVertexException(""));
body.add(countResult);
} catch (Exception e) {
LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e));
}
+ } else if (this.format instanceof LifecycleFormat) {
+ LifecycleFormat lifecycleFormat = (LifecycleFormat) format;
+ body = lifecycleFormat.process(queryResults);
+ } else if (this.format instanceof Aggregate) {
+ Aggregate aggregateFormat = (Aggregate) format;
+ body = aggregateFormat.process(queryResults, properties);
+ JsonObject result = new JsonObject();
+ if (body != null && body.size() > 0) {
+ result.add("results", (body.get(0)).getAsJsonObject().get("results"));
+ }
+ return result;
} else {
+
+ body = new JsonArray();
+ Stream<Object> stream;
if (queryResults.size() >= format.parallelThreshold()) {
stream = queryResults.parallelStream();
} else {
@@ -70,7 +94,11 @@ public class Formatter {
stream.map(o -> {
try {
- return format.formatObject(o);
+ if (properties!= null && !properties.isEmpty()){
+ return format.formatObject(o, properties);
+ } else {
+ return format.formatObject(o);
+ }
} catch (AAIFormatVertexException e) {
LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e));
} catch (AAIFormatQueryResultFormatNotSupported e) {
@@ -78,19 +106,38 @@ public class Formatter {
}
return Optional.<JsonObject>empty();
- }).filter(Optional::isPresent).map(Optional::get).forEach(json -> {
- if (isParallel) {
- synchronized (body) {
+ }).filter(Optional::isPresent)
+ .map(Optional::get)
+ .forEach(json -> {
+ if (isParallel) {
+ synchronized (body) {
+ body.add(json);
+ }
+ } else {
body.add(json);
}
- } else {
- body.add(json);
- }
- });
+ });
}
+
+ if (params !=null && params.containsKey("as-tree")) {
+ String isAsTree = params.get("as-tree").get(0);
+ if (isAsTree != null && isAsTree.equalsIgnoreCase("true")
+ && body != null && body.size() != 0) {
+ JsonObject jsonObjectBody = body.get(0).getAsJsonObject();
+ if (jsonObjectBody != null && jsonObjectBody.size() > 0) {
+ return body.get(0).getAsJsonObject();
+ }
+ }
+ }
+ JsonObject result = new JsonObject();
result.add("results", body);
return result.getAsJsonObject();
+
+ }
+
+ public JsonObject output(List<Object> queryResults) {
+ return output(queryResults, null);
}
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java
index eeac2195..609f6b0f 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/GraphSON.java
@@ -28,16 +28,15 @@ import com.google.gson.JsonParser;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter;
import org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
public class GraphSON implements FormatMapper {
@@ -79,6 +78,11 @@ public class GraphSON implements FormatMapper {
}
+ @Override
+ public Optional<JsonObject> formatObject(Object o, Map<String, List<String>> properties) throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ return Optional.empty();
+ }
+
/**
* Removes the private edges from the json object
*
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/HistoryFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/HistoryFormat.java
new file mode 100644
index 00000000..b11f14aa
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/HistoryFormat.java
@@ -0,0 +1,246 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.serialization.queryformats;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.tinkerpop.gremlin.structure.*;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.serialization.db.DBSerializer;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.EndTs;
+import org.onap.aai.serialization.queryformats.params.NodesOnly;
+import org.onap.aai.serialization.queryformats.params.StartTs;
+import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public abstract class HistoryFormat extends MultiFormatMapper {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HistoryFormat.class);
+
+ protected static final String KEY = "key";
+ protected static final String VALUE = "value";
+ protected static final String TIMESTAMP = "timestamp";
+ protected static final String NODE_TYPE = "node-type";
+ protected static final String END_TIMESTAMP = "end-timestamp";
+ protected static final String SOT = "sot";
+ protected static final String END_SOT = "end-sot";
+ protected static final String TX_ID = "tx-id";
+ protected static final String END_TX_ID = "end-tx-id";
+ protected static final String PROPERTIES = "properties";
+ protected static final String RELATED_TO = "related-to";
+ protected static final String NODE_ACTIONS = "node-actions";
+
+ protected JsonParser parser = new JsonParser();
+ protected final DBSerializer serializer;
+ protected final Loader loader;
+ protected final UrlBuilder urlBuilder;
+ protected final int depth;
+ protected final boolean nodesOnly;
+ protected long startTs;
+ protected long endTs;
+ protected static final Set<String> ignoredKeys =
+ Stream.of(AAIProperties.LAST_MOD_TS, AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, AAIProperties.CREATED_TS)
+ .collect(Collectors.toSet());
+
+ protected HistoryFormat(Builder builder) {
+ this.urlBuilder = builder.getUrlBuilder();
+ this.loader = builder.getLoader();
+ this.serializer = builder.getSerializer();
+ this.depth = builder.getDepth();
+ this.nodesOnly = builder.isNodesOnly();
+ this.startTs = builder.getStartTs();
+ this.endTs = builder.getEndTs();
+ }
+
+ @Override
+ public int parallelThreshold() {
+ return 100;
+ }
+
+ protected JsonObject createMetaPropertiesObject(VertexProperty<Object> prop) {
+ JsonObject json = new JsonObject();
+ Iterator iter = prop.properties();
+
+ while (iter.hasNext()) {
+ Property<Object> metaProp = (Property) iter.next();
+ mapPropertyValues(json, metaProp.key(), metaProp.value());
+ }
+
+ return json;
+ }
+
+ protected JsonObject mapPropertyValues(JsonObject json, String propertyKey, Object propertyValue) {
+ if (propertyValue instanceof String) {
+ json.addProperty(propertyKey, (String) propertyValue);
+ } else if (propertyValue instanceof Boolean) {
+ json.addProperty(propertyKey, (Boolean) propertyValue);
+ } else if (propertyValue instanceof Number) {
+ json.addProperty(propertyKey, (Number) propertyValue);
+ } else {
+ if (!(propertyValue instanceof List)) {
+ return json;
+ }
+
+ Gson gson = new Gson();
+ String list = gson.toJson(propertyValue);
+ json.addProperty(propertyKey, list);
+ }
+ return json;
+ }
+
+ protected JsonArray createRelationshipObject(Vertex v) throws AAIFormatVertexException {
+ JsonArray relatedToList = new JsonArray();
+ Iterator<Edge> inIter = v.edges(Direction.IN);
+ Iterator<Edge> outIter = v.edges(Direction.OUT);
+
+ while (inIter.hasNext()) {
+ Edge e = inIter.next();
+ if (isValidEdge(e)) {
+ relatedToList.add(getRelatedObject(e, e.outVertex()));
+ }
+ }
+
+ while (outIter.hasNext()) {
+ Edge e = outIter.next();
+ if (isValidEdge(e)) {
+ relatedToList.add(getRelatedObject(e, e.inVertex()));
+ }
+ }
+
+ return relatedToList;
+
+ }
+
+ protected abstract boolean isValidEdge(Edge e);
+
+ protected abstract JsonObject getRelatedObject(Edge e, Vertex related) throws AAIFormatVertexException;
+
+
+
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, StartTs<Builder>, EndTs<Builder> {
+
+ protected final Loader loader;
+ protected final DBSerializer serializer;
+ protected final UrlBuilder urlBuilder;
+ protected boolean includeUrl = false;
+ protected boolean nodesOnly = false;
+ protected int depth = 1;
+ protected boolean modelDriven = false;
+ protected long startTs = -1;
+ protected long endTs = -1;
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ }
+
+ protected Loader getLoader() {
+ return this.loader;
+ }
+
+ protected DBSerializer getSerializer() {
+ return this.serializer;
+ }
+
+ protected UrlBuilder getUrlBuilder() {
+ return this.urlBuilder;
+ }
+
+ public Builder includeUrl() {
+ this.includeUrl = true;
+ return this;
+ }
+
+ public Builder nodesOnly(Boolean nodesOnly) {
+ this.nodesOnly = nodesOnly;
+ return this;
+ }
+
+ public Builder startTs(String startTs) {
+ this.startTs = Long.parseLong(startTs);
+ return this;
+ }
+
+ public Builder endTs(String endTs) {
+ this.endTs = Long.parseLong(endTs);
+ return this;
+ }
+
+
+ public boolean isNodesOnly() {
+ return this.nodesOnly;
+ }
+
+ public Builder depth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+
+ public boolean isIncludeUrl() {
+ return this.includeUrl;
+ }
+
+ public Builder modelDriven() {
+ this.modelDriven = true;
+ return this;
+ }
+
+ public boolean getModelDriven() {
+ return this.modelDriven;
+ }
+
+ public long getStartTs() {
+ return this.startTs;
+ }
+
+ public long getEndTs() {
+ return this.endTs;
+ }
+
+ public HistoryFormat build(Format format) {
+
+ if(Format.state.equals(format)) {
+ return new StateFormat(this);
+ } else {
+ return new LifecycleFormat(this);
+ }
+
+ }
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java
index c5cb9254..c2c252a2 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/IdURL.java
@@ -23,6 +23,8 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -31,9 +33,15 @@ import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.params.AsTree;
+import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.NodesOnly;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import javax.ws.rs.core.MultivaluedMap;
+
public class IdURL extends MultiFormatMapper {
private final UrlBuilder urlBuilder;
@@ -46,6 +54,13 @@ public class IdURL extends MultiFormatMapper {
this.loader = loader;
}
+ public IdURL(Builder builder) throws AAIException {
+ this.urlBuilder = builder.getUrlBuilder();
+ this.parser = new JsonParser();
+ this.loader = builder.getLoader();
+ this.isTree = builder.isTree();
+ }
+
@Override
public int parallelThreshold() {
return 2500;
@@ -69,4 +84,101 @@ public class IdURL extends MultiFormatMapper {
}
}
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
+
+ private final Loader loader;
+ private final DBSerializer serializer;
+ private final UrlBuilder urlBuilder;
+ private boolean includeUrl = false;
+ private boolean nodesOnly = false;
+ private int depth = 1;
+ private MultivaluedMap<String, String> params;
+ private boolean tree = false;
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ }
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder, MultivaluedMap<String, String> params) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ this.params = params;
+ }
+
+ protected Loader getLoader() {
+ return this.loader;
+ }
+
+ protected DBSerializer getSerializer() {
+ return this.serializer;
+ }
+
+ protected UrlBuilder getUrlBuilder() {
+ return this.urlBuilder;
+ }
+
+ protected MultivaluedMap<String, String> getParams() { return this.params; }
+
+ public boolean isSkipRelatedTo() {
+ if (params != null) {
+ boolean isSkipRelatedTo = true;
+ if (params.containsKey("skip-related-to")) {
+ String skipRelatedTo = params.getFirst("skip-related-to");
+ isSkipRelatedTo = !(skipRelatedTo != null && skipRelatedTo.equals("false"));
+ } else {
+ // if skip-related-to param is missing, then default it to false;
+ isSkipRelatedTo = false;
+ }
+ return isSkipRelatedTo;
+ }
+ return true;
+ }
+
+ protected boolean isTree() { return this.tree; }
+
+ public Builder isTree(Boolean tree) {
+ this.tree = tree;
+ return this;
+ }
+
+ public Builder includeUrl() {
+ this.includeUrl = true;
+ return this;
+ }
+
+ public Builder nodesOnly(Boolean nodesOnly) {
+ this.nodesOnly = nodesOnly;
+ return this;
+ }
+
+ public boolean isNodesOnly() {
+ return this.nodesOnly;
+ }
+
+ public Builder depth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+
+ public boolean isIncludeUrl() {
+ return this.includeUrl;
+ }
+
+ public IdURL build() throws AAIException {
+ return new IdURL(this);
+ }
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java
new file mode 100644
index 00000000..57bb17c2
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/LifecycleFormat.java
@@ -0,0 +1,313 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.serialization.queryformats;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+
+public class LifecycleFormat extends HistoryFormat {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LifecycleFormat.class);
+
+ protected LifecycleFormat(Builder builder) {
+ super(builder);
+ }
+
+ protected JsonArray createPropertiesObject(Vertex v) {
+ JsonArray jsonArray = new JsonArray();
+ Iterator<VertexProperty<Object>> iter = v.properties();
+ List<JsonObject> jsonList = new ArrayList<>();
+
+ Map<String, Set<Long>> propStartTimes = new HashMap<>(); //vertex end
+ while (iter.hasNext()) {
+ JsonObject json = new JsonObject();
+ VertexProperty<Object> prop = iter.next();
+ if(prop.key() != null && ignoredKeys.contains(prop.key())){
+ continue;
+ }
+ if (!propStartTimes.containsKey(prop.key())) {
+ propStartTimes.put(prop.key(), new HashSet<>());
+ if (v.property(AAIProperties.END_TS).isPresent()) {
+ propStartTimes.get(prop.key()).add(v.<Long>value(AAIProperties.END_TS));
+ }
+ }
+
+ json.addProperty(KEY, prop.key());
+ json = mapPropertyValues(json, VALUE, prop.value());
+ JsonObject metaProperties = createMetaPropertiesObject(prop);
+ if (isTsInRange(metaProperties.get(AAIProperties.START_TS).getAsLong())) {
+ JsonObject jo = new JsonObject();
+ jo.add(KEY, json.get(KEY));
+ jo.add(VALUE, json.get(VALUE));
+ jo.add(TIMESTAMP, metaProperties.get(AAIProperties.START_TS));
+ jo.add(SOT, metaProperties.get(AAIProperties.SOURCE_OF_TRUTH));
+ jo.add(TX_ID, metaProperties.get(AAIProperties.START_TX_ID));
+ jsonList.add(jo);
+ propStartTimes.get(prop.key()).add(metaProperties.get(AAIProperties.START_TS).getAsLong());
+ }
+ if (!AAIProperties.RESOURCE_VERSION.equals(prop.key())
+ && metaProperties.has(AAIProperties.END_TS)
+ && isTsInRange(metaProperties.get(AAIProperties.END_TS).getAsLong())
+ && !propStartTimes.get(prop.key()).contains(metaProperties.get(AAIProperties.END_TS).getAsLong())) {
+ JsonObject jo = new JsonObject();
+ jo.add(KEY, json.get(KEY));
+ jo.add(VALUE, null);
+ jo.add(TIMESTAMP, metaProperties.get(AAIProperties.END_TS));
+ jo.add(SOT, metaProperties.get(AAIProperties.END_SOT));
+ jo.add(TX_ID, metaProperties.get(AAIProperties.END_TX_ID));
+ jsonList.add(jo);
+ }
+
+ }
+ jsonList.stream()
+ // remove all the null values that is the start time for another value
+ .filter(jo -> !jo.get(VALUE).isJsonNull() || !propStartTimes.get(jo.get(KEY).getAsString()).contains(jo.get(TIMESTAMP).getAsLong()))
+ // sort by ts in decreasing order
+ .sorted((o1, o2) -> {
+ if (o1.get(TIMESTAMP).getAsLong() == o2.get(TIMESTAMP).getAsLong()) {
+ return o1.get(KEY).getAsString().compareTo(o2.get(KEY).getAsString());
+ } else {
+ return Long.compare(o2.get(TIMESTAMP).getAsLong(), o1.get(TIMESTAMP).getAsLong());
+ }
+ }).forEach(jsonArray::add);
+
+ return jsonArray;
+ }
+
+ private boolean isTsInRange(long ts) {
+ return ts >= startTs && ts <= endTs;
+ }
+
+
+ @Override
+ protected boolean isValidEdge(Edge e) {
+ if (e.property(AAIProperties.END_TS).isPresent()) {
+ long edgeStartTs = e.<Long>value(AAIProperties.START_TS);
+ long edgeEndTs = e.<Long>value(AAIProperties.END_TS);
+ return isTsInRange(edgeStartTs) || isTsInRange(edgeEndTs);
+ } else {
+ long edgeStartTs = e.<Long>value(AAIProperties.START_TS);
+ return isTsInRange(edgeStartTs);
+ }
+ }
+
+ @Override
+ protected JsonObject getRelatedObject(Edge e, Vertex related) throws AAIFormatVertexException {
+
+ JsonObject json = new JsonObject();
+ json.addProperty("relationship-label", e.label());
+ json.addProperty("node-type", related.<String>value(AAIProperties.NODE_TYPE));
+ json.addProperty("url", this.urlBuilder.pathed(related));
+ if (related.property(AAIProperties.AAI_URI).isPresent()) {
+ json.addProperty("uri", related.<String>value(AAIProperties.AAI_URI));
+ } else {
+ LOGGER.warn("Vertex {} is missing aai-uri", related.id());
+ json.addProperty("uri", "NA");
+ }
+
+ if(e.property(AAIProperties.START_TS).isPresent()) {
+ long edgeStartTimestamp = e.<Long>value(AAIProperties.START_TS);
+ if (isTsInRange(edgeStartTimestamp)) {
+ json.addProperty(TIMESTAMP, e.property(AAIProperties.START_TS).isPresent()? e.<Long>value(AAIProperties.START_TS) : 0);
+ json.addProperty(SOT, e.property(AAIProperties.SOURCE_OF_TRUTH).isPresent()? e.value(AAIProperties.SOURCE_OF_TRUTH) : "");
+ json.addProperty(TX_ID, e.property(AAIProperties.START_TX_ID).isPresent()? e.value(AAIProperties.START_TX_ID) : "N/A");
+ }
+ }
+
+ if(e.property(AAIProperties.END_TS).isPresent()) {
+ long edgeEndTimestamp = e.<Long>value(AAIProperties.END_TS);
+ if (isTsInRange(edgeEndTimestamp)) {
+ json.addProperty(END_TIMESTAMP, edgeEndTimestamp);
+ json.addProperty(END_SOT, e.property(AAIProperties.END_SOT).isPresent() ? e.value(AAIProperties.END_SOT) : "");
+ json.addProperty(END_TX_ID, e.property(AAIProperties.END_TX_ID).isPresent() ? e.value(AAIProperties.END_TX_ID) : "N/A");
+ }
+ }
+
+ return json;
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+ json.addProperty(NODE_TYPE, v.<String>value(AAIProperties.NODE_TYPE));
+ json.addProperty("url", this.urlBuilder.pathed(v));
+ if (v.property(AAIProperties.AAI_URI).isPresent()) {
+ json.addProperty("uri", v.<String>value(AAIProperties.AAI_URI));
+ } else {
+ LOGGER.warn("Vertex {} is missing aai-uri", v.id());
+ json.addProperty("uri", "NA");
+ }
+ json.addProperty(TIMESTAMP, v.<Long>value(AAIProperties.START_TS));
+
+ json.add(PROPERTIES, this.createPropertiesObject(v));
+
+ if (!nodesOnly) {
+ json.add(RELATED_TO, this.createRelationshipObject(v));
+ }
+
+ json.add(NODE_ACTIONS, getNodeActions(v, json));
+
+ if (json.getAsJsonObject().get(PROPERTIES).getAsJsonArray().size() == 0
+ && json.getAsJsonObject().get(RELATED_TO).getAsJsonArray().size() == 0
+ && json.getAsJsonObject().get(NODE_ACTIONS).getAsJsonArray().size() == 0) {
+ return Optional.empty();
+ } else if (json.getAsJsonObject().get(PROPERTIES).getAsJsonArray().size() == 1
+ && (json.getAsJsonObject().get(RELATED_TO).getAsJsonArray().size() > 0
+ || json.getAsJsonObject().get(NODE_ACTIONS).getAsJsonArray().size() > 0)) {
+ if (json.getAsJsonObject().get(PROPERTIES).getAsJsonArray()
+ .get(0).getAsJsonObject().get("key").getAsString().equals(AAIProperties.END_TS)) {
+ json.getAsJsonObject().add(PROPERTIES, new JsonArray());
+ }
+ }
+
+ return Optional.of(json);
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+
+ private JsonArray getNodeActions(Vertex v, JsonObject json) {
+ JsonArray nodeActions = new JsonArray();
+ JsonObject action;
+ if (v.property(AAIProperties.END_TS).isPresent()) {
+ long deletedTs = (Long) v.property(AAIProperties.END_TS).value();
+ if (isTsInRange(deletedTs)) {
+ action = new JsonObject();
+ action.addProperty("action", "DELETED");
+ action.addProperty(TIMESTAMP, deletedTs);
+ if (v.property(AAIProperties.END_TS).property(AAIProperties.SOURCE_OF_TRUTH).isPresent()) {
+ action.addProperty(SOT, v.property(AAIProperties.END_TS).<String>value(AAIProperties.SOURCE_OF_TRUTH));
+ }
+ if (v.property(AAIProperties.END_TS).property(AAIProperties.END_TX_ID).isPresent()) {
+ action.addProperty(TX_ID, v.property(AAIProperties.END_TS).<String>value(AAIProperties.END_TX_ID));
+ } else {
+ action.addProperty(TX_ID, "N/A");
+ }
+ nodeActions.add(action);
+ }
+ }
+ long createdTs = json.get(TIMESTAMP).getAsLong();
+ if (isTsInRange(createdTs)) {
+ action = new JsonObject();
+ action.addProperty("action", "CREATED");
+ action.addProperty(TIMESTAMP, createdTs);
+ action.addProperty(SOT, v.<String>value(AAIProperties.SOURCE_OF_TRUTH));
+ if (v.property(AAIProperties.SOURCE_OF_TRUTH).property(AAIProperties.START_TX_ID).isPresent()) {
+ action.addProperty(TX_ID, v.property(AAIProperties.SOURCE_OF_TRUTH).<String>value(AAIProperties.START_TX_ID));
+ } else {
+ action.addProperty(TX_ID, "N/A");
+ }
+ nodeActions.add(action);
+ }
+ return nodeActions;
+ }
+
+ public JsonArray process(List<Object> queryResults) {
+ JsonArray body = new JsonArray();
+ Stream<Object> stream;
+ if (queryResults.size() >= this.parallelThreshold()) {
+ stream = queryResults.parallelStream();
+ } else {
+ stream = queryResults.stream();
+ }
+
+ final boolean isParallel = stream.isParallel();
+
+ stream.map(o -> {
+ try {
+ return this.formatObject(o);
+ } catch (AAIFormatVertexException e) {
+ LOGGER.warn("Failed to format vertex, returning a partial list " + LogFormatTools.getStackTop(e));
+ } catch (AAIFormatQueryResultFormatNotSupported e) {
+ LOGGER.warn("Failed to format result type of the query " + LogFormatTools.getStackTop(e));
+ }
+
+ return Optional.<JsonObject>empty();
+ }).filter(Optional::isPresent)
+ .map(Optional::get)
+ .forEach(json -> {
+ if (isParallel) {
+ synchronized (body) {
+ body.add(json);
+ }
+ } else {
+ body.add(json);
+ }
+ });
+ JsonArray result = organizeBody(body);
+ result.forEach(jsonElement -> jsonElement.getAsJsonObject().remove(TIMESTAMP));
+ return result;
+ }
+
+ private JsonArray organizeBody(JsonArray body) {
+
+ final MultiValueMap<String, Integer> toBeMerged = new LinkedMultiValueMap<>();
+ for (int i = 0; i < body.size(); i++) {
+ toBeMerged.add(body.get(i).getAsJsonObject().get("uri").getAsString(), i);
+ }
+
+ final List<List<Integer>> dupes = toBeMerged.values().stream().filter(l -> l.size() > 1).collect(Collectors.toList());
+ if (dupes.isEmpty()) {
+ return body;
+ } else {
+ Set<Integer> remove = new HashSet<>();
+ for (List<Integer> dupe : dupes) {
+ dupe.sort((a,b) -> Long.compare(body.get(b).getAsJsonObject().get(TIMESTAMP).getAsLong(), body.get(a).getAsJsonObject().get(TIMESTAMP).getAsLong()));
+ int keep = dupe.remove(0);
+ for (Integer idx : dupe) {
+ body.get(keep).getAsJsonObject().getAsJsonArray(NODE_ACTIONS)
+ .addAll(body.get(idx).getAsJsonObject().getAsJsonArray(NODE_ACTIONS));
+ body.get(keep).getAsJsonObject().getAsJsonArray(PROPERTIES)
+ .addAll(body.get(idx).getAsJsonObject().getAsJsonArray(PROPERTIES));
+ body.get(keep).getAsJsonObject().getAsJsonArray(RELATED_TO)
+ .addAll(body.get(idx).getAsJsonObject().getAsJsonArray(RELATED_TO));
+ remove.add(idx);
+ }
+ }
+ final JsonArray newBody = new JsonArray();
+ for (int i = 0; i < body.size(); i++) {
+ if (!remove.contains(i)) {
+ newBody.add(body.get(i));
+ }
+ }
+ return newBody;
+ }
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java
index 21b666f2..b06ef7c3 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/MultiFormatMapper.java
@@ -22,26 +22,49 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatQueryResultFormatNotSupported;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
public abstract class MultiFormatMapper implements FormatMapper {
+ protected boolean isTree = false;
+
@Override
public Optional<JsonObject> formatObject(Object input)
throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
if (input instanceof Vertex) {
return this.getJsonFromVertex((Vertex) input);
} else if (input instanceof Tree) {
- return this.getJsonFomTree((Tree<?>) input);
+ if (isTree) {
+ return this.getRelatedNodesFromTree((Tree<?>) input);
+ } else {
+ return this.getJsonFomTree((Tree<?>) input);
+ }
+ } else if (input instanceof Path) {
+ return this.getJsonFromPath((Path) input);
+ } else {
+ throw new AAIFormatQueryResultFormatNotSupported();
+ }
+ }
+
+ @Override
+ public Optional<JsonObject> formatObject(Object input, Map<String, List<String>> properties)
+ throws AAIFormatVertexException, AAIFormatQueryResultFormatNotSupported {
+ if (input instanceof Vertex) {
+ return this.getJsonFromVertex((Vertex) input, properties);
+ } else if (input instanceof Tree) {
+ if (isTree) {
+ return this.getRelatedNodesFromTree((Tree<?>) input);
+ } else {
+ return this.getJsonFomTree((Tree<?>) input);
+ }
} else if (input instanceof Path) {
return this.getJsonFromPath((Path) input);
} else {
@@ -50,6 +73,7 @@ public abstract class MultiFormatMapper implements FormatMapper {
}
protected abstract Optional<JsonObject> getJsonFromVertex(Vertex input) throws AAIFormatVertexException;
+ protected abstract Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException;
protected Optional<JsonObject> getJsonFromPath(Path input) throws AAIFormatVertexException {
List<Object> path = input.objects();
@@ -59,7 +83,8 @@ public abstract class MultiFormatMapper implements FormatMapper {
for (Object o : path) {
if (o instanceof Vertex) {
- ja.add(this.getJsonFromVertex((Vertex) o).get());
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) o);
+ obj.ifPresent(ja::add);
}
}
@@ -74,7 +99,7 @@ public abstract class MultiFormatMapper implements FormatMapper {
}
JsonObject t = new JsonObject();
- JsonArray ja = this.getNodesArray(tree);
+ JsonArray ja = this.getNodesArray(tree, "nodes");
if (ja.size() > 0) {
t.add("nodes", ja);
}
@@ -82,20 +107,37 @@ public abstract class MultiFormatMapper implements FormatMapper {
return Optional.of(t);
}
- private JsonArray getNodesArray(Tree<?> tree) throws AAIFormatVertexException {
+ protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree) throws AAIFormatVertexException {
+ if (tree.isEmpty()) {
+ return Optional.of(new JsonObject());
+ }
- JsonArray nodes = new JsonArray();
- Iterator<?> it = tree.keySet().iterator();
+ JsonObject t = new JsonObject();
+ JsonArray ja = this.getNodesArray(tree, "related-nodes");
+ if (ja.size() > 0) {
+ t.add("results", ja);
+ return Optional.of(t);
+ }
+
+ return Optional.empty();
+ }
+
+ protected JsonArray getNodesArray(Tree<?> tree, String nodeIdentifier) throws AAIFormatVertexException {
- while (it.hasNext()) {
- Object o = it.next();
+ JsonArray nodes = new JsonArray();
+ for (Map.Entry<?, ? extends Tree<?>> entry : tree.entrySet()) {
JsonObject me = new JsonObject();
- if (o instanceof Vertex) {
- me = this.getJsonFromVertex((Vertex) o).get();
+ if (entry.getKey() instanceof Vertex) {
+ Optional<JsonObject> obj = this.getJsonFromVertex((Vertex) entry.getKey());
+ if (obj.isPresent()) {
+ me = obj.get();
+ } else {
+ continue;
+ }
}
- JsonArray ja = this.getNodesArray((Tree<?>) tree.get(o));
+ JsonArray ja = this.getNodesArray(entry.getValue(), nodeIdentifier);
if (ja.size() > 0) {
- me.add("nodes", ja);
+ me.add(nodeIdentifier, ja);
}
nodes.add(me);
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java
index a99ba7f4..417f73cd 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/PathedURL.java
@@ -23,6 +23,8 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -31,9 +33,15 @@ import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.params.AsTree;
+import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.NodesOnly;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import javax.ws.rs.core.MultivaluedMap;
+
public final class PathedURL extends MultiFormatMapper {
private final UrlBuilder urlBuilder;
@@ -47,6 +55,13 @@ public final class PathedURL extends MultiFormatMapper {
this.loader = loader;
}
+ public PathedURL(Builder builder) {
+ this.urlBuilder = builder.getUrlBuilder();
+ this.parser = new JsonParser();
+ this.loader = builder.getLoader();
+ this.isTree = builder.isTree();
+ }
+
@Override
public int parallelThreshold() {
return 20;
@@ -79,4 +94,101 @@ public final class PathedURL extends MultiFormatMapper {
}
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
+
+ private final Loader loader;
+ private final DBSerializer serializer;
+ private final UrlBuilder urlBuilder;
+ private boolean includeUrl = false;
+ private boolean nodesOnly = false;
+ private int depth = 1;
+ private MultivaluedMap<String, String> params;
+ private boolean tree = false;
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ }
+
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder, MultivaluedMap<String, String> params) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ this.params = params;
+ }
+
+ protected Loader getLoader() {
+ return this.loader;
+ }
+
+ protected DBSerializer getSerializer() {
+ return this.serializer;
+ }
+
+ protected UrlBuilder getUrlBuilder() {
+ return this.urlBuilder;
+ }
+
+ protected MultivaluedMap<String, String> getParams() { return this.params; }
+
+ public boolean isSkipRelatedTo() {
+ if (params != null) {
+ boolean isSkipRelatedTo = true;
+ if (params.containsKey("skip-related-to")) {
+ String skipRelatedTo = params.getFirst("skip-related-to");
+ isSkipRelatedTo = !(skipRelatedTo != null && skipRelatedTo.equals("false"));
+ } else {
+ // if skip-related-to param is missing, then default it to false;
+ isSkipRelatedTo = false;
+ }
+ return isSkipRelatedTo;
+ }
+ return true;
+ }
+
+ protected boolean isTree() { return this.tree; }
+
+ public Builder isTree(Boolean tree) {
+ this.tree = tree;
+ return this;
+ }
+
+ public Builder includeUrl() {
+ this.includeUrl = true;
+ return this;
+ }
+
+ public Builder nodesOnly(Boolean nodesOnly) {
+ this.nodesOnly = nodesOnly;
+ return this;
+ }
+
+ public boolean isNodesOnly() {
+ return this.nodesOnly;
+ }
+
+ public Builder depth(Integer depth) {
+ this.depth = depth;
+ return this;
+ }
+
+ public int getDepth() {
+ return this.depth;
+ }
+
+ public boolean isIncludeUrl() {
+ return this.includeUrl;
+ }
+
+ public PathedURL build() throws AAIException {
+ return new PathedURL(this);
+ }
+ }
+
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java
index 8636ebfa..8dcd3a83 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/RawFormat.java
@@ -25,9 +25,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
+import java.util.stream.Collectors;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -38,6 +37,7 @@ import org.onap.aai.introspection.Loader;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.AsTree;
import org.onap.aai.serialization.queryformats.params.NodesOnly;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
@@ -55,6 +55,25 @@ public class RawFormat extends MultiFormatMapper {
this.serializer = builder.getSerializer();
this.depth = builder.getDepth();
this.nodesOnly = builder.isNodesOnly();
+ this.isTree = builder.isTree();
+ }
+
+ @Override
+ public Optional<JsonObject> getJsonFromVertex(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+ json.addProperty("id", v.id().toString());
+ json.addProperty("node-type", v.<String>value(AAIProperties.NODE_TYPE));
+ json.addProperty("url", this.urlBuilder.pathed(v));
+ Optional<JsonObject> properties = this.createSelectedPropertiesObject(v, selectedProps);
+ if (properties.isPresent()) {
+ json.add("properties", properties.get());
+ } else {
+ return Optional.empty();
+ }
+ if (!nodesOnly) {
+ json.add("related-to", this.createRelationshipObject(v));
+ }
+ return Optional.of(json);
}
@Override
@@ -88,6 +107,48 @@ public class RawFormat extends MultiFormatMapper {
return Optional.of(json);
}
+ public Optional<JsonObject> createSelectedPropertiesObject(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
+ JsonObject json = new JsonObject();
+ String nodeType = v.<String>value(AAIProperties.NODE_TYPE);
+ Set<String> propList = removeSingleQuotesForProperties(selectedProps.get(nodeType));
+ Iterator<VertexProperty<Object>> iter = v.properties();
+
+ Gson gson = new Gson();
+ while (iter.hasNext()) {
+ VertexProperty<Object> prop = iter.next();
+ if (propList != null && !propList.isEmpty()) {
+ if (propList.contains(prop.label())) {
+ if (prop.value() instanceof String) {
+ json.addProperty(prop.key(), (String) prop.value());
+ } else if (prop.value() instanceof Boolean) {
+ json.addProperty(prop.key(), (Boolean) prop.value());
+ } else if (prop.value() instanceof Number) {
+ json.addProperty(prop.key(), (Number) prop.value());
+ } else if (prop.value() instanceof List) {
+ json.addProperty(prop.key(), gson.toJson(prop.value()));
+ } else {
+ // throw exception?
+ return null;
+ }
+ }
+ } else {
+ return this.createPropertiesObject(v);
+ }
+ }
+
+ return Optional.of(json);
+ }
+
+ private Set<String> removeSingleQuotesForProperties(List<String> props){
+ if (props != null && !props.isEmpty()) {
+ return props.stream().map(
+ e -> e.substring(1, e.length()-1)).collect(Collectors.toSet());
+ } else {
+ return Collections.emptySet();
+ }
+
+ }
+
protected JsonArray createRelationshipObject(Vertex v) throws AAIFormatVertexException {
JsonArray jarray = new JsonArray();
Iterator<Edge> inIter = v.edges(Direction.IN);
@@ -122,7 +183,7 @@ public class RawFormat extends MultiFormatMapper {
return json;
}
- public static class Builder implements NodesOnly<Builder>, Depth<Builder> {
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
protected final Loader loader;
protected final DBSerializer serializer;
@@ -131,6 +192,7 @@ public class RawFormat extends MultiFormatMapper {
protected boolean nodesOnly = false;
protected int depth = 1;
protected boolean modelDriven = false;
+ protected boolean tree = false;
public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
this.loader = loader;
@@ -150,6 +212,13 @@ public class RawFormat extends MultiFormatMapper {
return this.urlBuilder;
}
+ protected boolean isTree() { return this.tree; }
+
+ public Builder isTree(Boolean tree) {
+ this.tree = tree;
+ return this;
+ }
+
public Builder includeUrl() {
this.includeUrl = true;
return this;
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java
index b92f5858..a53be6a3 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/Resource.java
@@ -20,14 +20,17 @@
package org.onap.aai.serialization.queryformats;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
+import java.util.stream.Stream;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.exceptions.AAIException;
@@ -37,9 +40,12 @@ import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
import org.onap.aai.serialization.queryformats.params.Depth;
+import org.onap.aai.serialization.queryformats.params.AsTree;
import org.onap.aai.serialization.queryformats.params.NodesOnly;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
+import javax.ws.rs.core.MultivaluedMap;
+
public class Resource extends MultiFormatMapper {
private final Loader loader;
@@ -49,8 +55,9 @@ public class Resource extends MultiFormatMapper {
private final boolean includeUrl;
private final boolean nodesOnly;
private final int depth;
+ private final boolean isSkipRelatedTo;
- private Resource(Builder builder) {
+ public Resource(Builder builder) {
this.parser = new JsonParser();
this.loader = builder.getLoader();
this.serializer = builder.getSerializer();
@@ -58,6 +65,54 @@ public class Resource extends MultiFormatMapper {
this.includeUrl = builder.isIncludeUrl();
this.nodesOnly = builder.isNodesOnly();
this.depth = builder.getDepth();
+ this.isSkipRelatedTo = builder.isSkipRelatedTo();
+ this.isTree = builder.isTree();
+ }
+
+ @Override
+ protected Optional<JsonObject> getRelatedNodesFromTree(Tree<?> tree) throws AAIFormatVertexException {
+ if (tree.isEmpty()) {
+ return Optional.of(new JsonObject());
+ }
+ JsonObject t = new JsonObject();
+ JsonArray ja = this.getRelatedNodesArray(tree, "related-nodes");
+ if (ja.size() > 0) {
+ t.add("results", ja);
+ return Optional.of(t);
+ }
+
+ return Optional.empty();
+ }
+
+ protected JsonArray getRelatedNodesArray(Tree<?> tree, String nodeIdentifier) throws AAIFormatVertexException {
+ JsonArray nodes = new JsonArray();
+ if (tree.isEmpty()) {
+ return nodes;
+ }
+ for (Map.Entry<?, ? extends Tree<?>> entry : tree.entrySet()) {
+ JsonObject me = new JsonObject();
+ if (entry.getKey() instanceof Vertex) {
+ Optional<JsonObject> obj = null;
+ if (entry.getKey() != null) {
+ obj = this.getJsonFromVertex((Vertex) entry.getKey());
+ }
+ if (obj != null && obj.isPresent()) {
+ me = obj.get();
+ } else {
+ continue;
+ }
+ }
+ JsonArray ja = this.getRelatedNodesArray(entry.getValue(), nodeIdentifier);
+ if (ja.size() > 0) {
+ try {
+ me.entrySet().stream().findFirst().get().getValue().getAsJsonObject().add(nodeIdentifier, ja);
+ } catch(Exception e) {
+ throw new AAIFormatVertexException("Failed to add related-nodes array: " + e.getMessage(), e);
+ }
+ }
+ nodes.add(me);
+ }
+ return nodes;
}
@Override
@@ -77,7 +132,15 @@ public class Resource extends MultiFormatMapper {
return Optional.of(json);
}
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+
protected Optional<JsonObject> vertexToJsonObject(Vertex v) throws AAIFormatVertexException {
+ if (v == null) {
+ return Optional.empty();
+ }
try {
final Introspector obj =
getLoader().introspectorFromName(v.<String>property(AAIProperties.NODE_TYPE).orElse(null));
@@ -87,7 +150,7 @@ public class Resource extends MultiFormatMapper {
wrapper.add(v);
try {
- getSerializer().dbToObject(wrapper, obj, this.depth, this.nodesOnly, "false");
+ getSerializer().dbToObject(wrapper, obj, this.depth, this.nodesOnly, "false", isSkipRelatedTo);
} catch (AAIException | UnsupportedEncodingException e) {
throw new AAIFormatVertexException(
"Failed to format vertex - error while serializing: " + e.getMessage(), e);
@@ -118,7 +181,7 @@ public class Resource extends MultiFormatMapper {
return parser;
}
- public static class Builder implements NodesOnly<Builder>, Depth<Builder> {
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
private final Loader loader;
private final DBSerializer serializer;
@@ -126,6 +189,8 @@ public class Resource extends MultiFormatMapper {
private boolean includeUrl = false;
private boolean nodesOnly = false;
private int depth = 1;
+ private MultivaluedMap<String, String> params;
+ private boolean tree = false;
public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
this.loader = loader;
@@ -133,6 +198,13 @@ public class Resource extends MultiFormatMapper {
this.urlBuilder = urlBuilder;
}
+ public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder, MultivaluedMap<String, String> params) {
+ this.loader = loader;
+ this.serializer = serializer;
+ this.urlBuilder = urlBuilder;
+ this.params = params;
+ }
+
protected Loader getLoader() {
return this.loader;
}
@@ -145,6 +217,31 @@ public class Resource extends MultiFormatMapper {
return this.urlBuilder;
}
+ protected MultivaluedMap<String, String> getParams() { return this.params; }
+
+ public boolean isSkipRelatedTo() {
+ if (params != null) {
+ boolean isSkipRelatedTo = true;
+ if (params.containsKey("skip-related-to")) {
+ String skipRelatedTo = params.getFirst("skip-related-to");
+ isSkipRelatedTo = !(skipRelatedTo != null && skipRelatedTo.equals("false"));
+ } else {
+ // if skip-related-to param is missing, then default it to false;
+ isSkipRelatedTo = false;
+ }
+ return isSkipRelatedTo;
+ }
+ return true;
+ }
+
+ protected boolean isTree() { return this.tree; }
+
+ public Builder isTree(Boolean tree) {
+ this.tree = tree;
+ return this;
+ }
+
+
public Builder includeUrl() {
this.includeUrl = true;
return this;
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ResourceWithSoT.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ResourceWithSoT.java
index e4107aa9..d70f5c8e 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ResourceWithSoT.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/ResourceWithSoT.java
@@ -23,6 +23,8 @@ package org.onap.aai.serialization.queryformats;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -30,11 +32,14 @@ import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.introspection.Loader;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+import org.onap.aai.serialization.queryformats.params.AsTree;
import org.onap.aai.serialization.queryformats.params.Depth;
import org.onap.aai.serialization.queryformats.params.NodesOnly;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
import org.onap.aai.util.AAIConfig;
+import java.util.Optional;
+
public class ResourceWithSoT extends MultiFormatMapper {
protected JsonParser parser = new JsonParser();
protected final DBSerializer serializer;
@@ -49,6 +54,7 @@ public class ResourceWithSoT extends MultiFormatMapper {
this.serializer = builder.getSerializer();
this.depth = builder.getDepth();
this.nodesOnly = builder.isNodesOnly();
+ this.isTree = builder.isTree();
}
@Override
@@ -56,7 +62,7 @@ public class ResourceWithSoT extends MultiFormatMapper {
return 100;
}
- public static class Builder implements NodesOnly<Builder>, Depth<Builder> {
+ public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
protected final Loader loader;
protected final DBSerializer serializer;
@@ -65,6 +71,7 @@ public class ResourceWithSoT extends MultiFormatMapper {
protected boolean nodesOnly = false;
protected int depth = 1;
protected boolean modelDriven = false;
+ protected boolean tree = false;
public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
this.loader = loader;
@@ -89,6 +96,13 @@ public class ResourceWithSoT extends MultiFormatMapper {
return this;
}
+ protected boolean isTree() { return this.tree; }
+
+ public Builder isTree(Boolean tree) {
+ this.tree = tree;
+ return this;
+ }
+
public Builder nodesOnly(Boolean nodesOnly) {
this.nodesOnly = nodesOnly;
return this;
@@ -139,8 +153,9 @@ public class ResourceWithSoT extends MultiFormatMapper {
@Override
protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
// Null check
- if (v == null)
+ if (v == null) {
return null;
+ }
JsonObject json = new JsonObject();
@@ -148,9 +163,9 @@ public class ResourceWithSoT extends MultiFormatMapper {
Object lastModifiedTimestampObj = v.property(AAIProperties.LAST_MOD_TS).value();
Object sotObj = v.property(AAIProperties.SOURCE_OF_TRUTH).value();
Object lastModSotObj = v.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH).value();
- long createdTimestamp = Long.valueOf(createdTimestampObj.toString());
- long lastModifiedTimestamp = Long.valueOf(lastModifiedTimestampObj.toString());
- long threshold = Long.valueOf(AAIConfig.get("aai.resource.format.threshold", "10"));
+ long createdTimestamp = Long.parseLong(createdTimestampObj.toString());
+ long lastModifiedTimestamp = Long.parseLong(lastModifiedTimestampObj.toString());
+ long threshold = Long.parseLong(AAIConfig.get("aai.resource.format.threshold", "10"));
// Add to the property field of the JSON payload
json.addProperty("aai-created-ts", createdTimestampObj.toString());
@@ -172,4 +187,9 @@ public class ResourceWithSoT extends MultiFormatMapper {
return Optional.of(json);
}
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/StateFormat.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/StateFormat.java
new file mode 100644
index 00000000..b2813476
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/StateFormat.java
@@ -0,0 +1,144 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.serialization.queryformats;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
+
+import java.util.*;
+
+public class StateFormat extends HistoryFormat {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(StateFormat.class);
+
+ protected StateFormat(HistoryFormat.Builder builder) {
+ super(builder);
+ }
+
+ protected JsonArray createPropertiesObject(Vertex v) {
+ Iterator<VertexProperty<Object>> iter = v.properties();
+ List<JsonObject> jsonList = new ArrayList<>();
+ while (iter.hasNext()) {
+ VertexProperty<Object> prop = iter.next();
+ if (prop.key() != null && ignoredKeys.contains(prop.key())) {
+ continue;
+ }
+
+ JsonObject metaProperties = createMetaPropertiesObject(prop);
+ if (isTsInRange(metaProperties)) {
+ JsonObject json = new JsonObject();
+ json.addProperty(KEY, prop.key());
+ json = mapPropertyValues(json, VALUE, prop.value());
+ addMetaProperties(json, metaProperties);
+ jsonList.add(json);
+ }
+ }
+
+ JsonArray jsonArray = new JsonArray();
+ jsonList.stream().sorted(Comparator.comparingLong(o -> o.get(TIMESTAMP).getAsLong())).forEach(jsonArray::add);
+ return jsonArray;
+ }
+
+ private boolean isTsInRange(JsonObject metaProperties) {
+ long sTs = metaProperties.get(AAIProperties.START_TS).getAsLong();
+ long eTs = Long.MAX_VALUE;
+ if (metaProperties.has(AAIProperties.END_TS)) {
+ eTs = metaProperties.get(AAIProperties.END_TS).getAsLong();
+ }
+
+ return startTs >= sTs && eTs > startTs;
+ }
+
+ @Override
+ protected boolean isValidEdge(Edge e) {
+ if (e.property(AAIProperties.END_TS).isPresent()) {
+ long edgeEndTs = e.value(AAIProperties.END_TS);
+ if (startTs >= edgeEndTs) {
+ return false;
+ }
+ }
+ if (e.property(AAIProperties.START_TS).isPresent()) {
+ long edgeStartTs = e.value(AAIProperties.START_TS);
+ return startTs >= edgeStartTs;
+ }
+ return true;
+ }
+
+ @Override
+ protected JsonObject getRelatedObject(Edge e, Vertex related) throws AAIFormatVertexException {
+
+ JsonObject json = new JsonObject();
+ json.addProperty("relationship-label", e.label());
+ json.addProperty(NODE_TYPE, related.<String>value(AAIProperties.NODE_TYPE));
+ json.addProperty("url", this.urlBuilder.pathed(related));
+ if (related.property(AAIProperties.AAI_URI).isPresent()) {
+ json.addProperty("uri", related.<String>value(AAIProperties.AAI_URI));
+ } else {
+ LOGGER.warn("Vertex {} is missing aai-uri", related.id());
+ json.addProperty("uri", "NA");
+ }
+ json.addProperty(TIMESTAMP, e.property(AAIProperties.START_TS).isPresent()? e.value(AAIProperties.START_TS) : 0);
+ json.addProperty(SOT, e.property(AAIProperties.SOURCE_OF_TRUTH).isPresent()? e.value(AAIProperties.SOURCE_OF_TRUTH) : "");
+ json.addProperty(TX_ID, e.property(AAIProperties.START_TX_ID).isPresent()? e.value(AAIProperties.START_TX_ID) : "N/A");
+
+ return json;
+ }
+
+
+ protected void addMetaProperties(JsonObject json, JsonObject metaProperties) {
+ json.addProperty(TIMESTAMP, metaProperties.get(AAIProperties.START_TS) != null ? metaProperties.get(AAIProperties.START_TS).getAsLong() : 0);
+ json.addProperty(SOT, metaProperties.get(AAIProperties.SOURCE_OF_TRUTH) != null ? metaProperties.get(AAIProperties.SOURCE_OF_TRUTH).getAsString() : "");
+ json.addProperty(TX_ID, metaProperties.get(AAIProperties.START_TX_ID) != null ? metaProperties.get(AAIProperties.START_TX_ID).getAsString() : "N/A");
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
+
+ JsonObject json = new JsonObject();
+ json.addProperty(NODE_TYPE, v.<String>value(AAIProperties.NODE_TYPE));
+ json.addProperty("url", this.urlBuilder.pathed(v));
+ json.addProperty("uri", v.property(AAIProperties.AAI_URI).value().toString());
+ JsonArray properties = this.createPropertiesObject(v);
+
+ if (properties.size() > 0) {
+ json.add(PROPERTIES, properties);
+ } else {
+ return Optional.empty();
+ }
+ if (!nodesOnly) {
+ json.add(RELATED_TO, this.createRelationshipObject(v));
+ }
+ return Optional.of(json);
+ }
+
+ @Override
+ protected Optional<JsonObject> getJsonFromVertex(Vertex input, Map<String, List<String>> properties) throws AAIFormatVertexException {
+ return Optional.empty();
+ }
+
+}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/LoggingContextNotExistsException.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/AsTree.java
index f1d4c59c..c7479147 100644
--- a/aai-core/src/main/java/org/onap/aai/logging/LoggingContextNotExistsException.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/AsTree.java
@@ -18,9 +18,11 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.logging;
+package org.onap.aai.serialization.queryformats.params;
-public class LoggingContextNotExistsException extends RuntimeException {
+@Inject(name = "as-tree")
+public interface AsTree<T> {
- private static final long serialVersionUID = -4965807709525739623L;
+ @Setter
+ public T isTree(Boolean tree);
}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/ErrorObjectFormatException.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/EndTs.java
index 8d53f2e3..937d87f2 100644
--- a/aai-core/src/main/java/org/onap/aai/logging/ErrorObjectFormatException.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/EndTs.java
@@ -18,13 +18,11 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.logging;
+package org.onap.aai.serialization.queryformats.params;
-public class ErrorObjectFormatException extends Exception {
+@Inject(name = "endTs")
+public interface EndTs<T> {
- private static final long serialVersionUID = 3732705544448553685L;
-
- public ErrorObjectFormatException() {
- super();
- }
+ @Setter
+ public T endTs(String endTs);
}
diff --git a/aai-core/src/main/java/org/onap/aai/logging/CustomLogPatternLayout.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/StartTs.java
index 63cc49f7..e94b893d 100644
--- a/aai-core/src/main/java/org/onap/aai/logging/CustomLogPatternLayout.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/params/StartTs.java
@@ -18,11 +18,11 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.logging;
+package org.onap.aai.serialization.queryformats.params;
-public class CustomLogPatternLayout extends ch.qos.logback.access.PatternLayout {
- static {
- defaultConverterMap.put("z", CNName.class.getName());
- defaultConverterMap.put("y", DME2RestFlag.class.getName());
- }
+@Inject(name = "startTs")
+public interface StartTs<T> {
+
+ @Setter
+ public T startTs(String startTs);
}
diff --git a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/QueryParamInjector.java b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/QueryParamInjector.java
index 1b51088e..f90907e2 100644
--- a/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/QueryParamInjector.java
+++ b/aai-core/src/main/java/org/onap/aai/serialization/queryformats/utils/QueryParamInjector.java
@@ -20,25 +20,23 @@
package org.onap.aai.serialization.queryformats.utils;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Set;
+import org.onap.aai.serialization.queryformats.exceptions.QueryParamInjectionException;
+import org.onap.aai.serialization.queryformats.params.*;
import javax.ws.rs.core.MultivaluedMap;
-
-import org.onap.aai.serialization.queryformats.exceptions.QueryParamInjectionException;
-import org.onap.aai.serialization.queryformats.params.Inject;
-import org.onap.aai.serialization.queryformats.params.Setter;
-import org.reflections.Reflections;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
public class QueryParamInjector {
- private final Set<Class<?>> results;
-
- private QueryParamInjector() {
- Reflections reflections = new Reflections("org.onap.aai.serialization.queryformats.params");
- results = reflections.getTypesAnnotatedWith(Inject.class);
- }
+ //TODO reimplement this using reflections.
+ private static final Class<?>[] PARAM_CLASSES = new Class[] {
+ AsTree.class,
+ Depth.class,
+ EndTs.class,
+ NodesOnly.class,
+ StartTs.class
+ };
private static class Helper {
private static final QueryParamInjector INSTANCE = new QueryParamInjector();
@@ -50,7 +48,7 @@ public class QueryParamInjector {
public <T> T injectParams(T obj, MultivaluedMap<String, String> params) throws QueryParamInjectionException {
try {
- for (Class<?> item : results) {
+ for (Class<?> item : PARAM_CLASSES) {
if (item.isAssignableFrom(obj.getClass())) {
String name = item.getAnnotation(Inject.class).name();
diff --git a/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java b/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java
index 316e3017..6c57616e 100644
--- a/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java
+++ b/aai-core/src/main/java/org/onap/aai/service/NodeValidationService.java
@@ -20,8 +20,8 @@
package org.onap.aai.service;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
@@ -37,7 +37,7 @@ import org.springframework.stereotype.Service;
@PropertySource(value = "file:${schema.ingest.file}", ignoreResourceNotFound = true)
public class NodeValidationService {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(NodeValidationService.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(NodeValidationService.class);
@Autowired(required = false)
private NodeValidator nodeValidator;
diff --git a/aai-core/src/main/java/org/onap/aai/tasks/ScheduledTasks.java b/aai-core/src/main/java/org/onap/aai/tasks/ScheduledTasks.java
index 911603d2..16c41166 100644
--- a/aai-core/src/main/java/org/onap/aai/tasks/ScheduledTasks.java
+++ b/aai-core/src/main/java/org/onap/aai/tasks/ScheduledTasks.java
@@ -20,32 +20,30 @@
package org.onap.aai.tasks;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.UUID;
-
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.comparator.LastModifiedFileComparator;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.LoggingContext.StatusCode;
+import org.onap.aai.aailog.logs.AaiScheduledTaskAuditLog;
import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.AAIConstants;
+import org.onap.logging.filter.base.ONAPComponents;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Date;
+
@Component
public class ScheduledTasks {
- private static EELFLogger LOGGER = EELFManager.getInstance().getLogger(ScheduledTasks.class);
+ @Autowired
+ private AaiScheduledTaskAuditLog auditLog;
- private static final String COMPONENT = "Scheduler";
- private static final String FROM_APP_ID = "CronApp";
+ private static Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class);
private static final long PROPERTY_READ_INTERVAL = 60000; // every minute
-
private String GlobalPropFileName = AAIConstants.AAI_CONFIG_FILENAME;
// for read and possibly reloading aaiconfig.properties and other
@@ -55,19 +53,7 @@ public class ScheduledTasks {
// configuration properties files
@Scheduled(fixedRate = PROPERTY_READ_INTERVAL)
public void loadAAIProperties() {
- final UUID transId = UUID.randomUUID();
-
- // LoggingContext.init();
- LoggingContext.save();
- LoggingContext.requestId(transId);
- LoggingContext.partnerName(FROM_APP_ID);
- LoggingContext.component(COMPONENT);
- LoggingContext.targetEntity("AAI");
- LoggingContext.targetServiceName("loadAAIProperties");
- LoggingContext.serviceName("AAI");
- LoggingContext.statusCode(StatusCode.COMPLETE);
- LoggingContext.responseCode(LoggingContext.SUCCESS);
-
+ auditLog.logBefore("LoadAaiPropertiesTask", ONAPComponents.AAI.toString() );
String dir = FilenameUtils.getFullPathNoEndSeparator(GlobalPropFileName);
if (dir == null || dir.length() < 3) {
dir = "/opt/aai/etc";
@@ -94,6 +80,6 @@ public class ScheduledTasks {
break;
}
}
- LoggingContext.restoreIfPossible();
+ auditLog.logAfter();
}
}
diff --git a/aai-core/src/main/java/org/onap/aai/transforms/XmlFormatTransformer.java b/aai-core/src/main/java/org/onap/aai/transforms/XmlFormatTransformer.java
new file mode 100644
index 00000000..ce7ead4f
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/transforms/XmlFormatTransformer.java
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.transforms;
+
+import com.bazaarvoice.jolt.Chainr;
+import com.bazaarvoice.jolt.JsonUtils;
+import org.json.JSONObject;
+import org.json.XML;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class XmlFormatTransformer {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(XmlFormatTransformer.class);
+
+ private static final String RESULT_WITH_QUOTES = "\"result\"";
+ private static final String RESULTS_STRING = "results";
+
+ private Chainr chainr;
+
+ public XmlFormatTransformer() {
+ List<Object> spec = JsonUtils.classpathToList("/specs/transform-related-to-node.json");
+ this.chainr = Chainr.fromSpec(spec);
+ }
+
+ public String transform(String input) {
+
+ Object transformedOutput;
+
+ if(!input.contains(RESULT_WITH_QUOTES)){
+ Object inputMap = JsonUtils.jsonToMap(input);
+ transformedOutput = chainr.transform(inputMap);
+
+ JSONObject jsonObject;
+ if(transformedOutput == null){
+ LOGGER.debug("For the input {}, unable to transform it so returning null", input);
+ jsonObject = new JSONObject();
+ } else {
+ jsonObject = new JSONObject(JsonUtils.toJsonString(transformedOutput));
+ }
+
+ return XML.toString(jsonObject, RESULTS_STRING);
+ } else {
+ // If the json is already conforming to the following format
+ // {"results":[{"results":"v[2]"}]}
+ // Then no transformation is required
+ return XML.toString(new JSONObject(input));
+ }
+
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/util/AAIConfig.java b/aai-core/src/main/java/org/onap/aai/util/AAIConfig.java
deleted file mode 100644
index c2103071..00000000
--- a/aai-core/src/main/java/org/onap/aai/util/AAIConfig.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.util;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.util.Properties;
-import java.util.UUID;
-
-import org.eclipse.jetty.util.security.Password;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.LoggingContext.StatusCode;
-
-public class AAIConfig {
-
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIConfig.class);
- private static final String GLOBAL_PROP_FILE_NAME = AAIConstants.AAI_CONFIG_FILENAME;
- private static Properties serverProps;
- private static boolean propsInitialized = false;
-
- /**
- * Instantiates a new AAI config.
- */
- // Don't instantiate
- private AAIConfig() {
- }
-
- /**
- * Inits the.
- *
- * @throws AAIException the AAI exception
- */
- public synchronized static void init() throws AAIException {
-
- LoggingContext.save();
- LoggingContext.component("config");
- LoggingContext.partnerName("NA");
- LoggingContext.targetEntity("AAI");
- LoggingContext.requestId(UUID.randomUUID().toString());
- LoggingContext.serviceName("AAI");
- LoggingContext.targetServiceName("init");
- LoggingContext.statusCode(StatusCode.COMPLETE);
-
- LOGGER.info("Initializing AAIConfig");
-
- AAIConfig.getConfigFile();
- AAIConfig.reloadConfig();
-
- if (AAIConstants.AAI_NODENAME == null || AAIConstants.AAI_NODENAME == "") {
- ErrorLogHelper.logError("AAI_4005", " AAI_NODENAME is not defined");
- } else {
- LOGGER.info("A&AI Server Node Name = " + AAIConstants.AAI_NODENAME);
- }
- LoggingContext.restore();
- }
-
- /**
- * Gets the config file.
- *
- * @return the config file
- */
- public static String getConfigFile() {
- return GLOBAL_PROP_FILE_NAME;
- }
-
- /**
- * Reload config.
- */
- public synchronized static void reloadConfig() {
-
- String propFileName = GLOBAL_PROP_FILE_NAME;
- Properties newServerProps = null;
-
- LOGGER.debug("Reloading config from " + propFileName);
-
- try (InputStream is = new FileInputStream(propFileName)) {
- newServerProps = new Properties();
- newServerProps.load(is);
- propsInitialized = true;
- serverProps = newServerProps;
- } catch (FileNotFoundException fnfe) {
- ErrorLogHelper.logError("AAI_4001", " " + propFileName + ". Exception: " + fnfe.getMessage());
- } catch (IOException e) {
- ErrorLogHelper.logError("AAI_4002", " " + propFileName + ". IOException: " + e.getMessage());
- }
- }
-
- /**
- * Gets the.
- *
- * @param key the key
- * @param defaultValue the default value
- * @return the string
- */
- public static String get(String key, String defaultValue) {
- String result = defaultValue;
- try {
- result = get(key);
- } catch (AAIException a) {
- }
- if (result == null || result.isEmpty()) {
- result = defaultValue;
- }
- return (result);
- }
-
- /**
- * Gets the.
- *
- * @param key the key
- * @return the string
- * @throws AAIException the AAI exception
- */
- public static String get(String key) throws AAIException {
- String response = null;
-
- if (key.equals(AAIConstants.AAI_NODENAME)) {
- // Get this from InetAddress rather than the properties file
- String nodeName = getNodeName();
- if (nodeName != null) {
- return nodeName;
- }
- // else get from property file
- }
-
- if (!propsInitialized || (serverProps == null)) {
- reloadConfig();
- }
-
- if ((key.endsWith("password") || key.endsWith("passwd") || key.endsWith("apisecret"))
- && serverProps.containsKey(key + ".x")) {
- String valx = serverProps.getProperty(key + ".x");
- return Password.deobfuscate(valx);
- }
-
- if (!serverProps.containsKey(key)) {
- throw new AAIException("AAI_4005", "Property key " + key + " cannot be found");
- } else {
- response = serverProps.getProperty(key);
- if (response == null || response.isEmpty()) {
- throw new AAIException("AAI_4005", "Property key " + key + " is null or empty");
- }
- }
- return response;
- }
-
- /**
- * Gets the int.
- *
- * @param key the key
- * @return the int
- * @throws AAIException the AAI exception
- */
- public static int getInt(String key) throws AAIException {
- return Integer.parseInt(AAIConfig.get(key));
- }
-
- /**
- * Gets the int.
- *
- * @param key the key
- * @return the int
- */
- public static int getInt(String key, String value) {
- return Integer.parseInt(AAIConfig.get(key, value));
- }
-
- /**
- * Gets the server props.
- *
- * @return the server props
- */
- public static Properties getServerProps() {
- return serverProps;
- }
-
- /**
- * Gets the node name.
- *
- * @return the node name
- */
- public static String getNodeName() {
- try {
- InetAddress ip = InetAddress.getLocalHost();
- if (ip != null) {
- String hostname = ip.getHostName();
- if (hostname != null) {
- return hostname;
- }
- }
- } catch (Exception e) {
- return null;
- }
- return null;
- }
-
- /**
- * Check if a null or an Empty string is passed in.
- *
- * @param s the s
- * @return boolean
- */
- public static boolean isEmpty(String s) {
- return (s == null || s.length() == 0);
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java b/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java
deleted file mode 100644
index e906c280..00000000
--- a/aai-core/src/main/java/org/onap/aai/util/AAIConstants.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Modifications Copyright © 2018 IBM.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.util;
-
-public final class AAIConstants {
- private static final String AJSC_HOME = "AJSC_HOME";
- //
- //
- /** Default to unix file separator if system property file.separator is null */
- public static final String AAI_FILESEP =
- (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator");
- //
- /** Default to opt aai if system property aai.home is null, using file.separator */
- public static final String AAI_HOME =
- (System.getProperty(AJSC_HOME) == null) ? AAI_FILESEP + "opt" + AAI_FILESEP + "app" + AAI_FILESEP + "aai"
- : System.getProperty(AJSC_HOME);
- public static final String AAI_BUNDLECONFIG_NAME =
- (System.getProperty("BUNDLECONFIG_DIR") == null) ? "bundleconfig" : System.getProperty("BUNDLECONFIG_DIR");
- public static final String AAI_HOME_BUNDLECONFIG = (System.getProperty(AJSC_HOME) == null)
- ? AAI_FILESEP + "opt" + AAI_FILESEP + "app" + AAI_FILESEP + "aai" + AAI_FILESEP + AAI_BUNDLECONFIG_NAME
- : System.getProperty(AJSC_HOME) + AAI_FILESEP + AAI_BUNDLECONFIG_NAME;
-
- /** etc directory, relative to AAI_HOME */
- public static final String AAI_HOME_ETC = AAI_HOME_BUNDLECONFIG + AAI_FILESEP + "etc" + AAI_FILESEP;
- public static final String AAI_HOME_ETC_APP_PROPERTIES = AAI_HOME_ETC + "appprops" + AAI_FILESEP;
- public static final String AAI_HOME_ETC_AUTH = AAI_HOME_ETC + "auth" + AAI_FILESEP;
- public static final String AAI_CONFIG_FILENAME = AAI_HOME_ETC_APP_PROPERTIES + "aaiconfig.properties";
- public static final String AAI_AUTH_CONFIG_FILENAME = AAI_HOME_ETC_AUTH + "aai_policy.json";
- public static final String REALTIME_DB_CONFIG = AAI_HOME_ETC_APP_PROPERTIES + "janusgraph-realtime.properties";
- public static final String CACHED_DB_CONFIG = AAI_HOME_ETC_APP_PROPERTIES + "janusgraph-cached.properties";
- public static final String AAI_HOME_ETC_OXM = AAI_HOME_ETC + "oxm" + AAI_FILESEP;
- public static final String AAI_EVENT_DMAAP_PROPS =
- AAI_HOME_ETC_APP_PROPERTIES + "aaiEventDMaaPPublisher.properties";
- public static final String AAI_HOME_ETC_SCRIPT = AAI_HOME_ETC + AAI_FILESEP + "scriptdata" + AAI_FILESEP;
-
- public static final String AAI_LOGBACK_PROPS = "logback.xml";
- public static final String AAI_SCHEMA_MOD_LOGBACK_PROPS = "schemaMod-logback.xml";
- public static final String AAI_FORCE_DELETE_LOGBACK_PROPS = "forceDelete-logback.xml";
-
- public static final String AAI_TRUSTSTORE_FILENAME = "aai.truststore.filename";
- public static final String AAI_TRUSTSTORE_PASSWD = "aai.truststore.passwd";
- public static final String AAI_KEYSTORE_FILENAME = "aai.keystore.filename";
- public static final String AAI_KEYSTORE_PASSWD = "aai.keystore.passwd";
-
- public static final String AAI_SERVER_URL_BASE = "aai.server.url.base";
- public static final String AAI_SERVER_URL = "aai.server.url";
- public static final String AAI_OLDSERVER_URL = "aai.oldserver.url";
- public static final String AAI_LOCAL_REST = "https://localhost:%d/aai/%s/";
- public static final String AAI_LOCAL_OVERRIDE = "aai.server.localhost.override.url";
- public static final String AAI_LOCAL_OVERRIDE_DEFAULT = "NA";
- public static final String AAI_LOCAL_REST_OVERRIDE = "%s/aai/%s/";
-
- public static final int AAI_RESOURCES_PORT = 8447;
- public static final int AAI_QUERY_PORT = 8446;
- public static final int AAI_LEGACY_PORT = 8443;
-
- public static final String AAI_DEFAULT_API_VERSION = "v10";
- public static final String AAI_DEFAULT_API_VERSION_PROP = "aai.default.api.version";
- public static final String AAI_NOTIFICATION_CURRENT_VERSION = "aai.notification.current.version";
-
- public static final String AAI_NODENAME = "aai.config.nodename";
-
- /*
- * Logs the objects being deleted when an client deletes objects via implied delete during PUT operation
- */
- public static final String AAI_IMPLIED_DELETE_LOG_ENABLED = "aai.implied.delete.log.enabled";
- /*
- * Specifies how many objects maximum to log
- */
- public static final String AAI_IMPLIED_DELETE_LOG_LIMIT = "aai.implied.delete.log.limit";
-
- public static final String AAI_BULKCONSUMER_LIMIT = "aai.bulkconsumer.payloadlimit";
- public static final String AAI_BULKCONSUMER_OVERRIDE_LIMIT = "aai.bulkconsumer.payloadoverride";
-
- public static final String AAI_TRAVERSAL_TIMEOUT_LIMIT = "aai.traversal.timeoutlimit";
- public static final String AAI_TRAVERSAL_TIMEOUT_ENABLED = "aai.traversal.timeoutenabled";
- public static final String AAI_TRAVERSAL_TIMEOUT_APP = "aai.traversal.timeout.appspecific";
-
- public static final String AAI_GRAPHADMIN_TIMEOUT_LIMIT = "aai.graphadmin.timeoutlimit";
- public static final String AAI_GRAPHADMIN_TIMEOUT_ENABLED = "aai.graphadmin.timeoutenabled";
- public static final String AAI_GRAPHADMIN_TIMEOUT_APP = "aai.graphadmin.timeout.appspecific";
-
- public static final String AAI_CRUD_TIMEOUT_LIMIT = "aai.crud.timeoutlimit";
- public static final String AAI_CRUD_TIMEOUT_ENABLED = "aai.crud.timeoutenabled";
- public static final String AAI_CRUD_TIMEOUT_APP = "aai.crud.timeout.appspecific";
-
- public static final String AAI_RESVERSION_ENABLEFLAG = "aai.resourceversion.enableflag";
- public static final String AAI_RESVERSION_DISABLED_UUID = "aai.resourceversion.disabled.uuid";
- public static final String AAI_RESVERSION_DISABLED_UUID_DEFAULT = "38cf3090-6a0c-4e9d-8142-4332a7352846";
-
- public static final long HISTORY_MAX_HOURS = 192;
-
- public static final String LOGGING_MAX_STACK_TRACE_ENTRIES = "aai.logging.maxStackTraceEntries";
-
- /*** UEB ***/
- public static final String UEB_PUB_PARTITION_AAI = "AAI";
-
- /** Micro-service Names */
- public static final String AAI_TRAVERSAL_MS = "aai-traversal";
- public static final String AAI_RESOURCES_MS = "aai-resources";
-
- /**
- * Instantiates a new AAI constants.
- */
- private AAIConstants() {
- // prevent instantiation
- }
-
-}
diff --git a/aai-core/src/main/java/org/onap/aai/util/FileWatcher.java b/aai-core/src/main/java/org/onap/aai/util/FileWatcher.java
deleted file mode 100644
index 07ac2642..00000000
--- a/aai-core/src/main/java/org/onap/aai/util/FileWatcher.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.util;
-
-import java.io.*;
-import java.util.*;
-
-public abstract class FileWatcher extends TimerTask {
- private long timeStamp;
- private File file;
-
- /**
- * Instantiates a new file watcher.
- *
- * @param file the file
- */
- public FileWatcher(File file) {
- this.file = file;
- this.timeStamp = file.lastModified();
- }
-
- /**
- * runs a timer task
- *
- * @see TimerTask.run
- */
- public final void run() {
- long timeStamp = file.lastModified();
-
- if ((timeStamp - this.timeStamp) > 500) {
- this.timeStamp = timeStamp;
- onChange(file);
- }
- }
-
- /**
- * On change.
- *
- * @param file the file
- */
- protected abstract void onChange(File file);
-}
diff --git a/aai-core/src/main/java/org/onap/aai/util/FormatDate.java b/aai-core/src/main/java/org/onap/aai/util/FormatDate.java
deleted file mode 100644
index 9ee2b71d..00000000
--- a/aai-core/src/main/java/org/onap/aai/util/FormatDate.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.util;
-
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-
-public class FormatDate {
-
- private final String timeZone;
- private final String pattern;
-
- public FormatDate(String pattern) {
- this.pattern = pattern;
- this.timeZone = "GMT";
- }
-
- public FormatDate(String pattern, String timeZone) {
- this.pattern = pattern;
- this.timeZone = timeZone;
- }
-
- public String getDateTime() {
-
- final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
- return formatter.format(ZonedDateTime.now(ZoneId.of(timeZone)));
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java b/aai-core/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java
deleted file mode 100644
index a41ad27b..00000000
--- a/aai-core/src/main/java/org/onap/aai/util/HbaseSaltPrefixer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.util;
-
-/*
- * logging to hbase encountered hotspotting issues, so per
- * http://archive.cloudera.com/cdh5/cdh/5/hbase-0.98.6-cdh5.3.8/book/rowkey.design.html
- * we decided to salt the rowkeys
- * as these keys are generated in a couple places, I made a class to contain that logic
- */
-public class HbaseSaltPrefixer {
- private int NUM_REGION_BUCKETS = 3; // the number of hbase region servers per cluster
-
- private static class SingletonHolder {
- private static final HbaseSaltPrefixer INSTANCE = new HbaseSaltPrefixer();
- }
-
- /**
- * Instantiates a new hbase salt prefixer.
- */
- private HbaseSaltPrefixer() {
- }
-
- /**
- * Gets the single instance of HbaseSaltPrefixer.
- *
- * @return single instance of HbaseSaltPrefixer
- */
- public static HbaseSaltPrefixer getInstance() {
- return SingletonHolder.INSTANCE;
- }
-
- /**
- * Prepend salt.
- *
- * @param key the key
- * @return the string
- */
- public String prependSalt(String key) {
- int salt = key.hashCode() % NUM_REGION_BUCKETS;
- return salt + "-" + key;
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java
index 133c26a7..c2bfabf4 100644
--- a/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java
+++ b/aai-core/src/main/java/org/onap/aai/util/HttpsAuthClient.java
@@ -27,10 +27,13 @@ import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import org.onap.aai.aailog.filter.RestControllerClientLoggingInterceptor;
+import org.onap.aai.exceptions.AAIException;
import java.io.FileInputStream;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
+import java.io.IOException;
+import java.security.*;
+import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@@ -63,29 +66,25 @@ public class HttpsAuthClient {
e.printStackTrace();
}
}
-
/**
* Gets the client.
*
+ * @param truststorePath the truststore path
+ * @param truststorePassword the truststore password
+ * @param keystorePath the keystore path
+ * @param keystorePassword the keystore password
* @return the client
* @throws KeyManagementException the key management exception
*/
- public static Client getClient() throws KeyManagementException {
+ public static Client getClient(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws KeyManagementException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
ClientConfig config = new DefaultClientConfig();
config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
config.getClasses().add(org.onap.aai.restcore.CustomJacksonJaxBJsonProvider.class);
-
SSLContext ctx = null;
try {
- String truststore_path =
- AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_FILENAME);
- String truststore_password = AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_PASSWD);
- String keystore_path = AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_KEYSTORE_FILENAME);
- String keystore_password = AAIConfig.get(AAIConstants.AAI_KEYSTORE_PASSWD);
-
- System.setProperty("javax.net.ssl.trustStore", truststore_path);
- System.setProperty("javax.net.ssl.trustStorePassword", truststore_password);
+ System.setProperty("javax.net.ssl.trustStore", truststorePath);
+ System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword);
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String string, SSLSession ssls) {
return true;
@@ -96,36 +95,62 @@ public class HttpsAuthClient {
KeyManagerFactory kmf = null;
try {
kmf = KeyManagerFactory.getInstance("SunX509");
- FileInputStream fin = new FileInputStream(keystore_path);
+ FileInputStream fin = new FileInputStream(keystorePath);
KeyStore ks = KeyStore.getInstance("PKCS12");
- char[] pwd = keystore_password.toCharArray();
+ char[] pwd = keystorePassword.toCharArray();
ks.load(fin, pwd);
kmf.init(ks, pwd);
} catch (Exception e) {
System.out.println("Error setting up kmf: exiting");
e.printStackTrace();
- System.exit(1);
+ throw e;
+ //System.exit(1);
}
ctx.init(kmf.getKeyManagers(), null, null);
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
- new HTTPSProperties(new HostnameVerifier() {
- @Override
- public boolean verify(String s, SSLSession sslSession) {
- return true;
- }
- }, ctx));
+ new HTTPSProperties(new HostnameVerifier() {
+ @Override
+ public boolean verify(String s, SSLSession sslSession) {
+ return true;
+ }
+ }, ctx));
} catch (Exception e) {
System.out.println("Error setting up config: exiting");
e.printStackTrace();
- System.exit(1);
+ throw e;
+ //System.exit(1);
}
Client client = Client.create(config);
+ client.addFilter(new RestControllerClientLoggingInterceptor());
// uncomment this line to get more logging for the request/response
// client.addFilter(new LoggingFilter(System.out));
return client;
}
+ /**
+ * Gets the client.
+ *
+ * @return the client
+ * @throws KeyManagementException the key management exception
+ */
+ public static Client getClient() throws KeyManagementException, AAIException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
+ String truststore_path = null;
+ String truststore_password = null;
+ String keystore_path = null;
+ String keystore_password = null;
+ try {
+ truststore_path =
+ AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_FILENAME);
+ truststore_password = AAIConfig.get(AAIConstants.AAI_TRUSTSTORE_PASSWD);
+ keystore_path = AAIConstants.AAI_HOME_ETC_AUTH + AAIConfig.get(AAIConstants.AAI_KEYSTORE_FILENAME);
+ keystore_password = AAIConfig.get(AAIConstants.AAI_KEYSTORE_PASSWD);
+ }
+ catch (AAIException e) {
+ throw e;
+ }
+ return(getClient(truststore_path, truststore_password, keystore_path, keystore_password));
+ }
}
diff --git a/aai-core/src/main/java/org/onap/aai/util/MapperUtil.java b/aai-core/src/main/java/org/onap/aai/util/MapperUtil.java
deleted file mode 100644
index 47a937d4..00000000
--- a/aai-core/src/main/java/org/onap/aai/util/MapperUtil.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Modifications Copyright © 2018 IBM.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.util;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
-
-import org.onap.aai.exceptions.AAIException;
-
-public class MapperUtil {
-
- /**
- * Instantiates MapperUtil.
- */
- private MapperUtil() {
- // prevent instantiation
- }
-
- /**
- * Read as object of.
- *
- * @param <T> the generic type
- * @param clazz the clazz
- * @param value the value
- * @return the t
- * @throws AAIException the AAI exception
- */
- public static <T> T readAsObjectOf(Class<T> clazz, String value) throws AAIException {
- ObjectMapper mapper = new ObjectMapper();
- try {
- return mapper.readValue(value, clazz);
- } catch (Exception e) {
- throw new AAIException("AAI_4007", e);
- }
- }
-
- /**
- * Read with dashes as object of.
- *
- * @param <T> the generic type
- * @param clazz the clazz
- * @param value the value
- * @return the t
- * @throws AAIException the AAI exception
- */
- public static <T> T readWithDashesAsObjectOf(Class<T> clazz, String value) throws AAIException {
- ObjectMapper mapper = new ObjectMapper();
- try {
- mapper.registerModule(new JaxbAnnotationModule());
- mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
-
- return mapper.readValue(value, clazz);
- } catch (Exception e) {
- throw new AAIException("AAI_4007", e);
- }
- }
-
- /**
- * Write as JSON string.
- *
- * @param obj the obj
- * @return the string
- * @throws AAIException the AAI exception
- */
- public static String writeAsJSONString(Object obj) throws AAIException {
- ObjectMapper mapper = new ObjectMapper();
- try {
- return mapper.writeValueAsString(obj);
- } catch (Exception e) {
- throw new AAIException("AAI_4008", e);
- }
- }
-
- /**
- * Write as JSON string with dashes.
- *
- * @param obj the obj
- * @return the string
- * @throws AAIException the AAI exception
- */
- public static String writeAsJSONStringWithDashes(Object obj) throws AAIException {
- ObjectMapper mapper = new ObjectMapper();
- try {
- mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
-
- mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
- mapper.configure(SerializationFeature.INDENT_OUTPUT, false);
- mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
-
- mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
-
- mapper.registerModule(new JaxbAnnotationModule());
- return mapper.writeValueAsString(obj);
- } catch (Exception e) {
- throw new AAIException("AAI_4008", e);
- }
- }
-}
diff --git a/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java b/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java
index 218f0dd8..05cbf97c 100644
--- a/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java
+++ b/aai-core/src/main/java/org/onap/aai/util/PojoUtils.java
@@ -129,11 +129,7 @@ public class PojoUtils {
mapper.registerModule(new JaxbAnnotationModule());
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- mapper.writeValue(baos, clazz);
-
- return baos.toString();
+ return mapper.writeValueAsString(clazz);
}
/**
diff --git a/aai-core/src/main/java/org/onap/aai/util/RestController.java b/aai-core/src/main/java/org/onap/aai/util/RestController.java
index a1419d14..8527ffe5 100644
--- a/aai-core/src/main/java/org/onap/aai/util/RestController.java
+++ b/aai-core/src/main/java/org/onap/aai/util/RestController.java
@@ -20,26 +20,30 @@
package org.onap.aai.util;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
+import java.io.IOException;
import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.logging.LoggingContext;
public class RestController implements RestControllerInterface {
private static final String TARGET_NAME = "AAI";
- private static EELFLogger LOGGER = EELFManager.getInstance().getLogger(RestController.class);
+ private static Logger LOGGER = LoggerFactory.getLogger(RestController.class);
private static Client client = null;
@@ -85,6 +89,9 @@ public class RestController implements RestControllerInterface {
this.initRestClient();
}
+ public RestController(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
+ this.initRestClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
+ }
/**
* Inits the rest client.
*
@@ -101,11 +108,29 @@ public class RestController implements RestControllerInterface {
}
}
}
+ /**
+ * Inits the rest client.
+ *
+ * @throws AAIException the AAI exception
+ */
+ public void initRestClient(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws AAIException {
+ if (client == null) {
+ try {
+ client = getHttpsAuthClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
+ } catch (KeyManagementException e) {
+ throw new AAIException("AAI_7117", "KeyManagementException in REST call to DB: " + e.toString());
+ } catch (Exception e) {
+ throw new AAIException("AAI_7117", " Exception in REST call to DB: " + e.toString());
+ }
+ }
+ }
+ public Client getHttpsAuthClient(String truststorePath, String truststorePassword, String keystorePath, String keystorePassword) throws KeyManagementException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
+ return HttpsAuthClient.getClient(truststorePath, truststorePassword, keystorePath, keystorePassword);
+ }
- public Client getHttpsAuthClient() throws KeyManagementException {
+ public Client getHttpsAuthClient() throws KeyManagementException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, AAIException {
return HttpsAuthClient.getClient();
}
-
/**
* Sets the rest srvr base URL.
*
@@ -151,13 +176,6 @@ public class RestController implements RestControllerInterface {
String url = "";
transId += ":" + UUID.randomUUID().toString();
- LoggingContext.save();
- LoggingContext.partnerName(sourceID);
- LoggingContext.targetEntity(TARGET_NAME);
- LoggingContext.requestId(transId);
- LoggingContext.serviceName(methodName);
- LoggingContext.targetServiceName(methodName);
-
LOGGER.debug(methodName + " start");
restObject.set(t);
@@ -177,7 +195,6 @@ public class RestController implements RestControllerInterface {
AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
}
}
- initRestClient();
LOGGER.debug(url + " for the get REST API");
ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
.header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
@@ -192,12 +209,9 @@ public class RestController implements RestControllerInterface {
restObject.set(t);
LOGGER.debug(methodName + "REST api GET was successfull!");
} else {
- LoggingContext.restore();
// System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
}
-
- LoggingContext.restore();
}
/**
@@ -219,20 +233,12 @@ public class RestController implements RestControllerInterface {
String url = "";
transId += ":" + UUID.randomUUID().toString();
- LoggingContext.save();
- LoggingContext.partnerName(sourceID);
- LoggingContext.targetEntity(TARGET_NAME);
- LoggingContext.requestId(transId);
- LoggingContext.serviceName(methodName);
- LoggingContext.targetServiceName(methodName);
-
LOGGER.debug(methodName + " start");
restObject.set(t);
url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
- initRestClient();
LOGGER.debug(url + " for the get REST API");
ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
.header("X-FromAppId", sourceID).header("Real-Time", "true").type("application/json")
@@ -247,12 +253,9 @@ public class RestController implements RestControllerInterface {
restObject.set(t);
LOGGER.debug(methodName + "REST api GET was successfull!");
} else {
- LoggingContext.restore();
// System.out.println(methodName + ": url=" + url + " failed with status=" + cres.getStatus());
throw new AAIException("AAI_7116", methodName + " with status=" + cres.getStatus() + ", url=" + url);
}
-
- LoggingContext.restore();
}
/**
@@ -320,17 +323,8 @@ public class RestController implements RestControllerInterface {
String url = "";
transId += ":" + UUID.randomUUID().toString();
- LoggingContext.save();
- LoggingContext.partnerName(sourceID);
- LoggingContext.targetEntity(TARGET_NAME);
- LoggingContext.requestId(transId);
- LoggingContext.serviceName(methodName);
- LoggingContext.targetServiceName(methodName);
-
LOGGER.debug(methodName + " start");
- initRestClient();
-
if (oldserver) {
url = AAIConfig.get(AAIConstants.AAI_OLDSERVER_URL) + path;
} else {
@@ -356,9 +350,7 @@ public class RestController implements RestControllerInterface {
int statuscode = cres.getStatus();
if (statuscode >= 200 && statuscode <= 299) {
LOGGER.debug(methodName + ": url=" + url + ", request=" + path);
- LoggingContext.restore();
} else {
- LoggingContext.restore();
throw new AAIException("AAI_7116", methodName + " with status=" + statuscode + ", url=" + url + ", msg="
+ cres.getEntity(String.class));
}
@@ -381,16 +373,8 @@ public class RestController implements RestControllerInterface {
String url = "";
transId += ":" + UUID.randomUUID().toString();
- LoggingContext.save();
- LoggingContext.partnerName(sourceID);
- LoggingContext.targetEntity(TARGET_NAME);
- LoggingContext.requestId(transId);
- LoggingContext.serviceName(methodName);
- LoggingContext.targetServiceName(methodName);
-
LOGGER.debug(methodName + " start");
- initRestClient();
String request = "{}";
if (overrideLocalHost == null) {
overrideLocalHost = AAIConfig.get(AAIConstants.AAI_LOCAL_OVERRIDE, AAIConstants.AAI_LOCAL_OVERRIDE_DEFAULT);
@@ -408,13 +392,10 @@ public class RestController implements RestControllerInterface {
if (cres.getStatus() == 404) { // resource not found
LOGGER.info("Resource does not exist...: " + cres.getStatus() + ":" + cres.getEntity(String.class));
- LoggingContext.restore();
} else if (cres.getStatus() == 200 || cres.getStatus() == 204) {
LOGGER.info("Resource " + url + " deleted");
- LoggingContext.restore();
} else {
LOGGER.error("Deleting Resource failed: " + cres.getStatus() + ":" + cres.getEntity(String.class));
- LoggingContext.restore();
throw new AAIException("AAI_7116", "Error during DELETE");
}
}
@@ -440,18 +421,10 @@ public class RestController implements RestControllerInterface {
String url = "";
transId += ":" + UUID.randomUUID().toString();
- LoggingContext.save();
- LoggingContext.partnerName(sourceID);
- LoggingContext.targetEntity(TARGET_NAME);
- LoggingContext.requestId(transId);
- LoggingContext.serviceName(methodName);
- LoggingContext.targetServiceName(methodName);
-
LOGGER.debug(methodName + " start");
try {
- initRestClient();
url = AAIConfig.get(AAIConstants.AAI_SERVER_URL_BASE) + apiVersion + "/" + path;
ClientResponse cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
@@ -473,7 +446,6 @@ public class RestController implements RestControllerInterface {
throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
} finally {
- LoggingContext.restore();
}
}
@@ -558,13 +530,6 @@ public class RestController implements RestControllerInterface {
String url = "";
transId += ":" + UUID.randomUUID().toString();
- LoggingContext.save();
- LoggingContext.partnerName(sourceID);
- LoggingContext.targetEntity(TARGET_NAME);
- LoggingContext.requestId(transId);
- LoggingContext.serviceName(methodName);
- LoggingContext.targetServiceName(methodName);
-
int numRetries = 5;
ClientResponse cres = null;
int statusCode = -1;
@@ -582,7 +547,6 @@ public class RestController implements RestControllerInterface {
AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP)) + path;
}
- initRestClient();
do {
cres = client.resource(url).accept("application/json").header("X-TransactionId", transId)
@@ -613,7 +577,6 @@ public class RestController implements RestControllerInterface {
throw new AAIException("AAI_7116", methodName + " with url=" + url + ", Exception: " + e.toString());
} finally {
- LoggingContext.restore();
}
}
diff --git a/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java b/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java
index 8b2bf50a..01d21ca7 100644
--- a/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java
+++ b/aai-core/src/main/java/org/onap/aai/util/StoreNotificationEvent.java
@@ -20,8 +20,8 @@
package org.onap.aai.util;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.StringWriter;
import java.util.Iterator;
@@ -45,7 +45,7 @@ import org.springframework.core.env.Environment;
public class StoreNotificationEvent {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(StoreNotificationEvent.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(StoreNotificationEvent.class);
private MessageProducer messageProducer;
private String fromAppId = "";
@@ -81,7 +81,7 @@ public class StoreNotificationEvent {
* @throws AAIException
* the AAI exception
*/
- public String storeEvent(NotificationEvent.EventHeader eh, Object obj) throws AAIException {
+ public String storeEventAndSendToJms(NotificationEvent.EventHeader eh, Object obj) throws AAIException {
if (obj == null) {
throw new AAIException("AAI_7350");
@@ -235,7 +235,94 @@ public class StoreNotificationEvent {
}
}
- public String storeEvent(Loader loader, Introspector eventHeader, Introspector obj) throws AAIException {
+ public String storeEventOnly(Loader loader, Introspector eventHeader, Introspector obj) throws AAIException {
+ if (obj == null) {
+ throw new AAIException("AAI_7350");
+ }
+
+ try {
+ final Introspector notificationEvent = loader.introspectorFromName("notification-event");
+
+ if (eventHeader.getValue("id") == null) {
+ eventHeader.setValue("id", genDate2() + "-" + UUID.randomUUID().toString());
+ }
+
+ if (eventHeader.getValue("timestamp") == null) {
+ eventHeader.setValue("timestamp", genDate());
+ }
+
+ if (eventHeader.getValue("entity-link") == null) {
+ eventHeader.setValue("entity-link", "UNK");
+ }
+
+ if (eventHeader.getValue("action") == null) {
+ eventHeader.setValue("action", "UNK");
+ }
+
+ if (eventHeader.getValue("event-type") == null) {
+ eventHeader.setValue("event-type", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+ }
+
+ if (eventHeader.getValue("domain") == null) {
+ eventHeader.setValue("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+ }
+
+ if (eventHeader.getValue("source-name") == null) {
+ eventHeader.setValue("source-name", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+ }
+
+ if (eventHeader.getValue("sequence-number") == null) {
+ eventHeader.setValue("sequence-number",
+ AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+ }
+
+ if (eventHeader.getValue("severity") == null) {
+ eventHeader.setValue("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+ }
+
+ if (eventHeader.getValue("version") == null) {
+ eventHeader.setValue("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+ }
+
+ if (notificationEvent.getValue("cambria-partition") == null) {
+ notificationEvent.setValue("cambria-partition",
+ AAIConfig.get("aai.notificationEvent.default.partition", AAIConstants.UEB_PUB_PARTITION_AAI));
+ }
+
+ notificationEvent.setValue("event-header", eventHeader.getUnderlyingObject());
+ notificationEvent.setValue("entity", obj.getUnderlyingObject());
+
+ String entityJson = notificationEvent.marshal(false);
+ JSONObject entityJsonObject = new JSONObject(entityJson);
+
+ JSONObject entityJsonObjectUpdated = new JSONObject();
+
+ JSONObject entityHeader = entityJsonObject.getJSONObject("event-header");
+ String cambriaPartition = entityJsonObject.getString("cambria.partition");
+
+ entityJsonObject.remove("event-header");
+ entityJsonObject.remove("cambria.partition");
+
+ entityJsonObjectUpdated.put("event-header", entityHeader);
+ entityJsonObjectUpdated.put("cambria.partition", cambriaPartition);
+
+ Iterator<String> iter = entityJsonObject.keys();
+ JSONObject entity = new JSONObject();
+ if (iter.hasNext()) {
+ entity = entityJsonObject.getJSONObject(iter.next());
+ }
+
+ entityJsonObjectUpdated.put("entity", entity);
+
+ return entityJsonObjectUpdated.toString();
+ } catch (JSONException e) {
+ throw new AAIException("AAI_7350", e);
+ } catch (AAIUnknownObjectException e) {
+ throw new AAIException("AAI_7350", e);
+ }
+ }
+
+ public String storeEventAndSendToJms(Loader loader, Introspector eventHeader, Introspector obj) throws AAIException {
if (obj == null) {
throw new AAIException("AAI_7350");
}
diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/DeltaAction.java b/aai-core/src/main/java/org/onap/aai/util/delta/DeltaAction.java
new file mode 100644
index 00000000..1b1e49ae
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/util/delta/DeltaAction.java
@@ -0,0 +1,30 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.util.delta;
+
+public enum DeltaAction {
+ CREATE,
+ UPDATE,
+ DELETE,
+ CREATE_REL,
+ DELETE_REL,
+ STATIC
+}
diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java b/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java
new file mode 100644
index 00000000..f240f4e8
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/util/delta/DeltaEvents.java
@@ -0,0 +1,136 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.util.delta;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.gson.*;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.dmaap.AAIDmaapEventJMSProducer;
+import org.onap.aai.dmaap.MessageProducer;
+import org.onap.aai.util.AAIConfig;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+public class DeltaEvents {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DeltaEvents.class);
+
+ private static final Gson gson = new GsonBuilder()
+ .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
+ .create();
+
+ private String transId;
+ private String sourceName;
+ private String eventVersion = "v1";
+ private String schemaVersion;
+ private Map<String, ObjectDelta> objectDeltas;
+
+ private MessageProducer messageProducer;
+
+ public DeltaEvents(String transId, String sourceName, String schemaVersion, Map<String, ObjectDelta> objectDeltas) {
+ this(transId, sourceName, schemaVersion, objectDeltas, new AAIDmaapEventJMSProducer());
+ }
+
+ public DeltaEvents(String transId, String sourceName, String schemaVersion, Map<String, ObjectDelta> objectDeltas, MessageProducer messageProducer) {
+ this.transId = transId;
+ this.sourceName = sourceName;
+ this.schemaVersion = schemaVersion;
+ this.objectDeltas = objectDeltas;
+ this.messageProducer = messageProducer;
+ }
+
+ public boolean triggerEvents() {
+ if (objectDeltas.isEmpty()) {
+ return false;
+ }
+
+ JsonObject finalJson = new JsonObject();
+ finalJson.addProperty("event-topic", "DELTA");
+ finalJson.addProperty("transId", transId);
+ finalJson.addProperty("fromAppId", sourceName);
+ finalJson.addProperty("fullId", "");
+ finalJson.add("aaiEventPayload", buildEvent());
+
+ this.messageProducer.sendMessageToDefaultDestination(finalJson.toString());
+ return true;
+ }
+
+ private JsonObject buildEvent() {
+ JsonObject event = new JsonObject();
+ event.addProperty("cambria.partition", this.getPartition());
+ event.add("event-header", getHeader());
+ event.add("entities", gson.toJsonTree(objectDeltas.values()));
+ return event;
+ }
+
+ private String getPartition() {
+ return "DELTA";
+ }
+
+ private JsonObject getHeader() {
+ ObjectDelta first = objectDeltas.values().iterator().next();
+ JsonObject header = new JsonObject();
+ header.addProperty("id", this.transId);
+ header.addProperty("timestamp", this.getTimeStamp(first.getTimestamp()));
+ header.addProperty("source-name", this.sourceName);
+ header.addProperty("domain", this.getDomain());
+ header.addProperty("event-type", this.getEventType());
+ header.addProperty("event-version", this.eventVersion);
+ header.addProperty("schema-version", this.schemaVersion);
+ header.addProperty("action", first.getAction().toString());
+ header.addProperty("entity-type", this.getEntityType(first));
+ header.addProperty("entity-link", first.getUri());
+ header.addProperty("entity-uuid", this.getUUID(first));
+
+ return header;
+ }
+
+ private String getUUID(ObjectDelta objectDelta) {
+ return (String) objectDelta.getPropertyDeltas().get(AAIProperties.AAI_UUID).getValue();
+ }
+
+ private String getEntityType(ObjectDelta objectDelta) {
+ return (String) objectDelta.getPropertyDeltas().get(AAIProperties.NODE_TYPE).getValue();
+ }
+
+ private String getEventType() {
+ return "DELTA";
+ }
+
+ private String getDomain() {
+ return AAIConfig.get("aai.notificationEvent.default.domain", "UNK");
+ }
+
+ /**
+ * Given Long timestamp convert to format YYYYMMdd-HH:mm:ss:SSS
+ * @param timestamp milliseconds since epoc
+ * @return long timestamp in format YYYYMMdd-HH:mm:ss:SSS
+ */
+ private String getTimeStamp(long timestamp) {
+ //SimpleDateFormat is not thread safe new instance needed
+ DateFormat df = new SimpleDateFormat("YYYYMMdd-HH:mm:ss:SSS");
+ return df.format(new Date(timestamp));
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java b/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java
new file mode 100644
index 00000000..c560dbf6
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/util/delta/ObjectDelta.java
@@ -0,0 +1,126 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.util.delta;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ObjectDelta {
+
+ @SerializedName("uri")
+ private String uri;
+
+ @SerializedName("action")
+ private DeltaAction action;
+
+ @SerializedName("source-of-truth")
+ private String sourceOfTruth;
+
+ @SerializedName("timestamp")
+ private long timestamp;
+
+ @SerializedName("property-deltas")
+ private Map<String, PropertyDelta> propertyDeltas = new HashMap<>();
+
+ @SerializedName("relationship-deltas")
+ private List<RelationshipDelta> relationshipDeltas = new ArrayList<>();
+
+ public ObjectDelta(String uri, DeltaAction action, String sourceOfTruth, long timestamp) {
+ this.uri = uri;
+ this.action = action;
+ this.sourceOfTruth = sourceOfTruth;
+ this.timestamp = timestamp;
+ }
+
+ public void addPropertyDelta(String prop, PropertyDelta propertyDelta) {
+ propertyDeltas.put(prop, propertyDelta);
+ }
+
+ public void addRelationshipDelta(RelationshipDelta relationshipDelta) {
+ relationshipDeltas.add(relationshipDelta);
+ }
+
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public DeltaAction getAction() {
+ return action;
+ }
+
+ public void setAction(DeltaAction action) {
+ this.action = action;
+ }
+
+ public String getSourceOfTruth() {
+ return sourceOfTruth;
+ }
+
+ public void setSourceOfTruth(String sourceOfTruth) {
+ this.sourceOfTruth = sourceOfTruth;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public void setPropertyDeltas(Map<String, PropertyDelta> propertyDeltas) {
+ this.propertyDeltas = propertyDeltas;
+ }
+
+ public void setRelationshipDeltas(List<RelationshipDelta> relationshipDeltas) {
+ this.relationshipDeltas = relationshipDeltas;
+ }
+
+ public Map<String, PropertyDelta> getPropertyDeltas() {
+ return propertyDeltas;
+ }
+
+ public List<RelationshipDelta> getRelationshipDeltas() {
+ return relationshipDeltas;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .append("uri", uri)
+ .append("action", action)
+ .append("sourceOfTruth", sourceOfTruth)
+ .append("timestamp", timestamp)
+ .append("propertyDeltas", propertyDeltas)
+ .append("relationshipDeltas", relationshipDeltas)
+ .toString();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java b/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java
new file mode 100644
index 00000000..46a0072c
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDelta.java
@@ -0,0 +1,79 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.aai.util.delta;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class PropertyDelta {
+
+ @SerializedName("action")
+ protected DeltaAction action;
+
+ @SerializedName("value")
+ protected Object value;
+
+ @SerializedName("old-value")
+ private Object oldValue;
+
+
+ public PropertyDelta(DeltaAction action, Object value) {
+ this.action = action;
+ this.value = value;
+ }
+
+ public PropertyDelta(DeltaAction action, Object value, Object oldValue) {
+ this(action, value);
+ this.oldValue = oldValue;
+ }
+
+ public DeltaAction getAction() {
+ return action;
+ }
+
+ public void setAction(DeltaAction action) {
+ this.action = action;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ public void setOldValue(Object oldValue) {
+ this.oldValue = oldValue;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .append("action", action)
+ .append("value", value)
+ .append("oldValue", oldValue)
+ .toString();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDeltaFactory.java b/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDeltaFactory.java
new file mode 100644
index 00000000..366d6886
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/util/delta/PropertyDeltaFactory.java
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.util.delta;
+
+public class PropertyDeltaFactory {
+
+ public static PropertyDelta getDelta(DeltaAction action, Object value, Object oldValue) {
+ //TODO handle if action is not UPDATE
+ return new PropertyDelta(action, value, oldValue);
+ }
+
+ public static PropertyDelta getDelta(DeltaAction action, Object value) {
+ //TODO handle if action is UPDATE
+ return new PropertyDelta(action, value);
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/util/delta/RelationshipDelta.java b/aai-core/src/main/java/org/onap/aai/util/delta/RelationshipDelta.java
new file mode 100644
index 00000000..1dcad1b3
--- /dev/null
+++ b/aai-core/src/main/java/org/onap/aai/util/delta/RelationshipDelta.java
@@ -0,0 +1,133 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.aai.util.delta;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RelationshipDelta {
+
+ @SerializedName("action")
+ private DeltaAction action;
+
+ @SerializedName("in-v-uuid")
+ private String inVUuid;
+
+ @SerializedName("out-v-uuid")
+ private String outVUuid;
+
+ @SerializedName("in-v-uri")
+ private String inVUri;
+
+ @SerializedName("out-v-uri")
+ private String outVUri;
+
+ @SerializedName("label")
+ private String label;
+
+ @SerializedName("props")
+ private Map<String, Object> props = new HashMap<>();
+
+ public RelationshipDelta(DeltaAction action, String inVUUID, String outVUUID, String inVUri, String outVUri, String label) {
+ this.action = action;
+ this.inVUuid = inVUUID;
+ this.outVUuid = outVUUID;
+ this.inVUri = inVUri;
+ this.outVUri = outVUri;
+ this.label = label;
+ }
+
+ public DeltaAction getAction() {
+ return action;
+ }
+
+ public void setAction(DeltaAction action) {
+ this.action = action;
+ }
+
+ public String getInVUuid() {
+ return inVUuid;
+ }
+
+ public void setInVUuid(String inVUuid) {
+ this.inVUuid = inVUuid;
+ }
+
+ public String getOutVUuid() {
+ return outVUuid;
+ }
+
+ public void setOutVUuid(String outVUuid) {
+ this.outVUuid = outVUuid;
+ }
+
+ public String getInVUri() {
+ return inVUri;
+ }
+
+ public void setInVUri(String inVUri) {
+ this.inVUri = inVUri;
+ }
+
+ public String getOutVUri() {
+ return outVUri;
+ }
+
+ public void setOutVUri(String outVUri) {
+ this.outVUri = outVUri;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public Map<String, Object> getProps() {
+ return props;
+ }
+
+ public void setProps(Map<String, Object> props) {
+ this.props = props;
+ }
+
+ public void addProp(String key, String value) {
+ this.props.put(key, value);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .append("action", action)
+ .append("inVUuid", inVUuid)
+ .append("outVUuid", outVUuid)
+ .append("inVUri", inVUri)
+ .append("outVUri", outVUri)
+ .append("label", label)
+ .append("props", props)
+ .toString();
+ }
+}
diff --git a/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java b/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java
index d552f231..c5629254 100644
--- a/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java
+++ b/aai-core/src/main/java/org/onap/aai/web/EventClientPublisher.java
@@ -20,8 +20,8 @@
package org.onap.aai.web;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
@@ -37,7 +37,7 @@ import org.springframework.web.client.RestTemplate;
@Configuration
public class EventClientPublisher {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(EventClientPublisher.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(EventClientPublisher.class);
@Value("${dmaap.ribbon.listOfServers:}")
private String hosts;
diff --git a/aai-core/src/main/resources/specs/transform-related-to-node.json b/aai-core/src/main/resources/specs/transform-related-to-node.json
new file mode 100644
index 00000000..c7e018a8
--- /dev/null
+++ b/aai-core/src/main/resources/specs/transform-related-to-node.json
@@ -0,0 +1,21 @@
+[
+ {
+ "operation": "shift",
+ "spec": {
+ "results": "result",
+ "*": "&"
+ }
+ },
+ {
+ "operation": "shift",
+ "spec": {
+ "result": {
+ "*": {
+ "related-to": "result.[&(1,0)].&(0,0).node",
+ "*": "result.[&(1,0)].&(0,0)"
+ }
+ },
+ "*": "&"
+ }
+ }
+] \ No newline at end of file
diff --git a/aai-core/src/main/resources/swagger.html.ftl b/aai-core/src/main/resources/swagger.html.ftl
new file mode 100644
index 00000000..1a2827f8
--- /dev/null
+++ b/aai-core/src/main/resources/swagger.html.ftl
@@ -0,0 +1,241 @@
+<#--
+
+ ============LICENSE_START=======================================================
+ org.onap.aai
+ ================================================================================
+ Copyright © 2017-18 AT&T Intellectual Property. All rights reserved.
+ Copyright © 2018 Huawei Technologies (Australia) Pty Ltd. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<style>/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{p EdgeRules.ftl
+ ont-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:800px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:900px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#337ab7}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#fff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eee;color:#777;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-moz-transition:-moz-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform 0.6s ease-in-out;-moz-transition:-moz-transform 0.6s ease-in-out;-o-transition:-o-transform 0.6s ease-in-out;transition:transform 0.6s ease-in-out;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;-moz-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.panel-definition{border-color:#a2a2a2}.panel-definition>.panel-heading{color:#000;background-color:#eee;border-color:#a2a2a2}.panel-definition>.panel-heading+.panel-collapse>.panel-body{border-top-color:#a2a2a2}.panel-definition>.panel-heading .badge{color:#eee;background-color:#000}.panel-definition>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#a2a2a2}.json-schema-description:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Description";padding-bottom:.5em;display:block}.json-schema-description:not(:last-child){padding-bottom:1.5em}.json-schema-properties:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Properties";padding-bottom:.5em;display:block}.json-schema-properties:not(:last-child){padding-bottom:1.5em}.json-schema-properties dd:not(:last-child){padding-bottom:1em}.json-schema-properties dl{margin:0}.json-schema-example:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Example";padding-bottom:.5em;display:block}.json-schema-example:not(:last-child){padding-bottom:1.5em}.json-schema-array-items:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Items";padding-bottom:.5em;display:block}.json-schema-array-items:not(:last-child){padding-bottom:1.5em}.json-schema-allOf-inherited:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Inherited";padding-bottom:.5em;display:block}.json-schema-allOf-inherited:not(:last-child){padding-bottom:1.5em}.json-schema-allOf-inherited ul{padding-left:0;list-style:none}.json-schema-anyOf>dl{border-left:2px solid #a2a2a2;padding-left:1em}.json-schema-anyOf>dl dt:not(:first-child):before{content:"or "}.json-schema-anyOf>dl dt:first-child:before{content:"either "}.json-schema-additionalProperties:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Additional properties";padding-bottom:.5em;display:block}.json-schema-additionalProperties:not(:last-child){padding-bottom:1.5em}.json-inner-schema .json-schema-properties,.json-inner-schema .json-schema-array-items,.json-inner-schema .json-schema-description,.json-inner-schema .json-schema-example{padding-left:1em;margin-top:.5em;padding-bottom:.5em;border-left:2px solid #a2a2a2}.json-property-discriminator:before{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;background-color:#777;content:"discriminator"}a.json-property-discriminator:before:hover,a.json-property-discriminator:before:focus{color:#fff;text-decoration:none;cursor:pointer}.json-property-discriminator:before:empty{display:none}.btn .json-property-discriminator:before{position:relative;top:-1px}.json-property-discriminator:before[href]:hover,.json-property-discriminator:before[href]:focus{background-color:#5e5e5e}.json-property-required:before{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;background-color:#777;content:"required"}a.json-property-required:before:hover,a.json-property-required:before:focus{color:#fff;text-decoration:none;cursor:pointer}.json-property-required:before:empty{display:none}.btn .json-property-required:before{position:relative;top:-1px}.json-property-required:before[href]:hover,.json-property-required:before[href]:focus{background-color:#5e5e5e}.json-property-read-only:before{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;background-color:#777;content:"read only"}a.json-property-read-only:before:hover,a.json-property-read-only:before:focus{color:#fff;text-decoration:none;cursor:pointer}.json-property-read-only:before:empty{display:none}.btn .json-property-read-only:before{position:relative;top:-1px}.json-property-read-only:before[href]:hover,.json-property-read-only:before[href]:focus{background-color:#5e5e5e}.json-property-type{font-style:italic;font-weight:100}.json-property-format{font-size:smaller}.json-property-enum{font-weight:lighter;font-size:small}.json-property-default-value{font-weight:lighter;font-size:small}.json-property-default-value:before{content:'(default: "'}.json-property-default-value:after{content:'")'}.json-property-enum-item{font-weight:lighter;font-size:small}.json-property-enum-item:before,.json-property-enum-item:after{content:"\""}.json-schema--reference{font-size:90%}.table.swagger--summary>tbody>tr>td.swagger--summary-path{vertical-align:middle}.table.swagger--summary>tbody>tr>td p{margin:0}.swagger--panel-operation-post{border-color:#78cc94}.swagger--panel-operation-post>.panel-heading{color:#333;background-color:#e7f6ec;border-color:#78cc94}.swagger--panel-operation-post>.panel-heading+.panel-collapse>.panel-body{border-top-color:#78cc94}.swagger--panel-operation-post>.panel-heading .badge{color:#e7f6ec;background-color:#333}.swagger--panel-operation-post>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#78cc94}.swagger--panel-operation-post .operation-name{font-weight:bold}.swagger--panel-operation-post .operation-summary{float:right !important}.swagger--panel-operation-get{border-color:#74a8d1}.swagger--panel-operation-get>.panel-heading{color:#333;background-color:#e7f0f7;border-color:#74a8d1}.swagger--panel-operation-get>.panel-heading+.panel-collapse>.panel-body{border-top-color:#74a8d1}.swagger--panel-operation-get>.panel-heading .badge{color:#e7f0f7;background-color:#333}.swagger--panel-operation-get>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#74a8d1}.swagger--panel-operation-get .operation-name{font-weight:bold}.swagger--panel-operation-get .operation-summary{float:right !important}.swagger--panel-operation-put{border-color:#d8ab71}.swagger--panel-operation-put>.panel-heading{color:#333;background-color:#f9f2e9;border-color:#d8ab71}.swagger--panel-operation-put>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d8ab71}.swagger--panel-operation-put>.panel-heading .badge{color:#f9f2e9;background-color:#333}.swagger--panel-operation-put>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d8ab71}.swagger--panel-operation-put .operation-name{font-weight:bold}.swagger--panel-operation-put .operation-summary{float:right !important}.swagger--panel-operation-patch{border-color:#ed7c59}.swagger--panel-operation-patch>.panel-heading{color:#333;background-color:#FCE9E3;border-color:#ed7c59}.swagger--panel-operation-patch>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ed7c59}.swagger--panel-operation-patch>.panel-heading .badge{color:#FCE9E3;background-color:#333}.swagger--panel-operation-patch>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ed7c59}.swagger--panel-operation-patch .operation-name{font-weight:bold}.swagger--panel-operation-patch .operation-summary{float:right !important}.swagger--panel-operation-options{border-color:#74a8d1}.swagger--panel-operation-options>.panel-heading{color:#333;background-color:#e7f0f7;border-color:#74a8d1}.swagger--panel-operation-options>.panel-heading+.panel-collapse>.panel-body{border-top-color:#74a8d1}.swagger--panel-operation-options>.panel-heading .badge{color:#e7f0f7;background-color:#333}.swagger--panel-operation-options>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#74a8d1}.swagger--panel-operation-options .operation-name{font-weight:bold}.swagger--panel-operation-options .operation-summary{float:right !important}.swagger--panel-operation-delete{border-color:#c77d7d}.swagger--panel-operation-delete>.panel-heading{color:#333;background-color:#f5e8e8;border-color:#c77d7d}.swagger--panel-operation-delete>.panel-heading+.panel-collapse>.panel-body{border-top-color:#c77d7d}.swagger--panel-operation-delete>.panel-heading .badge{color:#f5e8e8;background-color:#333}.swagger--panel-operation-delete>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#c77d7d}.swagger--panel-operation-delete .operation-name{font-weight:bold}.swagger--panel-operation-delete .operation-summary{float:right !important}.swagger--panel-operation-head{border-color:#f3ff34}.swagger--panel-operation-head>.panel-heading{color:#333;background-color:#fcffcd;border-color:#f3ff34}.swagger--panel-operation-head>.panel-heading+.panel-collapse>.panel-body{border-top-color:#f3ff34}.swagger--panel-operation-head>.panel-heading .badge{color:#fcffcd;background-color:#333}.swagger--panel-operation-head>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#f3ff34}.swagger--panel-operation-head .operation-name{font-weight:bold}.swagger--panel-operation-head .operation-summary{float:right !important}.sw-operation-description:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Description";padding-bottom:.5em;display:block}.sw-operation-description:not(:last-child){padding-bottom:1.5em}.sw-request-params:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Request parameters";padding-bottom:.5em;display:block}.sw-request-params:not(:last-child){padding-bottom:1.5em}.sw-request-body:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Request body";padding-bottom:.5em;display:block}.sw-request-body:not(:last-child){padding-bottom:1.5em}.sw-responses:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Responses";padding-bottom:.5em;display:block}.sw-responses:not(:last-child){padding-bottom:1.5em}.swagger--global:before{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;background-color:#777;content:'global'}a.swagger--global:before:hover,a.swagger--global:before:focus{color:#fff;text-decoration:none;cursor:pointer}.swagger--global:before:empty{display:none}.btn .swagger--global:before{position:relative;top:-1px}.swagger--global:before[href]:hover,.swagger--global:before[href]:focus{background-color:#5e5e5e}table.table th.sw-param-key{width:auto}table.table th.sw-param-key:before{content:"Key"}table.table th.sw-param-name{width:auto}table.table th.sw-param-name:before{content:"Name"}table.table th.sw-param-description{width:auto}table.table th.sw-param-description:before{content:"Description"}table.table th.sw-param-data-type{width:auto}table.table th.sw-param-data-type:before{content:"Data type"}table.table th.sw-param-type{width:auto}table.table th.sw-param-type:before{content:"Type"}table.table th.sw-request-security-schema{width:auto}table.table th.sw-request-security-schema:before{content:"Schema"}table.table th.sw-request-security-scopes{width:auto}table.table th.sw-request-security-scopes:before{content:"Scopes"}table.table th.sw-response-header-name{width:auto}table.table th.sw-response-header-name:before{content:"Header"}table.table th.sw-response-header-description{width:auto}table.table th.sw-response-header-description:before{content:"Description"}table.table th.sw-response-header-data-type{width:auto}table.table th.sw-response-header-data-type:before{content:"Data type"}.sw-response-name-value{font-weight:bold}.sw-response-description-text{padding-bottom:.5em}code.highlight{padding:0}.panel-security-definition{border-color:#a2a2a2}.panel-security-definition>.panel-heading{color:#000;background-color:#eee;border-color:#a2a2a2}.panel-security-definition>.panel-heading+.panel-collapse>.panel-body{border-top-color:#a2a2a2}.panel-security-definition>.panel-heading .badge{color:#eee;background-color:#000}.panel-security-definition>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#a2a2a2}.sw-request-security:before{font-weight:bold;color:#555;text-transform:uppercase;content:"Security";padding-bottom:.5em;display:block}.sw-request-security:not(:last-child){padding-bottom:1.5em}.sw-security-definition-basic:before{color:#555;font-size:smaller;content:"(HTTP Basic Authentication)"}span.sw-default-value-header{font-weight:bold}.sw-info-version{font-weight:bold}.sw-info-version span{font-family:monospace;font-weight:normal;font-size:1.1em}</style>
+
+ <meta charset="UTF-8">
+ <title>Active and Available Inventory REST API.</title>
+</head>
+<body>
+<div class="container">
+ <h1>Active and Available Inventory REST API.</h1>
+ <p class="sw-info-version">Version: <span>${version}</span></p>
+ <p><p>${description}</p>
+ </p>
+
+ <div id="sw-schemes" class="sw-default-value">
+ <span class="sw-default-value-header">Schemes:</span>
+ https
+ </div>
+
+ <h2 id="swagger--summary-tags">Summary</h2>
+ <ol>
+ <#list aaiApis?keys as key>
+ <li><a href="#tag-${key}">Tag: ${key}</a>
+ </#list>
+ <li><a href="#Paths">Paths</a>
+ <li><a href="#SchemaDefinitions">Schema definitions</a>
+ </ol>
+
+ <#list aaiApis?keys as key>
+ <h3 id="tag-${key}" class="swagger-summary-tag">Tag: ${key}</h3>
+ <table class="table table-bordered table-condensed swagger--summary">
+ <thead><tr>
+ <th>Operation</th><th>Description</th>
+ </tr></thead>
+ <tbody>
+ <#list aaiApis[key] as api>
+ <#list api.getHttpMethods() as httpVerb>
+ <tr><td><a href="#operation-${api.getOperation()}${httpVerb.getType()}">
+ ${httpVerb.getType()?upper_case} ${api.getPath()}</a></td>
+ <td><p>${httpVerb.getSummary()}</p></td>
+ </tr>
+ </#list>
+ </#list>
+ </tbody>
+ </table>
+ </#list>
+
+ <h2 id="Paths">Paths</h2>
+ <#list sortedAaiApis?keys as key>
+ <#list sortedAaiApis[key] as api>
+ <#list api.getHttpMethods() as httpVerb>
+ <span id="path-${api.getOperation()}"></span>
+ <div id="operation-${api.getOperation()}${httpVerb.getType()}" class="swagger--panel-operation-${httpVerb.getType()} panel">
+ <div class="panel-heading">
+ <div class="operation-summary">${httpVerb.getSummary()}</div>
+ <h3 class="panel-title"><span class="operation-name">${httpVerb.getType()?upper_case}</span>
+ <strong>${api.getPath()}</strong></h3>
+ Tags: <a href="#tag-${api.getTag()}">${api.getTag()}</a>
+ </div>
+ <div class="panel-body">
+ <section class="sw-operation-description">
+ <p>${httpVerb.getSummary()}</p>
+ </section>
+ <#if httpVerb.isConsumerEnabled()>
+ <section class="sw-request-body">
+ <p><span class="label label-default">application/json</span> <span class="label label-default">application/xml</span> </p>
+ <#if httpVerb.isBodyParametersEnabled()>
+ <div class="row">
+ <div class="col-md-6">
+ <p><p>${httpVerb.getBodyParameters()["description"]}</p></p>
+ </div>
+ <div class="col-md-6 sw-request-model">
+ <div class="panel panel-definition">
+ <div class="panel-body">
+ <a class="json-schema-ref" href="${httpVerb.getSchemaLink()}">${httpVerb.getSchemaType()}</a>
+ </div></div></div></div>
+ </#if>
+ </section>
+ </#if>
+ <#if httpVerb.isParametersEnabled()>
+ <section class="sw-request-params">
+ <table class="table">
+ <thead><tr>
+ <th class="sw-param-name"></th>
+ <th class="sw-param-description"></th>
+ <th class="sw-param-type"></th>
+ <th class="sw-param-data-type"></th>
+ <th class="sw-param-annotation"></th>
+ </tr></thead>
+ <tbody>
+ <#list httpVerb.getParameters() as param>
+ <tr><td>${param["name"]}</td>
+ <td>
+ <#if param['description']??>
+ <p>${param["description"]}</p>
+ </#if>
+ </td>
+ <td>${param["in"]}</td>
+ <td>
+ <#if param['type']??>
+ <span class="json-property-type">${param["type"]}</span>
+ <span class="json-property-range" title="Value limits"></span>
+ </#if>
+ </td>
+ <td>
+ <#if param['required']>
+ <span class="json-property-required"></span>
+ </#if>
+ </td>
+ </tr>
+ </#list>
+ </tbody>
+ </table></section>
+ </#if>
+
+ <section class="sw-responses">
+ <p><span class="label label-default">application/json</span> <span class="label label-default">application/xml</span> </p>
+ <dl>
+ <#list httpVerb.getResponses() as response>
+ <dt class="sw-response-${response.getResponseCode()}">
+ ${response.getResponseCode()} OK
+ </dt>
+ <dd class="sw-response-${response.getResponseCode()}">
+ <div class="row"><div class="col-md-12">
+ <p>successful operation</p>
+ </div></div>
+ <div class="row">
+ <#if httpVerb.isHasReturnSchema()>
+ <div class="col-md-6 sw-response-model">
+ <div class="panel panel-definition">
+ <div class="panel-body">
+ <a class="json-schema-ref" href="${httpVerb.getReturnSchemaLink()}">${httpVerb.getReturnSchemaObject()}</a>
+ </div></div></div>
+ </#if>
+ </div>
+ </dd>
+ </#list>
+ <dt class="sw-response-default">default</dt>
+ <dd class="sw-response-default">
+ <div class="row"><div class="col-md-12">
+ <p>Response codes found in <a href="${wikiLink}">response codes</a>.</p>
+ </div></div>
+ <div class="row"><div class="col-md-6 sw-response-model"></div></div>
+ </dd>
+ </dl>
+ </section>
+ </div>
+ </div>
+
+ </#list>
+ </#list>
+ </#list>
+
+ <h2 id="SchemaDefinitions">Schema definitions</h2>
+ <#list definitions as definition>
+ <div id="definition-${definition.getDefinitionName()}" class="panel panel-definition">
+ <div class="panel-heading"><h3 class="panel-title">
+ <a name="/definitions/${definition.getDefinitionName()}"></a>${definition.getDefinitionName()}:
+ <span class="json-property-type"><span class="json-property-type">object</span>
+ <span class="json-property-range" title="Value limits"></span></span>
+ </h3></div>
+ <div class="panel-body">
+ <#if definition.isHasDescription()>
+ <section class="json-schema-description">
+ ${definition.getDefinitionDescription()}
+ </section>
+ </#if>
+ <section class="json-schema-properties"><dl>
+ <#list definition.getRegularPropertyList() as definitionProperty>
+ <dt data-property-name="${definitionProperty.getPropertyName()}">
+ <span class="json-property-name">${definitionProperty.getPropertyName()}:</span>
+ <#if definitionProperty.isHasType()>
+ <span class="json-property-type">${definitionProperty.getPropertyType()}</span>
+ </#if>
+ <span class="json-property-range" title="Value limits"></span>
+ <#if definitionProperty.isRequired()>
+ <span class="json-property-required"></span>
+ </#if>
+ </dt>
+ <dd>
+ <#if definitionProperty.isHasPropertyDescription()>
+ <p>${definitionProperty.getPropertyDescription()}</p>
+ </#if>
+ <div class="json-inner-schema"></div>
+ </dd>
+ </#list>
+ <#list definition.getSchemaPropertyList() as definitionProperty>
+ <dt data-property-name="${definitionProperty.getPropertyName()}">
+ <span class="json-property-name">${definitionProperty.getPropertyName()}:</span>
+ <#if definitionProperty.isHasType()>
+ <span class="json-property-type">${definitionProperty.getPropertyType()}</span>
+ </#if>
+ <span class="json-property-range" title="Value limits"></span>
+ <#if definitionProperty.isRequired()>
+ <span class="json-property-required"></span>
+ </#if>
+ </dt>
+ <dd><div class="json-inner-schema"><section class="json-schema-array-items">
+ <span class="json-property-type">
+ <a class="json-schema-ref" href="${definitionProperty.getPropertyReference()}">${definitionProperty.getPropertyReferenceObjectName()}</a></span>
+ <span class="json-property-range" title="Value limits"></span>
+ <div class="json-inner-schema"></div>
+ </section></div></dd>
+ </#list>
+ </dl></section>
+ </div></div>
+
+ </#list>
+</div>
+</body>
+</html>