summaryrefslogtreecommitdiffstats
path: root/dcaedt_be/src
diff options
context:
space:
mode:
authorStone, Avi (as206k) <as206k@att.com>2018-04-12 15:46:31 +0300
committerStone, Avi (as206k) <as206k@att.com>2018-04-12 15:49:38 +0300
commit5032434b101f25fa44d2e1f8dc8393e30af1ed4f (patch)
tree2dc7d37a8048e025c7412af080640da4c9a22b65 /dcaedt_be/src
parent2205633792f95f46a02bbf8f87f0c2637265d924 (diff)
DCAE-D be initial commit
DCAE-D be initial commit Issue-ID: SDC-1218 Change-Id: Id18ba96c499e785aa9ac395fbaf32d57f08c281b Signed-off-by: Stone, Avi (as206k) <as206k@att.com>
Diffstat (limited to 'dcaedt_be/src')
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java87
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java140
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java80
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java239
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java338
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java63
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java84
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java453
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java230
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java183
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java77
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java97
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java29
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java23
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java49
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java74
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java283
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ActionStatus.java48
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/BasicConfiguration.java5
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/DcaeException.java15
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrConfMgr.java306
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfiguration.java46
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfigurationLoader.java121
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorInfo.java99
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormatManager.java103
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java247
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java22
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java32
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java58
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java149
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java47
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java40
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java47
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java49
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java43
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java50
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java50
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java69
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java44
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java51
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java14
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java38
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java20
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java40
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java29
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java40
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java40
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java41
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java9
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java49
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java56
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/EventListenerDefinition.java101
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataItemsDefinition.java9
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataTypeDefinition.java270
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesJsonDeserializer.java20
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesSimpleTypesEnum.java26
-rw-r--r--dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesStructureLoader.java115
-rw-r--r--dcaedt_be/src/main/resources/logback-spring.xml181
-rw-r--r--dcaedt_be/src/main/resources/schema.sql4
-rw-r--r--dcaedt_be/src/main/webapp/META-INF/MANIFEST.MF8
-rw-r--r--dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties22
-rw-r--r--dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/error-configuration.yaml286
-rw-r--r--dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v4.1.json1165
-rw-r--r--dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v5.3.json2004
-rw-r--r--dcaedt_be/src/main/webapp/WEB-INF/jetty-web.xml12
-rw-r--r--dcaedt_be/src/main/webapp/WEB-INF/web.xml5
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/VesStructureLoaderMock.java116
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java123
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java310
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java304
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/services/GetServicesTest.java143
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/EventListenerDefinitionTest.java61
-rw-r--r--dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/VesStructureLoaderTest.java129
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1.json1165
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1WithoutCommonEventHeader.json1087
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v5.3.json2004
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidJson.json288
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidRequiredEntry.json1165
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidSchemaStructure.json1165
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidType.json1165
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vNoEventProperty.json1165
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vUnresolvable.json288
-rw-r--r--dcaedt_be/src/test/resources/ves-schema/unsupportedFilename.json1165
83 files changed, 20717 insertions, 0 deletions
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java
new file mode 100644
index 0000000..ee8f5c6
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionConfig.java
@@ -0,0 +1,87 @@
+package org.onap.sdc.dcae.composition;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.PostConstruct;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.context.annotation.PropertySources;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+@Component
+@PropertySources({
+ @PropertySource(value="classpath:application-fe.properties", ignoreResourceNotFound=true),
+ @PropertySource(value="file:${jetty.base}/config/dcae-be/application.properties", ignoreResourceNotFound=true)
+})
+
+public class CompositionConfig {
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @Value("${compositionConfig.flowTypes}")
+ private String flowTypes;
+ @JsonIgnore
+ private Map<String, FlowType> flowTypesMap;
+ @Value("${compositionConfig.isRuleEditorActive}")
+ private boolean isRuleEditorActive;
+
+ // get flowTypes as the parsed keySet
+ public Set<String> getFlowTypes() {
+ return flowTypesMap.keySet();
+ }
+
+ @JsonProperty("isRuleEditorActive")
+ public boolean isRuleEditorActive() {
+ return isRuleEditorActive;
+ }
+
+ public Map<String, FlowType> getFlowTypesMap() {
+ return flowTypesMap;
+ }
+
+ public static class FlowType {
+
+ private String entryPointPhaseName;
+ private String lastPhaseName;
+
+ public String getEntryPointPhaseName() {
+ return entryPointPhaseName;
+ }
+
+ public void setEntryPointPhaseName(String entryPointPhaseName) {
+ this.entryPointPhaseName = entryPointPhaseName;
+ }
+
+ public String getLastPhaseName() {
+ return lastPhaseName;
+ }
+
+ public void setLastPhaseName(String lastPhaseName) {
+ this.lastPhaseName = lastPhaseName;
+ }
+ }
+
+
+ @PostConstruct
+ public void init() {
+ try {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Reading flow type definitions from configuration");
+ Type map = new TypeToken<Map<String, FlowType>>(){}.getType();
+ flowTypesMap = new Gson().fromJson(flowTypes, map);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error – Failed to read flow type definitions");
+ }
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java
new file mode 100644
index 0000000..186f3f6
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/CompositionEngine.java
@@ -0,0 +1,140 @@
+package org.onap.sdc.dcae.composition;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import javax.servlet.ServletContext;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.util.SystemProperties;
+import org.onap.sdc.dcae.filter.LoggingFilter;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrorConfiguration;
+import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+@EnableScheduling
+@SpringBootApplication
+@ComponentScan("org.onap.sdc.dcae")
+@EnableAutoConfiguration
+@PropertySource("file:${jetty.base}/config/dcae-be/application.properties")
+public class CompositionEngine extends SpringBootServletInitializer implements CommandLineRunner{
+ private static final String SPECIFICATION_VERSION = "Specification-Version";
+ @Autowired
+ ServletContext servletContext;
+ private static final String MANIFEST_FILE_NAME = "/META-INF/MANIFEST.MF";
+ private static String dcaeVersion;
+ private OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ public static void main(String[] args) {
+ SpringApplication.run(CompositionEngine.class, args);
+ }
+
+ /**
+ * Creates and returns a new instance of a {@link SystemProperties} class.
+ *
+ * @return New instance of {@link SystemProperties}.
+ */
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(CompositionEngine.class);
+ }
+
+
+ @Bean
+ public WebMvcConfigurer corsConfigurer() {
+ return new WebMvcConfigurerAdapter() {
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("*")
+ .allowedHeaders("*")
+ .allowedMethods("GET", "POST", "OPTIONS", "PUT")
+ .allowCredentials(false)
+ .maxAge(3600);
+
+ }
+ };
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ ErrorConfigurationLoader errorConfigurationLoader = new ErrorConfigurationLoader(System.getProperty("jetty.base"));
+ ErrConfMgr instance = ErrConfMgr.INSTANCE;
+ InputStream inputStream = servletContext.getResourceAsStream(MANIFEST_FILE_NAME);
+
+ //setLogbackXmlLocation();
+
+ String version = null;
+ try {
+ Manifest mf = new Manifest(inputStream);
+ Attributes atts = mf.getMainAttributes();
+ version = atts.getValue(SPECIFICATION_VERSION);
+ if (version == null || version.isEmpty()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "failed to read DCAE version from MANIFEST.");
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "DCAE version from MANIFEST is {}", version);
+ dcaeVersion = version;
+ }
+
+ } catch (IOException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "failed to read DCAE version from MANIFEST: {}", e.getMessage());
+ }
+
+ }
+
+ private void setLogbackXmlLocation() throws Exception {
+ String jettyBase = System.getProperty("config.home");
+ Properties props = System.getProperties();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Current System Properties are: {}", props);
+ if (jettyBase == null) {
+ String msg = "Couldn't resolve config.home environmental variable";
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new Exception(msg + ". Failed to configure logback.xml location... aborting.");
+ }
+ String logbackXmlLocation = jettyBase+"/dcae-be/logback.xml";
+ props.setProperty("logback.configurationFile", logbackXmlLocation);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Successfuly set the logback.xml location to {}", logbackXmlLocation);
+ }
+
+ @Bean
+ public FilterRegistrationBean contextLifecycleFilter() {
+ Collection<String> urlPatterns = new ArrayList<>();
+ urlPatterns.add("/*");
+
+ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new LoggingFilter());
+ filterRegistrationBean.setUrlPatterns(urlPatterns);
+
+ return filterRegistrationBean;
+ }
+
+ public static String getDcaeVersion() {
+ return dcaeVersion;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java
new file mode 100644
index 0000000..8b590ca
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BaseController.java
@@ -0,0 +1,80 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.impl.BaseBusinessLogic;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.SystemProperties;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.DcaeException;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+import com.google.gson.Gson;
+
+public abstract class BaseController {
+
+ protected Gson gson = new Gson();
+
+ @Autowired
+ protected SystemProperties systemProperties;
+
+ @Autowired
+ protected BaseBusinessLogic baseBusinessLogic;
+
+ protected OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ protected OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @ModelAttribute("requestId")
+ public String getRequestId(HttpServletRequest request) {
+ return request.getAttribute("requestId").toString();
+ }
+
+ Asset checkout(String userId, String uuid, AssetType assetType, String requestId) throws Exception {
+ return baseBusinessLogic.getSdcRestClient().changeAssetLifecycleState(userId, uuid, LifecycleOperationType.CHECKOUT.name(), null, assetType, requestId);
+ }
+
+ Asset checkin(String userId, String uuid, AssetType assetType, String requestId) throws Exception {
+ return baseBusinessLogic.getSdcRestClient().changeAssetLifecycleState(userId, uuid, LifecycleOperationType.CHECKIN.name(), "checking in " + assetType.name() + uuid, assetType, requestId);
+ }
+
+
+ boolean isNeedToCheckOut(String lifecycleState) {
+ return DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(lifecycleState);
+ }
+
+ void checkUserIfResourceCheckedOut(String userId, Asset asset) throws DcaeException {
+ if (DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(asset.getLifecycleState())) {
+ String lastUpdaterUserId = asset.getLastUpdaterUserId();
+ if (lastUpdaterUserId != null && !lastUpdaterUserId.equals(userId)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "User conflicts. Operation not allowed for user {} on resource checked out by {}", userId, lastUpdaterUserId);
+ ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.USER_CONFLICT, null, userId, asset.getName(), lastUpdaterUserId);
+ throw new DcaeException(HttpStatus.FORBIDDEN, responseFormat.getRequestError());
+ }
+ }
+ }
+
+ void checkVfcmtType(ResourceDetailed vfcmt) {
+ if (!"VFCMT".equals(vfcmt.getResourceType()) || !"Template".equals(vfcmt.getCategory())) {
+ ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.RESOURCE_NOT_VFCMT_ERROR, null, vfcmt.getUuid());
+ throw new DcaeException(HttpStatus.BAD_REQUEST, responseFormat.getRequestError());
+ }
+ }
+
+ ResponseEntity handleException(Exception e, ApiType apiType, String... variables){
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), e.getMessage());
+ return ErrConfMgr.INSTANCE.handleException(e, apiType, variables);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java
new file mode 100644
index 0000000..a12c6b8
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/BlueprintController.java
@@ -0,0 +1,239 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.apache.commons.lang.StringUtils;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
+import org.onap.sdc.dcae.catalog.asdc.ASDC;
+import org.onap.sdc.dcae.catalog.asdc.ASDCUtils;
+import org.onap.sdc.dcae.catalog.asdc.Blueprinter;
+import org.onap.sdc.dcae.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.PostConstruct;
+import java.io.StringReader;
+import java.net.URI;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class BlueprintController extends BaseController{
+
+ @Autowired
+ private Blueprinter blueprinter;
+
+ @Autowired
+ private ASDC asdc;
+
+ private static final String CREATE_DESC = "creating new artifact blueprint on the service vfi";
+ private static final String UPDATE_DESC = "updating artifact blueprint on the service vfi";
+
+
+
+ @PostConstruct
+ public void init(){
+ URI sdcUri = URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.URI));
+ asdc.setUri(sdcUri);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "SDC uri: {}", sdcUri);
+ }
+
+ /***
+ * VFCMT - Resource, blueprint - as an artifact as an service.
+ * @param userId
+ * @param vfcmtUuid
+ * @param serviceUuid
+ * @param serviceInstanceName
+ * @param monitoringFlowType
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/createBluePrint/{VFCMTUuid}/{serviceUuid}/{instanceName}/{monitoringFlowType}", method = RequestMethod.POST)
+ public ResponseEntity createBluePrint(@RequestHeader("USER_ID") String userId,
+ @PathVariable("VFCMTUuid") String vfcmtUuid,
+ @PathVariable("serviceUuid") String serviceUuid,
+ @PathVariable("instanceName") String serviceInstanceName,
+ @PathVariable("monitoringFlowType") String monitoringFlowType,
+ @ModelAttribute("requestId") String requestId) {
+ try {
+
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+ Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt);
+ if (null != cdumpArtifactData) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found the cdump (composition.yml) on top of VFCMT {}", vfcmtUuid);
+ String cdump = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, cdumpArtifactData.getArtifactUUID(), requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------CDUMP: -----------------------------------------------------------------------------");
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), cdump);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "---------------------------------------------------------------------------------------------------------------------------------------------------");
+ ASDCUtils utils = new ASDCUtils(asdc, blueprinter);
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to use python procedure to create a blueprint....");
+ String resultBlueprintCreation;
+ try{
+ resultBlueprintCreation = utils.buildBlueprintViaToscaLab(new StringReader(cdump)).waitForResult().waitForResult();
+ }catch (Exception e){
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, e.getMessage(), vfcmt.getName());
+ }
+ if (StringUtils.isEmpty(resultBlueprintCreation)) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERATE_BLUEPRINT_ERROR, "", vfcmt.getName());
+ }
+
+ // 1806 US374595 flowType in cdump
+ String flowTypeFromCdump = StringUtils.substringBetween(cdump,"\"flowType\":\"","\"");
+ if(StringUtils.isNotBlank(flowTypeFromCdump)) {
+ monitoringFlowType = flowTypeFromCdump;
+ }
+ // saving to serviceVfInstance
+ Artifact savedBluePrint = saveBluePrint(userId, serviceUuid, serviceInstanceName, resultBlueprintCreation, monitoringFlowType, vfcmt.getName(), requestId);
+ if(savedBluePrint!=null){
+ MessageResponse response = new MessageResponse();
+ response.setSuccessResponse("Blueprint build complete \n. Blueprint="+savedBluePrint.getArtifactName());
+ //1806 US374593 - certify VFCMT after BP generation
+ certifyVfcmt(vfcmt, requestId);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ }
+ else{
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SUBMIT_BLUEPRINT_ERROR);
+ }
+
+ }else{
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName());
+ }
+ } catch (Exception e) {
+ return handleException(e, ApiType.SUBMIT_BLUEPRINT);
+ }
+ }
+
+
+ /********************* private function ********************/
+
+ /**
+ * @param userId
+ * @param serviceUuid
+ * @param resourceInstanceName
+ * @param bluePrint
+ * @param monitoringFlowType
+ * @param vfcmtName
+ * @param requestId
+ * @return
+ * @throws Exception
+ */
+ private Artifact saveBluePrint(String userId, String serviceUuid, String resourceInstanceName, String bluePrint, String monitoringFlowType, String vfcmtName, String requestId) throws Exception {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "BLUEPRINT:\n{}", bluePrint);
+ try {
+ ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(serviceUuid, requestId);
+ //Validations
+ checkUserIfResourceCheckedOut(userId, service);
+ ResourceInstance vfi = findVfiOnService(service, resourceInstanceName);
+ if(null == vfi){
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VF instance {} not found on service {}", resourceInstanceName, serviceUuid);
+ return null;
+ }
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), service.toString());
+
+ String normalizedArtifactLabel = Normalizers.normalizeArtifactLabel("blueprint-" + monitoringFlowType);
+ Artifact blueprintArtifact = CollectionUtils.isEmpty(vfi.getArtifacts()) ? null : vfi.getArtifacts().stream()
+ .filter(p -> normalizedArtifactLabel.equals(Normalizers.normalizeArtifactLabel(p.getArtifactLabel())))
+ .findAny()
+ .orElse(null);
+
+ boolean isNeed2Checkout = isNeedToCheckOut(service.getLifecycleState());
+ if (isNeed2Checkout) {
+ Asset result = checkout(userId, serviceUuid, AssetType.SERVICE, requestId);
+ if (result != null) {
+ serviceUuid = result.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New service after checkout is: {}", serviceUuid);
+ }
+ }
+ //update mode
+ if (null != blueprintArtifact) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Found that service {} already consist of {} ----> updateMode", serviceUuid, normalizedArtifactLabel);
+ blueprintArtifact.setDescription(UPDATE_DESC);
+ blueprintArtifact.setPayloadData(Base64Utils.encodeToString(bluePrint.getBytes()));
+ blueprintArtifact = baseBusinessLogic.getSdcRestClient().updateVfInstanceArtifact(userId, serviceUuid, Normalizers.normalizeComponentInstanceName(resourceInstanceName), blueprintArtifact, requestId);
+ //create mode
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Service {} does not consist {} ----> createMode", serviceUuid, normalizedArtifactLabel);
+ blueprintArtifact = SdcRestClientUtils.generateDeploymentArtifact(CREATE_DESC, generateBlueprintFileName(monitoringFlowType, vfcmtName), ArtifactType.DCAE_INVENTORY_BLUEPRINT.name(), normalizedArtifactLabel, bluePrint.getBytes());
+ blueprintArtifact = baseBusinessLogic.getSdcRestClient().createVfInstanceArtifact(userId, serviceUuid, Normalizers.normalizeComponentInstanceName(resourceInstanceName), blueprintArtifact, requestId);
+ }
+
+ //No need to check the service in in 1806
+// Asset blueprintAsJson = checkin(user_id, serviceUuid, AssetType.SERVICE);
+// debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "service result after check-in: {}", blueprintAsJson.toString());
+
+ return blueprintArtifact;
+
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while trying to save blueprint {}", e.toString());
+ throw e;
+ }
+ }
+
+ /**
+ *
+ * @param monitoringFlowType
+ * @param vfcmtName
+ * @return
+ */
+ private String generateBlueprintFileName(String monitoringFlowType, String vfcmtName) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(monitoringFlowType);
+ sb.append(".");
+ sb.append(Normalizers.normalizeComponentName(vfcmtName));
+ sb.append(".");
+ sb.append(DcaeBeConstants.Composition.fileNames.EVENT_PROC_BP_YAML);
+ return sb.toString();
+ }
+
+ private ResourceInstance findVfiOnService(ServiceDetailed service, String vfiName) {
+ return null == service ? null : CollectionUtils.isEmpty(service.getResources()) ? null : service.getResources().stream().filter(p -> vfiName.equals(p.getResourceInstanceName())).findAny().orElse(null);
+ }
+
+ private Artifact findCdumpArtifactData(ResourceDetailed vfcmt) {
+ return null == vfcmt ? null : CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream()
+ .filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName())).findAny().orElse(null);
+ }
+
+ private void certifyVfcmt(ResourceDetailed vfcmt, String requestId){
+ String state = vfcmt.getLifecycleState();
+ if(null == state) {
+ debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't read Vfcmt lifecycle state");
+ return;
+ }
+ DcaeBeConstants.LifecycleStateEnum lifeCycleState = DcaeBeConstants.LifecycleStateEnum.findState(state);
+ if(null == lifeCycleState) {
+ debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Undefined lifecycle state: {}", state);
+ return;
+ }
+ try{
+ switch (lifeCycleState){
+ case NOT_CERTIFIED_CHECKOUT:
+ baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(vfcmt.getLastUpdaterUserId(), vfcmt.getUuid(), LifecycleOperationType.CHECKIN.name(), "check in VFCMT after blueprint successful submission", requestId);
+ case NOT_CERTIFIED_CHECKIN:
+ baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(vfcmt.getLastUpdaterUserId(), vfcmt.getUuid(), LifecycleOperationType.CERTIFY.name(), "certify VFCMT after blueprint successful submission", requestId);
+ }
+ }
+ catch (Exception e){
+ //informative only. no message to user (TBA)
+ debugLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred during vfcmt lifecycle operation: {}", e.toString());
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java
new file mode 100644
index 0000000..5cba14f
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/CompositionController.java
@@ -0,0 +1,338 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.catalog.Catalog;
+import org.onap.sdc.dcae.catalog.Catalog.*;
+import org.onap.sdc.dcae.catalog.engine.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.async.DeferredResult;
+
+import javax.annotation.PostConstruct;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class CompositionController extends BaseController{
+
+ @Autowired
+ private CatalogController catalogController;
+
+ @PostConstruct
+ public void init() {
+ catalogController.setDefaultCatalog(URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_CATALOG_URL)));
+ }
+
+ @RequestMapping(value = { "/utils/clone/{assetType}/{sourceId}/{targetId}" }, method = {RequestMethod.GET }, produces = { "application/json" })
+ public ResponseEntity clone(@RequestHeader("USER_ID") String userId, @PathVariable("assetType") String theAssetType, @PathVariable("sourceId") String theSourceId, @PathVariable("targetId") String theTargetId,
+ @ModelAttribute("requestId") String requestId) {
+ MessageResponse response = new MessageResponse();
+
+ try {
+ // fetch the source and assert it is a vfcmt containing clone worthy artifacts (composition + rules)
+ ResourceDetailed sourceVfcmt = baseBusinessLogic.getSdcRestClient().getResource(theSourceId, requestId);
+ checkVfcmtType(sourceVfcmt);
+ List<Artifact> artifactsToClone = CollectionUtils.isEmpty(sourceVfcmt.getArtifacts()) ? null : sourceVfcmt.getArtifacts().stream()
+ .filter(p -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(p.getArtifactName()) || p.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX))
+ .collect(Collectors.toList());
+ if(CollectionUtils.isEmpty(artifactsToClone)) {
+ response.setSuccessResponse("Nothing to clone");
+ return new ResponseEntity<>(response ,HttpStatus.NO_CONTENT);
+ }
+
+ // fetch the target
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(theTargetId, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+ boolean isTargetNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState());
+ if (isTargetNeed2Checkout) {
+ ResourceDetailed targetVfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT before clone", requestId);
+ if(null == targetVfcmt){
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.GENERAL_ERROR);
+ }
+ theTargetId = targetVfcmt.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New targetVfcmt (for artifact clone) after checkout is: {}", theTargetId);
+ }
+
+ Map<String, Artifact> currentArtifacts = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? new HashMap<>() : vfcmt.getArtifacts().stream()
+ .collect(Collectors.toMap(Artifact::getArtifactName, Function.identity()));
+
+ //TODO target VFCMT rule artifacts should be removed
+ for(Artifact artifactToClone : artifactsToClone) {
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(theSourceId, artifactToClone.getArtifactUUID(), requestId);
+ baseBusinessLogic.cloneArtifactToTarget(userId, theTargetId, payload, artifactToClone, currentArtifacts.get(artifactToClone.getArtifactName()), requestId);
+ }
+
+ baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, theTargetId, LifecycleOperationType.CHECKIN.name(), "check in VFCMT after clone", requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Cloning {} from {} has finished successfully", theSourceId, theTargetId);
+ response.setSuccessResponse("Clone VFCMT complete");
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.CLONE_VFCMT);
+ }
+ }
+
+ @RequestMapping(value = "/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json")
+ public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest) {
+
+ final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout());
+
+ catalog.rootsByLabel(request.getStartingLabel())
+ .setHandler(catalogController.new CatalogHandler<Folders>(request, result) {
+ public CatalogResponse handleData(Folders theFolders) {
+ JSONArray ja = new JSONArray();
+ if (theFolders != null) {
+ for (Folder folder : theFolders) {
+ ja.put(catalogController.patchData(catalog, folder.data()));
+ }
+ }
+ CatalogResponse response = new CatalogResponse(this.request);
+ try {
+ response.data().put("elements", ja);
+ } catch (JSONException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting json elements to response {}", e);
+ }
+ return response;
+ }
+ });
+ return result;
+ }
+
+ @RequestMapping(value = "/{theItemId}/elements", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json")
+ public DeferredResult<CatalogResponse> items(@RequestBody(required = false) ItemsRequest theRequest, @PathVariable String theItemId) {
+
+ final ItemsRequest request = (theRequest == null) ? ItemsRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout());
+
+ catalog
+ // .fetchFolderByItemId(theItemId)
+ .folder(theItemId).withParts().withPartAnnotations().withItems().withItemAnnotations().withItemModels()
+ .execute().setHandler(catalogController.new CatalogHandler<Folder>(request, result) {
+ public CatalogResponse handleData(Folder theFolder) {
+ CatalogResponse response = new CatalogResponse(this.request);
+ if (theFolder == null) {
+ return response;
+ }
+
+ try {
+ Elements folders = theFolder.elements("parts", Folders.class);
+ if (folders != null) {
+ for (Object folder : folders) {
+ catalogController.patchData(catalog, ((Element) folder).data());
+ // lots of ephemere proxies created here ..
+ Elements annotations = ((Element) folder).elements("annotations",
+ Annotations.class);
+ if (annotations != null) {
+ for (Object a : annotations) {
+ catalogController.patchData(catalog, ((Annotation) a).data());
+ }
+ }
+ }
+ }
+ Elements items = theFolder.elements("items", Items.class);
+ if (items != null) {
+ for (Object i : items) {
+ catalogController.patchData(catalog, ((Element) i).data());
+ // lots of ephemere proxies created here ..
+ Elements annotations = ((Element) i).elements("annotations", Annotations.class);
+ if (annotations != null) {
+ for (Object a : annotations) {
+ catalogController.patchData(catalog, ((Annotation) a).data());
+ }
+ }
+ }
+ }
+ } catch (Exception x) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", x);
+ return new CatalogError(this.request, "", x);
+ }
+
+ try {
+ response.data().put("element", theFolder.data());
+ } catch (JSONException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting element to response {}", e);
+ }
+ return response;
+ }
+ });
+
+ return result;
+ }
+
+ @RequestMapping(value = "/{theItemId}/model", method = { RequestMethod.POST,RequestMethod.GET }, produces = "application/json")
+ public DeferredResult model(@RequestBody(required = false) ElementRequest theRequest,
+ @PathVariable String theItemId) {
+ final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<>(request.getTimeout());
+
+ catalog
+ .item(theItemId).withModels().execute()
+ .setHandler(catalogController.new CatalogHandler<Item>(request, result) {
+ public CatalogResponse handleData(Item theItem) {
+ if (theItem == null) {
+ return new CatalogError(this.request, "No such item");
+ }
+ Templates models = null;
+ try {
+ models = (Templates) theItem.elements("models", Templates.class);
+ if (models == null || models.isEmpty()) {
+ return new CatalogError(this.request, "Item has no models");
+ }
+ if (models.size() > 1) {
+ return new CatalogError(this.request, "Item has more than one model !?");
+ }
+ catalog.template(models.get(0).id()).withInputs().withOutputs().withNodes()
+ .withNodeProperties().withNodePropertiesAssignments().withNodeRequirements()
+ .withNodeCapabilities().withNodeCapabilityProperties()
+ .withNodeCapabilityPropertyAssignments().withPolicies().withPolicyProperties()
+ .withPolicyPropertiesAssignments().execute().setHandler(
+ catalogController.new CatalogHandler<Template>(this.request, this.result) {
+ public CatalogResponse handleData(Template theTemplate) {
+ CatalogResponse response = new CatalogResponse(this.request);
+ if (theTemplate != null) {
+ try {
+ response.data().put("model", catalogController
+ .patchData(catalog, theTemplate.data()));
+ } catch (JSONException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "JSONException putting model to response {}", e);
+ }
+ }
+ return response;
+ }
+ });
+ } catch (Exception e) {
+ handleException(e, ApiType.GET_MODEL, models.get(0).name());
+ }
+ return null;
+ }
+ });
+
+ return result;
+ }
+
+ @RequestMapping(value = "/{theItemId}/type/{theTypeName}", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json")
+ public DeferredResult<CatalogResponse> model(@RequestBody(required = false) ElementRequest theRequest, @PathVariable String theItemId, @PathVariable String theTypeName) {
+ final ElementRequest request = (theRequest == null) ? ElementRequest.EMPTY_REQUEST : theRequest;
+
+ Catalog catalog = catalogController.getCatalog(request.getCatalog());
+ DeferredResult<CatalogResponse> result = new DeferredResult<CatalogResponse>(request.getTimeout());
+
+ catalog.type(theItemId, theTypeName).withHierarchy().withCapabilities().withRequirements().execute()
+ .setHandler(catalogController.new CatalogHandler<Type>(request, result) {
+ public CatalogResponse handleData(Type theType) {
+ CatalogResponse response = new CatalogResponse(this.request);
+ if (theType != null) {
+ try {
+ response.data().put("type", catalogController.patchData(catalog, theType.data()));
+ } catch (JSONException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Exception processing catalog {}", e);
+ }
+ }
+ return response;
+ }
+ });
+
+ return result;
+ }
+
+ @RequestMapping(value = { "/getComposition/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getComposition(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+ MessageResponse response = new MessageResponse();
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+
+ Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null);
+
+ if(null == compositionArtifact){
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Couldn't find {} in VFCMT artifacts", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ response.setErrorResponse("No Artifacts");
+ return new ResponseEntity<>(response, HttpStatus.NO_CONTENT);
+ }
+
+ String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, compositionArtifact.getArtifactUUID(), requestId);
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT: {}", artifact);
+ response.setSuccessResponse(artifact);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_CDUMP);
+ }
+ }
+
+ @RequestMapping(value = "/saveComposition/{vfcmtUuid}", method = RequestMethod.POST)
+ public ResponseEntity saveComposition(@RequestHeader("USER_ID") String userId, @RequestBody String theCdump, @PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ARTIFACT CDUMP: {}", theCdump);
+
+ try {
+
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT: {}", vfcmt);
+
+ checkVfcmtType(vfcmt);
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+ boolean isNeed2Checkout = isNeedToCheckOut(vfcmt.getLifecycleState());
+ Artifact compositionArtifact = CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equals(a.getArtifactName())).findAny().orElse(null);
+ String resourceUuid = vfcmtUuid; // by default the resource is the original vfcmtId unless a checkout will be done
+ if (isNeed2Checkout) {
+ vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, resourceUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId);
+ if (vfcmt != null) {
+ resourceUuid = vfcmt.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkout is: {}", resourceUuid);
+ }
+ }
+ boolean isUpdateMode = null != compositionArtifact;
+ if (isUpdateMode) {
+ compositionArtifact.setDescription("updating composition file");
+ compositionArtifact.setPayloadData(Base64Utils.encodeToString(theCdump.getBytes()));
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT {} does consist {} ----> updateMode", resourceUuid, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, resourceUuid, compositionArtifact, requestId);
+
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VFCMT {} does not consist {} ----> createMode", resourceUuid, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ compositionArtifact = SdcRestClientUtils.generateDeploymentArtifact("creating composition file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, ArtifactType.DCAE_TOSCA.name(), "composition", theCdump.getBytes());
+ baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, resourceUuid, compositionArtifact, requestId);
+ }
+ Asset result = checkin(userId, resourceUuid, org.onap.sdc.dcae.enums.AssetType.RESOURCE, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "vfcmt check-in result: {}", result);
+
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.SAVE_CDUMP);
+ }
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java
new file mode 100644
index 0000000..4f083ca
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ConfigurationController.java
@@ -0,0 +1,63 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.CompositionConfig;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.ves.VesStructureLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+@RequestMapping("/conf")
+public class ConfigurationController extends BaseController{
+
+ @Autowired
+ private CompositionConfig compositionConfig;
+
+ @ApiOperation(value = "Get a list of available flow types", response = CompositionConfig.class)
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "Successfully retrieved available flow types list"),
+ @ApiResponse(code = 500, message = "Flow types couldn't be fetched due to internal error")})
+ @RequestMapping(value = "/composition", method = RequestMethod.GET)
+ public ResponseEntity getCompositionConfig() {
+ try {
+ return new ResponseEntity<>(compositionConfig, HttpStatus.OK);
+ }catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Exception:{}",e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.FLOW_TYPES_CONFIGURATION_ERROR);
+ }
+ }
+
+ @RequestMapping(value = "/ves/schemaversions", method = RequestMethod.GET)
+ public ResponseEntity getCommonEventFormatVersion() {
+ try {
+ Set<String> availableVersionsSet = VesStructureLoader.getAvailableVersionsList();
+ List<String> availableVersionsList = new ArrayList<>(availableVersionsSet.size());
+ availableVersionsList.addAll(availableVersionsSet);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got a request to return available ves schema versions: {}", availableVersionsSet);
+ return new ResponseEntity<>(availableVersionsList, HttpStatus.OK);
+ }catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Exception:{}",e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND);
+ }
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java
new file mode 100644
index 0000000..3007335
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/LifecycleController.java
@@ -0,0 +1,84 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.UUID;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class LifecycleController extends BaseController {
+
+ private static final String VFCMT = "vfcmt";
+
+ @RequestMapping(value={"/checkin/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"})
+ public ResponseEntity putCheckin(
+ @PathVariable("assetType") String assetType,
+ @PathVariable("uuid") UUID uuid,
+ @RequestHeader("USER_ID") String user_id,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ switch (assetType) {
+ case VFCMT:
+ Asset res_checkin = checkin(user_id, uuid.toString(), AssetType.RESOURCE, requestId);
+ return new ResponseEntity<>(res_checkin, HttpStatus.OK);
+
+ default:
+ return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+ }
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.CHECK_IN_RESOURCE);
+ }
+ }
+
+ @RequestMapping(value={"/checkout/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"})
+ public ResponseEntity putCheckout(
+ @PathVariable("assetType") String assetType,
+ @PathVariable("uuid") UUID uuid,
+ @RequestHeader("USER_ID") String user_id,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ switch (assetType) {
+ case VFCMT:
+ Asset asset = checkout(user_id, uuid.toString(), AssetType.RESOURCE, requestId);
+ return new ResponseEntity<>(asset, HttpStatus.OK);
+
+ default:
+ return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+ }
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.CHECK_OUT_RESOURCE);
+ }
+ }
+
+ @RequestMapping(value={"/certify/{assetType}/{uuid}"}, method={RequestMethod.PUT}, produces={"application/json"})
+ public ResponseEntity putCertify(
+ @PathVariable("assetType") String assetType,
+ @PathVariable("uuid") String uuid,
+ @RequestHeader("USER_ID") String user_id,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ switch (assetType) {
+ case VFCMT:
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(user_id, uuid, LifecycleOperationType.CERTIFY.name(), "certifying VFCMT", requestId);
+ return new ResponseEntity<>(vfcmt, HttpStatus.OK);
+
+ default:
+ return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
+ }
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.CHECK_OUT_RESOURCE);
+ }
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java
new file mode 100644
index 0000000..3f5ff1a
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/RuleEditorController.java
@@ -0,0 +1,453 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import com.google.gson.JsonParseException;
+import org.apache.commons.collections.ListUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Asset;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.composition.CompositionConfig;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.onap.sdc.dcae.errormng.ServiceException;
+import org.onap.sdc.dcae.rule.editor.impl.RulesBusinessLogic;
+import org.onap.sdc.dcae.rule.editor.utils.RulesPayloadUtils;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.onap.sdc.dcae.ves.VesDataItemsDefinition;
+import org.onap.sdc.dcae.ves.VesDataTypeDefinition;
+import org.onap.sdc.dcae.ves.VesSimpleTypesEnum;
+import org.onap.sdc.dcae.ves.VesStructureLoader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+@RequestMapping("/rule-editor")
+public class RuleEditorController extends BaseController {
+
+ private static final String EXCEPTION = "Exception {}";
+ @Autowired
+ private CompositionConfig compositionConfig;
+
+ @Autowired
+ private RulesBusinessLogic rulesBusinessLogic;
+
+ @RequestMapping(value = "/list-events-by-versions", method = RequestMethod.GET)
+ public ResponseEntity getEventsByVersion() {
+ try {
+
+ Map<String, Set<String>> eventsByVersions = VesStructureLoader.getAvailableVersionsAndEventTypes();
+
+ List<EventTypesByVersionUI> resBody = eventsByVersions.entrySet().stream().map(entry -> {
+ Set<String> events = entry.getValue().stream().filter(event -> !EventTypesByVersionUI.DEFAULT_EVENTS.contains(event)).collect(Collectors.toSet());
+ return new EventTypesByVersionUI(entry.getKey(), events);
+ }).collect(Collectors.toList());
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got a request to return all ves event types by versions {}", eventsByVersions);
+ return new ResponseEntity<>(resBody, HttpStatus.OK);
+
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND);
+ }
+ }
+
+ @RequestMapping(value = { "/definition/{version:.*}/{eventType}" }, method = { RequestMethod.GET }, produces = { "application/json" })
+ public ResponseEntity getDefinition(@PathVariable("version") String version,
+ @PathVariable("eventType") String eventType) {
+
+ try {
+ List<EventTypeDefinitionUI> result = getEventTypeDefinitionUIs(version, eventType);
+
+ return new ResponseEntity<>(result, HttpStatus.OK);
+
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.VES_SCHEMA_NOT_FOUND);
+ }
+ }
+
+ /**
+ * This endpoint functions as a 'create/update' service for the rule editor UI
+ *
+ * @param json - json representing the saved rule
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @return json representing the rule editor UI
+ * Validations:
+ * 1. That the user is able to edit the VFCMT
+ * 2. That the cdump holds a dcae component with such nid (to avoid orphan rules)
+ * 3. Check that the fetched VFCMT is actually a VFCMT and not a regular VF
+ */
+ @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.POST }, produces = "application/json")
+ public ResponseEntity saveRule(@RequestBody String json, @ModelAttribute("requestId") String requestId,
+ @RequestHeader("USER_ID") String userId,
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam) {
+ try {
+ Rule rule = RulesPayloadUtils.parsePayloadToRule(json);
+ if (null == rule) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT);
+ }
+
+ List<ServiceException> errors = rulesBusinessLogic.validateRule(rule);
+ if(!errors.isEmpty()){
+ return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors);
+ }
+
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ checkVfcmtType(vfcmt);
+
+ if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED);
+ }
+
+ String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam);
+
+ // check for MappingRules artifact in existing artifacts
+ Artifact artifactFound = vfcmt.getArtifacts().stream()
+ .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel())))
+ .findAny().orElse(null);
+
+ // exception thrown if vfcmt is checked out and current user is not its owner
+ // performs vfcmt checkout if required
+ String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId);
+ // new mappingRules artifact, validate nid exists in composition before creating new artifact
+ if (null == artifactFound) {
+ if(cdumpContainsNid(vfcmt, nid, requestId)) {
+ return saveNewRulesArtifact(rule, vfcmtId, generateMappingRulesFileName(dcaeCompLabel, nid, configParam), artifactLabel , userId, requestId);
+ }
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.NODE_NOT_FOUND, "", dcaeCompLabel);
+ }
+
+ //update artifact flow - append new rule or edit existing rule
+ return addOrEditRuleInArtifact(rule, vfcmtId, userId, artifactFound, requestId);
+
+ } catch (JsonParseException je) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Rule format is invalid: {}", je);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_RULE_FORMAT, "", je.getMessage());
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.SAVE_RULE_ARTIFACT);
+ }
+
+ }
+
+
+ /**
+ * This endpoint functions as a 'fetch' service for the rule editor UI
+ *
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @return json representing the rule editor UI
+ */
+ @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.GET }, produces = "application/json")
+ public ResponseEntity getRules(
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam,
+ @ModelAttribute("requestId") String requestId) {
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) {
+ return new ResponseEntity<>("{}", HttpStatus.OK);
+ }
+ String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam);
+
+ // check for MappingRules artifact in existing artifacts
+ Artifact artifactListed = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null);
+ if (null == artifactListed) {
+ return new ResponseEntity<>("{}", HttpStatus.OK);
+ }
+ String ruleFile = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactListed.getArtifactUUID(), requestId);
+
+ // To avoid opening the file for reading we search for the eventType and SchemaVer from the artifact metadata's description
+ SchemaInfo schemainfo = RulesPayloadUtils.extractInfoFromDescription(artifactListed);
+ List<EventTypeDefinitionUI> schema = null == schemainfo? new ArrayList<>() : getEventTypeDefinitionUIs(schemainfo.getVersion(), schemainfo.getEventType());
+ return new ResponseEntity<>(RulesPayloadUtils.buildSchemaAndRulesResponse(ruleFile, schema), HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_RULE_ARTIFACT);
+ }
+
+ }
+
+ /**
+ * This endpoint functions as a 'delete' service for the rule editor UI
+ *
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @param ruleUid - the unique id of the rule to delete
+ * @return operation result
+ */
+ @RequestMapping(value = "/rule/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}/{ruleUid}", method = { RequestMethod.DELETE }, produces = "application/json")
+ public ResponseEntity deleteRule(
+ @RequestHeader("USER_ID") String userId,
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam,
+ @PathVariable("ruleUid") String ruleUid,
+ @ModelAttribute("requestId") String requestId){
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ if (null == vfcmt.getArtifacts()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "VFCMT {} doesn't have artifacts", vfcmtUuid);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED);
+ }
+ String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam);
+
+ // check for MappingRules artifact in existing artifacts
+ Artifact mappingRuleFile = vfcmt.getArtifacts().stream()
+ .filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel())))
+ .findAny().orElse(null);
+
+ if (null == mappingRuleFile) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't exist for VFCMT {}", artifactLabel, vfcmtUuid);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED);
+ }
+
+ String vfcmtId = assertOwnershipOfVfcmtId(userId, vfcmt, requestId);
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtId, mappingRuleFile.getArtifactUUID(), requestId);
+ MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload);
+ Rule removedRule = rulesBusinessLogic.deleteRule(rules, ruleUid);
+ if(null == removedRule){
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Rule {} not found.", ruleUid);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_RULE_FAILED);
+ }
+ if(rules.isEmpty()){ // if file doesn't contain any rules after last deletion -> let's delete the file
+ baseBusinessLogic.getSdcRestClient().deleteResourceArtifact(userId, vfcmtId, mappingRuleFile.getArtifactUUID(), requestId);
+ } else {
+ updateRulesArtifact(vfcmtId, userId, mappingRuleFile, rules, requestId);
+ }
+ return checkInAndReturnSaveArtifactResult(removedRule, vfcmtId, userId, requestId);
+ } catch (Exception e) {
+ return handleException(e, ApiType.SAVE_RULE_ARTIFACT);
+ }
+
+ }
+
+ /**
+ * This endpoint functions as a 'translate' service for the rule editor UI
+ *
+ * @param vfcmtUuid - VFCMT that the rule editor ui is saved in
+ * @param dcaeCompLabel - the name of the DCAE Component which the rule is applied to
+ * @param nid - A unique id of the DCAE Component which the rule is applied to - exists also in the cdump
+ * @param configParam - the name of the DCAE Component configuration property the rule is linked to
+ * @param flowType - the mapping rules flow type (SNMP,Syslog,FOI)
+ * @return translateJson representing the translated Rules
+ * Validations:
+ * 1. That the user is able to edit the VFCMT
+ * 2. That the cdump holds a dcae component with such nid (to avoid orphan rules)
+ * 3. Check that the fetched VFCMT is actually a VFCMT and not a regular VF
+ * @throws Exception
+ */
+ @RequestMapping(value = "/rule/translate/{vfcmtUuid}/{dcaeCompLabel}/{nid}/{configParam}", method = { RequestMethod.GET }, produces = "application/json")
+ public ResponseEntity translateRules(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId,
+ @PathVariable("dcaeCompLabel") String dcaeCompLabel,
+ @PathVariable("nid") String nid,
+ @PathVariable("configParam") String configParam,
+ @RequestParam("flowType") String flowType) throws Exception {
+
+ try {
+
+ if (StringUtils.isBlank(flowType) || MapUtils.isEmpty(compositionConfig.getFlowTypesMap()) || null == compositionConfig.getFlowTypesMap().get(flowType)) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "Flow type " + flowType + " not found");
+ }
+
+ // extract entry phase name and last phase name from configuration:
+ String entryPointPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getEntryPointPhaseName();
+ String lastPhaseName = compositionConfig.getFlowTypesMap().get(flowType).getLastPhaseName();
+
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ checkVfcmtType(vfcmt);
+
+ if (CollectionUtils.isEmpty(vfcmt.getArtifacts())) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", "No rules found on VFCMT " + vfcmtUuid);
+ }
+ String artifactLabel = Normalizers.normalizeArtifactLabel(dcaeCompLabel + nid + configParam);
+
+ // check for MappingRules artifact in existing artifacts
+ Artifact rulesArtifact = vfcmt.getArtifacts().stream().filter(a -> artifactLabel.equals(Normalizers.normalizeArtifactLabel(a.getArtifactLabel()))).findAny().orElse(null);
+
+ if (rulesArtifact == null) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.TRANSLATE_FAILED, "", artifactLabel + " doesn't exist on VFCMT " + vfcmtUuid);
+ }
+
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Retrieved mapping rules artifact {}, start parsing rules...", artifactLabel);
+ MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished parsing rules, calling validator...");
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(rules);
+ if (!errors.isEmpty()) {
+ return ErrConfMgr.INSTANCE.buildErrorArrayResponse(errors);
+ }
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Validation completed successfully, calling translator...");
+ String translateJson = rulesBusinessLogic.translateRules(rules, entryPointPhaseName, lastPhaseName, vfcmt.getName());
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translation completed successfully");
+ return new ResponseEntity<>(translateJson, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.SAVE_RULE_ARTIFACT);
+ }
+ }
+
+
+ ///////////////////PRIVATE METHODS////////////////////////////////////////////////////////////////////////
+
+ private String assertOwnershipOfVfcmtId(String userId, ResourceDetailed vfcmt, String requestId) throws Exception {
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+ String newVfcmtId = vfcmt.getUuid(); // may change after checking out a certified vfcmt
+ if (isNeedToCheckOut(vfcmt.getLifecycleState())) {
+ Asset result = checkout(userId, newVfcmtId, AssetType.RESOURCE, requestId);
+ if (result != null) {
+ newVfcmtId = result.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New resource after checkout is: {}", newVfcmtId);
+ }
+ }
+ return newVfcmtId;
+ }
+
+
+
+ // called after validating vfcmt.getArtifacts() is not null
+ private boolean cdumpContainsNid(ResourceDetailed vfcmt, String nid, String requestId) {
+ Artifact cdump = vfcmt.getArtifacts().stream()
+ .filter(a -> DcaeBeConstants.Composition.fileNames.COMPOSITION_YML.equalsIgnoreCase(a.getArtifactName()))
+ .findAny().orElse(null);
+ if (null == cdump || null == cdump.getArtifactUUID()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No {} found on vfcmt {}", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, vfcmt.getUuid());
+ return false;
+ }
+ try {
+ String artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmt.getUuid(), cdump.getArtifactUUID(), requestId);
+ if (!artifact.contains("\"nid\":\""+nid)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "{} doesn't contain nid {}. Cannot save mapping rule file", DcaeBeConstants.Composition.fileNames.COMPOSITION_YML, nid);
+ return false;
+ }
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), EXCEPTION, e);
+ return false;
+ }
+ return true;
+ }
+
+ private ResponseEntity<String> saveNewRulesArtifact(Rule rule, String vfcmtUuid, String artifactFileName, String artifactLabel, String userId, String requestId) throws Exception {
+ MappingRules body = new MappingRules(rule);
+ Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact(body.describe(), artifactFileName, ArtifactType.OTHER.name(), artifactLabel, body.convertToPayload());
+ baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, vfcmtUuid, artifact, requestId);
+ return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId);
+ }
+
+ private ResponseEntity addOrEditRuleInArtifact(Rule rule, String vfcmtUuid, String userId, Artifact rulesArtifact, String requestId) throws Exception {
+ String payload = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, rulesArtifact.getArtifactUUID(), requestId);
+ MappingRules rules = RulesPayloadUtils.parseMappingRulesArtifactPayload(payload);
+
+ // in case the rule id is passed but the rule doesn't exist on the mapping rule file:
+ if(!rulesBusinessLogic.addOrEditRule(rules, rule)) {
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.SAVE_RULE_FAILED);
+ }
+ updateRulesArtifact(vfcmtUuid, userId, rulesArtifact, rules, requestId);
+ return checkInAndReturnSaveArtifactResult(rule, vfcmtUuid, userId, requestId);
+ }
+
+ // regardless of check in result, return save artifact success
+ private ResponseEntity<String> checkInAndReturnSaveArtifactResult(Rule rule, String vfcmtUuid, String userId, String requestId) {
+ try {
+ checkin(userId, vfcmtUuid, AssetType.RESOURCE, requestId);
+ } catch (Exception e) {
+ // swallowing the exception intentionally since it is on the check in action
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occurred while performing check in on VFCMT {}:{}", vfcmtUuid, e);
+ }
+ return new ResponseEntity<>(rule.toJson(), HttpStatus.OK);
+ }
+
+ private void updateRulesArtifact(String vfcmtUuid, String userId, Artifact artifactInfo, MappingRules rules, String requestId) throws Exception {
+ artifactInfo.setPayloadData(Base64Utils.encodeToString(rules.convertToPayload()));
+ // POST must contain 'description' while GET returns 'artifactDescription'
+ artifactInfo.setDescription(artifactInfo.getArtifactDescription());
+ baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, vfcmtUuid, artifactInfo, requestId);
+ }
+
+
+ /**
+ * @param eventMapStream
+ * @param parent
+ * @param path
+ * @return
+ */
+ private List<EventTypeDefinitionUI> convertToEventTypeDefinition(Stream<Entry<String, VesDataTypeDefinition>> eventMapStream, VesDataTypeDefinition parent, String path) {
+
+ return eventMapStream.map(entry -> {
+ Map<String, VesDataTypeDefinition> properties = entry.getValue().getProperties();
+ VesDataItemsDefinition items = entry.getValue().getItems();
+ String newPath = path + "." + entry.getKey();
+ List<EventTypeDefinitionUI> children = (properties == null) ? null : convertToEventTypeDefinition(properties.entrySet().stream(), entry.getValue(), newPath);
+ if(VesSimpleTypesEnum.ARRAY.getType().equals(entry.getValue().getType())) {
+ newPath += "[]";
+ if(innerTypeIsComplex(items)) {
+ children = convertComplexArrayType(items, newPath);
+ } else if(innerTypeIsArray(items)) {
+ newPath += "[]";
+ }
+ }
+
+ boolean isRequired = (parent != null) ? parent.getRequired().contains(entry.getKey()) : false;
+ return new EventTypeDefinitionUI(entry.getKey(), children, isRequired, newPath);
+ }).collect(Collectors.toList());
+ }
+
+ private boolean innerTypeIsComplex(VesDataItemsDefinition items){
+ return items != null && items.stream().anyMatch(p -> p.getProperties() != null);
+ }
+
+ private boolean innerTypeIsArray(VesDataItemsDefinition items){
+ return items != null && items.stream().anyMatch(p -> p.getItems() != null);
+ }
+
+ private List<EventTypeDefinitionUI> convertComplexArrayType(VesDataItemsDefinition items, String path){
+ return items.stream().map(item -> item.getProperties() != null ? convertToEventTypeDefinition(item.getProperties().entrySet().stream(), item, path) : new ArrayList<EventTypeDefinitionUI>())
+ .flatMap(List::stream).collect(Collectors.toList());
+ }
+
+
+ private String generateMappingRulesFileName(String dcaeCompLabel, String nid, String configParam) {
+ return dcaeCompLabel + "_" + nid + "_" + configParam + DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX;
+ }
+
+ private List<EventTypeDefinitionUI> getEventTypeDefinitionUIs(String version, String eventType) {
+ List<String> eventNamesToReturn = ListUtils.union(EventTypesByVersionUI.DEFAULT_EVENTS, Arrays.asList(eventType));
+ Map<String, VesDataTypeDefinition> eventDefs = VesStructureLoader.getEventListenerDefinitionByVersion(version);
+ Stream<Entry<String, VesDataTypeDefinition>> filteredEvents = eventDefs.entrySet().stream().filter(entry -> eventNamesToReturn.contains(entry.getKey()));
+
+ return convertToEventTypeDefinition(filteredEvents, null, "event");
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java
new file mode 100644
index 0000000..257d1a9
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/ServicesController.java
@@ -0,0 +1,230 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.AttachVFCMTServiceRequest;
+import org.onap.sdc.dcae.composition.restmodels.DcaeMinimizedService;
+import org.onap.sdc.dcae.composition.restmodels.MessageResponse;
+import org.onap.sdc.dcae.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.DcaeException;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class ServicesController extends BaseController {
+
+ /***
+ * GET services list by VFCMT
+ * @param userId
+ * @param vfcmtUuid
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/services/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity services(@RequestHeader("USER_ID") String userId, @PathVariable String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET ({}) Vfcmt form SDC: {}", vfcmtUuid, vfcmt);
+ checkVfcmtType(vfcmt);
+ checkUserIfResourceCheckedOut(userId, vfcmt);
+
+ List<Service> services = baseBusinessLogic.getSdcRestClient().getServices(requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "GET services data from SDC: {}", services);
+ List<Service> uuids = filterServicesByUser(services, userId);
+ return new ResponseEntity<>(uuids, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.GET_SERVICE);
+ }
+ }
+
+ /***
+ * GET a single service
+ * @param theServiceId
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/service/{theServiceId}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity service(@PathVariable String theServiceId, @ModelAttribute("requestId") String requestId) {
+ try {
+ ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(theServiceId, requestId);
+ if (service != null) {
+ if(service.getResources()!=null){
+ List<ResourceInstance> vfResourcesOnly = service.getResources().stream().filter(vfi -> vfi.getResoucreType().equals("VF")).collect(Collectors.toList());
+ service.setResources(vfResourcesOnly);
+ }else{
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Service {} doesn't have any resources (e.g VFi's)", theServiceId);
+ }
+ } else {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Couldn't fetch service with uuid {} from SDC", theServiceId);
+ }
+ return new ResponseEntity<>(service, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.GET_SERVICE);
+ }
+ }
+
+
+ /***
+ * Attach service and service instance to VFCMT
+ * @param userId
+ * @param request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/{vfcmtUuid}/attachment", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity attachService(
+ @PathVariable("vfcmtUuid") String vfcmtUuid,
+ @RequestHeader("USER_ID") String userId,
+ @RequestBody AttachVFCMTServiceRequest request,
+ @ModelAttribute("requestId") String requestId) {
+
+ String serviceUuid = request.getServiceUuid();
+ String vfiName = request.getInstanceName();
+ String resourceUuid = vfcmtUuid;
+ MessageResponse response = new MessageResponse();
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+
+ checkVfcmtType(vfcmt);
+ verifyVfiExists(serviceUuid, vfiName, requestId);
+
+ boolean isUpdateMode = false;
+ Artifact artifactObj = null;
+
+ String reference = serviceUuid + "/resources/" + vfiName;
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************");
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Reference between service and vfi {}", reference);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*****************************************");
+
+ if(!CollectionUtils.isEmpty(vfcmt.getArtifacts())){
+ artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null);
+ isUpdateMode = null != artifactObj;
+ }
+
+ if (isNeedToCheckOut(vfcmt.getLifecycleState())) {
+ vfcmt = baseBusinessLogic.getSdcRestClient().changeResourceLifecycleState(userId, vfcmtUuid, LifecycleOperationType.CHECKOUT.name(), null, requestId);
+ if (vfcmt != null) {
+ resourceUuid = vfcmt.getUuid();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "New vfcmt uuid after checkout is: {}", resourceUuid);
+ }
+ }
+
+ if(isUpdateMode){
+ updateReferenceArtifact(userId, resourceUuid, artifactObj, reference, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} updated with content: {}", reference, DcaeBeConstants.Composition.fileNames.SVC_REF, reference);
+ }else{
+ Artifact artifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", reference.getBytes());
+ baseBusinessLogic.getSdcRestClient().createResourceArtifact(userId, resourceUuid, artifact, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} created with content: {}", DcaeBeConstants.Composition.fileNames.SVC_REF, reference);
+ }
+ checkin(userId, resourceUuid, org.onap.sdc.dcae.enums.AssetType.RESOURCE, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Attachment of reference={} in VFCMT {} has finished successfully", reference, resourceUuid);
+
+ response.setSuccessResponse("Artifact updated");
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.ATTACH_TO_SERVICE);
+ }
+ }
+
+ @RequestMapping(value = { "/{vfcmtUuid}/attachment" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getAttachedService(@PathVariable("vfcmtUuid") String vfcmtUuid, @ModelAttribute("requestId") String requestId) {
+
+ MessageResponse response = new MessageResponse();
+
+ try {
+ ResourceDetailed vfcmt = baseBusinessLogic.getSdcRestClient().getResource(vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), vfcmt.toString());
+ checkVfcmtType(vfcmt);
+ String artifact = "No Artifacts";
+
+ if (!CollectionUtils.isEmpty(vfcmt.getArtifacts())) {
+ Artifact artifactObj = vfcmt.getArtifacts().stream().filter(a -> DcaeBeConstants.Composition.fileNames.SVC_REF.equals(a.getArtifactName())).findAny().orElse(null);
+ if (null != artifactObj)
+ artifact = baseBusinessLogic.getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactObj.getArtifactUUID(), requestId);
+ }
+ response.setSuccessResponse(artifact);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ErrConfMgr.ApiType.GET_VFCMT);
+ }
+ }
+
+ /**** PRIVATE METHODS ****/
+
+ private void updateReferenceArtifact(String userId, String VFCMTUuid, Artifact artifactObj, String reference, String requestId) throws Exception {
+ artifactObj.setDescription("updateReferenceArtifact");
+ artifactObj.setPayloadData(Base64Utils.encodeToString(reference.getBytes()));
+ baseBusinessLogic.getSdcRestClient().updateResourceArtifact(userId, VFCMTUuid, artifactObj, requestId);
+ }
+
+
+ /**
+ *
+ * @param lastUpdaterUserId
+ * @param services
+ * @param userId
+ * @return
+ */
+
+ //TODO move method to ci tests
+ public List<DcaeMinimizedService> parseAndFilterServicesByUser(String lastUpdaterUserId, List<LinkedHashMap<String, String>> services, String userId) {
+ List<DcaeMinimizedService> uuids = null;
+ if (services != null) {
+ //services.stream().filter(predicate)
+ uuids = services.stream()
+ .map(x -> new DcaeMinimizedService(x.get("uuid"), x.get("name"), x.get("lastUpdaterUserId"), x.get("lifecycleState"), x.get("version"), x.get("invariantUUID")))
+ .collect(Collectors.groupingBy(DcaeMinimizedService::getInvariantUUID)).values().stream()
+ .map(p -> p.stream()
+ .sorted(Comparator.comparing(DcaeMinimizedService::getVersionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0))
+ .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifeCycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()))))
+ .sorted(Comparator.comparing(DcaeMinimizedService::getName)).collect(Collectors.toList());
+ }
+ return uuids;
+ }
+
+ private List<Service> filterServicesByUser(List<Service> services, String userId) {
+ return CollectionUtils.isEmpty(services) ? new ArrayList<>() : services.stream()
+ .collect(Collectors.groupingBy(Service::getInvariantUUID)).values().stream()
+ .map(p -> p.stream()
+ .sorted(Comparator.comparing(Service::versionAsFloat).reversed())).map(p -> p.collect(Collectors.toList())).map(p -> p.get(0))
+ .filter(x -> (!(!x.getLastUpdaterUserId().equals(userId) && x.getLifecycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()))))
+ .sorted(Comparator.comparing(Service::getName)).collect(Collectors.toList());
+ }
+
+ /**
+ *
+ * @param serviceUuid
+ * @param vfiName
+ * @param requestId
+ * @throws Exception
+ */
+ private void verifyVfiExists(String serviceUuid, String vfiName, String requestId) throws Exception {
+ ServiceDetailed service = baseBusinessLogic.getSdcRestClient().getService(serviceUuid, requestId);
+ boolean isServiceContainsVfi = null != service && !CollectionUtils.isEmpty(service.getResources()) && service.getResources().stream()
+ .filter(vfi -> "VF".equals(vfi.getResoucreType()))
+ .anyMatch(vfi -> vfiName.equals(vfi.getResourceInstanceName()));
+ if (!isServiceContainsVfi) {
+ ResponseFormat responseFormat = ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.VFI_FETCH_ERROR, null, serviceUuid, vfiName);
+ throw new DcaeException(HttpStatus.NOT_FOUND, responseFormat.getRequestError());
+ }
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java
new file mode 100644
index 0000000..0e1b209
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/VfcmtController.java
@@ -0,0 +1,183 @@
+package org.onap.sdc.dcae.composition.controller;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.impl.ReferenceBusinessLogic;
+import org.onap.sdc.dcae.composition.impl.VfcmtBusinessLogic;
+import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.ImportVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Resource;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.errormng.ErrConfMgr.ApiType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class VfcmtController extends BaseController{
+
+
+ @Autowired
+ private VfcmtBusinessLogic vfcmtBusinessLogic;
+ @Autowired
+ private ReferenceBusinessLogic referenceBusinessLogic;
+
+ private static final String VFCMT = "VFCMT";
+ private static final String TEMPLATE = "Template";
+ private static final String BASE_MONITORING_TEMPLATE = "Base Monitoring Template";
+
+
+
+ /***
+ * Get one resource information
+ * @param theResourceId retrieved resource id
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/resource/{theResourceId}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity resource(@PathVariable String theResourceId, @ModelAttribute("requestId") String requestId) {
+ try {
+ ResourceDetailed resource = baseBusinessLogic.getSdcRestClient().getResource(theResourceId, requestId);
+ return new ResponseEntity<>(resource, HttpStatus.OK);
+ }catch (Exception e) {
+ return handleException(e, ApiType.GET_VFCMT);
+ }
+ }
+
+ /***
+ * Get All resources
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/getResourcesByCategory" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getResourcesByCategory(@ModelAttribute("requestId") String requestId) {
+ try {
+ List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(VFCMT, null, null, requestId);
+ return new ResponseEntity<>(resources, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_ALL_VFCMTS);
+ }
+ }
+
+ /***
+ * Get All resources by Service
+ * @return ResponseEntity
+ */
+
+ @RequestMapping(value = { "/{contextType}/{uuid}/{version}/getVfcmtsForMigration" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getVfcmtsForMigration(@RequestHeader("USER_ID") String userId,
+ @PathVariable String contextType,
+ @PathVariable String uuid,
+ @PathVariable String version,
+ @ModelAttribute("requestId") String requestId){
+
+ return vfcmtBusinessLogic.getVfcmtsForMigration(userId, contextType, uuid, version, requestId);
+ }
+
+ /***
+ * Get All resources by Monitoring Template Category
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/getResourcesByMonitoringTemplateCategory" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getResourcesByMonitoringTemplateCategory(@ModelAttribute("requestId") String requestId) {
+ try {
+ List<Resource> resources = baseBusinessLogic.getSdcRestClient().getResources(VFCMT, TEMPLATE, BASE_MONITORING_TEMPLATE, requestId);
+ return new ResponseEntity<>(resources, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_ALL_VFCMTS);
+ }
+ }
+
+ /***
+ * Create new Vfcmt
+ * @param userId retrieved user ID
+ * @param request retrieved request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/createVFCMT", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity createVFCMT(@RequestHeader("USER_ID") String userId, @RequestBody CreateVFCMTRequest request, @ModelAttribute("requestId") String requestId) {
+ vfcmtBusinessLogic.addSdcMandatoryFields(request, userId);
+ try {
+ ResourceDetailed response = baseBusinessLogic.getSdcRestClient().createResource(userId, request, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "createVFCMT after post: {}", response);
+ return new ResponseEntity<>(response, HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.CREATE_NEW_VFCMT);
+ }
+ }
+
+ /***
+ * Create new Vfcmt from general screen
+ * @param userId retrieved user ID
+ * @param request retrieved request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/createMC", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity createMC(@RequestHeader("USER_ID") String userId, @RequestBody CreateVFCMTRequest request, @ModelAttribute("requestId") String requestId) {
+ return vfcmtBusinessLogic.createMcFromTemplate(userId, request, requestId);
+ }
+
+
+ /***
+ * Clone or import existing VFCMT and attach to selected service/resource
+ * @param userId
+ * @param request
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = "/importMC", method = RequestMethod.POST, produces = {"application/json" })
+ public ResponseEntity importMC(@RequestHeader("USER_ID") String userId, @RequestBody ImportVFCMTRequest request, @ModelAttribute("requestId") String requestId) {
+ return vfcmtBusinessLogic.importMC(userId, request, requestId);
+ }
+
+ /***
+ * GET a list of Monitoring Components of a service by uuid and version
+ * @param context the context type of this request
+ * @param uuid the uuid of the type requested
+ * @param version the version of the entity requested
+ * @return ResponseEntity
+ */
+ @RequestMapping(value = { "/{context}/{uuid}/{version}/monitoringComponents" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getMonitoringComponents(@PathVariable String context, @PathVariable String uuid, @PathVariable String version, @ModelAttribute("requestId") String requestId) {
+ try {
+ ExternalReferencesMap mcRefs = baseBusinessLogic.getSdcRestClient().getMonitoringReferences(context, uuid, version, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Got monitoring references map from SDC: {}", mcRefs.values());
+ return new ResponseEntity<>(referenceBusinessLogic.fetchMonitoringComponents(mcRefs, requestId), HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_SERVICE);
+ }
+ }
+
+ @RequestMapping(value = { "/{context}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" })
+ public ResponseEntity deleteVfcmtReference(@RequestHeader("USER_ID") String userId, @PathVariable String context, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) {
+ try {
+ referenceBusinessLogic.deleteVfcmtReference(userId, context, serviceUuid, vfiName, vfcmtUuid, requestId);
+ return new ResponseEntity<>(HttpStatus.OK);
+ } catch (Exception e) {
+ return handleException(e, ApiType.DELETE_VFCMT_REFERENCE);
+ }
+ }
+
+ @RequestMapping(value = { "/{context}/{monitoringComponentName}/{serviceUuid}/{vfiName}/{vfcmtUuid}/deleteVfcmtReference" }, method = { RequestMethod.DELETE }, produces = {"application/json" })
+ public ResponseEntity deleteVfcmtReferenceWithBlueprint(@RequestHeader("USER_ID") String userId, @PathVariable String context, @PathVariable String monitoringComponentName, @PathVariable String serviceUuid, @PathVariable String vfiName, @PathVariable String vfcmtUuid, @ModelAttribute String requestId) {
+ try {
+ referenceBusinessLogic.deleteVfcmtReference(userId, context, serviceUuid, vfiName, vfcmtUuid, requestId);
+ } catch (Exception e) {
+ return handleException(e, ApiType.DELETE_VFCMT_REFERENCE);
+ }
+ return referenceBusinessLogic.deleteVfcmtReferenceBlueprint(userId, context, monitoringComponentName, serviceUuid, vfiName, vfcmtUuid, requestId);
+ }
+
+ @RequestMapping(value = { "/getVfcmtReferenceData/{vfcmtUuid}" }, method = { RequestMethod.GET }, produces = {"application/json" })
+ public ResponseEntity getVfcmtReferenceData(@PathVariable String vfcmtUuid, @ModelAttribute String requestId) {
+ try {
+ return vfcmtBusinessLogic.getVfcmtReferenceData(vfcmtUuid, requestId);
+ } catch (Exception e) {
+ return handleException(e, ApiType.GET_VFCMT);
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java
new file mode 100644
index 0000000..eaad1b0
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthController.java
@@ -0,0 +1,77 @@
+package org.onap.sdc.dcae.composition.controller.health;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.health.ComponentsInfo;
+import org.onap.sdc.dcae.composition.restmodels.health.HealthResponse;
+import org.onap.sdc.dcae.composition.CompositionEngine;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.google.gson.Gson;
+
+@RestController
+@EnableAutoConfiguration
+@CrossOrigin
+public class HealthController {
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+ Gson gson = new Gson();
+
+ @Autowired
+ ToscaLabHealthState toscaLabHealthState;
+
+ @RequestMapping(value = "/healthCheck", method = RequestMethod.GET)
+ public ResponseEntity<String> healthCheck() {
+ HttpStatus httpSts = HttpStatus.OK;
+ try{
+ HealthResponse healthResponse = new HealthResponse();
+ healthResponse.setHealthCheckComponent(DcaeBeConstants.Health.APP_NAME);
+ healthResponse.setHealthCheckStatus(DcaeBeConstants.Health.UP);
+ healthResponse.setSdcVersion(CompositionEngine.getDcaeVersion());
+ healthResponse.setDescription(DcaeBeConstants.Health.OK);
+
+ List<ComponentsInfo> componentsInfoList = new ArrayList<ComponentsInfo>();
+ ComponentsInfo componentsInfo = new ComponentsInfo();
+ componentsInfo.setHealthCheckComponent(DcaeBeConstants.Health.BE);
+ componentsInfo.setHealthCheckStatus(DcaeBeConstants.Health.UP);
+ componentsInfo.setVersion(CompositionEngine.getDcaeVersion());
+ componentsInfo.setDescription(DcaeBeConstants.Health.OK);
+ componentsInfoList.add(componentsInfo);
+
+ ComponentsInfo toscaLab = new ComponentsInfo();
+ ComponentsInfo toscaLabHealthRes = toscaLabHealthState.getToscaLabHealthResponse();
+ if(toscaLabHealthRes.getHealthCheckStatus().equals(DcaeBeConstants.Health.DOWN)){
+ healthResponse.setHealthCheckStatus(DcaeBeConstants.Health.DOWN);
+ healthResponse.setDescription(toscaLabHealthRes.getHealthCheckComponent()+" is down");
+ httpSts = HttpStatus.INTERNAL_SERVER_ERROR;
+ }
+ toscaLab.setHealthCheckComponent(toscaLabHealthRes.getHealthCheckComponent());
+ toscaLab.setHealthCheckStatus(toscaLabHealthRes.getHealthCheckStatus());
+ toscaLab.setVersion(toscaLabHealthRes.getVersion());
+ toscaLab.setDescription(toscaLabHealthRes.getDescription());
+ componentsInfoList.add(toscaLab);
+
+ healthResponse.setComponentsInfo(componentsInfoList);
+ String json = gson.toJson(healthResponse, HealthResponse.class);
+
+ return new ResponseEntity<String>(json, httpSts);
+ }
+ catch(Exception e){
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error occured while performing HealthCheck: {}", e.getLocalizedMessage());
+ return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java
new file mode 100644
index 0000000..609480d
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/HealthPoller.java
@@ -0,0 +1,97 @@
+package org.onap.sdc.dcae.composition.controller.health;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.health.ComponentsInfo;
+import org.onap.sdc.dcae.catalog.commons.Future;
+import org.onap.sdc.dcae.catalog.commons.Http;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import com.google.gson.Gson;
+
+@Configuration
+@EnableAsync
+@EnableScheduling
+@ConfigurationProperties(prefix="blueprinter")
+public class HealthPoller {
+ private URI hcuri;
+ private String hcretrynum;
+ private Gson gson;
+
+ private OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @Autowired
+ private ToscaLabHealthState toscaLabHealthState;
+
+ public HealthPoller() {
+ super();
+ gson = new Gson();
+ }
+
+ @Scheduled(fixedDelayString="${healthpoller.fixedDelay}")
+ public void pollToscaLabHealth() {
+ ComponentsInfo toscaLabHealthRes = null;
+ ResponseEntity<String> healthRes = null;
+ try {
+ for(int i=0; i<Integer.valueOf(hcretrynum); i++){ // 3 tries
+ healthRes = sendHealthCheck();
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Try #{}: {}", i, healthRes);
+ if(healthRes.getStatusCode()==HttpStatus.OK){
+ String result = (String) healthRes.getBody();
+ toscaLabHealthRes = gson.fromJson(result, ComponentsInfo.class);
+ break;
+ }
+ }
+ } catch (Exception e) {
+ toscaLabHealthRes = getNegativeHealth(e.getMessage());
+ }
+ if(toscaLabHealthRes == null){
+ toscaLabHealthRes = getNegativeHealth(healthRes.getBody() + "-" + healthRes.getStatusCode());
+ }
+ toscaLabHealthState.setToscaLabHealthResponse(toscaLabHealthRes);
+ }
+
+ private ComponentsInfo getNegativeHealth(String msg) {
+ ComponentsInfo toscaLabHealthRes = new ComponentsInfo();
+ String description = "DCAE-D BE failed while trying to fetch Tosca_Lab healthcheck. Exception: " +msg;
+ toscaLabHealthRes.setDescription(description);
+ toscaLabHealthRes.setHealthCheckComponent(DcaeBeConstants.Health.TOSCA_LAB);
+ toscaLabHealthRes.setHealthCheckStatus(DcaeBeConstants.Health.DOWN);
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), description);
+ return toscaLabHealthRes;
+ }
+
+ public ResponseEntity<String> sendHealthCheck() {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+ HttpEntity<String> entity = new HttpEntity<String>(headers);
+ return Http.exchangeSync(hcuri.toString(), HttpMethod.GET, entity, String.class, 5000);
+ }
+
+ public void setHcuri(URI hcuri) {
+ this.hcuri = hcuri;
+ }
+
+ public void setHcretrynum(String hcretrynum) {
+ this.hcretrynum = hcretrynum;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java
new file mode 100644
index 0000000..6fe469f
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/health/ToscaLabHealthState.java
@@ -0,0 +1,29 @@
+package org.onap.sdc.dcae.composition.controller.health;
+
+import org.onap.sdc.dcae.composition.restmodels.health.ComponentsInfo;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Scope(value = "singleton")
+@Component
+public class ToscaLabHealthState {
+ private ComponentsInfo toscaLabHealthResponse;
+
+ public ToscaLabHealthState() {
+ super();
+ toscaLabHealthResponse = new ComponentsInfo();
+ toscaLabHealthResponse.setDescription("Not up yet");
+ toscaLabHealthResponse.setHealthCheckComponent(DcaeBeConstants.Health.TOSCA_LAB);
+ toscaLabHealthResponse.setHealthCheckStatus(DcaeBeConstants.Health.DOWN);
+ }
+
+ public ComponentsInfo getToscaLabHealthResponse() {
+ return toscaLabHealthResponse;
+ }
+
+ public void setToscaLabHealthResponse(ComponentsInfo toscaLabHealthResponse) {
+ this.toscaLabHealthResponse = toscaLabHealthResponse;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java
new file mode 100644
index 0000000..48c7153
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/controller/swagger/SwaggerConfig.java
@@ -0,0 +1,23 @@
+package org.onap.sdc.dcae.composition.controller.swagger;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+ @Bean
+ public Docket productApi() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("org.onap.sdc.dcae.composition.controller"))
+ .paths(PathSelectors.regex("/*.*"))
+ .build();
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java
new file mode 100644
index 0000000..f26c885
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/BaseBusinessLogic.java
@@ -0,0 +1,49 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.dcae.client.ISdcClient;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.CollectionUtils;
+
+@Component
+public class BaseBusinessLogic {
+ @Autowired
+ protected ISdcClient sdcRestClient;
+
+ protected static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ protected static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ public ISdcClient getSdcRestClient() {
+ return sdcRestClient;
+ }
+
+ void setSdcRestClient(ISdcClient sdcRestClient) {
+ this.sdcRestClient = sdcRestClient;
+ }
+
+ Artifact cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, String requestId) throws Exception {
+ Artifact cloned = SdcRestClientUtils.generateDeploymentArtifact(artifactToClone.getArtifactDescription(), artifactToClone.getArtifactName(), artifactToClone.getArtifactType(), artifactToClone.getArtifactLabel(), payload.getBytes());
+ return sdcRestClient.createResourceArtifact(userId, targetId, cloned, requestId);
+ }
+
+ public void cloneArtifactToTarget(String userId, String targetId, String payload, Artifact artifactToClone, Artifact artifactToOverride, String requestId) throws Exception{
+ if (null != artifactToOverride) {
+ artifactToOverride.setDescription(artifactToOverride.getArtifactDescription());
+ artifactToOverride.setPayloadData(Base64Utils.encodeToString(payload.getBytes()));
+ sdcRestClient.updateResourceArtifact(userId, targetId, artifactToOverride, requestId);
+ } else {
+ cloneArtifactToTarget(userId, targetId, payload, artifactToClone, requestId);
+ }
+ }
+
+ Artifact findArtifactDataByArtifactName(ResourceDetailed vfcmt, String artifactName) {
+ return null == vfcmt ? null : CollectionUtils.isEmpty(vfcmt.getArtifacts()) ? null : vfcmt.getArtifacts().stream()
+ .filter(p -> artifactName.equals(p.getArtifactName())).findAny().orElse(null);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java
new file mode 100644
index 0000000..d229b67
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogic.java
@@ -0,0 +1,74 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceInstance;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ServiceDetailed;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+import static org.springframework.util.CollectionUtils.isEmpty;
+
+@Component
+public class ReferenceBusinessLogic extends BaseBusinessLogic {
+
+ public ResponseEntity deleteVfcmtReferenceBlueprint(String userId, String context, String monitoringComponentName, String serviceUuid, String vfiName, String vfcmtUuid, String requestId) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to delete blueprint, monitoringComponentName = {}, vfiName = {}", monitoringComponentName, vfiName);
+ try {
+ String normalizedVfiName = Normalizers.normalizeComponentInstanceName(vfiName);
+ ServiceDetailed serviceDetailed = sdcRestClient.getService(serviceUuid, requestId);
+ Optional<ResourceInstance> resourceInstance = serviceDetailed.getResources().stream().filter(item -> item.getResourceInstanceName().equalsIgnoreCase(vfiName)).findAny();
+ if (resourceInstance.isPresent() && resourceInstance.get().getArtifacts() != null) {
+ Optional<Artifact> artifact = resourceInstance.get().getArtifacts().stream().filter(item -> item.getArtifactName().contains(monitoringComponentName)).findAny();
+ artifact.ifPresent(artifact1 -> sdcRestClient.deleteInstanceResourceArtifact(userId, context, serviceUuid, normalizedVfiName, artifact1.getArtifactUUID(), requestId));
+ }
+ } catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Failed to delete blueprint with serviceUuid {}, vfcmtUuid . message: {} ", serviceUuid, vfcmtUuid, e);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.DELETE_BLUEPRINT_FAILED);
+ }
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+
+ public void deleteVfcmtReference(String userId, String context, String serviceUuid, String vfiName, String vfcmtUuid, String requestId) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to delete vfcmt reference, vfiName = {}", vfiName);
+ String normalizedVfiName = Normalizers.normalizeComponentInstanceName(vfiName);
+ sdcRestClient.deleteExternalMonitoringReference(userId, context, serviceUuid, normalizedVfiName, vfcmtUuid, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished to delete vfcmt reference. serviceUuid {}, vfcmtUuid {}", serviceUuid, vfcmtUuid);
+ }
+
+ // 1806 US381853 Return a list of monitoring components by external reference id. Support partial success
+ public Map<String, List<MonitoringComponent>> fetchMonitoringComponents(ExternalReferencesMap mcRefs, String requestId) {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Going to fetch monitoring components metadata for vfis {}", mcRefs.keySet());
+ Map<String, List<MonitoringComponent>> result = new LinkedHashMap<>();
+ List<MonitoringComponent> monitoringComponents = Collections.synchronizedList(new ArrayList<>());
+ List<MonitoringComponent> unavailable = Collections.synchronizedList(new ArrayList<>());
+ mcRefs.entrySet().parallelStream().forEach(entry ->
+ entry.getValue().parallelStream().forEach(id -> {
+ try{
+ monitoringComponents.add(new MonitoringComponent(getSdcRestClient().getResource(id, requestId), entry.getKey()));
+ } catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Failed to fetch monitoring component with uuid {}. message: {} ", id, e);
+ unavailable.add(new MonitoringComponent(id, entry.getKey(), "unavailable"));
+ }
+
+ })
+ );
+ result.put("monitoringComponents", monitoringComponents);
+ if(!isEmpty(unavailable)) {
+ result.put("unavailable", unavailable);
+ }
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished fetching monitoring components metadata for vfis {}", mcRefs.keySet());
+ return result;
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java
new file mode 100644
index 0000000..e68a8ee
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogic.java
@@ -0,0 +1,283 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.lang.StringUtils;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.*;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Resource;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.enums.LifecycleOperationType;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT;
+import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.findState;
+
+@Component
+public class VfcmtBusinessLogic extends BaseBusinessLogic {
+
+ private static final String VFCMT = "VFCMT";
+ private static final String TEMPLATE = "Template";
+ private static final String MONITORING_TEMPLATE = "Monitoring Template";
+ private static final String DEFAULTICON = "defaulticon";
+ private static final String VENDOR_NAME = "vendorName";
+ private static final String VENDOR_RELEASE = "vendorRelease";
+
+ public ResponseEntity createMcFromTemplate(String userId, CreateVFCMTRequest request, String requestId) {
+ if(!validateMCRequestFields(request)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Missing information");
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_CONTENT);
+ }
+ return cloneMcAndAddServiceReference(userId, request, requestId);
+ }
+
+ //1806 US388513 collect existing VFCMT data - flowType from cdump artifact and external reference from svc_reference artifact. If cdump not found - return error
+
+ public ResponseEntity getVfcmtReferenceData(String vfcmtUuid, String requestId) throws Exception {
+ ResourceDetailed vfcmt = sdcRestClient.getResource(vfcmtUuid, requestId);
+ Artifact artifactData = findCdumpArtifactData(vfcmt);
+ if(null == artifactData) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"No composition found on vfcmt {}", vfcmtUuid);
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName());
+ }
+ VfcmtData vfcmtData = new VfcmtData(vfcmt);
+ //fetch cdump payload
+ String payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactData.getArtifactUUID(), requestId);
+ //extract and set flowType from cdump payload
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Looking for flowType definition in cdump");
+ vfcmtData.setFlowType(StringUtils.substringBetween(payload,"\"flowType\":\"","\""));
+ //find svc_reference
+ artifactData = findArtifactDataByArtifactName(vfcmt, DcaeBeConstants.Composition.fileNames.SVC_REF);
+ if(null != artifactData) {
+ //fetch svc_reference payload
+ payload = getSdcRestClient().getResourceArtifact(vfcmtUuid, artifactData.getArtifactUUID(), requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"Looking for attached service and vfi info in svc_reference");
+ //extract and set serviceUuid from svc_reference payload
+ vfcmtData.setServiceUuid(StringUtils.substringBefore(payload, "/"));
+ //extract and set vfiName from svc_reference payload
+ vfcmtData.setVfiName(StringUtils.substringAfterLast(payload, "/"));
+ }
+ return new ResponseEntity<>(vfcmtData, HttpStatus.OK);
+ }
+
+
+ //1806 US388525 import or clone VFCMT - always pass the flowType - update will only take place if missing from cdump
+ public ResponseEntity importMC(String userId, ImportVFCMTRequest request, String requestId) {
+ if(!validateMCRequestFields(request)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Missing information");
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.INVALID_CONTENT);
+ }
+ // option 1 - clone
+ if(request.isCloneVFCMT()) {
+ return cloneMcAndAddServiceReference(userId, request, requestId);
+ }
+
+ ResourceDetailed vfcmt = null;
+ boolean undoCheckoutOnFailure = false;
+ // fetch vfcmt and cdump
+ try {
+ vfcmt = sdcRestClient.getResource(request.getTemplateUuid(), requestId);
+ Artifact cdumpArtifactData = fetchCdumpAndSetFlowType(vfcmt, request.getFlowType(), requestId);
+ if (null == cdumpArtifactData) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "No cdump found for monitoring component {}", vfcmt.getUuid());
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", vfcmt.getName());
+ }
+ String cdumpPayload = cdumpArtifactData.getPayloadData();
+
+ // option 2 - edit original cdump - requires check out
+ if(request.isUpdateFlowType()) {
+ if(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT != DcaeBeConstants.LifecycleStateEnum.findState(vfcmt.getLifecycleState())) {
+ vfcmt = sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKOUT.name(), "checking out VFCMT", requestId);
+ undoCheckoutOnFailure = true;
+ }
+ cdumpArtifactData.setDescription("updating flowType on cdump");
+ cdumpArtifactData.setPayloadData(Base64Utils.encodeToString(cdumpPayload.getBytes()));
+ sdcRestClient.updateResourceArtifact(userId, vfcmt.getUuid(), cdumpArtifactData, requestId);
+ }
+ // option 3 - update service reference only
+ updateReferenceToService(userId, request, vfcmt.getUuid(), requestId);
+ if(DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT == DcaeBeConstants.LifecycleStateEnum.findState(vfcmt.getLifecycleState())) {
+ // this will not throw an exception
+ checkinVfcmtAfterClone(userId, vfcmt, requestId);
+ }
+ return new ResponseEntity<>(buildVfcmtAndCdumpResponse(vfcmt, request.getVfiName(), request.getFlowType(), cdumpPayload), HttpStatus.OK);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed updating Monitoring Component:{}", e.getMessage());
+ if(undoCheckoutOnFailure) {
+ rollBack(userId, vfcmt, requestId);
+ }
+ return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.CREATE_NEW_VFCMT);
+ }
+
+ }
+
+ private boolean validateMCRequestFields(CreateVFCMTRequest request) {
+ return Stream.of(request.getFlowType(), request.getTemplateUuid(), request.getName(), request.getDescription(), request.getContextType(), request.getServiceUuid(), request.getVfiName())
+ .allMatch(StringUtils::isNotBlank);
+ }
+
+ private void updateReferenceToService(String userId, CreateVFCMTRequest request, String newVfcmtUuid, String requestId) {
+ String serviceUuid = request.getServiceUuid();
+ String vfiName = request.getVfiName();
+
+ debugLogger.log(LogLevel.INFO, this.getClass().getName(),"About to update service {}/{} to monitoring component {} ", serviceUuid, vfiName, request.getName());
+
+ sdcRestClient.addExternalMonitoringReference(userId, request, new ReferenceUUID(newVfcmtUuid), requestId);
+
+ }
+
+ private void rollBack(String userId, ResourceDetailed newVfcmt, String requestId) {
+ if (null != newVfcmt) {
+ try {
+ getSdcRestClient().changeResourceLifecycleState(userId, newVfcmt.getUuid(), LifecycleOperationType.UNDO_CHECKOUT.getValue(), "DCAE rollback", requestId);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed rolling back Monitoring Component. ID:{}", newVfcmt.getUuid());
+ debugLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed rolling back Monitoring Component:{}", e);
+ }
+ }
+ }
+
+ private ResponseEntity cloneMcAndAddServiceReference(String userId, CreateVFCMTRequest request, String requestId) {
+ addSdcMandatoryFields(request, userId);
+ ResourceDetailed newVfcmt = null;
+ try {
+ // Retrieve the Template VFCMT from SDC - use the template UUID provided from UI
+ ResourceDetailed templateMC = sdcRestClient.getResource(request.getTemplateUuid(), requestId);
+ // Download the CDUMP file from the template VFCMT
+ Artifact cdumpArtifactData = fetchCdumpAndSetFlowType(templateMC, request.getFlowType(), requestId);
+ if (null == cdumpArtifactData) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"No cdump found for template {} while creating monitoring component", templateMC.getUuid());
+ return ErrConfMgr.INSTANCE.buildErrorResponse(ActionStatus.MISSING_TOSCA_FILE, "", templateMC.getName());
+ }
+ newVfcmt = sdcRestClient.createResource(userId, request, requestId);
+ // The cdump has the original template id. we need to replace it with the new vfcmt id
+ String newVfcmtUuid = newVfcmt.getUuid();
+ String cdumpPayload = cdumpArtifactData.getPayloadData().replaceAll(templateMC.getUuid(), newVfcmtUuid);
+
+ // Upload it to newly created VFCMT
+ cloneArtifactToTarget(userId, newVfcmtUuid, cdumpPayload, cdumpArtifactData, requestId);
+ cloneRuleArtifacts(userId, templateMC, newVfcmtUuid, requestId);
+ createReferenceArtifact(userId, request, newVfcmtUuid, requestId);
+ updateReferenceToService(userId, request, newVfcmtUuid, requestId);
+
+ // this will not throw an exception
+ checkinVfcmtAfterClone(userId, newVfcmt, requestId);
+ return new ResponseEntity<>(buildVfcmtAndCdumpResponse(newVfcmt, request.getVfiName(), request.getFlowType(), cdumpPayload), HttpStatus.OK);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed creating Monitoring Component:{}", e.getMessage());
+ rollBack(userId, newVfcmt, requestId);
+ return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.CREATE_NEW_VFCMT);
+ }
+ }
+
+ private CreateMcResponse buildVfcmtAndCdumpResponse(ResourceDetailed vfcmt, String vfiName, String flowType, String cdumpPayload) throws IOException {
+ return new CreateMcResponse(new VfcmtData(vfcmt, vfiName, flowType), new ObjectMapper().readValue(cdumpPayload, Object.class));
+ }
+
+ private void checkinVfcmtAfterClone(String userId, ResourceDetailed vfcmt, String requestId) {
+ try {
+ vfcmt = sdcRestClient.changeResourceLifecycleState(userId, vfcmt.getUuid(), LifecycleOperationType.CHECKIN.getValue(), "check in after clone", requestId);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Failed to check in Monitoring Component: {}. message: {}", vfcmt.getUuid(), e);
+ }
+ }
+
+
+ private Artifact findCdumpArtifactData(ResourceDetailed vfcmt) {
+ return findArtifactDataByArtifactName(vfcmt, DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ }
+
+ private void cloneRuleArtifacts(String userId, ResourceDetailed templateMC, String newVfcmtUuid, String requestId) throws Exception {
+ // handle rule artifacts using java 7 for-loop - exception propagation to calling method
+ for(Artifact artifact : templateMC.getArtifacts()) {
+ if(artifact.getArtifactName().endsWith(DcaeBeConstants.Composition.fileNames.MAPPING_RULE_POSTFIX)) {
+ cloneArtifactToTarget(userId, newVfcmtUuid, sdcRestClient.getResourceArtifact(templateMC.getUuid(), artifact.getArtifactUUID(), requestId), artifact, requestId);
+ }
+ }
+ }
+
+ // fetch the vfcmt cdump artifact payload and insert the flowType. Return the artifact with updated payload or null (artifact doesn't exist)
+ private Artifact fetchCdumpAndSetFlowType(ResourceDetailed vfcmt, String flowType, String requestId) throws Exception {
+ Artifact cdumpArtifactData = findCdumpArtifactData(vfcmt);
+ if (null != cdumpArtifactData) {
+ String cdumpPayload = sdcRestClient.getResourceArtifact(vfcmt.getUuid(), cdumpArtifactData.getArtifactUUID(), requestId);
+ // Add flowType data to cdump if provided
+ if(!cdumpPayload.contains("\"flowType\":\"") && StringUtils.isNotBlank(flowType)) {
+ cdumpPayload = cdumpPayload.replaceFirst("\\{", "{\"flowType\":\"" + flowType + "\",");
+ }
+ cdumpArtifactData.setPayloadData(cdumpPayload);
+ }
+ return cdumpArtifactData;
+ }
+
+ // backward compatibility (very backward)
+ private void createReferenceArtifact(String userId, CreateVFCMTRequest request, String newVfcmtUuid, String requestId) throws Exception {
+ String referencePayload = request.getServiceUuid() + "/resources/" + request.getVfiName();
+ Artifact refArtifact = SdcRestClientUtils.generateDeploymentArtifact("createReferenceArtifact", DcaeBeConstants.Composition.fileNames.SVC_REF, ArtifactType.DCAE_TOSCA.name(), "servicereference", referencePayload.getBytes());
+ sdcRestClient.createResourceArtifact(userId, newVfcmtUuid, refArtifact, requestId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Artifact {} created with content: {}", DcaeBeConstants.Composition.fileNames.SVC_REF, referencePayload);
+ }
+
+ public ResponseEntity getVfcmtsForMigration(String userId, String contextType, String uuid, String version,
+ String requestId) {
+ List<Resource> resources;
+ ExternalReferencesMap connectedVfcmts;
+ try {
+ connectedVfcmts = getSdcRestClient().getMonitoringReferences(contextType, uuid, version, requestId);
+ resources = getSdcRestClient().getResources(VFCMT, TEMPLATE, MONITORING_TEMPLATE, requestId);
+ } catch (Exception e) {
+ errLogger.log(LogLevel.ERROR,this.getClass().getName(),"Exception getVfcmtsForMigration {}", e);
+ debugLogger.log(LogLevel.DEBUG,this.getClass().getName(),"Exception getVfcmtsForMigration {}", e);
+ return ErrConfMgr.INSTANCE.handleException(e, ErrConfMgr.ApiType.GET_ALL_VFCMTS);
+ }
+
+ List<Resource> vfcmts = resources.stream()
+ .filter(resource -> notCheckedOutOrMine(userId, resource))
+ .filter(resource -> !connected(resource, connectedVfcmts))
+ .collect(Collectors.toList());
+ return new ResponseEntity<>(vfcmts, HttpStatus.OK);
+ }
+
+ private boolean connected(Resource resource, ExternalReferencesMap connectedVfcmts){
+ return connectedVfcmts.values().stream().anyMatch(p -> p.contains(resource.getUuid()));
+ }
+
+ private boolean notCheckedOutOrMine(String userId, Resource resource) {
+ // if the resource belongs to this user then it is kosher
+ // or if it doesn't belong to the user check the lifecycle state is checked out
+
+ return resource.getLastUpdaterUserId().equalsIgnoreCase(userId) ||
+ NOT_CERTIFIED_CHECKOUT != findState(resource.getLifecycleState());
+ }
+
+
+ public void addSdcMandatoryFields(CreateVFCMTRequest createRequest, String user) {
+ createRequest.setContactId(user);
+ createRequest.setIcon(DEFAULTICON);
+ createRequest.setResourceType(VFCMT);
+ createRequest.setVendorName(VENDOR_NAME);
+ createRequest.setVendorRelease(VENDOR_RELEASE);
+ if (StringUtils.isBlank(createRequest.getCategory())) {
+ createRequest.setCategory(TEMPLATE);
+ }
+ if (StringUtils.isBlank(createRequest.getSubcategory())) {
+ createRequest.setSubcategory(MONITORING_TEMPLATE);
+ }
+ createRequest.setTags(new String[]{createRequest.getName()});
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ActionStatus.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ActionStatus.java
new file mode 100644
index 0000000..cac92f5
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ActionStatus.java
@@ -0,0 +1,48 @@
+package org.onap.sdc.dcae.errormng;
+
+public enum ActionStatus {
+
+ OK,
+ CREATED,
+ NO_CONTENT,
+ NOT_ALLOWED,
+ GENERAL_ERROR,
+ INVALID_CONTENT,
+ NOT_FOUND,
+ CONFIGURATION_ERROR,
+ VES_SCHEMA_NOT_FOUND,
+ VES_SCHEMA_INVALID,
+ FLOW_TYPES_CONFIGURATION_ERROR,
+ CLONE_FAILED,
+ EMPTY_SERVICE_LIST,
+ MONITORING_TEMPLATE_ATTACHMENT_ERROR,
+ MISSING_TOSCA_FILE,
+ VALIDATE_TOSCA_ERROR,
+ SUBMIT_BLUEPRINT_ERROR,
+ GENERATE_BLUEPRINT_ERROR,
+ INVALID_RULE_FORMAT,
+ SAVE_RULE_FAILED,
+ RESOURCE_NOT_VFCMT_ERROR,
+ VFI_FETCH_ERROR,
+ USER_CONFLICT,
+ MISSING_RULE_DESCRIPTION,
+ MISSING_ACTION,
+ MISSING_ACTION_FIELD,
+ MISSING_CONCAT_VALUE,
+ INVALID_GROUP_CONDITION,
+ MISSING_CONDITION_ITEM,
+ MISSING_OPERAND,
+ INVALID_OPERATOR,
+ MISSING_ENTRY,
+ MISSING_DEFAULT_VALUE,
+ DUPLICATE_KEY,
+ ACTION_DEPENDENCY,
+ RULE_DEPENDENCY,
+ NODE_NOT_FOUND,
+ DELETE_RULE_FAILED,
+ TRANSLATE_FAILED,
+ CATALOG_NOT_AVAILABLE,
+ AUTH_ERROR,
+ DELETE_BLUEPRINT_FAILED,
+ AS_IS
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/BasicConfiguration.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/BasicConfiguration.java
new file mode 100644
index 0000000..001109e
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/BasicConfiguration.java
@@ -0,0 +1,5 @@
+package org.onap.sdc.dcae.errormng;
+
+public class BasicConfiguration {
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/DcaeException.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/DcaeException.java
new file mode 100644
index 0000000..60b8e0e
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/DcaeException.java
@@ -0,0 +1,15 @@
+package org.onap.sdc.dcae.errormng;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.client.HttpClientErrorException;
+
+public class DcaeException extends BaseException {
+
+// public DcaeException(HttpClientErrorException theError) {
+// super(theError);
+// }
+
+ public DcaeException(HttpStatus status, RequestError re){
+ super(status, re);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrConfMgr.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrConfMgr.java
new file mode 100644
index 0000000..de1d06b
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrConfMgr.java
@@ -0,0 +1,306 @@
+package org.onap.sdc.dcae.errormng;
+
+import org.onap.sdc.dcae.catalog.asdc.ASDCException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.util.*;
+
+public enum ErrConfMgr {
+ INSTANCE;
+
+ private static EnumMap<ApiType, Map<String, String>> sdcDcaeMsgIdMap;
+ public static final String AS_IS = "AS_IS";
+ private ResponseFormatManager responseFormatManager;
+
+ ErrConfMgr() {
+ responseFormatManager = ResponseFormatManager.getInstance();
+ populateSdcDcaeMsgIdMap();
+ }
+
+ private void setSdcCatalogPolicyMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("POL5000", AS_IS);
+ map.put("POL5001", "POL5500");
+ map.put("POL5002", "POL5501");
+ sdcDcaeMsgIdMap.put(ApiType.ALL_SDC_CATALOG, map);
+ }
+
+ private void setGetVfcmtMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", AS_IS);
+ map.put("SVC4505", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.GET_VFCMT, map);
+ }
+
+ private void setCreateNewVfcmtMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4050", AS_IS);
+ map.put("SVC4126", AS_IS);
+ map.put("SVC4500", AS_IS);
+ map.put("SVC4062", AS_IS);
+ map.put("SVC4064", AS_IS);
+ map.put("SVC4065", AS_IS);
+ map.put("SVC4066", AS_IS);
+ map.put("SVC4067", AS_IS);
+ map.put("SVC4068", AS_IS);
+ map.put("SVC4069", AS_IS);
+ map.put("SVC4070", AS_IS);
+ map.put("SVC4071", AS_IS);
+ map.put("SVC4072", AS_IS);
+ map.put("SVC4073", AS_IS);
+ map.put("SVC4053", AS_IS);
+ map.put("POL5003", AS_IS);
+ // adding service referencing error handling to create scenario
+ map.put("SVC4063", AS_IS);
+ map.put("SVC4122", AS_IS);
+ map.put("SVC4124", AS_IS);
+ map.put("SVC4128", AS_IS);
+ map.put("SVC4125", AS_IS);
+ map.put("SVC4127", AS_IS);
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.CREATE_NEW_VFCMT, map);
+ }
+
+ private void setCloneVfcmtMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", AS_IS);
+ map.put("SVC4505", AS_IS);
+ map.put("SVC4085", AS_IS);
+ map.put("SVC4080", AS_IS);
+ map.put("SVC4122", "SVC6010");
+ map.put("SVC4124", "SVC6010");
+ map.put("SVC4128", "SVC6010");
+ map.put("SVC4125", AS_IS);
+ map.put("SVC4127", "SVC6010");
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ map.put("SVC4086", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.CLONE_VFCMT, map);
+ }
+
+
+ private void setGetServiceMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4503", AS_IS);
+ map.put("SVC4642", "200");
+ sdcDcaeMsgIdMap.put(ApiType.GET_SERVICE, map);
+ }
+
+ private void setAttachToServiceMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", "SVC6021");
+ map.put("SVC4122", "SVC6021");
+ map.put("SVC4124", "SVC6021");
+ map.put("SVC4128", "SVC6021");
+ map.put("SVC4125", AS_IS);
+ map.put("SVC4127", "SVC6021");
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ map.put("SVC4503", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.ATTACH_TO_SERVICE, map);
+ }
+
+ private void setGetCdumpMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", AS_IS);
+ map.put("SVC4505", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.GET_CDUMP, map);
+ }
+
+ private void setGetModelMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", AS_IS);
+ map.put("SVC4505", "SVC6031");
+ sdcDcaeMsgIdMap.put(ApiType.GET_MODEL, map);
+ }
+
+ private void setCheckoutResourceMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", "SVC6021");
+ map.put("SVC4085", AS_IS);
+ map.put("SVC4080", AS_IS);
+ map.put("SVC4002", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.CHECK_OUT_RESOURCE, map);
+ }
+
+ private void setCheckinResourceMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", "SVC6021");
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ map.put("SVC4084", AS_IS);
+ map.put("SVC4085", AS_IS);
+ map.put("SVC4002", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.CHECK_IN_RESOURCE, map);
+ }
+
+ private void setSaveCdumpMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", "SVC6021");
+ map.put("SVC4122", "SVC6021");
+ map.put("SVC4124", "SVC6021");
+ map.put("SVC4128", "SVC6021");
+ map.put("SVC4125", AS_IS);
+ map.put("SVC4127", "SVC6021");
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.SAVE_CDUMP, map);
+ }
+
+ private void setSubmitBlueprintMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", AS_IS);
+ map.put("SVC4505", "SVC6031");
+ map.put("SVC4503", AS_IS);
+ map.put("SVC4085", AS_IS);
+ map.put("SVC4080", AS_IS);
+ map.put("SVC4122", "SVC6033");
+ map.put("SVC4124", "SVC6033");
+ map.put("SVC4128", "SVC6033");
+ map.put("SVC4125", AS_IS);
+ map.put("SVC4127", "SVC6033");
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.SUBMIT_BLUEPRINT, map);
+ }
+
+ private void setGetRuleMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.GET_RULE_ARTIFACT, map);
+ }
+
+ private void setSaveRuleMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4063", "SVC6036");
+ map.put("SVC4122", "SVC6036");
+ map.put("SVC4124", "SVC6036");
+ map.put("SVC4128", "SVC6036");
+ map.put("SVC4125", AS_IS);
+ map.put("SVC4127", "SVC6036");
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ map.put("SVC4000", "SVC6036");
+ sdcDcaeMsgIdMap.put(ApiType.SAVE_RULE_ARTIFACT, map);
+ }
+
+ private void setGetAllVfcmtMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("SVC4642", "200");
+ sdcDcaeMsgIdMap.put(ApiType.GET_ALL_VFCMTS, map);
+ }
+
+
+ private void setDeleteReferenceMapping(){
+ Map<String, String> map = new HashMap<>();
+ map.put("POL5003", AS_IS);
+ map.put("SVC4063", AS_IS);
+ map.put("POL4050", AS_IS);
+ map.put("SVC4086", AS_IS);
+ map.put("SVC4301", AS_IS);
+ map.put("SVC4687", AS_IS);
+ sdcDcaeMsgIdMap.put(ApiType.DELETE_VFCMT_REFERENCE, map);
+ }
+
+ private void populateSdcDcaeMsgIdMap() {
+ sdcDcaeMsgIdMap = new EnumMap<>(ApiType.class);
+ setAttachToServiceMapping();
+ setCheckinResourceMapping();
+ setCheckoutResourceMapping();
+ setCloneVfcmtMapping();
+ setGetAllVfcmtMapping();
+ setGetRuleMapping();
+ setCreateNewVfcmtMapping();
+ setGetCdumpMapping();
+ setGetModelMapping();
+ setSaveCdumpMapping();
+ setSaveRuleMapping();
+ setSubmitBlueprintMapping();
+ setGetServiceMapping();
+ setGetVfcmtMapping();
+ setSdcCatalogPolicyMapping();
+ setDeleteReferenceMapping();
+ }
+
+ public enum ApiType {
+ CREATE_NEW_VFCMT,
+ GET_ALL_VFCMTS,
+ CLONE_VFCMT,
+ GET_VFCMT,
+ GET_SERVICE,
+ ATTACH_TO_SERVICE,
+ GET_CDUMP,
+ GET_MODEL,
+ CHECK_OUT_RESOURCE,
+ CHECK_IN_RESOURCE,
+ SAVE_CDUMP,
+ SUBMIT_BLUEPRINT,
+ GET_RULE_ARTIFACT,
+ SAVE_RULE_ARTIFACT,
+ ALL_SDC_CATALOG,
+ DELETE_VFCMT_REFERENCE
+ }
+
+ public ResponseFormat getResponseFormat(ActionStatus actionStatus, String notes, String... variables) {
+ return responseFormatManager.getResponseFormat(actionStatus, notes, variables);
+ }
+
+ public ResponseEntity buildErrorResponse(ActionStatus actionStatus, String notes, String... variables) {
+ ResponseFormat response = responseFormatManager.getResponseFormat(actionStatus, notes, variables);
+ return new ResponseEntity<>(response, HttpStatus.valueOf(response.getStatus()));
+ }
+
+ public ResponseEntity buildErrorResponse(ActionStatus actionStatus) {
+ ResponseFormat response = responseFormatManager.getResponseFormat(actionStatus, "");
+ return new ResponseEntity<>(response, HttpStatus.valueOf(response.getStatus()));
+ }
+
+ public ResponseEntity buildErrorResponse(BaseException baseException) {
+ ResponseFormat response = responseFormatManager.getResponseFormat(baseException);
+ return new ResponseEntity<>(response, HttpStatus.valueOf(response.getStatus()));
+ }
+
+ public ResponseEntity buildErrorArrayResponse(List<ServiceException> errors) {
+ ResponseFormat response = responseFormatManager.getResponseFormat(errors);
+ return new ResponseEntity<>(response, HttpStatus.valueOf(response.getStatus()));
+ }
+
+ // ActionStatus determined by sdc to dcae mapping
+ public ActionStatus convertToDcaeActionStatus(String messageId, ApiType apiType) {
+ // try the apiType's specific mapping from SDC messageId to dcaeMessageId
+ String dcaeMessageId = sdcDcaeMsgIdMap.get(apiType).get(messageId);
+ // if no specific mapping found try the general mapping
+ if(null == dcaeMessageId)
+ dcaeMessageId = sdcDcaeMsgIdMap.get(ApiType.ALL_SDC_CATALOG).get(messageId);
+ // if no mapping found return general error
+ if(null == dcaeMessageId)
+ return ActionStatus.GENERAL_ERROR;
+ // if mapped to 'AS_IS' return 'AS_IS'
+ if(AS_IS.equals(dcaeMessageId))
+ return ActionStatus.AS_IS;
+ // for any other valid mapping fetch the ActionStatus by corresponding dcaeMessageId
+ return responseFormatManager.getMsgIdToActionStatusMap().get(dcaeMessageId);
+ }
+
+ public ResponseEntity handleException(Exception e, ApiType apiType, String... variables){
+ if (e instanceof ASDCException){
+ ASDCException se = (ASDCException)e;
+ ActionStatus status = convertToDcaeActionStatus(se.getMessageId(), apiType);
+ switch (status) {
+ case AS_IS:
+ return buildErrorResponse(se);
+ case OK:
+ return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK);
+ default:
+ return buildErrorResponse(status, se.getMessage(), variables);
+ }
+ }
+ //TODO refactor - don't throw DcaeException
+ if (e instanceof DcaeException){
+ return buildErrorResponse((DcaeException)e);
+ }
+ return buildErrorResponse(ActionStatus.GENERAL_ERROR, e.getMessage());
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfiguration.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfiguration.java
new file mode 100644
index 0000000..8f6f5af
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfiguration.java
@@ -0,0 +1,46 @@
+package org.onap.sdc.dcae.errormng;
+
+import java.util.Map;
+
+/**
+ * Example:
+ * VES_SCHEMA_INVALID: {
+ code: 500,
+ message: "Error – Failed to parse VES Schema file '%1'. [%2]",
+ messageId: "SVC6007"
+ }
+
+ key will be "VES_SCHEMA_INVALID"
+ value is the json object containing code, message, messageId
+ */
+
+import org.onap.sdc.dcae.errormng.BasicConfiguration;
+
+public class ErrorConfiguration extends BasicConfiguration {
+
+ private Map<String, ErrorInfo> errors;
+
+ public Map<String, ErrorInfo> getErrors() {
+ return errors;
+ }
+
+ public void setErrors(Map<String, ErrorInfo> errors) {
+ this.errors = errors;
+ }
+
+ public ErrorInfo getErrorInfo(String key) {
+ ErrorInfo clone = null;
+ ErrorInfo other = errors.get(key);
+ if (other != null) {
+ clone = new ErrorInfo();
+ clone.cloneData(other);
+ }
+ return clone;
+ }
+
+ @Override
+ public String toString() {
+ return "ErrorConfiguration [errors=" + errors + "]";
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfigurationLoader.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfigurationLoader.java
new file mode 100644
index 0000000..8b7ab44
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorConfigurationLoader.java
@@ -0,0 +1,121 @@
+package org.onap.sdc.dcae.errormng;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+
+public class ErrorConfigurationLoader {
+
+ private static ErrorConfigurationLoader instance;
+ private String jettyBase;
+ private ErrorConfiguration errorConfiguration = new ErrorConfiguration();
+ private OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ public ErrorConfigurationLoader(String sourcePath) {
+ jettyBase = sourcePath;
+ loadErrorConfiguration();
+ instance = this;
+ }
+
+ private void loadErrorConfiguration(){
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "ErrorConfigurationLoader: Trying to load error configuration");
+ if (jettyBase == null) {
+ String msg = "Couldn't resolve jetty.base environmental variable";
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new ExceptionInInitializerError (msg + ". Failed to load error configuration files... aborting");
+ }
+
+ String path = jettyBase + "/config/dcae-be";
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "jetty.base={}", jettyBase);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Configuration Path={}", path);
+
+ File dir = new File(path);
+ File[] files = dir.listFiles(new FilenameFilter() {
+ @Override public boolean accept(File dir, String name) {
+ return name.equals("error-configuration.yaml");
+ }
+ });
+
+ if (ArrayUtils.isEmpty(files)) {
+ String msg = "No error configuration files found";
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new ExceptionInInitializerError (msg);
+ }else if (files.length>1){
+ String msg = "Multiple configuration files found. Make sure only one file exists. Path: "+ path;
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new ExceptionInInitializerError (msg);
+ }
+ else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Loading error configuration file: {}", files[0].getName());
+ try {
+ errorConfiguration = parseErrConfFileAndSaveToMap(files[0].getCanonicalPath());
+// convertToUsefulMaps(errorConfiguration);
+ } catch (IOException e) {
+ String msg = "Exception thrown while trying to read the error configuration file path. File="+files[0].getName();
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new ExceptionInInitializerError (msg);
+ }
+ if(errorConfiguration == null){
+ String msg = "Error configuration file couldn't be parsed";
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new ExceptionInInitializerError (msg);
+ }
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Error Configuration: {}", errorConfiguration.toString());
+ }
+ }
+
+
+ private ErrorConfiguration parseErrConfFileAndSaveToMap(String fullFileName) {
+
+ Yaml yaml = new Yaml();
+
+ InputStream in = null;
+ ErrorConfiguration errorConfiguration = null;
+ try {
+
+ File f = new File(fullFileName);
+ if (false == f.exists()) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "The file {} cannot be found. Ignore reading configuration.", fullFileName);
+ return null;
+ }
+ in = Files.newInputStream(Paths.get(fullFileName));
+
+ errorConfiguration = yaml.loadAs(in, ErrorConfiguration.class);
+
+ } catch (Exception e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Failed to convert yaml file {} to object. {}", fullFileName, e);
+ return null;
+ }
+ finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Failed to close input stream {}", e.getMessage());
+ }
+ }
+ }
+
+ return errorConfiguration;
+ }
+
+ ErrorConfiguration getErrorConfiguration() {
+ return errorConfiguration;
+ }
+
+ public static ErrorConfigurationLoader getErrorConfigurationLoader() {
+ return instance;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorInfo.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorInfo.java
new file mode 100644
index 0000000..3ec3cef
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ErrorInfo.java
@@ -0,0 +1,99 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 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.sdc.dcae.errormng;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+
+public class ErrorInfo {
+
+ private Integer code;
+ private String message;
+ private String messageId;
+ private ErrorInfoType errorInfoType;
+
+ private static final String SVC_PREFIX = "SVC";
+ private static final String POL_PREFIX = "POL";
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+
+ public ErrorInfo() {
+ this.errorInfoType = ErrorInfoType.OK;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getMessageId() {
+ return messageId;
+ }
+
+ public void setMessageId(String messageId) {
+ // Determining the type of error
+ if (messageId == null || "200".equals(messageId) || "201".equals(messageId) || "204".equals(messageId)) {
+ this.errorInfoType = ErrorInfoType.OK;
+ } else if (messageId.startsWith(SVC_PREFIX)) {
+ this.errorInfoType = ErrorInfoType.SERVICE_EXCEPTION;
+ } else if (messageId.startsWith(POL_PREFIX)) {
+ this.errorInfoType = ErrorInfoType.POLICY_EXCEPTION;
+ } else {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Error: unexpected error message ID {}, should start with {} or {}", messageId, SVC_PREFIX, POL_PREFIX);
+ }
+ this.messageId = messageId;
+ }
+
+ public ErrorInfoType getErrorInfoType() {
+ return this.errorInfoType;
+ }
+
+ public void cloneData(ErrorInfo other) {
+ this.code = other.getCode();
+ this.message = other.getMessage();
+ this.messageId = other.getMessageId();
+ this.errorInfoType = other.errorInfoType;
+ }
+
+ @Override
+ public String toString() {
+ return "ErrorInfo [code=" + code + ", messageId=" + messageId + ", message=" + message + "]";
+ }
+
+ public enum ErrorInfoType {
+ OK, POLICY_EXCEPTION, SERVICE_EXCEPTION
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormatManager.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormatManager.java
new file mode 100644
index 0000000..ada790f
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormatManager.java
@@ -0,0 +1,103 @@
+package org.onap.sdc.dcae.errormng;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.errormng.ErrorInfo.ErrorInfoType;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ResponseFormatManager {
+
+ private volatile static ResponseFormatManager instance;
+ private static ErrorConfiguration errorConfiguration;
+ private static Map<String, ActionStatus> msgIdToActionStatusMap = new HashMap<>();
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+
+ public static ResponseFormatManager getInstance() {
+ if (instance == null) {
+ instance = init();
+ }
+ return instance;
+ }
+
+ private static synchronized ResponseFormatManager init() {
+ if (instance == null) {
+ instance = new ResponseFormatManager();
+ errorConfiguration = ErrorConfigurationLoader.getErrorConfigurationLoader().getErrorConfiguration();
+ convertToActionMap();
+ }
+ return instance;
+ }
+
+ ResponseFormat getResponseFormat(ActionStatus actionStatus, String notes, String... variables) {
+ ErrorInfo errorInfo = errorConfiguration.getErrorInfo(actionStatus.name());
+ if (errorInfo == null) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "failed to locate {} in error configuration", actionStatus.name());
+ errorInfo = errorConfiguration.getErrorInfo(ActionStatus.GENERAL_ERROR.name());
+ }
+
+ ResponseFormat responseFormat = new ResponseFormat(errorInfo.getCode());
+ String errorMessage = errorInfo.getMessage();
+ String errorMessageId = errorInfo.getMessageId();
+ ErrorInfoType errorInfoType = errorInfo.getErrorInfoType();
+ responseFormat.setNotes(notes);
+
+ if (errorInfoType==ErrorInfoType.SERVICE_EXCEPTION) {
+ responseFormat.setServiceException(new ServiceException(errorMessageId, errorMessage, variables));
+ }
+ else if (errorInfoType==ErrorInfoType.POLICY_EXCEPTION) {
+ responseFormat.setPolicyException(new PolicyException(errorMessageId, errorMessage, variables));
+ }
+ else if (errorInfoType==ErrorInfoType.OK) {
+ responseFormat.setOkResponseInfo(new OkResponseInfo(errorMessageId, errorMessage, variables));
+ }
+ return responseFormat;
+ }
+
+ ResponseFormat getResponseFormat(BaseException baseException) {
+
+ ResponseFormat responseFormat = new ResponseFormat(baseException.getRawStatusCode());
+ AbstractSdncException e = baseException.getRequestError().getError();
+
+ if (e instanceof ServiceException) {
+ responseFormat.setServiceException((ServiceException)e);
+ }
+ else if (e instanceof PolicyException) {
+ responseFormat.setPolicyException((PolicyException)e);
+ }
+ else {
+ responseFormat.setOkResponseInfo((OkResponseInfo)e);
+ }
+ return responseFormat;
+ }
+
+ ResponseFormat getResponseFormat(List<ServiceException> errors) {
+ ResponseFormat responseFormat = new ResponseFormat(400);
+ responseFormat.setServiceExceptions(errors);
+ return responseFormat;
+ }
+
+ public Map<String, ActionStatus> getMsgIdToActionStatusMap() {
+ return msgIdToActionStatusMap;
+ }
+
+ private static void convertToActionMap() {
+ Map<String, ErrorInfo> errors = errorConfiguration.getErrors();
+
+ if(errors!=null){
+ errors.forEach((k, v) -> {
+ debugLogger.log(LogLevel.DEBUG, ResponseFormatManager.class.getName(), "{}, {}", v.getMessageId(), k);
+ msgIdToActionStatusMap.put(v.getMessageId(), ActionStatus.valueOf(k));
+ });
+ }
+ }
+
+ public ResponseFormatManager(){
+
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java
new file mode 100644
index 0000000..919d244
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/filter/LoggingFilter.java
@@ -0,0 +1,247 @@
+package org.onap.sdc.dcae.filter;
+
+import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
+import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
+import static java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT;
+import static java.net.HttpURLConnection.HTTP_CONFLICT;
+import static java.net.HttpURLConnection.HTTP_ENTITY_TOO_LARGE;
+import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
+import static java.net.HttpURLConnection.HTTP_GONE;
+import static java.net.HttpURLConnection.HTTP_LENGTH_REQUIRED;
+import static java.net.HttpURLConnection.HTTP_NOT_ACCEPTABLE;
+import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
+import static java.net.HttpURLConnection.HTTP_PAYMENT_REQUIRED;
+import static java.net.HttpURLConnection.HTTP_PRECON_FAILED;
+import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
+import static java.net.HttpURLConnection.HTTP_REQ_TOO_LONG;
+import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+import static java.net.HttpURLConnection.HTTP_UNSUPPORTED_TYPE;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.UUID;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.impl.EnglishReasonPhraseCatalog;
+import org.onap.sdc.common.onaplog.OnapLoggerAudit;
+import org.onap.sdc.common.onaplog.OnapMDCWrapper;
+import org.onap.sdc.common.onaplog.Enums.OnapLoggerErrorCode;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+
+public class LoggingFilter implements Filter {
+
+ private static final String serviceName = "DCAE-D-BE";
+
+ private OnapMDCWrapper commonLoggerArgs = OnapMDCWrapper.getInstance();
+ private OnapLoggerAudit auditLogger = OnapLoggerAudit.getInstance();
+
+ public LoggingFilter() {
+ super();
+ }
+
+
+ @Override
+ public void destroy() {}
+
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
+ throws IOException, ServletException {
+
+ boolean shouldLogRequest = true;
+
+ try {
+ if (request instanceof HttpServletRequest) {
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ if (httpRequest.getServletPath().equals("/healthCheck")) {
+ shouldLogRequest = false;
+ }
+
+ if (shouldLogRequest) {
+ beforeHandle(httpRequest);
+ }
+ }
+ } catch (Exception e) {
+ // TODO: log problem with extracting parameters or writing to log
+ }
+
+ filterChain.doFilter(request, response); // handle request
+
+ try {
+ if (response instanceof HttpServletResponse && shouldLogRequest) {
+ afterHandle((HttpServletResponse) response);
+ }
+ } catch (Exception e) {
+ // TODO: log problem with extracting parameters or writing to log
+ }
+ }
+
+
+ private void beforeHandle(HttpServletRequest request) {
+
+ String requestId = getRequestId(request);
+ request.setAttribute("requestId", requestId); // making requestId available for the API controllers
+ commonLoggerArgs
+ .clear()
+ .startTimer()
+ .setRemoteHost(request.getRemoteAddr())
+ .setServiceName(serviceName)
+ .setPartnerName(getPartnerName(request.getHeader("USER_ID"), request.getHeader("user-agent")))
+ .setKeyRequestId(requestId)
+ .setAutoServerIPAddress(request.getLocalAddr())
+ .setOptCustomField1(request.getProtocol())
+ .setOptCustomField2(request.getMethod())
+ .setOptCustomField3(request.getServletPath());
+
+ }
+
+
+ private static String getRequestId(HttpServletRequest request) {
+ String requestId = request.getHeader("X-ECOMP-RequestID");
+ return isNullOrEmpty(requestId)
+ ? UUID.randomUUID().toString()
+ : requestId;
+ }
+
+
+ private void afterHandle(HttpServletResponse response) {
+ String responseDesc = EnglishReasonPhraseCatalog.INSTANCE.getReason(response.getStatus(), Locale.ENGLISH);
+ commonLoggerArgs
+ .stopTimer()
+ .setResponseCode(getLoggingErrorCode(response.getStatus()).getErrorCode())
+ .setResponseDesc(responseDesc)
+ .setOptCustomField4(Integer.toString(response.getStatus()));
+
+ auditLogger
+ .setStatusCode(Integer.toString(response.getStatus()))
+ .log(LogLevel.INFO, this.getClass().getName(), responseDesc);
+ }
+
+
+ private OnapLoggerErrorCode getLoggingErrorCode(int httpResponseCode) {
+ if (isSuccessError(httpResponseCode)) {
+ return OnapLoggerErrorCode.SUCCESS;
+ }
+ else if (isSchemaError(httpResponseCode)) {
+ return OnapLoggerErrorCode.SCHEMA_ERROR;
+ }
+ else if (isDataError(httpResponseCode)) {
+ return OnapLoggerErrorCode.DATA_ERROR;
+ }
+ else if (isPermissionsError(httpResponseCode)) {
+ return OnapLoggerErrorCode.PERMISSION_ERROR;
+ }
+ else if (isTimeoutOrAvailabilityError(httpResponseCode)) {
+ return OnapLoggerErrorCode.AVAILABILITY_TIMEOUTS_ERROR;
+ }
+ else if (isBusinessProcessError(httpResponseCode)) {
+ return OnapLoggerErrorCode.BUSINESS_PROCESS_ERROR;
+ }
+ else {
+ return OnapLoggerErrorCode.UNKNOWN_ERROR;
+ }
+ }
+
+
+ private boolean isTimeoutOrAvailabilityError(int httpResponseCode) {
+
+ switch (httpResponseCode) {
+ case HTTP_BAD_REQUEST:
+ case HTTP_UNAUTHORIZED:
+ case HTTP_NOT_FOUND:
+ case HTTP_CLIENT_TIMEOUT:
+ case HTTP_GONE:
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isPermissionsError(int httpResponseCode) {
+
+ switch (httpResponseCode) {
+ case HTTP_PAYMENT_REQUIRED:
+ case HTTP_FORBIDDEN:
+ case HTTP_BAD_METHOD:
+ case HTTP_PROXY_AUTH:
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isDataError(int httpResponseCode) {
+
+ switch (httpResponseCode) {
+ case HTTP_NOT_ACCEPTABLE:
+ case HTTP_LENGTH_REQUIRED:
+ case HTTP_PRECON_FAILED:
+ case HTTP_REQ_TOO_LONG:
+ case HTTP_ENTITY_TOO_LARGE:
+ case HTTP_UNSUPPORTED_TYPE:
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isSchemaError(int httpResponseCode) {
+
+ switch (httpResponseCode) {
+ case HTTP_CONFLICT:
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean isSuccessError(int httpResponseCode) {
+ return httpResponseCode < 399;
+ }
+
+ private boolean isBusinessProcessError(int httpResponseCode) {
+ return httpResponseCode > 499;
+ }
+
+ private String getPartnerName(String userId, String userAgent) {
+ return (isNullOrEmpty(userId))
+ ? getClientApplication(userAgent)
+ : userId;
+ }
+
+ private String getClientApplication(String userAgent) {
+ if (userAgent != null && userAgent.length() > 0) {
+ if (userAgent.toLowerCase().contains("firefox")) {
+ return "fireFox_FE";
+ }
+
+ if (userAgent.toLowerCase().contains("msie")) {
+ return "explorer_FE";
+ }
+
+ if (userAgent.toLowerCase().contains("chrome")) {
+ return "chrome_FE";
+ }
+
+ return userAgent;
+ }
+ return "";
+ }
+
+
+ private static boolean isNullOrEmpty(String str) {
+ return (str == null || str.isEmpty());
+ }
+
+
+ @Override
+ public void init(FilterConfig config) throws ServletException {}
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java
new file mode 100644
index 0000000..e4921e2
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/ConditionTypeEnum.java
@@ -0,0 +1,22 @@
+package org.onap.sdc.dcae.rule.editor.enums;
+
+import java.util.Arrays;
+
+public enum ConditionTypeEnum {
+ ALL("And"), ANY("Or");
+
+ public String getFilterClass() {
+ return filterClass;
+ }
+
+ private String filterClass;
+
+ ConditionTypeEnum(String filterClass) {
+
+ this.filterClass = filterClass;
+ }
+
+ public static ConditionTypeEnum getTypeByName(String name) {
+ return Arrays.stream(ConditionTypeEnum.values()).filter(type -> name.equalsIgnoreCase(type.name())).findAny().orElse(null);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java
new file mode 100644
index 0000000..2cd03a7
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/OperatorTypeEnum.java
@@ -0,0 +1,32 @@
+package org.onap.sdc.dcae.rule.editor.enums;
+
+import java.util.Arrays;
+
+public enum OperatorTypeEnum {
+ EQUALS("Equals", "OneOf"),
+ NOT_EQUAL("NotEqual", "NotOneOf"),
+ CONTAINS("Contains", null),
+ ENDS_WITH("EndsWith", null),
+ STARTS_WITH("StartsWith", null);
+
+ private String type;
+ private String modifiedType;
+
+ OperatorTypeEnum(String type, String modifiedType) {
+ this.type = type;
+ this.modifiedType = modifiedType;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getModifiedType() {
+ return modifiedType;
+ }
+
+ public static OperatorTypeEnum getTypeByName(String name) {
+ return Arrays.stream(OperatorTypeEnum.values()).filter(type -> name.replaceAll(" ", "").equalsIgnoreCase(type.getType())).findAny().orElse(null);
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java
new file mode 100644
index 0000000..0bec7d8
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/enums/RuleEditorElementType.java
@@ -0,0 +1,58 @@
+package org.onap.sdc.dcae.rule.editor.enums;
+
+import java.util.Arrays;
+
+import org.onap.sdc.dcae.rule.editor.translators.ConditionGroupTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.ConditionTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.CopyActionTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.DateFormatterTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.FieldConditionTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.IRuleElementTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.MapActionTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.MappingRulesTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.RegexActionTranslator;
+import org.onap.sdc.dcae.rule.editor.translators.RuleTranslator;
+import org.onap.sdc.dcae.rule.editor.validators.ActionValidator;
+import org.onap.sdc.dcae.rule.editor.validators.ConcatActionValidator;
+import org.onap.sdc.dcae.rule.editor.validators.ConditionGroupValidator;
+import org.onap.sdc.dcae.rule.editor.validators.ConditionValidator;
+import org.onap.sdc.dcae.rule.editor.validators.DateFormatterValidator;
+import org.onap.sdc.dcae.rule.editor.validators.IRuleElementValidator;
+import org.onap.sdc.dcae.rule.editor.validators.MapActionValidator;
+import org.onap.sdc.dcae.rule.editor.validators.RuleValidator;
+
+public enum RuleEditorElementType {
+ COPY("Copy", ActionValidator.getInstance(), CopyActionTranslator.getInstance()),
+ CONCAT("Concat", ConcatActionValidator.getInstance(), CopyActionTranslator.getInstance()),
+ MAP("Map", MapActionValidator.getInstance(), MapActionTranslator.getInstance()),
+ REGEX("Regex", ActionValidator.getInstance(), RegexActionTranslator.getInstance()),
+ DATE_FORMATTER("DateFormatter", DateFormatterValidator.getInstance(), DateFormatterTranslator.getInstance()),
+ CONDITION("Condition", ConditionValidator.getInstance(), ConditionTranslator.getInstance()),
+ FIELD_CONDITION("FieldCondition", ConditionValidator.getInstance(), FieldConditionTranslator.getInstance()),
+ CONDITION_GROUP("ConditionGroup", ConditionGroupValidator.getInstance(), ConditionGroupTranslator.getInstance()),
+ RULE("Rule", RuleValidator.getInstance(), RuleTranslator.getInstance()),
+ MAPPING_RULES("MappingRules", null, MappingRulesTranslator.getInstance());
+
+ private String elementType;
+ private IRuleElementValidator validator;
+ private IRuleElementTranslator translator;
+
+ public IRuleElementValidator getValidator() {
+ return validator;
+ }
+
+ public IRuleElementTranslator getTranslator() {
+ return translator;
+ }
+
+ RuleEditorElementType(String elementType, IRuleElementValidator validator, IRuleElementTranslator translator) {
+ this.elementType = elementType;
+ this.validator = validator;
+ this.translator = translator;
+ }
+
+ public static RuleEditorElementType getElementTypeByName(String name) {
+ return Arrays.stream(RuleEditorElementType.values()).filter(p -> p.elementType.equalsIgnoreCase(name))
+ .findAny().orElse(null);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java
new file mode 100644
index 0000000..849ad42
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogic.java
@@ -0,0 +1,149 @@
+package org.onap.sdc.dcae.rule.editor.impl;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.errormng.ServiceException;
+import org.onap.sdc.dcae.rule.editor.translators.MappingRulesTranslator;
+import org.onap.sdc.dcae.rule.editor.utils.EmptyStringTranslationSerializer;
+import org.onap.sdc.dcae.rule.editor.validators.RuleValidator;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Component
+public class RulesBusinessLogic {
+
+ protected OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+ private RuleValidator ruleValidator = RuleValidator.getInstance();
+ private MappingRulesTranslator mappingRulesTranslator = MappingRulesTranslator.getInstance();
+ private static Gson gsonTranslator = new GsonBuilder().registerTypeAdapter(String.class, new EmptyStringTranslationSerializer()).enableComplexMapKeySerialization().create();
+
+ public List<ServiceException> validateRule(Rule rule) {
+ List<ResponseFormat> errors = new ArrayList<>();
+ if(ruleValidator.validate(rule, errors))
+ detectAndResolveActionDependencies(rule, errors);
+ return errors.stream().map(r -> r.getRequestError().getServiceException()).collect(Collectors.toList());
+ }
+
+ public List<ServiceException> validateRules(MappingRules rules) {
+ List<ResponseFormat> errors = new ArrayList<>();
+ detectAndResolveRuleDependencies(rules, errors);
+ return errors.stream().map(r -> r.getRequestError().getServiceException()).collect(Collectors.toList());
+ }
+
+ public String translateRules(MappingRules rules, String entryPointPhase, String lastPhase, String runPhase) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Start translating mapping rules");
+ return gsonTranslator.toJson(mappingRulesTranslator.translateToHpJson(rules, entryPointPhase, lastPhase, runPhase));
+ }
+
+ public boolean addOrEditRule(MappingRules rules, Rule rule) {
+ // in case the rule id is passed but the rule doesn't exist on the mapping rule file:
+ if(StringUtils.isNotBlank(rule.getUid()) && !rules.ruleExists(rule))
+ return false;
+ rules.addOrReplaceRule(rule);
+ return true;
+ }
+
+ public Rule deleteRule(MappingRules rules, String ruleUid) {
+ return rules.removeRule(ruleUid);
+ }
+
+ private <T> List<T> detectDependentItemsByDependencyDefinition(Collection<T> allItems, BiFunction<T, Collection<T>, Boolean> dependencyDefinition) {
+ return allItems.stream().filter(i -> dependencyDefinition.apply(i, allItems)).collect(Collectors.toList());
+ }
+
+ // if all dependencies are resolvable returns empty list
+ // else returns list of non resolvable items (circular dependent items)
+ // iterate through all dependentItems removing resolvable items each iteration.
+
+ private <T> List<T> detectCircularDependenciesByDependencyDefinition(List<T> dependentItems, BiFunction<T, Collection<T>, Boolean> dependencyDetector) {
+ while(!CollectionUtils.isEmpty(dependentItems)) {
+ List<T> resolvable = dependentItems.stream()
+ .filter(i -> !dependencyDetector.apply(i, dependentItems))
+ .collect(Collectors.toList());
+ if(CollectionUtils.isEmpty(resolvable))
+ break;
+ dependentItems.removeAll(resolvable);
+ }
+ return dependentItems;
+ }
+
+ private <T> List<T> reorderItemsByDependencyDefinition(Collection<T> allItems, BiFunction<T, T, Boolean> dependencyDetector) {
+ List<T> ordered = new ArrayList<>(allItems);
+ allItems.forEach(i -> {
+ List<T> dependencies = allItems.stream().filter(o -> dependencyDetector.apply(i, o)).collect(Collectors.toList());
+ dependencies.forEach(d -> {
+ if(ordered.indexOf(d) > ordered.indexOf(i)) {
+ ordered.remove(d);
+ ordered.add(ordered.indexOf(i), d);
+ }
+ });
+ });
+ return ordered;
+ }
+
+ private void detectAndResolveActionDependencies(Rule rule, List<ResponseFormat> errors) {
+ List<BaseAction> dependentActions = detectDependentItemsByDependencyDefinition(rule.getActions(), BaseAction::hasDependencies);
+ if(!CollectionUtils.isEmpty(dependentActions)) {
+ List<BaseAction> nonResolvable = detectCircularDependenciesByDependencyDefinition(dependentActions, BaseAction::hasDependencies);
+ if (!CollectionUtils.isEmpty(nonResolvable)) {
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.ACTION_DEPENDENCY, null, nonResolvable.stream().map(BaseAction::getTarget).collect(Collectors.joining(", "))));
+ return;
+ }
+ List<BaseAction> actions = reorderItemsByDependencyDefinition(rule.getActions(), BaseAction::referencesTarget);
+ rule.setActions(actions);
+ }
+ }
+
+ // first identify dependent rules
+ // if no dependencies found return true
+ // if non resolvable dependencies found return false
+ // else reorder and return true
+
+ private void detectAndResolveRuleDependencies(MappingRules rules, List<ResponseFormat> errors) {
+ List<Rule> dependentRules = detectDependentItemsByDependencyDefinition(rules.getRules().values(), Rule::referencesOtherRules);
+ if(!CollectionUtils.isEmpty(dependentRules)) {
+ List<Rule> nonResolvable = detectCircularDependenciesByDependencyDefinition(dependentRules, Rule::referencesOtherRules);
+ if (!CollectionUtils.isEmpty(nonResolvable)) {
+ String nonResolvableRuleIds = nonResolvable.stream().map(Rule::getUid).collect(Collectors.joining(", "));
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.RULE_DEPENDENCY, null, nonResolvableRuleIds, extractDependentActionTargetsFromRules(nonResolvable)));
+ return;
+ }
+ reorderRulesByDependency(rules);
+ }
+ }
+
+ private String extractDependentActionTargetsFromRules(List<Rule> dependentRules) {
+ List<BaseAction> allActions = dependentRules.stream().map(Rule::getActions).flatMap(List::stream).collect(Collectors.toList());
+ // option 1: circular dependency between actions
+ List<BaseAction> nonResolvable = detectCircularDependenciesByDependencyDefinition(allActions, BaseAction::hasDependencies);
+ if(CollectionUtils.isEmpty(nonResolvable))
+ // option 2: circular dependency between rules - collect dependent actions and condition dependencies
+ nonResolvable = dependentRules.stream()
+ .map(r -> r.findDependencies(dependentRules))
+ .flatMap(List::stream)
+ .collect(Collectors.toList());
+ return nonResolvable.stream()
+ .map(BaseAction::getTarget)
+ .collect(Collectors.joining(", "));
+ }
+
+ private void reorderRulesByDependency(MappingRules rules) {
+ List<Rule> ordered = reorderItemsByDependencyDefinition(rules.getRules().values(), Rule::referencesOtherRule);
+ Map<String, Rule> rulesMap = ordered.stream().collect(Collectors.toMap(Rule::getUid, Function.identity(), (u, v) -> {
+ throw new IllegalStateException(String.format("Duplicate key %s", u));
+ }, LinkedHashMap::new));
+ rules.setRules(rulesMap);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java
new file mode 100644
index 0000000..093c239
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionGroupTranslator.java
@@ -0,0 +1,47 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+import org.onap.sdc.dcae.rule.editor.enums.ConditionTypeEnum;
+import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class ConditionGroupTranslator implements IRuleElementTranslator<ConditionGroup> {
+
+ private static ConditionGroupTranslator conditionGroupTranslator = new ConditionGroupTranslator();
+
+ public static ConditionGroupTranslator getInstance() {
+ return conditionGroupTranslator;
+ }
+
+ private ConditionGroupTranslator(){}
+
+ public Translation translateToHpJson(ConditionGroup conditionGroup) {
+ String clazz = ConditionTypeEnum.getTypeByName(conditionGroup.getType()).getFilterClass();
+ FiltersTranslation translation = new FiltersTranslation(clazz, conditionGroup.getChildren().stream()
+ .map(this::getTranslation)
+ .collect(Collectors.toList()));
+ flattenNestedFilters(translation, clazz);
+ return translation;
+ }
+
+
+ private IRuleElementTranslator getConditionTranslator(BaseCondition condition){
+ return condition instanceof ConditionGroup ? ConditionGroupTranslator.getInstance() :
+ ValidationUtils.validateNotEmpty(OperatorTypeEnum.getTypeByName(((Condition)condition).getOperator()).getModifiedType()) ? FieldConditionTranslator.getInstance() : ConditionTranslator.getInstance();
+ }
+
+ private Translation getTranslation(BaseCondition condition) {
+ return getConditionTranslator(condition).translateToHpJson(condition);
+ }
+
+ private void flattenNestedFilters(FiltersTranslation filtersTranslation, String clazz) {
+ Map<Boolean, List<Translation>> partitioned = filtersTranslation.filters.stream().collect(Collectors.partitioningBy(f -> clazz.equals(((ProcessorTranslation) f).clazz)));
+ filtersTranslation.filters.removeAll(partitioned.get(Boolean.TRUE));
+ filtersTranslation.filters.addAll(partitioned.get(Boolean.TRUE).stream().map(f -> ((FiltersTranslation) f).filters).flatMap(List::stream).collect(Collectors.toList()));
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java
new file mode 100644
index 0000000..f93101b
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/ConditionTranslator.java
@@ -0,0 +1,40 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Condition;
+import org.onap.sdc.dcae.rule.editor.enums.ConditionTypeEnum;
+import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum;
+
+import java.util.stream.Collectors;
+
+public class ConditionTranslator implements IRuleElementTranslator<Condition> {
+
+ private static ConditionTranslator conditionTranslator = new ConditionTranslator();
+
+ public static ConditionTranslator getInstance() {
+ return conditionTranslator;
+ }
+
+ private ConditionTranslator(){}
+
+ private class StringFilterTranslation extends ProcessorTranslation {
+ private String string;
+ private String value;
+
+ private StringFilterTranslation(Condition condition, String value){
+ this.clazz = OperatorTypeEnum.getTypeByName(condition.getOperator()).getType();
+ this.string = condition.getLeft();
+ this.value = value;
+ }
+
+ private StringFilterTranslation(Condition condition){
+ this(condition, condition.getRight().get(0));
+ }
+ }
+
+ public Translation translateToHpJson(Condition condition) {
+ return 1 == condition.getRight().size() ? new StringFilterTranslation(condition) : new FiltersTranslation(ConditionTypeEnum.ANY.getFilterClass(), condition.getRight().stream()
+ .map(r -> new StringFilterTranslation(condition, r)).collect(Collectors.toList()));
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java
new file mode 100644
index 0000000..9d02c8e
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/CopyActionTranslator.java
@@ -0,0 +1,47 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction;
+
+public class CopyActionTranslator<A extends BaseAction> implements IRuleElementTranslator<A>{
+
+ private static CopyActionTranslator copyActionTranslator = new CopyActionTranslator();
+
+ public static CopyActionTranslator getInstance() {
+ return copyActionTranslator;
+ }
+
+ CopyActionTranslator(){}
+
+ public Translation translateToHpJson(A action) {
+ return new CopyActionSetTranslation(action.getTarget(), action.getFromValue());
+ }
+
+ void addToHpJsonProcessors(A action, List<Translation> processors) {
+ processors.add(translateToHpJson(action));
+ }
+
+ public boolean addToHpJsonProcessors(A action, List<Translation> processors, boolean asNewProcessor) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating {} action. New Processor: {}", action.getActionType(), asNewProcessor);
+ if(asNewProcessor)
+ addToHpJsonProcessors(action, processors);
+ else
+ ((CopyActionSetTranslation) processors.get(processors.size()-1)).updates.put(action.getTarget(), action.getFromValue());
+ return false;
+ }
+
+ class CopyActionSetTranslation extends ProcessorTranslation {
+ Map<String, String> updates = new LinkedHashMap<>();
+ CopyActionSetTranslation(String target, String from) {
+ clazz = "Set";
+ updates.put(target, from);
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java
new file mode 100644
index 0000000..89f0def
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/DateFormatterTranslator.java
@@ -0,0 +1,49 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import java.util.List;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.DateFormatterAction;
+
+public class DateFormatterTranslator extends CopyActionTranslator<DateFormatterAction> {
+
+ private static DateFormatterTranslator dateFormatterTranslator = new DateFormatterTranslator();
+
+ public static DateFormatterTranslator getInstance() {
+ return dateFormatterTranslator;
+ }
+
+ private DateFormatterTranslator(){}
+
+ private class DateFormatterTranslation extends ProcessorTranslation {
+ private String fromFormat;
+ private String fromTz;
+ private String toField;
+ private String toFormat;
+ private String toTz;
+ private String value;
+
+ private DateFormatterTranslation(DateFormatterAction action){
+ clazz = "DateFormatter";
+ fromFormat = action.getFromFormat();
+ fromTz = action.getFromTz();
+ toField = action.getTarget();
+ toFormat = action.getToFormat();
+ toTz = action.getToTz();
+ value = action.getFromValue();
+ }
+ }
+
+ @Override
+ public boolean addToHpJsonProcessors(DateFormatterAction action, List<Translation> processors, boolean asNewProcessor) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating date formatter action");
+ addToHpJsonProcessors(action, processors);
+ return true;
+ }
+
+ @Override
+ public Translation translateToHpJson(DateFormatterAction action){
+ return new DateFormatterTranslation(action);
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java
new file mode 100644
index 0000000..ef2949e
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/FieldConditionTranslator.java
@@ -0,0 +1,43 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Condition;
+import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum;
+
+import java.util.List;
+
+public class FieldConditionTranslator implements IRuleElementTranslator<Condition> {
+
+ private static FieldConditionTranslator fieldConditionTranslator = new FieldConditionTranslator();
+
+ public static FieldConditionTranslator getInstance() {
+ return fieldConditionTranslator;
+ }
+
+ private FieldConditionTranslator(){}
+
+ private class FieldFilterTranslation extends ProcessorTranslation {
+ private String field;
+ private String value;
+
+ private FieldFilterTranslation(Condition condition) {
+ clazz = OperatorTypeEnum.getTypeByName(condition.getOperator()).getType();
+ field = condition.getLeft();
+ value = condition.getRight().get(0);
+ }
+ }
+
+ private class MultiFieldFilterTranslation extends ProcessorTranslation {
+ private String field;
+ private List<String> values;
+
+ private MultiFieldFilterTranslation(Condition condition) {
+ field = condition.getLeft();
+ values = condition.getRight();
+ clazz = OperatorTypeEnum.getTypeByName(condition.getOperator()).getModifiedType();
+ }
+ }
+
+ public Translation translateToHpJson(Condition condition) {
+ return 1 == condition.getRight().size() ? new FieldFilterTranslation(condition) : new MultiFieldFilterTranslation(condition);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java
new file mode 100644
index 0000000..dac818d
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/IRuleElementTranslator.java
@@ -0,0 +1,50 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import com.google.gson.annotations.SerializedName;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface IRuleElementTranslator<T> {
+
+ OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ Translation translateToHpJson(T element);
+
+ abstract class Translation {
+ }
+
+ class ProcessorTranslation extends Translation {
+ @SerializedName("class")
+ protected String clazz;
+ }
+
+
+ class FiltersTranslation extends ProcessorTranslation {
+ protected List<Translation> filters;
+
+ protected FiltersTranslation(String clazz, List<Translation> filters) {
+ this.clazz = clazz;
+ this.filters = filters;
+ }
+ }
+
+ class RuleTranslation extends Translation {
+ protected String phase;
+ protected Translation filter;
+ protected List<Translation> processors = new ArrayList<>();
+ }
+
+ class RunPhaseProcessorsTranslation extends ProcessorTranslation {
+ protected String phase;
+
+ protected RunPhaseProcessorsTranslation(String runPhase){
+ clazz ="RunPhase";
+ phase = runPhase;
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java
new file mode 100644
index 0000000..922312e
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MapActionTranslator.java
@@ -0,0 +1,50 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+
+import java.util.List;
+import java.util.Map;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MapAction;
+
+public class MapActionTranslator extends CopyActionTranslator<MapAction> {
+
+ private static MapActionTranslator mapActionTranslator = new MapActionTranslator();
+
+ public static MapActionTranslator getInstance() {
+ return mapActionTranslator;
+ }
+
+ private MapActionTranslator(){}
+
+ private class MapActionTranslation extends ProcessorTranslation {
+
+ private Map<String, String> map;
+ private String field;
+ private String toField;
+ @SerializedName("default")
+ private String Default;
+
+ private MapActionTranslation(MapAction action) {
+ clazz = "MapAlarmValues";
+ Default = action.getMapDefaultValue();
+ field = action.getFromValue();
+ toField = action.getTarget();
+ map = action.transformToMap();
+ }
+ }
+
+ @Override
+ public Translation translateToHpJson(MapAction action) {
+ return new MapActionTranslation(action);
+ }
+
+ @Override
+ public boolean addToHpJsonProcessors(MapAction action, List<Translation> processors, boolean asNewProcessor) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating map action");
+ addToHpJsonProcessors(action, processors);
+ return true;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java
new file mode 100644
index 0000000..0164446
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/MappingRulesTranslator.java
@@ -0,0 +1,69 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MappingRules;
+
+public class MappingRulesTranslator implements IRuleElementTranslator<MappingRules> {
+
+ private static MappingRulesTranslator mappingRulesTranslator = new MappingRulesTranslator();
+
+ public static MappingRulesTranslator getInstance() {
+ return mappingRulesTranslator;
+ }
+
+ private MappingRulesTranslator() {
+ }
+
+ private RuleTranslator ruleTranslator = RuleTranslator.getInstance();
+
+ public Translation translateToHpJson(MappingRules mappingRules) {
+ return new MappingRulesTranslation(mappingRules);
+ }
+
+ public Translation translateToHpJson(MappingRules mappingRules, String entryPointPhaseName, String lastPhaseName, String runPhase) {
+ // 1806 US349308 assign Vfcmt name as rule phaseName
+ mappingRules.getRules().forEach((k,v) -> v.setPhase(runPhase));
+ return new MappingRulesTranslation(mappingRules, entryPointPhaseName, lastPhaseName, runPhase);
+ }
+
+ private class MappingRulesTranslation extends Translation {
+
+ private List<Translation> processing;
+
+ private MappingRulesTranslation(MappingRules mappingRules) {
+ processing = mappingRules.getRules().values().stream().map(ruleTranslator::translateToHpJson).collect(Collectors.toList());
+ }
+
+ private MappingRulesTranslation(MappingRules mappingRules, String entryPointPhaseName, String lastPhaseName, String runPhase) {
+ this(mappingRules);
+ //hardcoded entry point processor
+ processing.add(0, new RunPhaseRuleTranslation(entryPointPhaseName, runPhase));
+ //hardcoded map_publish processor
+ processing.add(new RunPhaseRuleTranslation(runPhase, lastPhaseName));
+ }
+ }
+
+ private class RunPhaseRuleTranslation extends RuleTranslation {
+
+ private RunPhaseRuleTranslation(String phaseName, String runPhase) {
+ phase = phaseName;
+ if ("snmp_map".equals(phaseName))
+ processors.add(new SnmpConvertor());
+ processors.add(new RunPhaseProcessorsTranslation(runPhase));
+ }
+ }
+
+ // hardcoded SNMP processor
+ private class SnmpConvertor extends ProcessorTranslation {
+ private String array = "varbinds";
+ private String datacolumn = "varbind_value";
+ private String keycolumn = "varbind_oid";
+
+ private SnmpConvertor() {
+ clazz = "SnmpConvertor";
+ }
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java
new file mode 100644
index 0000000..c49a04e
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RegexActionTranslator.java
@@ -0,0 +1,44 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import java.util.List;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction;
+
+public class RegexActionTranslator extends CopyActionTranslator<BaseAction> {
+
+ private static RegexActionTranslator regexActionTranslator = new RegexActionTranslator();
+
+ public static RegexActionTranslator getInstance() {
+ return regexActionTranslator;
+ }
+
+ private RegexActionTranslator(){}
+
+ private class RegexCopyActionTranslation extends ProcessorTranslation {
+
+ private String regex;
+ private String field;
+ private String value;
+
+ private RegexCopyActionTranslation(BaseAction action) {
+ clazz = "ExtractText";
+ regex = action.getRegexValue();
+ field = action.getTarget();
+ value = action.getFromValue();
+ }
+ }
+
+ @Override
+ public boolean addToHpJsonProcessors(BaseAction action, List<Translation> processors, boolean asNewProcessor) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Translating copy action as regex action");
+ addToHpJsonProcessors(action, processors);
+ return true;
+ }
+
+ @Override
+ public Translation translateToHpJson(BaseAction action) {
+ return new RegexCopyActionTranslation(action);
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java
new file mode 100644
index 0000000..f7dea47
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/translators/RuleTranslator.java
@@ -0,0 +1,51 @@
+package org.onap.sdc.dcae.rule.editor.translators;
+
+import com.google.gson.Gson;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum;
+import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+
+public class RuleTranslator implements IRuleElementTranslator<Rule> {
+
+ private static RuleTranslator ruleTranslator = new RuleTranslator();
+
+ public static RuleTranslator getInstance() {
+ return ruleTranslator;
+ }
+
+ private RuleTranslator() {
+ }
+
+ private class ActionRuleTranslation extends RuleTranslation {
+ private ActionRuleTranslation(Rule rule) {
+ phase = rule.getPhase();
+ filter = rule.isConditionalRule() ? getConditionTranslator(rule.getCondition()).translateToHpJson(rule.getCondition()) : null;
+ boolean asNewProcessor = true;
+ for (BaseAction action : rule.getActions()) {
+ // consecutive copy actions are aggregated into a single processor
+ asNewProcessor = getActionTranslator(action).addToHpJsonProcessors(action, processors, asNewProcessor);
+ }
+ }
+ }
+
+ public Translation translateToHpJson(Rule rule) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Start translating rule {}", rule.getUid());
+ Translation translation = new ActionRuleTranslation(rule);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Finished translation for rule {}. Result: {}", rule.getUid(), new Gson().toJson(translation));
+ return translation;
+ }
+
+ private IRuleElementTranslator getConditionTranslator(BaseCondition condition){
+ return condition instanceof ConditionGroup ? ConditionGroupTranslator.getInstance() :
+ ValidationUtils.validateNotEmpty(OperatorTypeEnum.getTypeByName(((Condition)condition).getOperator()).getModifiedType()) ? FieldConditionTranslator.getInstance() : ConditionTranslator.getInstance();
+ }
+
+ private CopyActionTranslator getActionTranslator(BaseAction action) {
+ ActionTypeEnum type = ActionTypeEnum.getTypeByName(action.getActionType());
+ if(ActionTypeEnum.COPY == type && ValidationUtils.validateNotEmpty(action.getRegexValue()))
+ return RegexActionTranslator.getInstance();
+ return (CopyActionTranslator)RuleEditorElementType.getElementTypeByName(type.getType()).getTranslator();
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java
new file mode 100644
index 0000000..c65076f
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/EmptyStringTranslationSerializer.java
@@ -0,0 +1,14 @@
+package org.onap.sdc.dcae.rule.editor.utils;
+
+import com.google.gson.*;
+
+import java.lang.reflect.Type;
+
+public class EmptyStringTranslationSerializer implements JsonSerializer<String> {
+
+ public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
+ if("\"\"".equals(src))
+ return new JsonPrimitive("");
+ return new JsonPrimitive(src);
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java
new file mode 100644
index 0000000..33f9e92
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/RulesPayloadUtils.java
@@ -0,0 +1,38 @@
+package org.onap.sdc.dcae.rule.editor.utils;
+
+import java.util.List;
+
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonParseException;
+
+public class RulesPayloadUtils {
+ private static Gson gson = new GsonBuilder().serializeNulls()
+ .registerTypeAdapter(BaseAction.class, new ActionDeserializer())
+ .registerTypeAdapter(BaseCondition.class, new ConditionDeserializer()).create();
+
+ public static Rule parsePayloadToRule(String payload) throws JsonParseException {
+ return gson.fromJson(payload, Rule.class);
+ }
+
+ public static MappingRules parseMappingRulesArtifactPayload(String payload) throws JsonParseException {
+ return gson.fromJson(payload, MappingRules.class);
+ }
+
+ public static SchemaInfo extractInfoFromDescription(Artifact rulesArtifact) {
+ try {
+ return gson.fromJson(rulesArtifact.getArtifactDescription(), SchemaInfo.class);
+ }catch (JsonParseException e) {
+ return null;
+ }
+ }
+
+ public static String buildSchemaAndRulesResponse(String payload, List<EventTypeDefinitionUI> schema) {
+ return "{\"schema\":"+gson.toJson(schema)+","+payload.replaceFirst("\\{", "");
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java
new file mode 100644
index 0000000..7a3b206
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/utils/ValidationUtils.java
@@ -0,0 +1,20 @@
+package org.onap.sdc.dcae.rule.editor.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+
+public class ValidationUtils {
+
+ private static final String EXPLICIT_EMPTY = "\"\"";
+
+ public static boolean validateNotEmpty(String value){
+ return StringUtils.isNoneBlank(value);
+ }
+
+ public static boolean validateTargetField(String value) {
+ return validateNotEmpty(value) && !EXPLICIT_EMPTY.equals(value);
+ }
+
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java
new file mode 100644
index 0000000..3eb0eb5
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ActionValidator.java
@@ -0,0 +1,40 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+
+import java.util.List;
+
+public class ActionValidator<A extends BaseAction> implements IRuleElementValidator<A> {
+
+ private static ActionValidator actionValidator = new ActionValidator();
+
+ public static ActionValidator getInstance() {
+ return actionValidator;
+ }
+
+ ActionValidator(){}
+
+ public boolean validate(A action, List<ResponseFormat> errors) {
+
+ // validate from is populated
+ boolean valid = validateFromValue(action, errors);
+ //validate target is populated
+ if (!ValidationUtils.validateTargetField(action.getTarget())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "target", action.getActionType(), action.getTarget()));
+ }
+ return valid;
+ }
+
+ protected boolean validateFromValue(A action, List<ResponseFormat> errors) {
+ if(!ValidationUtils.validateNotEmpty(action.getFromValue())) {
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from", action.getActionType(), action.getTarget()));
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java
new file mode 100644
index 0000000..965c898
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConcatActionValidator.java
@@ -0,0 +1,29 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+
+import java.util.List;
+
+public class ConcatActionValidator extends ActionValidator<BaseAction> {
+
+ private static ConcatActionValidator concatActionValidator = new ConcatActionValidator();
+
+ public static ConcatActionValidator getInstance() {
+ return concatActionValidator;
+ }
+
+ private ConcatActionValidator(){}
+
+ @Override
+ protected boolean validateFromValue(BaseAction action, List<ResponseFormat> errors) {
+ if(!ValidationUtils.validateNotEmpty(action.getFromValue()) || 2 > action.getFromValues().size()) {
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_CONCAT_VALUE, null, action.getTarget()));
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java
new file mode 100644
index 0000000..995a817
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionGroupValidator.java
@@ -0,0 +1,40 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ConditionGroup;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.rule.editor.enums.ConditionTypeEnum;
+import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+public class ConditionGroupValidator implements IRuleElementValidator<ConditionGroup> {
+
+ private static ConditionGroupValidator conditionGroupValidator = new ConditionGroupValidator();
+
+ public static ConditionGroupValidator getInstance() {
+ return conditionGroupValidator;
+ }
+
+ private ConditionGroupValidator(){}
+
+ public boolean validate(ConditionGroup condition, List<ResponseFormat> errors) {
+ boolean valid = true;
+ if(!ValidationUtils.validateNotEmpty(condition.getType()) || null == ConditionTypeEnum.getTypeByName(condition.getType())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.INVALID_GROUP_CONDITION, null, condition.getType()));
+ }
+ if(CollectionUtils.isEmpty(condition.getChildren()) || 2 > condition.getChildren().size()) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_CONDITION_ITEM, null, null));
+ } else {
+ valid = condition.getChildren().stream()
+ .map(c -> RuleEditorElementType.getElementTypeByName(c.getClass().getSimpleName()).getValidator().validate(c, errors))
+ .reduce(true, (x,y) -> x && y) && valid;
+ }
+ return valid;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java
new file mode 100644
index 0000000..1b4ae94
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/ConditionValidator.java
@@ -0,0 +1,40 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Condition;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.rule.editor.enums.OperatorTypeEnum;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+public class ConditionValidator implements IRuleElementValidator<Condition> {
+
+ private static ConditionValidator conditionValidator = new ConditionValidator();
+
+ public static ConditionValidator getInstance() {
+ return conditionValidator;
+ }
+
+ private ConditionValidator(){}
+
+ public boolean validate(Condition condition, List<ResponseFormat> errors) {
+ boolean valid = true;
+ if(!ValidationUtils.validateNotEmpty(condition.getLeft())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_OPERAND, null, "left"));
+ }
+ if(CollectionUtils.isEmpty(condition.getRight())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_OPERAND, null, "right"));
+ }
+ if(!ValidationUtils.validateNotEmpty(condition.getOperator()) || null == OperatorTypeEnum.getTypeByName(condition.getOperator())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.INVALID_OPERATOR, null, condition.getOperator()));
+ }
+ return valid;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java
new file mode 100644
index 0000000..d5ec0fc
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/DateFormatterValidator.java
@@ -0,0 +1,41 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.DateFormatterAction;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+
+import java.util.List;
+
+public class DateFormatterValidator extends ActionValidator<DateFormatterAction> {
+ private static DateFormatterValidator dateFormatterValidator = new DateFormatterValidator();
+
+ public static DateFormatterValidator getInstance() {
+ return dateFormatterValidator;
+ }
+
+ private DateFormatterValidator(){}
+
+ @Override
+ public boolean validate(DateFormatterAction action, List<ResponseFormat> errors) {
+ boolean valid = super.validate(action, errors);
+ if(!ValidationUtils.validateNotEmpty(action.getFromFormat())){
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from format", action.getActionType(), action.getTarget()));
+ }
+ if(!ValidationUtils.validateNotEmpty(action.getFromTz())){
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "from timezone", action.getActionType(), action.getTarget()));
+ }
+ if(!ValidationUtils.validateNotEmpty(action.getToFormat())){
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "to format", action.getActionType(), action.getTarget()));
+ }
+ if(!ValidationUtils.validateNotEmpty(action.getToTz())){
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION_FIELD, null, "to timezone", action.getActionType(), action.getTarget()));
+ }
+ return valid;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java
new file mode 100644
index 0000000..dd1eaf4
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/IRuleElementValidator.java
@@ -0,0 +1,9 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+
+import java.util.List;
+
+public interface IRuleElementValidator <T> {
+ boolean validate(T element, List<ResponseFormat> errors);
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java
new file mode 100644
index 0000000..8cbcaa8
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/MapActionValidator.java
@@ -0,0 +1,49 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.MapAction;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+public class MapActionValidator extends ActionValidator<MapAction> {
+
+ private static MapActionValidator mapActionValidator = new MapActionValidator();
+
+ public static MapActionValidator getInstance() {
+ return mapActionValidator;
+ }
+
+ private MapActionValidator(){}
+
+ @Override
+ public boolean validate(MapAction action, List<ResponseFormat> errors) {
+ boolean valid = super.validate(action, errors);
+ if (action.getMap() == null || CollectionUtils.isEmpty(action.getMapValues())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ENTRY, null, action.getTarget()));
+ } else {
+ if (action.mapHasDefault() && !ValidationUtils.validateNotEmpty(action.getMapDefaultValue())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_DEFAULT_VALUE, null, action.getTarget()));
+ }
+ try {
+ if (!validateMapValues(action)) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ENTRY, null, action.getTarget()));
+ }
+ } catch (IllegalStateException err) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.DUPLICATE_KEY, null));
+ }
+ }
+ return valid;
+ }
+
+ private boolean validateMapValues(MapAction action) {
+ return action.transformToMap().entrySet().stream().noneMatch(p -> !ValidationUtils.validateNotEmpty(p.getKey()) || !ValidationUtils.validateNotEmpty(p.getValue()));
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java
new file mode 100644
index 0000000..371d1e9
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/rule/editor/validators/RuleValidator.java
@@ -0,0 +1,56 @@
+package org.onap.sdc.dcae.rule.editor.validators;
+
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.ActionTypeEnum;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseAction;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.BaseCondition;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.Rule;
+import org.onap.sdc.dcae.errormng.ActionStatus;
+import org.onap.sdc.dcae.errormng.ErrConfMgr;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.onap.sdc.dcae.errormng.ServiceException;
+import org.onap.sdc.dcae.rule.editor.enums.RuleEditorElementType;
+import org.onap.sdc.dcae.rule.editor.utils.ValidationUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+public class RuleValidator implements IRuleElementValidator<Rule> {
+
+ private static RuleValidator ruleValidator = new RuleValidator();
+
+ public static RuleValidator getInstance() {
+ return ruleValidator;
+ }
+
+ private RuleValidator(){}
+
+
+ public boolean validate(Rule rule, List<ResponseFormat> errors) {
+ boolean valid = true;
+ if(rule.isConditionalRule())
+ valid = getConditionValidator(rule.getCondition()).validate(rule.getCondition(), errors);
+ if(!ValidationUtils.validateNotEmpty(rule.getDescription())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_RULE_DESCRIPTION, null, null));
+ }
+ if(CollectionUtils.isEmpty(rule.getActions())) {
+ valid = false;
+ errors.add(ErrConfMgr.INSTANCE.getResponseFormat(ActionStatus.MISSING_ACTION, null, null));
+ } else {
+ valid = rule.getActions().stream()
+ .map(a -> getActionValidator(a).validate(a, errors))
+ .reduce(true, (x,y) -> x && y) && valid;
+ }
+ return valid;
+ }
+
+
+ private IRuleElementValidator getActionValidator(BaseAction action) {
+ ActionTypeEnum type = ActionTypeEnum.getTypeByName(action.getActionType());
+ return RuleEditorElementType.getElementTypeByName(type.getType()).getValidator();
+ }
+
+ private IRuleElementValidator getConditionValidator(BaseCondition condition) {
+ return RuleEditorElementType.getElementTypeByName(condition.getClass().getSimpleName()).getValidator();
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/EventListenerDefinition.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/EventListenerDefinition.java
new file mode 100644
index 0000000..cc5bec1
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/EventListenerDefinition.java
@@ -0,0 +1,101 @@
+package org.onap.sdc.dcae.ves;
+
+import com.google.gson.Gson;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+public class EventListenerDefinition extends VesDataTypeDefinition {
+
+ public static final String EVENT_ROOT = "event";
+ private String $schema;
+ private Map<String, VesDataTypeDefinition> definitions;
+
+ public String get$schema() {
+ return $schema;
+ }
+
+ public void set$schema(String $schema) {
+ this.$schema = $schema;
+ }
+
+ public Map<String, VesDataTypeDefinition> getDefinitions() {
+ return definitions;
+ }
+
+ public void setDefinitions(Map<String, VesDataTypeDefinition> definitions) {
+ this.definitions = definitions;
+ }
+
+ // returns error message detailing unresolvable types - or null (success)
+ public String resolveRefTypes() {
+
+ Predicate<Map.Entry<String, VesDataTypeDefinition>> isFullyResolved = dt -> !dt.getValue().containsAnyReferenceItem();
+ Map<String, VesDataTypeDefinition> resolved = definitions.entrySet().stream()
+ .filter(isFullyResolved)
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ int initialUnresolvedItems = -1;
+ int remainingUnresolvedItems = 0;
+
+ while (resolved.size() != definitions.size() && initialUnresolvedItems != remainingUnresolvedItems) {
+ initialUnresolvedItems = definitions.size() - resolved.size();
+ definitions.entrySet().forEach(definition -> {
+ if (!resolved.containsKey(definition.getKey()) && definition.getValue().isResolvable(resolved)) {
+ definition.getValue().resolveAllReferences(resolved);
+ resolved.put(definition.getKey(), definition.getValue());
+ }
+ });
+ remainingUnresolvedItems = definitions.size() - resolved.size();
+ }
+
+ if (resolved.size() != definitions.size()) {
+ definitions.keySet().removeAll(resolved.keySet());
+ return constructErrorMessage(definitions.keySet());
+ }
+ return resolveRootRefTypes();
+
+ }
+
+ private String constructErrorMessage(Set<String> unresolvable) {
+ return "the following definitions containing unresolvable references: " + new Gson().toJson(unresolvable);
+ }
+
+ private String resolveRootRefTypes() {
+ Set<String> unresolvable = new HashSet<>();
+ getProperties().forEach((k, v) -> {
+ if (isResolvable(definitions))
+ resolveAllReferences(definitions);
+ else
+ unresolvable.add(k);
+ });
+ return unresolvable.isEmpty() ? null : constructErrorMessage(unresolvable);
+
+ }
+
+ @Override
+ public String validate() {
+ String error = getProperties().containsKey(EVENT_ROOT) ? null : "schema not containing property: event";
+ if (StringUtils.isBlank(error))
+ error = super.validate();
+ if (StringUtils.isBlank(error))
+ error = validateDefinitions();
+ return error;
+ }
+
+ private String validateDefinitions() {
+ String error = null;
+ for (VesDataTypeDefinition def : definitions.values()) {
+ if (StringUtils.isBlank(error))
+ error = def.validate();
+ else
+ break;
+ }
+ return error;
+ }
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataItemsDefinition.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataItemsDefinition.java
new file mode 100644
index 0000000..ad1b2f9
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataItemsDefinition.java
@@ -0,0 +1,9 @@
+package org.onap.sdc.dcae.ves;
+
+import java.util.ArrayList;
+
+// json 'items' value can be either a single object or an array. customized POJO will always be an array
+public class VesDataItemsDefinition extends ArrayList<VesDataTypeDefinition> {
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataTypeDefinition.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataTypeDefinition.java
new file mode 100644
index 0000000..5465d62
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesDataTypeDefinition.java
@@ -0,0 +1,270 @@
+package org.onap.sdc.dcae.ves;
+
+import com.google.gson.JsonElement;
+import com.google.gson.annotations.SerializedName;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+
+import java.util.*;
+
+public class VesDataTypeDefinition {
+
+ private static final String jsonReferencePrefix = "#/definitions/";
+ private String type;
+ private String description;
+ private String format;
+ private String title;
+ private Map<String, VesDataTypeDefinition> properties;
+ private List<String> required = new ArrayList<>();
+ @SerializedName("enum")
+ private List<String> enums;
+ @SerializedName("default")
+ private JsonElement defaultValue;
+ private VesDataItemsDefinition items;
+ @SerializedName("$ref")
+ private String ref;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public Map<String, VesDataTypeDefinition> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, VesDataTypeDefinition> properties) {
+ this.properties = properties;
+ }
+
+ public List<String> getRequired() {
+ return required;
+ }
+
+ public void setRequired(List<String> required) {
+ this.required = required;
+ }
+
+ public List<String> getEnums() {
+ return enums;
+ }
+
+ public void setEnums(List<String> enums) {
+ this.enums = enums;
+ }
+
+ public JsonElement getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(JsonElement defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public VesDataItemsDefinition getItems() {
+ return items;
+ }
+
+ public void setItems(VesDataItemsDefinition items) {
+ this.items = items;
+ }
+
+ public String getRef() {
+ return ref;
+ }
+
+ public void setRef(String ref) {
+ this.ref = ref;
+ }
+
+ protected boolean hasReference() {
+ return StringUtils.isNotBlank(getRef());
+ }
+
+ protected boolean itemsContainReference() {
+ return CollectionUtils.isNotEmpty(getItems()) && getItems().stream().anyMatch(VesDataTypeDefinition::containsAnyReferenceItem);
+ }
+
+ protected boolean propertiesContainReference() {
+ return MapUtils.isNotEmpty(getProperties()) && getProperties().values().stream().anyMatch(VesDataTypeDefinition::containsAnyReferenceItem);
+ }
+
+ protected boolean containsAnyReferenceItem() {
+ return hasReference() || itemsContainReference() || propertiesContainReference();
+ }
+
+ protected String getJsonRefPointer() {
+ return getRef().replace(jsonReferencePrefix, "");
+ }
+
+ private void addReferenceItem(Set<String> allRefs) {
+ if (hasReference()) {
+ allRefs.add(getJsonRefPointer());
+ }
+ }
+
+ private Set<String> extractAllReferenceTokens() {
+ Set<String> allRefs = new HashSet<>();
+ extractReferenceTokens(allRefs);
+ return allRefs;
+ }
+
+ private void extractReferenceTokens(Set<String> allRefs) {
+
+ addReferenceItem(allRefs);
+ if (itemsContainReference()) {
+ getItems().forEach(item -> item.extractReferenceTokens(allRefs));
+ }
+ if (propertiesContainReference()) {
+ getProperties().values().forEach(property -> property.extractReferenceTokens(allRefs));
+ }
+ }
+
+ protected boolean isResolvable(Map<String, VesDataTypeDefinition> resolvedTypes) {
+ return resolvedTypes.keySet().containsAll(extractAllReferenceTokens());
+ }
+
+ private void resolveReference(Map<String, VesDataTypeDefinition> resolvedTypes) {
+ if (hasReference()) {
+ VesDataTypeDefinition other = resolvedTypes.get(getJsonRefPointer());
+ setType(other.getType());
+ setRef(other.getRef());
+ setDefaultValue(other.getDefaultValue());
+ setDescription(other.getDescription());
+ setEnums(other.getEnums());
+ setProperties(other.getProperties());
+ setFormat(other.getFormat());
+ setRequired(other.getRequired());
+ setItems(other.getItems());
+ setTitle(other.getTitle());
+ }
+ }
+
+ private void resolveItemReferences(Map<String, VesDataTypeDefinition> resolvedTypes) {
+ if (itemsContainReference()) {
+ for (VesDataTypeDefinition item : getItems()) {
+ item.resolveAllReferences(resolvedTypes);
+ }
+ }
+ }
+
+ private void resolvePropertyReferences(Map<String, VesDataTypeDefinition> resolvedTypes) {
+ if (propertiesContainReference()) {
+ for (VesDataTypeDefinition property : getProperties().values()) {
+ property.resolveAllReferences(resolvedTypes);
+ }
+ }
+ }
+
+ // the reference resolver is called on each VesDataTypeDefinition after it passes the 'isResolvable' validation, affirming that all its references(direct/properties/items) point to a resolved VesDataTypeDefinition (has no references)
+ protected void resolveAllReferences(Map<String, VesDataTypeDefinition> resolvedTypes) {
+ resolveReference(resolvedTypes);
+ resolveItemReferences(resolvedTypes);
+ resolvePropertyReferences(resolvedTypes);
+ }
+
+ private String validateType() {
+ return null == type? null : VesSimpleTypesEnum.getSimpleTypes().contains(type) ? null : "invalid type declaration: " + type;
+ }
+
+ private String validateRequired() {
+ String invalid = null == type? null : !type.equals(VesSimpleTypesEnum.OBJECT.getType()) ? null : required.stream().filter(r -> !properties.keySet().contains(r)).findAny().orElse(null);
+ return StringUtils.isBlank(invalid) ? invalid : "invalid required entry: " + invalid;
+ }
+
+ // returns error message detailing invalid 'type' or 'required' fields (null for success)
+ protected String validate() {
+ String error = validateType();
+ if (StringUtils.isBlank(error))
+ error = validateRequired();
+ if (StringUtils.isBlank(error) && CollectionUtils.isNotEmpty(items))
+ error = validateItems();
+ if(StringUtils.isBlank(error) && MapUtils.isNotEmpty(properties))
+ error = validateProperties();
+ return error;
+ }
+
+ private String validateItems(){
+ String error = null;
+ for (VesDataTypeDefinition def : items) {
+ if (StringUtils.isBlank(error))
+ error = def.validate();
+ else
+ break;
+ }
+ return error;
+ }
+
+ private String validateProperties(){
+ String error = null;
+ for (VesDataTypeDefinition def : properties.values()) {
+ if (StringUtils.isBlank(error))
+ error = def.validate();
+ else
+ break;
+ }
+ return error;
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (null == obj || getClass() != obj.getClass())
+ return false;
+ VesDataTypeDefinition other = (VesDataTypeDefinition) obj;
+ return Objects.equals(type, other.type) &&
+ Objects.equals(description, other.description) &&
+ Objects.equals(format, other.format) &&
+ Objects.equals(title, other.title) &&
+ Objects.equals(required, other.required) &&
+ Objects.equals(enums, other.enums) &&
+ Objects.equals(defaultValue, other.defaultValue) &&
+ Objects.equals(items, other.items) &&
+ Objects.equals(properties, other.properties) &&
+ Objects.equals(ref, other.ref);
+ }
+
+ @Override public int hashCode() {
+ int result = type != null ? type.hashCode() : 0;
+ result = 31 * result + (description != null ? description.hashCode() : 0);
+ result = 31 * result + (format != null ? format.hashCode() : 0);
+ result = 31 * result + (title != null ? title.hashCode() : 0);
+ result = 31 * result + (properties != null ? properties.hashCode() : 0);
+ result = 31 * result + (required != null ? required.hashCode() : 0);
+ result = 31 * result + (enums != null ? enums.hashCode() : 0);
+ result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0);
+ result = 31 * result + (items != null ? items.hashCode() : 0);
+ result = 31 * result + (ref != null ? ref.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesJsonDeserializer.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesJsonDeserializer.java
new file mode 100644
index 0000000..f5cfd2a
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesJsonDeserializer.java
@@ -0,0 +1,20 @@
+package org.onap.sdc.dcae.ves;
+
+import com.google.gson.*;
+
+import java.lang.reflect.Type;
+
+// json 'items' value can be either a single object or an array. customized POJO will always be an array
+public class VesJsonDeserializer implements JsonDeserializer<VesDataItemsDefinition> {
+ @Override
+ public VesDataItemsDefinition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+
+ if(json instanceof JsonArray){
+ return new Gson().fromJson(json, VesDataItemsDefinition.class);
+ }
+
+ VesDataItemsDefinition items = new VesDataItemsDefinition();
+ items.add(new Gson().fromJson(json, VesDataTypeDefinition.class));
+ return items;
+ }
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesSimpleTypesEnum.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesSimpleTypesEnum.java
new file mode 100644
index 0000000..0606a6d
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesSimpleTypesEnum.java
@@ -0,0 +1,26 @@
+package org.onap.sdc.dcae.ves;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public enum VesSimpleTypesEnum {
+
+ ARRAY("array"), BOOLEAN("boolean"), INTEGER("integer"), NULL("null"), NUMBER("number"), OBJECT("object"), STRING("string");
+
+ private String type;
+
+ public String getType() {
+ return type;
+ }
+
+ private VesSimpleTypesEnum(String type) {
+ this.type = type;
+ }
+
+ public static Set<String> getSimpleTypes() {
+ return Arrays.stream(VesSimpleTypesEnum.values()).map(t -> t.getType()).collect(Collectors.toSet());
+ }
+
+
+}
diff --git a/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesStructureLoader.java b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesStructureLoader.java
new file mode 100644
index 0000000..cb8a16c
--- /dev/null
+++ b/dcaedt_be/src/main/java/org/onap/sdc/dcae/ves/VesStructureLoader.java
@@ -0,0 +1,115 @@
+package org.onap.sdc.dcae.ves;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.io.*;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Service("vesstructureloader")
+public class VesStructureLoader {
+
+
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ private static Map<String, EventListenerDefinition> eventListeners = new HashMap<>();
+ private static final Type type = new TypeToken<VesDataItemsDefinition>(){}.getType();
+ private static final Gson gson = new GsonBuilder().registerTypeAdapter(type, new VesJsonDeserializer()).create();
+ private static final String SCHEMA_NAME_PREFIX = "CommonEventFormat_v";
+ private static final String SCHEMA_NAME_SUFFIX = ".json";
+
+ private VesStructureLoader() {
+ }
+
+ @PostConstruct public void init() {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "VesStructureLoader: Trying to load json schemas");
+ String jettyBase = System.getProperty("jetty.base");
+ if (jettyBase == null) {
+ String msg = "Couldn't resolve jetty.base environmental variable";
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), msg);
+ throw new IllegalArgumentException(msg + ". Failed to load VES schema files... aborting");
+ }
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "jetty.base={}", jettyBase);
+
+ File dir = new File(jettyBase + "/config/dcae-be/ves-schema");
+ File[] files = dir.listFiles((dir1, name) -> name.startsWith(SCHEMA_NAME_PREFIX) && name.endsWith(SCHEMA_NAME_SUFFIX));
+
+ if (ArrayUtils.isEmpty(files)) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error – Failed to find VES Schema definitions.");
+ } else {
+
+ for (File f : files) {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Loading VES schema file: {}", f.getName());
+ parseJsonFileAndSaveToMap(f);
+ }
+ }
+
+ }
+
+ private void parseJsonFileAndSaveToMap(File file) {
+
+ try {
+ EventListenerDefinition eventListener = gson.fromJson(new FileReader(file), EventListenerDefinition.class);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), gson.toJson(eventListener));
+ String validationError = getValidatorMessage(eventListener);
+ if (StringUtils.isEmpty(validationError)) {
+ eventListeners.put(getVersionFromFileName(file.getName()), eventListener);
+ } else {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Failed to parse VES schema file {}. [{}]", file.getName(), validationError);
+ }
+ } catch (FileNotFoundException | JsonIOException | JsonSyntaxException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "Error: Failed to parse VES schema file {}. [{}]", file.getName(), e);
+ }
+ }
+
+ public static Map<String, VesDataTypeDefinition> getEventListenerDefinitionByVersion(String version) {
+ return eventListeners.get(version).getProperties().get(EventListenerDefinition.EVENT_ROOT).getProperties();
+ }
+
+ public static Set<String> getAvailableVersionsList() {
+ return eventListeners.keySet();
+ }
+
+ public static Map<String, Set<String>> getAvailableVersionsAndEventTypes() {
+ return eventListeners.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> getEventListenerDefinitionByVersion(e.getKey()).keySet()));
+ }
+
+ public static Set<String> getEventTypeListByVersion(String version) {
+ return getEventListenerDefinitionByVersion(version).keySet();
+ }
+
+ private String getValidatorMessage(EventListenerDefinition eventListenerDefinition) {
+ String validationError = eventListenerDefinition.validate();
+ if (StringUtils.isBlank(validationError)) {
+ validationError = eventListenerDefinition.resolveRefTypes();
+ }
+ return validationError;
+ }
+
+ private String getVersionFromFileName(String fileName) {
+ return fileName.replace(SCHEMA_NAME_PREFIX, "").replace(SCHEMA_NAME_SUFFIX, "");
+ }
+
+ @PreDestroy
+ public void preDestroy() {
+ // why is this method empty?
+ }
+}
diff --git a/dcaedt_be/src/main/resources/logback-spring.xml b/dcaedt_be/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..62dc9c0
--- /dev/null
+++ b/dcaedt_be/src/main/resources/logback-spring.xml
@@ -0,0 +1,181 @@
+<!-- Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. -->
+<configuration scan="true" scanPeriod="3 seconds">
+ <include resource="org/springframework/boot/logging/logback/base.xml"/>
+ <!--<jmxConfigurator /> -->
+ <!-- specify the component name -->
+ <property name="componentName" value="DCAE"></property>
+ <!-- log file names -->
+ <property name="combinedLogName" value="all" />
+ <property name="generalLogName" value="application" />
+ <property name="errorLogName" value="error" />
+ <property name="metricsLogName" value="metrics" />
+ <property name="auditLogName" value="audit" />
+ <property name="debugLogName" value="debug" />
+ <property name="defaultPattern" value="%date{ISO8601,UTC}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Timer}| %msg%n" />
+ <property name="auditLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" />
+ <property name="metricsLoggerPattern" value="%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{VirtualServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{RemoteHost}|%X{ClassName}|%X{Unused}|%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}| %msg%n" />
+ <property name="errorLoggerPattern" value="%date{ISO8601,UTC}|%X{RequestId}|%thread|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%.-5level|%X{ErrorCode}|%X{ErrorDescription}| %msg%n" />
+ <property name="debugLoggerPattern" value="%date{ISO8601,UTC}|%X{RequestId}| %msg%n" />
+ <property name="logDirectory" value="${log.home}/${componentName}" />
+ <!-- ============================================================================ -->
+ <!-- EELF Appenders -->
+ <!-- ============================================================================ -->
+ <!-- The EELFAppender is used to record events to the general application
+ log -->
+ <appender name="EELF" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${generalLogName}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${generalLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${defaultPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELF" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELF" />
+ </appender>
+
+ <appender name="ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${combinedLogName}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${combinedLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${defaultPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncALL" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="ALL" />
+ </appender>
+ <!-- EELF Audit Appender. This appender is used to record audit engine
+ related logging events. The audit logger and appender are specializations
+ of the EELF application root logger and appender. This can be used to segregate
+ Policy engine events from other components, or it can be eliminated to record
+ these events as part of the application root log. -->
+ <!-- Audit log -->
+ <appender name="EELFAudit" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${auditLogName}.log</file>
+ <!-- Audit messages filter - accept audit messages -->
+ <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+ <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
+ <marker>AUDIT_MARKER</marker>
+ <marker>AUDIT</marker>
+ </evaluator>
+ <onMismatch>DENY</onMismatch>
+ <onMatch>ACCEPT</onMatch>
+ </filter>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip</fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>10</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>20MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${auditLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFAudit" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFAudit" />
+ </appender>
+ <appender name="EELFMetrics" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${metricsLogName}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${metricsLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} -
+ %msg%n"</pattern> -->
+ <pattern>${metricsLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFMetrics" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFMetrics"/>
+ </appender>
+ <appender name="EELFError" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${errorLogName}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${errorLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFError" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFError"/>
+ </appender>
+ <appender name="EELFDebug" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${logDirectory}/${debugLogName}.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <fileNamePattern>${logDirectory}/${debugLogName}.%i.log.zip
+ </fileNamePattern>
+ <minIndex>1</minIndex>
+ <maxIndex>9</maxIndex>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <maxFileSize>5MB</maxFileSize>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>${debugLoggerPattern}</pattern>
+ </encoder>
+ </appender>
+ <appender name="asyncEELFDebug" class="ch.qos.logback.classic.AsyncAppender">
+ <queueSize>256</queueSize>
+ <appender-ref ref="EELFDebug" />
+ <includeCallerData>true</includeCallerData>
+ </appender>
+ <!-- ============================================================================ -->
+ <!-- EELF loggers -->
+ <!-- ============================================================================ -->
+ <logger name="com.onap.eelf" level="info" additivity="true">
+ <appender-ref ref="asyncEELF" />
+ </logger>
+ <logger name="org.onap.sdc.common.onaplog" level="all" additivity="true">
+ <appender-ref ref="asyncALL" />
+ </logger>
+ <logger name="org.onap.sdc.common.onaplog.OnapLoggerAudit" level="info" additivity="true">
+ <appender-ref ref="asyncEELFAudit" />
+ </logger>
+ <logger name="org.onap.sdc.common.onaplog.OnapLoggerMetric" level="info" additivity="true">
+ <appender-ref ref="asyncEELFMetrics" />
+ </logger>
+ <logger name="org.onap.sdc.common.onaplog.OnapLoggerError" level="error" additivity="true">
+ <appender-ref ref="asyncEELFError" />
+ </logger>
+ <logger name="org.onap.sdc.common.onaplog.OnapLoggerDebug" level="debug" additivity="true">
+ <appender-ref ref="asyncEELFDebug" />
+ </logger>
+ <root level="INFO">
+ <appender-ref ref="asyncEELF" />
+ </root>
+</configuration>
diff --git a/dcaedt_be/src/main/resources/schema.sql b/dcaedt_be/src/main/resources/schema.sql
new file mode 100644
index 0000000..487b5e5
--- /dev/null
+++ b/dcaedt_be/src/main/resources/schema.sql
@@ -0,0 +1,4 @@
+--DROP TABLE composition_status;
+CREATE TABLE IF NOT EXISTS composition_status (id varchar(20) NOT NULL, revision varchar(20) DEFAULT 0, name blob(1024), is_changed varchar(2), PRIMARY KEY (id, revision));
+CREATE TABLE IF NOT EXISTS test (id varchar(20) NOT NULL, name varchar(20), is_changed varchar(2), PRIMARY KEY (id));
+
diff --git a/dcaedt_be/src/main/webapp/META-INF/MANIFEST.MF b/dcaedt_be/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..67a9713
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Implementation-Title: dcae-be
+Implementation-Version: APPLICATION_VERSION
+Implementation-Vendor-Id: org.onap.sdc.dcae
+Build-Jdk: 1.7.0_45
+Created-By: Apache Maven 3.2.1
+Archiver-Version: Plexus Archiver
+Specification-Version: 1707.0.0-SNAPSHOT
diff --git a/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties
new file mode 100644
index 0000000..d5333c4
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/application.properties
@@ -0,0 +1,22 @@
+# Configure the server to run with SSL/TLS and using HTTPS
+server.port=8446
+server.contextPath=/
+##ScheduleTimer
+scheduled.timer.value=5000
+asdc_catalog_url=asdc
+#uri=https://dcaeDesigner:Aa123456@zldcrdm2sdc2abe01.3f1a87.rdm2.tci.att.com:8443#demo
+uri=https://dcaeDesigner:Aa123456@zldcrdm2sdc4cbe01.3f1a87.rdm2.tci.att.com:8443#demo
+toscalab_url=http://localhost:8080/
+blueprinter.uri=${toscalab_url}translate
+blueprinter.hcuri=${toscalab_url}healthcheck
+blueprinter.hcretrynum=3
+asdc_rootPath=/sdc/v1/catalog/
+healthpoller.fixedDelay=15000
+compositionConfig.isRuleEditorActive=false
+compositionConfig.flowTypes={"Syslog":{"entryPointPhaseName":"syslog_map","lastPhaseName":"map_publish"},\
+ "SNMP":{"entryPointPhaseName":"snmp_map","lastPhaseName":"map_publish"},\
+ "FOI":{"entryPointPhaseName":"foi_map","lastPhaseName":"map_publish"},\
+ "Guest OS":{"entryPointPhaseName":"guest_os_map","lastPhaseName":"map_publish"},\
+ "Status Poller":{"entryPointPhaseName":"status_poller_map","lastPhaseName":"map_publish"},\
+ "SNMP Polling":{"entryPointPhaseName":"snmp_polling_map","lastPhaseName":"map_publish"},\
+ "TCA Hi Lo":{"entryPointPhaseName":"tca_hi_lo_map","lastPhaseName":"map_publish"}}
diff --git a/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/error-configuration.yaml b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/error-configuration.yaml
new file mode 100644
index 0000000..c60465c
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/error-configuration.yaml
@@ -0,0 +1,286 @@
+# DCAE-D Errors
+errors:
+ OK: {
+ code: 200,
+ message: "OK",
+ messageId: "200"
+ }
+ CREATED: {
+ code: 201,
+ message: "OK",
+ messageId: "201"
+ }
+ NO_CONTENT: {
+ code: 204,
+ message: "No Content",
+ messageId: "204"
+ }
+#--------POL4050-----------------------------
+ NOT_ALLOWED: {
+ code: 405,
+ message: "Error: Method not allowed.",
+ messageId: "POL4050"
+ }
+#--------POL5000-----------------------------
+ GENERAL_ERROR: {
+ code: 500,
+ message: "Error: Internal Server Error. Please try again later.",
+ messageId: "POL5000"
+ }
+#--------POL5500-----------------------------
+ CATALOG_NOT_AVAILABLE: {
+ code: 502,
+ message: "Error - SDC Catalog currently not available. Please try again later",
+ messageId: "POL5500"
+ }
+#--------POL5501-----------------------------
+ AUTH_ERROR: {
+ code: 502,
+ message: "Error – connection to SDC catalog could not be authenticated. Please contact your administrator",
+ messageId: "POL5501"
+ }
+
+#---------SVC4000-----------------------------
+ INVALID_CONTENT: {
+ code: 400,
+ message: "Error: Invalid content.",
+ messageId: "SVC4000"
+ }
+
+#---------SVC6001-----------------------------
+ NOT_FOUND: {
+ code: 404,
+ message: "No Monitoring Templates were found.",
+ messageId: "SVC6001"
+ }
+#---------SVC6005-----------------------------
+ CONFIGURATION_ERROR: {
+ code: 500,
+ message: "Error – Failed to find configuration.",
+ messageId: "SVC6005"
+ }
+#---------SVC6006-----------------------------
+ VES_SCHEMA_NOT_FOUND: {
+ code: 500,
+ message: "Error – Failed to find VES Schema definitions.",
+ messageId: "SVC6006"
+ }
+#---------SVC6007-----------------------------
+# %1 - VES Schema filename
+# %2 - error reason
+ VES_SCHEMA_INVALID: {
+ code: 500,
+ message: "Error – Failed to parse VES Schema file '%1'. [%2]",
+ messageId: "SVC6007"
+ }
+#---------SVC6008-----------------------------
+ FLOW_TYPES_CONFIGURATION_ERROR: {
+ code: 500,
+ message: "Error – Failed to read flow type definitions.",
+ messageId: "SVC6008"
+ }
+#---------SVC6010-----------------------------
+ CLONE_FAILED: {
+ code: 409,
+ message: "Error – could not import Monitoring Template.",
+ messageId: "SVC6010"
+ }
+#---------SVC6020-----------------------------
+ EMPTY_SERVICE_LIST: {
+ code: 404,
+ message: "Service List is not available.",
+ messageId: "SVC6020"
+ }
+#---------SVC6021-----------------------------
+ MONITORING_TEMPLATE_ATTACHMENT_ERROR: {
+ code: 409,
+ message: "Error – Monitoring Template is not available for editing.",
+ messageId: "SVC6021"
+ }
+
+#---------SVC6031-----------------------------
+# %1 - Component Name
+ MISSING_TOSCA_FILE: {
+ code: 404,
+ message: "Error – Could not read component %1 details.",
+ messageId: "SVC6031"
+ }
+#---------SVC6032-----------------------------
+# %1 - Component Name
+ VALIDATE_TOSCA_ERROR: {
+ code: 500,
+ message: "Error – Component %1 details could not be parsed.",
+ messageId: "SVC6032"
+ }
+#---------SVC6033-----------------------------
+ SUBMIT_BLUEPRINT_ERROR: {
+ code: 500,
+ message: "Error –Failed to submit blueprint.",
+ messageId: "SVC6033"
+ }
+#---------SVC6034-----------------------------
+# %1 -VFCMT Name
+ GENERATE_BLUEPRINT_ERROR: {
+ code: 500,
+ message: "Error – Failed to generate blueprint file for Monitoring Template %1.",
+ messageId: "SVC6034"
+ }
+#---------SVC6035-----------------------------
+# %1 - the error reason
+ INVALID_RULE_FORMAT: {
+ code: 400,
+ message: "Error - Rule format is invalid: %1.",
+ messageId: "SVC6035"
+ }
+#---------SVC6036-----------------------------
+ SAVE_RULE_FAILED: {
+ code: 409,
+ message: "Error - Failed to save rule. Internal persistence error",
+ messageId: "SVC6036"
+ }
+
+#---------SVC6038-----------------------------
+# %1 - VFCMT uuid
+ RESOURCE_NOT_VFCMT_ERROR: {
+ code: 400,
+ message: "Resource with uuid %1 is either not of resourceType='VFCMT' or not of category='Template'",
+ messageId: "SVC6038"
+ }
+#---------SVC6039-----------------------------
+# %1 - serviceUuid
+# %2 - vfiName
+ VFI_FETCH_ERROR: {
+ code: 404,
+ message: "Service %1 does not contain a VFI named %2",
+ messageId: "SVC6039"
+ }
+#-----------SVC6085---------------------------
+# %1 - current user id
+# %2 - resource/service name
+# %3 - last modifier user id
+ USER_CONFLICT: {
+ code: 403,
+ message: "Error: User conflict. Operation not allowed for user %1 on asset %2 checked out by %3.",
+ messageId: "SVC6085"
+ }
+
+#---------SVC6100-----------------------------
+ MISSING_RULE_DESCRIPTION: {
+ code: 400,
+ message: "Please enter a valid rule description.",
+ messageId: "SVC6100"
+ }
+#---------SVC6101-----------------------------
+ MISSING_ACTION: {
+ code: 400,
+ message: "Rule must have at least one action.",
+ messageId: "SVC6101"
+ }
+
+#---------SVC6104-----------------------------
+# %1 - action target
+ MISSING_CONCAT_VALUE: {
+ code: 400,
+ message: "Please fill all from fields of concat action to %1",
+ messageId: "SVC6104"
+ }
+#---------SVC6105-----------------------------
+# %1 - condition group type
+ INVALID_GROUP_CONDITION: {
+ code: 400,
+ message: "Undefined condition group type: %1",
+ messageId: "SVC6105"
+ }
+
+#---------SVC6106-----------------------------
+ MISSING_CONDITION_ITEM: {
+ code: 400,
+ message: "Please enter all condition items",
+ messageId: "SVC6106"
+ }
+#---------SVC6107-----------------------------
+# %1 - left/right
+ MISSING_OPERAND: {
+ code: 400,
+ message: "Please enter the %1 operand field",
+ messageId: "SVC6107"
+ }
+#---------SVC6108-----------------------------
+# %1 - operator
+ INVALID_OPERATOR: {
+ code: 400,
+ message: "Undefined operator: %1",
+ messageId: "SVC6108"
+ }
+#---------SVC6109-----------------------------
+# %1 - action target
+ MISSING_ENTRY: {
+ code: 400,
+ message: "Please fill all key-value pairs of map action to %1",
+ messageId: "SVC6109"
+ }
+#---------SVC6110-----------------------------
+# %1 - action target
+ MISSING_DEFAULT_VALUE: {
+ code: 400,
+ message: "Please fill the default value of map action to %1",
+ messageId: "SVC6110"
+ }
+#---------SVC6111-----------------------------
+ DUPLICATE_KEY: {
+ code: 400,
+ message: "Error: Duplication in map keys exists, please modify rule configuration",
+ messageId: "SVC6111"
+ }
+#---------SVC6112-----------------------------
+# %1 - dependent actions
+ ACTION_DEPENDENCY: {
+ code: 400,
+ message: "A circular dependency was detected between actions. The following fields should be resolved: %1",
+ messageId: "SVC6112"
+ }
+#---------SVC6113-----------------------------
+# %1 - dependent rule ids
+# %2 - dependent action targets
+ RULE_DEPENDENCY: {
+ code: 400,
+ message: "A circular dependency was detected between rules: %1 within fields: %2",
+ messageId: "SVC6113"
+ }
+#---------SVC6114-----------------------------
+# %1 - dcae component name
+ NODE_NOT_FOUND: {
+ code: 400,
+ message: "DCAE component %1 not found in composition",
+ messageId: "SVC6114"
+ }
+#---------SVC6115-----------------------------
+ DELETE_RULE_FAILED: {
+ code: 409,
+ message: "Delete rule failed. Internal persistence error",
+ messageId: "SVC6115"
+ }
+#---------SVC6116-----------------------------
+# %1 - reason
+ TRANSLATE_FAILED: {
+ code: 400,
+ message: "Translation failed. Reason: %1",
+ messageId: "SVC6116"
+ }
+
+#---------SVC6117-----------------------------
+# %1 - field name
+# %2 - action type
+# %3 - action target
+ MISSING_ACTION_FIELD: {
+ code: 400,
+ message: "Please fill the %1 field of %2 action to %3",
+ messageId: "SVC6117"
+ }
+
+#---------SVC6118-----------------------------
+ DELETE_BLUEPRINT_FAILED: {
+ code: 400,
+ message: "The request was partially successful. Removing the attached Blueprint from the service has failed. You must manually delete the artifact.",
+ messageId: "SVC6118"
+ } \ No newline at end of file
diff --git a/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v4.1.json b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v4.1.json
new file mode 100644
index 0000000..2f86c38
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v4.1.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v5.3.json b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v5.3.json
new file mode 100644
index 0000000..fca55d9
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/WEB-INF/config/dcae-be/ves-schema/CommonEventFormat_v5.3.json
@@ -0,0 +1,2004 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": {
+ "type": "string"
+ },
+ "numberInUse": {
+ "type": "integer"
+ }
+ },
+ "required": ["codecIdentifier",
+ "numberInUse"]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": ["heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"]
+ },
+ "eventDomainThrottleSpecification": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "heartbeatInterval": {
+ "type": "integer"
+ },
+ "measurementInterval": {
+ "type": "integer"
+ }
+ },
+ "required": ["commandType"]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/command"
+ },
+ "minItems": 0
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": ["fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "sipSignaling",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert",
+ "voiceQuality"]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventName": {
+ "description": "unique event name",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "for example - applicationVnf, guestOS, hostOS, platform",
+ "type": "string"
+ },
+ "internalHeaderFields": {
+ "$ref": "#/definitions/internalHeaderFields"
+ },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "nfcNamingCode": {
+ "description": "3 character network function component type, aligned with vfc naming standards",
+ "type": "string"
+ },
+ "nfNamingCode": {
+ "description": "4 character network function type, aligned with vnf naming standards",
+ "type": "string"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": ["High",
+ "Medium",
+ "Normal",
+ "Low"]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an EMS name; may be the same as sourceName",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": ["domain",
+ "eventId",
+ "eventName",
+ "lastEpochMicrosec",
+ "priority",
+ "reportingEntityName",
+ "sequence",
+ "sourceName",
+ "startEpochMicrosec",
+ "version"]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": {
+ "type": "string",
+ "enum": ["CRIT",
+ "MAJ"]
+ },
+ "name": {
+ "type": "string"
+ },
+ "thresholdCrossed": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "required": ["criticality",
+ "name",
+ "thresholdCrossed",
+ "value"]
+ },
+ "cpuUsage": {
+ "description": "usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": {
+ "description": "cpu identifer",
+ "type": "string"
+ },
+ "cpuIdle": {
+ "description": "percentage of CPU time spent in the idle task",
+ "type": "number"
+ },
+ "cpuUsageInterrupt": {
+ "description": "percentage of time spent servicing interrupts",
+ "type": "number"
+ },
+ "cpuUsageNice": {
+ "description": "percentage of time spent running user space processes that have been niced",
+ "type": "number"
+ },
+ "cpuUsageSoftIrq": {
+ "description": "percentage of time spent handling soft irq interrupts",
+ "type": "number"
+ },
+ "cpuUsageSteal": {
+ "description": "percentage of time spent in involuntary wait which is neither user, system or idle time and is effectively time that went missing",
+ "type": "number"
+ },
+ "cpuUsageSystem": {
+ "description": "percentage of time spent on system tasks running the kernel",
+ "type": "number"
+ },
+ "cpuUsageUser": {
+ "description": "percentage of time spent running un-niced user space processes",
+ "type": "number"
+ },
+ "cpuWait": {
+ "description": "percentage of CPU time spent waiting for I/O operations to complete",
+ "type": "number"
+ },
+ "percentUsage": {
+ "description": "aggregate cpu usage of the virtual machine on which the VNFC reporting the event is running",
+ "type": "number"
+ }
+ },
+ "required": ["cpuIdentifier",
+ "percentUsage"]
+ },
+ "diskUsage": {
+ "description": "usage of an identified disk",
+ "type": "object",
+ "properties": {
+ "diskIdentifier": {
+ "description": "disk identifier",
+ "type": "string"
+ },
+ "diskIoTimeAvg": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the average over the measurement interval",
+ "type": "number"
+ },
+ "diskIoTimeLast": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the last value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskIoTimeMax": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the maximum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskIoTimeMin": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the minimum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadAvg": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadLast": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the last value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadMax": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the maximum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadMin": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the minimum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteAvg": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteLast": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the last value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteMax": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the maximum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteMin": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the minimum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadAvg": {
+ "description": "number of octets per second read from a disk or partition; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadLast": {
+ "description": "number of octets per second read from a disk or partition; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadMax": {
+ "description": "number of octets per second read from a disk or partition; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadMin": {
+ "description": "number of octets per second read from a disk or partition; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteAvg": {
+ "description": "number of octets per second written to a disk or partition; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteLast": {
+ "description": "number of octets per second written to a disk or partition; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteMax": {
+ "description": "number of octets per second written to a disk or partition; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteMin": {
+ "description": "number of octets per second written to a disk or partition; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadAvg": {
+ "description": "number of read operations per second issued to the disk; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadLast": {
+ "description": "number of read operations per second issued to the disk; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadMax": {
+ "description": "number of read operations per second issued to the disk; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadMin": {
+ "description": "number of read operations per second issued to the disk; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteAvg": {
+ "description": "number of write operations per second issued to the disk; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteLast": {
+ "description": "number of write operations per second issued to the disk; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteMax": {
+ "description": "number of write operations per second issued to the disk; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteMin": {
+ "description": "number of write operations per second issued to the disk; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsAvg": {
+ "description": "queue size of pending I/O operations per second; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsLast": {
+ "description": "queue size of pending I/O operations per second; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsMax": {
+ "description": "queue size of pending I/O operations per second; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsMin": {
+ "description": "queue size of pending I/O operations per second; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadAvg": {
+ "description": "milliseconds a read operation took to complete; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadLast": {
+ "description": "milliseconds a read operation took to complete; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadMax": {
+ "description": "milliseconds a read operation took to complete; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadMin": {
+ "description": "milliseconds a read operation took to complete; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteAvg": {
+ "description": "milliseconds a write operation took to complete; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteLast": {
+ "description": "milliseconds a write operation took to complete; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteMax": {
+ "description": "milliseconds a write operation took to complete; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteMin": {
+ "description": "milliseconds a write operation took to complete; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ }
+ },
+ "required": ["diskIdentifier"]
+ },
+ "endOfCallVqmSummaries": {
+ "description": "provides end of call voice quality metrics",
+ "type": "object",
+ "properties": {
+ "adjacencyName": {
+ "description": " adjacency name",
+ "type": "string"
+ },
+ "endpointDescription": {
+ "description": "Either Caller or Callee",
+ "type": "string",
+ "enum": ["Caller",
+ "Callee"]
+ },
+ "endpointJitter": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpOctetsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpOctetsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpOctetsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpPacketsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpPacketsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpPacketsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "localJitter": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpOctetsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpOctetsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpOctetsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpPacketsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpPacketsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpPacketsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "mosCqe": {
+ "description": "1-5 1dp",
+ "type": "number"
+ },
+ "packetsLost": {
+ "description": "",
+ "type": "number"
+ },
+ "packetLossPercent": {
+ "description": "Calculated percentage packet loss based on Endpoint RTP packets lost (as reported in RTCP) and Local RTP packets sent. Direction is based on Endpoint description (Caller, Callee). Decimal (2 dp)",
+ "type": "number"
+ },
+ "rFactor": {
+ "description": "0-100",
+ "type": "number"
+ },
+ "roundTripDelay": {
+ "description": "millisecs",
+ "type": "number"
+ }
+ },
+ "required": ["adjacencyName",
+ "endpointDescription"]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": {
+ "$ref": "#/definitions/commonEventHeader"
+ },
+ "faultFields": {
+ "$ref": "#/definitions/faultFields"
+ },
+ "heartbeatFields": {
+ "$ref": "#/definitions/heartbeatFields"
+ },
+ "measurementsForVfScalingFields": {
+ "$ref": "#/definitions/measurementsForVfScalingFields"
+ },
+ "mobileFlowFields": {
+ "$ref": "#/definitions/mobileFlowFields"
+ },
+ "otherFields": {
+ "$ref": "#/definitions/otherFields"
+ },
+ "sipSignalingFields": {
+ "$ref": "#/definitions/sipSignalingFields"
+ },
+ "stateChangeFields": {
+ "$ref": "#/definitions/stateChangeFields"
+ },
+ "syslogFields": {
+ "$ref": "#/definitions/syslogFields"
+ },
+ "thresholdCrossingAlertFields": {
+ "$ref": "#/definitions/thresholdCrossingAlertFields"
+ },
+ "voiceQualityFields": {
+ "$ref": "#/definitions/voiceQualityFields"
+ }
+ },
+ "required": ["commonEventHeader"]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": ["eventDomain"]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": ["normal",
+ "throttled"]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "$ref": "#/definitions/eventDomainThrottleSpecificationList"
+ }
+ },
+ "required": ["eventThrottlingMode"]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventCategory": {
+ "description": "Event category, for example: license, link, routing, security, signaling",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity",
+ "type": "string",
+ "enum": ["CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: card, host, other, port, portThreshold, router, slotThreshold, switch, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": ["Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"]
+ }
+ },
+ "required": ["alarmCondition",
+ "eventSeverity",
+ "eventSourceType",
+ "faultFieldsVersion",
+ "specificProblem",
+ "vfStatus"]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": {
+ "type": "string"
+ },
+ "featureUtilization": {
+ "type": "integer"
+ }
+ },
+ "required": ["featureIdentifier",
+ "featureUtilization"]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "required": ["name",
+ "value"]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": {
+ "type": "number"
+ },
+ "blockIops": {
+ "type": "number"
+ },
+ "blockUsed": {
+ "type": "number"
+ },
+ "ephemeralConfigured": {
+ "type": "number"
+ },
+ "ephemeralIops": {
+ "type": "number"
+ },
+ "ephemeralUsed": {
+ "type": "number"
+ },
+ "filesystemName": {
+ "type": "string"
+ }
+ },
+ "required": ["blockConfigured",
+ "blockIops",
+ "blockUsed",
+ "ephemeralConfigured",
+ "ephemeralIops",
+ "ephemeralUsed",
+ "filesystemName"]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [{
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [{
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [{
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": ["avgBitErrorRate",
+ "avgPacketDelayVariation",
+ "avgPacketLatency",
+ "avgReceiveThroughput",
+ "avgTransmitThroughput",
+ "flowActivationEpoch",
+ "flowActivationMicrosec",
+ "flowDeactivationEpoch",
+ "flowDeactivationMicrosec",
+ "flowDeactivationTime",
+ "flowStatus",
+ "maxPacketDelayVariation",
+ "numActivationFailures",
+ "numBitErrors",
+ "numBytesReceived",
+ "numBytesTransmitted",
+ "numDroppedPackets",
+ "numL7BytesReceived",
+ "numL7BytesTransmitted",
+ "numLostPackets",
+ "numOutOfOrderPackets",
+ "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries",
+ "numTimeouts",
+ "numTunneledL7BytesReceived",
+ "roundTripTime",
+ "timeToFirstByte"]
+ },
+ "heartbeatFields": {
+ "description": "optional field block for fields specific to heartbeat events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional heartbeat fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "heartbeatFieldsVersion": {
+ "description": "version of the heartbeatFields block",
+ "type": "number"
+ },
+ "heartbeatInterval": {
+ "description": "current heartbeat interval in seconds",
+ "type": "integer"
+ }
+ },
+ "required": ["heartbeatFieldsVersion",
+ "heartbeatInterval"]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "jsonObject": {
+ "description": "json object schema, name and other meta-information along with one or more object instances",
+ "type": "object",
+ "properties": {
+ "objectInstances": {
+ "description": "one or more instances of the jsonObject",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/jsonObjectInstance"
+ }
+ },
+ "objectName": {
+ "description": "name of the JSON Object",
+ "type": "string"
+ },
+ "objectSchema": {
+ "description": "json schema for the object",
+ "type": "string"
+ },
+ "objectSchemaUrl": {
+ "description": "Url to the json schema for the object",
+ "type": "string"
+ },
+ "nfSubscribedObjectName": {
+ "description": "name of the object associated with the nfSubscriptonId",
+ "type": "string"
+ },
+ "nfSubscriptionId": {
+ "description": "identifies an openConfig telemetry subscription on a network function, which configures the network function to send complex object data associated with the jsonObject",
+ "type": "string"
+ }
+ },
+ "required": ["objectInstances",
+ "objectName"]
+ },
+ "jsonObjectInstance": {
+ "description": "meta-information about an instance of a jsonObject along with the actual object instance",
+ "type": "object",
+ "properties": {
+ "objectInstance": {
+ "description": "an instance conforming to the jsonObject schema",
+ "type": "object"
+ },
+ "objectInstanceEpochMicrosec": {
+ "description": "the unix time aka epoch time associated with this objectInstance--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "objectKeys": {
+ "description": "an ordered set of keys that identifies this particular instance of jsonObject",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/key"
+ }
+ }
+ },
+ "required": ["objectInstance"]
+ },
+ "key": {
+ "description": "tuple which provides the name of a key along with its value and relative order",
+ "type": "object",
+ "properties": {
+ "keyName": {
+ "description": "name of the key",
+ "type": "string"
+ },
+ "keyOrder": {
+ "description": "relative sequence or order of the key with respect to other keys",
+ "type": "integer"
+ },
+ "keyValue": {
+ "description": "value of the key",
+ "type": "string"
+ }
+ },
+ "required": ["keyName"]
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": {
+ "type": "number"
+ },
+ "highEndOfLatencyBucket": {
+ "type": "number"
+ },
+ "lowEndOfLatencyBucket": {
+ "type": "number"
+ }
+ },
+ "required": ["countsInTheBucket"]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional name-value-pair fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalMeasurements": {
+ "description": "array of named name-value-pair arrays",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/namedArrayOfFields"
+ }
+ },
+ "additionalObjects": {
+ "description": "array of JSON objects described by name, schema and other meta-information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/jsonObject"
+ }
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "integer"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "integer"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "diskUsageArray": {
+ "description": "usage of an array of disks",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/diskUsage"
+ }
+ },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryUsageArray": {
+ "description": "memory usage of an array of VMs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/memoryUsage"
+ }
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "integer"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "integer"
+ },
+ "vNicPerformanceArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicPerformance"
+ }
+ }
+ },
+ "required": ["measurementInterval",
+ "measurementsForVfScalingVersion"]
+ },
+ "memoryUsage": {
+ "description": "memory usage of an identified virtual machine",
+ "type": "object",
+ "properties": {
+ "memoryBuffered": {
+ "description": "kibibytes of temporary storage for raw disk blocks",
+ "type": "number"
+ },
+ "memoryCached": {
+ "description": "kibibytes of memory used for cache",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "kibibytes of memory configured in the virtual machine on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryFree": {
+ "description": "kibibytes of physical RAM left unused by the system",
+ "type": "number"
+ },
+ "memorySlabRecl": {
+ "description": "the part of the slab that can be reclaimed such as caches measured in kibibytes",
+ "type": "number"
+ },
+ "memorySlabUnrecl": {
+ "description": "the part of the slab that cannot be reclaimed even when lacking memory measured in kibibytes",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "total memory minus the sum of free, buffered, cached and slab memory measured in kibibytes",
+ "type": "number"
+ },
+ "vmIdentifier": {
+ "description": "virtual machine identifier associated with the memory metrics",
+ "type": "string"
+ }
+ },
+ "required": ["memoryFree",
+ "memoryUsed",
+ "vmIdentifier"]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": {
+ "$ref": "#/definitions/gtpPerFlowMetrics"
+ },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "integer"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "integer"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "integer"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": ["flowDirection",
+ "gtpPerFlowMetrics",
+ "ipProtocolType",
+ "ipVersion",
+ "mobileFlowFieldsVersion",
+ "otherEndpointIpAddress",
+ "otherEndpointPort",
+ "reportingEndpointIpAddr",
+ "reportingEndpointPort"]
+ },
+ "namedArrayOfFields": {
+ "description": "an array of name value pairs along with a name for the array",
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "arrayOfFields": {
+ "description": "array of name value pairs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": ["name",
+ "arrayOfFields"]
+ },
+ "otherFields": {
+ "description": "fields for events belonging to the 'other' domain of the commonEventHeader domain enumeration",
+ "type": "object",
+ "properties": {
+ "hashOfNameValuePairArrays": {
+ "description": "array of named name-value-pair arrays",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/namedArrayOfFields"
+ }
+ },
+ "jsonObjects": {
+ "description": "array of JSON objects described by name, schema and other meta-information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/jsonObject"
+ }
+ },
+ "nameValuePairs": {
+ "description": "array of name-value pairs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "otherFieldsVersion": {
+ "description": "version of the otherFields block",
+ "type": "number"
+ }
+ },
+ "required": ["otherFieldsVersion"]
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": ["messageId",
+ "text"]
+ },
+ "sipSignalingFields": {
+ "description": "sip signaling fields",
+ "type": "object",
+ "properties": {
+ "additionalInformation": {
+ "description": "additional sip signaling fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "compressedSip": {
+ "description": "the full SIP request/response including headers and bodies",
+ "type": "string"
+ },
+ "correlator": {
+ "description": "this is the same for all events on this call",
+ "type": "string"
+ },
+ "localIpAddress": {
+ "description": "IP address on VNF",
+ "type": "string"
+ },
+ "localPort": {
+ "description": "port on VNF",
+ "type": "string"
+ },
+ "remoteIpAddress": {
+ "description": "IP address of peer endpoint",
+ "type": "string"
+ },
+ "remotePort": {
+ "description": "port of peer endpoint",
+ "type": "string"
+ },
+ "sipSignalingFieldsVersion": {
+ "description": "version of the sipSignalingFields block",
+ "type": "number"
+ },
+ "summarySip": {
+ "description": "the SIP Method or Response (‘INVITE’, ‘200 OK’, ‘BYE’, etc)",
+ "type": "string"
+ },
+ "vendorVnfNameFields": {
+ "$ref": "#/definitions/vendorVnfNameFields"
+ }
+ },
+ "required": ["correlator",
+ "localIpAddress",
+ "localPort",
+ "remoteIpAddress",
+ "remotePort",
+ "sipSignalingFieldsVersion",
+ "vendorVnfNameFields"]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": ["inService",
+ "maintenance",
+ "outOfService"]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": ["inService",
+ "maintenance",
+ "outOfService"]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": ["newState",
+ "oldState",
+ "stateChangeFieldsVersion",
+ "stateInterface"]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": ["nvPairFieldName",
+ "suppressedNvPairNames"]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed provided as name=value delimited by a pipe ‘|’ symbol, for example: 'name1=value1|name2=value2|…'",
+ "type": "string"
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "integer"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "integer"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string",
+ "enum": ["Alert",
+ "Critical",
+ "Debug",
+ "Emergency",
+ "Error",
+ "Info",
+ "Notice",
+ "Warning"]
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": ["eventSourceType",
+ "syslogFieldsVersion",
+ "syslogMsg",
+ "syslogTag"]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": ["CLEAR",
+ "CONT",
+ "SET"]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": ["CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": ["CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": ["additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp",
+ "thresholdCrossingFieldsVersion"]
+ },
+ "vendorVnfNameFields": {
+ "description": "provides vendor, vnf and vfModule identifying information",
+ "type": "object",
+ "properties": {
+ "vendorName": {
+ "description": "VNF vendor name",
+ "type": "string"
+ },
+ "vfModuleName": {
+ "description": "ASDC vfModuleName for the vfModule generating the event",
+ "type": "string"
+ },
+ "vnfName": {
+ "description": "ASDC modelName for the VNF generating the event",
+ "type": "string"
+ }
+ },
+ "required": ["vendorName"]
+ },
+ "vNicPerformance": {
+ "description": "describes the performance and errors of an identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "receivedBroadcastPacketsAccumulated": {
+ "description": "Cumulative count of broadcast packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedBroadcastPacketsDelta": {
+ "description": "Count of broadcast packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedDiscardedPacketsAccumulated": {
+ "description": "Cumulative count of discarded packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedDiscardedPacketsDelta": {
+ "description": "Count of discarded packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedErrorPacketsAccumulated": {
+ "description": "Cumulative count of error packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedErrorPacketsDelta": {
+ "description": "Count of error packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedMulticastPacketsAccumulated": {
+ "description": "Cumulative count of multicast packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedMulticastPacketsDelta": {
+ "description": "Count of multicast packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedOctetsAccumulated": {
+ "description": "Cumulative count of octets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedOctetsDelta": {
+ "description": "Count of octets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedTotalPacketsAccumulated": {
+ "description": "Cumulative count of all packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedTotalPacketsDelta": {
+ "description": "Count of all packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedUnicastPacketsAccumulated": {
+ "description": "Cumulative count of unicast packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedUnicastPacketsDelta": {
+ "description": "Count of unicast packets received within the measurement interval",
+ "type": "number"
+ },
+ "transmittedBroadcastPacketsAccumulated": {
+ "description": "Cumulative count of broadcast packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedBroadcastPacketsDelta": {
+ "description": "Count of broadcast packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedDiscardedPacketsAccumulated": {
+ "description": "Cumulative count of discarded packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedDiscardedPacketsDelta": {
+ "description": "Count of discarded packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedErrorPacketsAccumulated": {
+ "description": "Cumulative count of error packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedErrorPacketsDelta": {
+ "description": "Count of error packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedMulticastPacketsAccumulated": {
+ "description": "Cumulative count of multicast packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedMulticastPacketsDelta": {
+ "description": "Count of multicast packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedOctetsAccumulated": {
+ "description": "Cumulative count of octets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedOctetsDelta": {
+ "description": "Count of octets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedTotalPacketsAccumulated": {
+ "description": "Cumulative count of all packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedTotalPacketsDelta": {
+ "description": "Count of all packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedUnicastPacketsAccumulated": {
+ "description": "Cumulative count of unicast packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedUnicastPacketsDelta": {
+ "description": "Count of unicast packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "valuesAreSuspect": {
+ "description": "Indicates whether vNicPerformance values are likely inaccurate due to counter overflow or other condtions",
+ "type": "string",
+ "enum": ["true",
+ "false"]
+ },
+ "vNicIdentifier": {
+ "description": "vNic identification",
+ "type": "string"
+ }
+ },
+ "required": ["valuesAreSuspect",
+ "vNicIdentifier"]
+ },
+ "voiceQualityFields": {
+ "description": "provides statistics related to customer facing voice products",
+ "type": "object",
+ "properties": {
+ "additionalInformation": {
+ "description": "additional voice quality fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "calleeSideCodec": {
+ "description": "callee codec for the call",
+ "type": "string"
+ },
+ "callerSideCodec": {
+ "description": "caller codec for the call",
+ "type": "string"
+ },
+ "correlator": {
+ "description": "this is the same for all events on this call",
+ "type": "string"
+ },
+ "endOfCallVqmSummaries": {
+ "$ref": "#/definitions/endOfCallVqmSummaries"
+ },
+ "phoneNumber": {
+ "description": "phone number associated with the correlator",
+ "type": "string"
+ },
+ "midCallRtcp": {
+ "description": "Base64 encoding of the binary RTCP data excluding Eth/IP/UDP headers",
+ "type": "string"
+ },
+ "vendorVnfNameFields": {
+ "$ref": "#/definitions/vendorVnfNameFields"
+ },
+ "voiceQualityFieldsVersion": {
+ "description": "version of the voiceQualityFields block",
+ "type": "number"
+ }
+ },
+ "required": ["calleeSideCodec",
+ "callerSideCodec",
+ "correlator",
+ "midCallRtcp",
+ "vendorVnfNameFields",
+ "voiceQualityFieldsVersion"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {
+ "$ref": "#/definitions/event"
+ }
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/main/webapp/WEB-INF/jetty-web.xml b/dcaedt_be/src/main/webapp/WEB-INF/jetty-web.xml
new file mode 100644
index 0000000..6d5a8f6
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/WEB-INF/jetty-web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE Configure PUBLIC
+ "-//Mort Bay Consulting//DTD Configure//EN"
+ "http://www.eclipse.org/jetty/configure_9_0.dtd">
+
+<Configure class="org.eclipse.jetty.webapp.WebAppContext">
+ <Set name="contextPath">/dcae</Set>
+ <Set name="parentLoaderPriority">true</Set>
+ <!-- <Call name="addServerClass">
+ <Arg>-org.eclise.jetty.util</Arg>
+ </Call> -->
+</Configure>
diff --git a/dcaedt_be/src/main/webapp/WEB-INF/web.xml b/dcaedt_be/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..ab6a37f
--- /dev/null
+++ b/dcaedt_be/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+</web-app>
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/VesStructureLoaderMock.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/VesStructureLoaderMock.java
new file mode 100644
index 0000000..34db9fa
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/VesStructureLoaderMock.java
@@ -0,0 +1,116 @@
+package org.onap.sdc.dcae;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.onap.sdc.dcae.ves.EventListenerDefinition;
+import org.onap.sdc.dcae.ves.VesDataItemsDefinition;
+import org.onap.sdc.dcae.ves.VesDataTypeDefinition;
+import org.onap.sdc.dcae.ves.VesJsonDeserializer;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FilenameFilter;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class VesStructureLoaderMock {
+
+ private Map<String, EventListenerDefinition> eventListeners = new HashMap<>();
+ private Type type = new TypeToken<VesDataItemsDefinition>() {
+ }.getType();
+ private Gson gson = new GsonBuilder().registerTypeAdapter(type, new VesJsonDeserializer()).create();
+ private final String schemaNamePrefix = "CommonEventFormat_v";
+ private final String schemaNameSuffix = ".json";
+ private List<String> initErrors;
+
+ public VesStructureLoaderMock() {
+ this(true);
+ }
+
+ public VesStructureLoaderMock(boolean validateAndResolve) {
+ this(validateAndResolve, System.getProperty("user.dir") + "/src/test/resources/ves-schema");
+ }
+
+ public VesStructureLoaderMock(boolean validateAndResolve, String path) {
+ initErrors = init(validateAndResolve, path);
+ }
+
+ public List<String> init(boolean validateAndResolve, String pathToSchemaDir) {
+
+ List<String> parseErrors = new ArrayList<>();
+ File dir = new File(pathToSchemaDir);
+ File[] files = dir.listFiles(new FilenameFilter() {
+ @Override public boolean accept(File dir, String name) {
+ return name.startsWith(schemaNamePrefix) && name.endsWith(schemaNameSuffix);
+ }
+ });
+ if (ArrayUtils.isEmpty(files)) {
+ parseErrors.add("No VES schema files found");
+ } else {
+ for (File f : files) {
+ String error = parseJsonFileAndSaveToMap(f, validateAndResolve);
+ if (StringUtils.isNotBlank(error)) {
+ parseErrors.add("Error: parsing VES schema file " + f.getName() + " failed due to " + error);
+ }
+ }
+ }
+ return parseErrors;
+
+ }
+
+ public Map<String, VesDataTypeDefinition> getEventListenerDefinitionByVersion(String version) {
+ return eventListeners.get(version).getProperties().get(EventListenerDefinition.EVENT_ROOT).getProperties();
+ }
+
+ public Set<String> getAvailableVersionsList() {
+ return eventListeners.keySet();
+ }
+
+ public Map<String, Set<String>> getAvailableVersionsAndEventTypes() {
+ return eventListeners.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> getEventListenerDefinitionByVersion(e.getKey()).keySet()));
+ }
+
+ public Set<String> getEventTypeListByVersion(String version) {
+ return getEventListenerDefinitionByVersion(version).keySet();
+ }
+
+ public String getVersionFromFileName(String fileName) {
+ return fileName.replace(schemaNamePrefix, "").replace(schemaNameSuffix, "");
+ }
+
+ private String parseJsonFileAndSaveToMap(File file, boolean validateAndResolve) {
+ String validationError = null;
+ try {
+ EventListenerDefinition eventListener = gson.fromJson(new FileReader(file), EventListenerDefinition.class);
+ if (validateAndResolve)
+ validationError = getValidatorMessage(eventListener);
+ if (StringUtils.isEmpty(validationError))
+ eventListeners.put(getVersionFromFileName(file.getName()), eventListener);
+ } catch (FileNotFoundException | JsonIOException | JsonSyntaxException e) {
+ validationError = e.getMessage();
+ }
+ return validationError;
+ }
+
+ public Map<String, EventListenerDefinition> getEventListeners() {
+ return eventListeners;
+ }
+
+ public List<String> getInitErrors() {
+ return initErrors;
+ }
+
+ private String getValidatorMessage(EventListenerDefinition eventListenerDefinition) {
+ String validationError = eventListenerDefinition.validate();
+ if (StringUtils.isBlank(validationError))
+ validationError = eventListenerDefinition.resolveRefTypes();
+ return validationError;
+ }
+}
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java
new file mode 100644
index 0000000..c353701
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/ReferenceBusinessLogicTest.java
@@ -0,0 +1,123 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.sdc.dcae.client.ISdcClient;
+import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent;
+import org.onap.sdc.dcae.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+
+import java.util.*;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ReferenceBusinessLogicTest {
+ private String userId = "me";
+ private String requestId = "1";
+ private String monitoringComponentName = "monitoringComponentName";
+ private String serviceUuid = "serviceUuid";
+ private String vfiName = "vfiName";
+
+ @Mock
+ private ISdcClient sdcClientMock;
+ @Mock
+ private ResourceDetailed templateMC;
+
+ @InjectMocks
+ ReferenceBusinessLogic classUnderTest;
+
+ @Before
+ public void setup(){
+ classUnderTest.setSdcRestClient(sdcClientMock);
+ new ErrorConfigurationLoader(System.getProperty("user.dir")+"/src/main/webapp/WEB-INF");
+ }
+
+ @Test
+ public void successfulFetchMonitoringComponents() throws Exception {
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ ExternalReferencesMap refs = new ExternalReferencesMap();
+ refs.put("vfi1", Arrays.asList("a","b","c","d"));
+ refs.put("vfi2", Arrays.asList("u","v","w","x","y","z"));
+ Map<String, List<MonitoringComponent>> result = classUnderTest.fetchMonitoringComponents(refs, requestId);
+ verify(sdcClientMock,times(10)).getResource(anyString(),anyString());
+ Assert.assertEquals(1, result.size());
+ Assert.assertEquals(10, result.get("monitoringComponents").size());
+ }
+
+ @Test
+ public void partialSuccessfulFetchMonitoringComponents() throws Exception {
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ when(sdcClientMock.getResource(eq("no_such_uuid"),anyString())).thenThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND));
+ ExternalReferencesMap refs = new ExternalReferencesMap();
+ refs.put("vfi1", Collections.singletonList("abc"));
+ refs.put("vfi2", Collections.singletonList("xyz"));
+ refs.put("vfi3", Collections.singletonList("no_such_uuid"));
+ Map<String, List<MonitoringComponent>> result = classUnderTest.fetchMonitoringComponents(refs, requestId);
+ verify(sdcClientMock,times(3)).getResource(anyString(),anyString());
+ Assert.assertEquals(2, result.size());
+ Assert.assertEquals(2, result.get("monitoringComponents").size());
+ Assert.assertEquals(1, result.get("unavailable").size());
+ }
+
+ @Test(expected=RuntimeException.class)
+ public void deleteVfcmtReference_deleteFailed() {
+ doThrow(RuntimeException.class).when(sdcClientMock).deleteExternalMonitoringReference(anyString(), anyString(), anyString(), anyString(), anyString(), anyString());
+ classUnderTest.deleteVfcmtReference(userId, "", "", "", "", requestId);
+ }
+ @Test
+ public void deleteVfcmtReference_deleteSuccess() {
+ classUnderTest.deleteVfcmtReference(userId, "", "", "", "", requestId);
+ verify(sdcClientMock).deleteExternalMonitoringReference(anyString(), anyString(), anyString(), anyString(), anyString(), anyString());
+ }
+
+ private void mockGetService() throws Exception {
+ ServiceDetailed serviceDetailed = new ServiceDetailed();
+ ResourceInstance resourceInstance = new ResourceInstance();
+ Artifact artifact = new Artifact();
+ artifact.setArtifactName(monitoringComponentName);
+ resourceInstance.setArtifacts(Collections.singletonList(artifact));
+ resourceInstance.setResourceInstanceName(vfiName);
+ serviceDetailed.setResources(Collections.singletonList(resourceInstance));
+ when(sdcClientMock.getService(serviceUuid, requestId)).thenReturn(serviceDetailed);
+ }
+
+ @Test
+ public void deleteVfcmtReferenceBlueprint_deleteSuccess() throws Exception {
+ mockGetService();
+ ResponseEntity responseEntity = classUnderTest.deleteVfcmtReferenceBlueprint(userId, "", monitoringComponentName, serviceUuid, vfiName, "", requestId);
+ verify(sdcClientMock).getService(serviceUuid, requestId);
+ verify(sdcClientMock).deleteInstanceResourceArtifact(anyString(), anyString(), anyString(), anyString(), anyString(), anyString());
+ Assert.assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
+ }
+
+ @Test
+ public void deleteVfcmtReferenceBlueprint_exceptionSdcGetService() throws Exception {
+ when(sdcClientMock.getService(serviceUuid, requestId)).thenThrow(new RuntimeException(""));
+
+ ResponseEntity<ResponseFormat> responseEntity = classUnderTest.deleteVfcmtReferenceBlueprint(userId, "", monitoringComponentName, serviceUuid, vfiName, "", requestId);
+
+ Assert.assertEquals("The request was partially successful. Removing the attached Blueprint from the service has failed. You must manually delete the artifact.", responseEntity.getBody().getRequestError().getServiceException().getFormattedErrorMessage());
+ }
+
+ @Test
+ public void deleteVfcmtReferenceBlueprint_exceptionSdcdeleteInstanceResourceArtifact() throws Exception {
+ mockGetService();
+ doThrow(new RuntimeException("")).when(sdcClientMock).deleteInstanceResourceArtifact(anyString(), anyString(), anyString(), anyString(), anyString(), anyString());
+
+ ResponseEntity<ResponseFormat> responseEntity = classUnderTest.deleteVfcmtReferenceBlueprint(userId, "", monitoringComponentName, serviceUuid, vfiName, "", requestId);
+
+ Assert.assertEquals("The request was partially successful. Removing the attached Blueprint from the service has failed. You must manually delete the artifact.", responseEntity.getBody().getRequestError().getServiceException().getFormattedErrorMessage());
+ }
+}
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java
new file mode 100644
index 0000000..12ed040
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/composition/impl/VfcmtBusinessLogicTest.java
@@ -0,0 +1,310 @@
+package org.onap.sdc.dcae.composition.impl;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.sdc.dcae.catalog.asdc.ASDCException;
+import org.onap.sdc.dcae.client.ISdcClient;
+import org.onap.sdc.dcae.client.SdcRestClient;
+import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.ImportVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.MonitoringComponent;
+import org.onap.sdc.dcae.composition.restmodels.VfcmtData;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ExternalReferencesMap;
+import org.onap.sdc.dcae.composition.restmodels.sdc.Resource;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader;
+import org.onap.sdc.dcae.errormng.PolicyException;
+import org.onap.sdc.dcae.errormng.RequestError;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+
+import java.util.*;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.CERTIFIED;
+import static org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT;
+
+public class VfcmtBusinessLogicTest {
+
+ private ISdcClient sdcClientMock = Mockito.mock(SdcRestClient.class);
+ private ResourceDetailed templateMC = Mockito.mock(ResourceDetailed.class);
+
+ private VfcmtBusinessLogic vfcmtBusinessLogic = new VfcmtBusinessLogic();
+ private ImportVFCMTRequest request = new ImportVFCMTRequest();
+
+ private String userId = "me";
+ private String requestId = "1";
+
+ @Before
+ public void setup(){
+ MockitoAnnotations.initMocks(this);
+ new ErrorConfigurationLoader(System.getProperty("user.dir")+"/src/main/webapp/WEB-INF");
+ vfcmtBusinessLogic.setSdcRestClient(sdcClientMock);
+ request.setTemplateUuid("577");
+ request.setVfiName("vfi_XX");
+ request.setDescription("description");
+ request.setFlowType("SNMP");
+ request.setName("newVfcmt");
+ request.setServiceUuid("service99999");
+ request.setContextType("services");
+ }
+
+ @Test
+ public void sdcIsDown_creatingVfcmt_gotResponseWithError500() throws Exception{
+ RequestError requestError = new RequestError();
+ requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null));
+ when(sdcClientMock.createResource(userId,request,requestId)).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError));
+
+ ResponseEntity res = vfcmtBusinessLogic.createMcFromTemplate(userId,request,requestId);
+ verify(sdcClientMock).getResource("577",requestId);
+ verify(sdcClientMock,times(0)).getResourceArtifact(anyString(),anyString(),anyString());
+ Assert.assertEquals(500, res.getStatusCodeValue());
+ }
+
+ @Test
+ public void uploadCloneCdumpFailed_creatingVfcmt_createVfcmtRolledBack() throws Exception {
+ RequestError requestError = new RequestError();
+ requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null));
+ when(sdcClientMock.createResourceArtifact(anyString(),anyString(),any(),anyString())).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError));
+ when(sdcClientMock.createResource(userId,request,requestId)).thenReturn(templateMC);
+ when(sdcClientMock.getResourceArtifact(anyString(), anyString(), anyString())).thenReturn("{\"flowType\":\"don't override\"");
+ when(templateMC.getUuid()).thenReturn("3");
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ emulateListOfArtifactsWithCompositionYml();
+
+ vfcmtBusinessLogic.createMcFromTemplate(userId, request, requestId);
+
+ // making sure rollback is performed if exception is thrown
+ verify(sdcClientMock).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString());
+ }
+
+ // happy happy joy joy
+ @Test
+ public void successfulCreationAndAttachmentOfVfcmt() throws Exception {
+ when(templateMC.getUuid()).thenReturn("3");
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ ResourceDetailed mockedVfcmt = Mockito.mock(ResourceDetailed.class);
+ when(mockedVfcmt.getUuid()).thenReturn("5");
+ when(sdcClientMock.createResource(anyString(),any(),anyString())).thenReturn(mockedVfcmt);
+ when(sdcClientMock.getResourceArtifact(anyString(),anyString(),anyString())).thenReturn("3243324");
+
+ emulateListOfArtifactsWithCompositionYml();
+
+ vfcmtBusinessLogic.createMcFromTemplate(userId, request,requestId);
+
+ verify(sdcClientMock).createResource(userId, request,requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock).getResourceArtifact(anyString(),anyString(),anyString());
+ verify(sdcClientMock, times(2)).createResourceArtifact(anyString(),anyString(),any(),anyString());
+ verify(sdcClientMock).addExternalMonitoringReference(anyString(),any(),any(),anyString());
+ verify(sdcClientMock).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString());
+ }
+
+ @Test
+ public void successfulImportAndAttachmentOfVfcmtAlreadyConnectedWithoutEditDoCheckin() throws Exception {
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ when(sdcClientMock.getResourceArtifact(anyString(),anyString(),anyString())).thenReturn("{\"flowType\":\"don't override\"}");
+ when(templateMC.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKOUT");
+ emulateListOfArtifactsWithCompositionYmlAndSvcRef();
+ request.setCloneVFCMT(false);
+ request.setUpdateFlowType(false);
+ vfcmtBusinessLogic.importMC(userId, request, requestId);
+
+ verify(sdcClientMock, times(0)).createResource(userId, request, requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock).getResourceArtifact(anyString(),anyString(),anyString());
+ verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString());
+ verify(sdcClientMock, times(0)).updateResourceArtifact(anyString(), anyString(), any(), anyString());
+ verify(sdcClientMock).addExternalMonitoringReference(anyString(),any(),any(),anyString());
+ verify(sdcClientMock).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString());
+ }
+
+
+ @Test
+ public void successfulImportAndAttachmentOfVfcmtAlreadyConnectedUpdateFlowTypeCheckoutCheckin() throws Exception {
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ when(templateMC.getUuid()).thenReturn("3");
+ when(sdcClientMock.changeResourceLifecycleState(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(templateMC);
+ when(sdcClientMock.updateResourceArtifact(anyString(), anyString(), any(), anyString())).thenReturn(new Artifact());
+ when(sdcClientMock.getResourceArtifact(anyString(),anyString(),anyString())).thenReturn("{\"cid\":\"xsssdaerrwr\"}");
+ when(templateMC.getLifecycleState()).thenReturn("NOT_CERTIFIED_CHECKIN").thenReturn("NOT_CERTIFIED_CHECKOUT");
+ emulateListOfArtifactsWithCompositionYmlAndSvcRef();
+ request.setCloneVFCMT(false);
+ request.setUpdateFlowType(true);
+ vfcmtBusinessLogic.importMC(userId, request, requestId);
+
+ verify(sdcClientMock, times(0)).createResource(userId, request, requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock).getResourceArtifact(anyString(),anyString(),anyString());
+ verify(sdcClientMock, times(0)).createResourceArtifact(anyString(),anyString(),any(),anyString());
+ verify(sdcClientMock, times(1)).updateResourceArtifact(anyString(), anyString(), any(), anyString());
+ verify(sdcClientMock).addExternalMonitoringReference(anyString(),any(),any(),anyString());
+ verify(sdcClientMock, times(2)).changeResourceLifecycleState(anyString(),anyString(),anyString(),anyString(),anyString());
+ }
+
+
+ @Test
+ public void successfulFetchVfcmtDataFull() throws Exception {
+ String templateUuid = "3";
+ when(templateMC.getUuid()).thenReturn(templateUuid);
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ emulateListOfArtifactsWithCompositionYmlAndSvcRef();
+ when(sdcClientMock.getResourceArtifact(templateUuid, "svcRefArtifactUuid", requestId)).thenReturn("thisIsTheServiceId/resources/thisIsTheVfiName");
+ when(sdcClientMock.getResourceArtifact(templateUuid, "compositionArtifactUuid", requestId)).thenReturn("\"flowType\":\"Syslog\"");
+ ResponseEntity<VfcmtData> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock,times(2)).getResourceArtifact(anyString(),anyString(),anyString());
+ Assert.assertEquals(200, result.getStatusCodeValue());
+ Assert.assertEquals("Syslog", result.getBody().getFlowType());
+ Assert.assertEquals("thisIsTheServiceId", result.getBody().getServiceUuid());
+ Assert.assertEquals("thisIsTheVfiName", result.getBody().getVfiName());
+ }
+
+ @Test
+ public void successfulFetchVfcmtDataPartial() throws Exception {
+ String templateUuid = "3";
+ when(templateMC.getUuid()).thenReturn(templateUuid);
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ emulateListOfArtifactsWithCompositionYml();
+ when(sdcClientMock.getResourceArtifact(templateUuid, "compositionArtifactUuid", requestId)).thenReturn("\"flowType\":\"Syslog\"");
+ ResponseEntity<VfcmtData> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock,times(1)).getResourceArtifact(anyString(),anyString(),anyString());
+ Assert.assertEquals(200, result.getStatusCodeValue());
+ Assert.assertEquals("Syslog", result.getBody().getFlowType());
+ Assert.assertEquals(null, result.getBody().getServiceUuid());
+ Assert.assertEquals(null, result.getBody().getVfiName());
+ }
+
+ @Test
+ public void successfulFetchVfcmtDataEmpty() throws Exception {
+
+ String templateUuid = "3";
+ when(templateMC.getUuid()).thenReturn(templateUuid);
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ emulateListOfArtifactsWithCompositionYml();
+ when(sdcClientMock.getResourceArtifact(templateUuid, "compositionArtifactUuid", requestId)).thenReturn("");
+ ResponseEntity<VfcmtData> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock,times(1)).getResourceArtifact(anyString(),anyString(),anyString());
+ Assert.assertEquals(200, result.getStatusCodeValue());
+ Assert.assertEquals(null, result.getBody().getFlowType());
+ Assert.assertEquals(null, result.getBody().getServiceUuid());
+ Assert.assertEquals(null, result.getBody().getVfiName());
+ }
+
+ @Test
+ public void fetchVfcmtDataNoCompositionFound() throws Exception {
+
+ String templateUuid = "3";
+ when(templateMC.getUuid()).thenReturn(templateUuid);
+ when(templateMC.getName()).thenReturn(templateUuid);
+ when(sdcClientMock.getResource(anyString(),anyString())).thenReturn(templateMC);
+ ResponseEntity<ResponseFormat> result = vfcmtBusinessLogic.getVfcmtReferenceData(templateUuid, requestId);
+ verify(sdcClientMock).getResource(anyString(),anyString());
+ verify(sdcClientMock,times(0)).getResourceArtifact(anyString(),anyString(),anyString());
+ Assert.assertEquals(404, result.getStatusCodeValue());
+ Assert.assertEquals("Error – Could not read component 3 details.", result.getBody().getRequestError().getServiceException().getFormattedErrorMessage());
+
+ }
+
+ @Test
+ public void getVfcmtsForMigration() throws Exception {
+ ExternalReferencesMap connectedVfcmts = new ExternalReferencesMap();
+ connectedVfcmts.put("11",Arrays.asList("Red", "Blue", "Yellow"));
+ connectedVfcmts.put("22",Arrays.asList("Ibiza", "Bora Bora", "Mykonos"));
+ connectedVfcmts.put("33",Arrays.asList("Large", "Medium", "Small"));
+ connectedVfcmts.put("44",Arrays.asList("Basket", "Foot", "Volley"));
+
+ when(sdcClientMock.getMonitoringReferences(anyString(),anyString(),anyString(),anyString())).thenReturn(connectedVfcmts);
+
+ Resource myRedResource = new Resource();
+ myRedResource.setUuid("Red");
+ myRedResource.setLastUpdaterUserId("me");
+ myRedResource.setLifecycleState(NOT_CERTIFIED_CHECKOUT.name());
+
+ Resource herRaphaelResource = new Resource();
+ herRaphaelResource.setUuid("Raphael");
+ herRaphaelResource.setLastUpdaterUserId("her");
+ herRaphaelResource.setLifecycleState(NOT_CERTIFIED_CHECKOUT.name());
+
+ Resource myMediumResource = new Resource();
+ myMediumResource.setUuid("Medium");
+ myMediumResource.setLastUpdaterUserId("me");
+
+ Resource herDonateloResource = new Resource();
+ herDonateloResource.setUuid("Donatelo");
+ herDonateloResource.setLastUpdaterUserId("her");
+ herDonateloResource.setVersion("1.0");
+
+ Resource hisMykonosResource = new Resource();
+ hisMykonosResource.setUuid("Mykonos");
+ hisMykonosResource.setLastUpdaterUserId("his");
+ hisMykonosResource.setLifecycleState(NOT_CERTIFIED_CHECKOUT.name());
+
+ Resource hisMichaelangeloResource = new Resource();
+ hisMichaelangeloResource.setUuid("Michaelangelo");
+ hisMichaelangeloResource.setLastUpdaterUserId("his");
+ hisMykonosResource.setLifecycleState(CERTIFIED.name());
+ hisMykonosResource.setVersion("1.1");
+
+ // Versions and connectivity to service shouldn't be part of this test as these are passed to SDC to be
+ // filtered by SDC requests (getMonitoringReference and getResource)
+
+ List<Resource> theVfcmts = Arrays.asList(myRedResource,herRaphaelResource,myMediumResource,herDonateloResource,hisMykonosResource,hisMichaelangeloResource);
+
+ when(sdcClientMock.getResources(anyString(),anyString(),anyString(),anyString())).thenReturn(theVfcmts);
+
+ ResponseEntity<List<Resource>> response = vfcmtBusinessLogic.getVfcmtsForMigration(userId,"service","5544","1.0",requestId);
+
+ Assert.assertEquals(2, response.getBody().size());
+ Assert.assertEquals(200, response.getStatusCodeValue());
+ }
+
+ private void emulateListOfArtifactsWithCompositionYml() {
+ List<Artifact> listOfArtifactCompositionYml = new ArrayList<>();
+ Artifact compositionArtifact = Mockito.mock(Artifact.class);
+ when(compositionArtifact.getArtifactName()).thenReturn(DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ when(compositionArtifact.getArtifactUUID()).thenReturn("compositionArtifactUuid");
+ when(compositionArtifact.getPayloadData()).thenReturn("{\"flowType\":\"don't override\"}");
+ listOfArtifactCompositionYml.add(compositionArtifact);
+ when(templateMC.getArtifacts()).thenReturn(listOfArtifactCompositionYml);
+ }
+
+ private void emulateListOfArtifactsWithCompositionYmlAndSvcRef() {
+ List<Artifact> listOfArtifactCompositionYml = new ArrayList<>();
+ Artifact compositionArtifact = Mockito.mock(Artifact.class);
+ Artifact svcRefArtifact = Mockito.mock(Artifact.class);
+ when(compositionArtifact.getArtifactName()).thenReturn(DcaeBeConstants.Composition.fileNames.COMPOSITION_YML);
+ when(compositionArtifact.getArtifactUUID()).thenReturn("compositionArtifactUuid");
+ when(compositionArtifact.getPayloadData()).thenReturn("{\"flowType\":\"don't override\"}");
+ when(svcRefArtifact.getArtifactName()).thenReturn(DcaeBeConstants.Composition.fileNames.SVC_REF);
+ when(svcRefArtifact.getArtifactUUID()).thenReturn("svcRefArtifactUuid");
+ listOfArtifactCompositionYml.add(compositionArtifact);
+ listOfArtifactCompositionYml.add(svcRefArtifact);
+ when(templateMC.getArtifacts()).thenReturn(listOfArtifactCompositionYml);
+ }
+
+ @Test
+ public void uiHasABug_creatingVfcmtWithBadRequestNoServiceUuid_gotResponseWithError400() throws Exception{
+ RequestError requestError = new RequestError();
+ requestError.setPolicyException(new PolicyException("POL5000", "Error: Internal Server Error. Please try again later.", null));
+ when(sdcClientMock.createResource(userId,request,requestId)).thenThrow(new ASDCException(HttpStatus.INTERNAL_SERVER_ERROR, requestError));
+ CreateVFCMTRequest req = new CreateVFCMTRequest();
+ req.setServiceUuid(null);
+ ResponseEntity res = vfcmtBusinessLogic.createMcFromTemplate(userId,req,requestId);
+ verify(sdcClientMock,times(0)).getResource(anyString(),anyString());
+ verify(sdcClientMock,times(0)).getResourceArtifact(anyString(),anyString(),anyString());
+ Assert.assertEquals(400, res.getStatusCodeValue());
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java
new file mode 100644
index 0000000..d3ae600
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/rule/editor/impl/RulesBusinessLogicTest.java
@@ -0,0 +1,304 @@
+package org.onap.sdc.dcae.rule.editor.impl;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.MockitoAnnotations;
+import org.onap.sdc.dcae.composition.restmodels.ruleeditor.*;
+import org.onap.sdc.dcae.errormng.ErrorConfigurationLoader;
+import org.onap.sdc.dcae.errormng.ResponseFormatManager;
+import org.onap.sdc.dcae.errormng.ServiceException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class RulesBusinessLogicTest {
+ private static Gson gson = new GsonBuilder()
+ .registerTypeAdapter(BaseAction.class, new ActionDeserializer())
+ .registerTypeAdapter(BaseCondition.class, new ConditionDeserializer()).create();
+
+ @InjectMocks
+ private RulesBusinessLogic rulesBusinessLogic = new RulesBusinessLogic();
+ private ResponseFormatManager responseFormatManager = null;
+
+ @Before
+ public void setup(){
+ MockitoAnnotations.initMocks(this);
+ ErrorConfigurationLoader errorConfigurationLoader = new ErrorConfigurationLoader(System.getProperty("user.dir")+"/src/main/webapp/WEB-INF");
+ responseFormatManager = ResponseFormatManager.getInstance();
+ }
+
+ @Test
+ public void translateSingleRuleSingleCopyActionAddSnmpHeader() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\"},\"class\":\"Set\"}]},"
+ + "{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+
+ Rule rule = new Rule();
+ rule.setActions(new ArrayList<>());
+ rule.getActions().add(buildCopyAction("2.0","event.commonEventHeader.version"));
+ rule.setDescription("description");
+ MappingRules mr = new MappingRules(rule);
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(mr);
+ assertTrue(errors.isEmpty());
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void translateSingleRuleSingleDateFormatterActionSnmpFlow() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"fromFormat\":\"fromFormat\",\"fromTz\":\"fromTZ\",\"toField\":\"targetField\",\"toFormat\":\"toFormat\",\"toTz\":\"toTz\",\"value\":\"fromField\",\"class\":\"DateFormatter\"}]},"
+ + "{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+
+ Rule rule = new Rule();
+ rule.setActions(new ArrayList<>());
+ rule.getActions().add(buildDateFormatterAction());
+ rule.setDescription("description");
+ MappingRules mr = new MappingRules(rule);
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(mr);
+ assertTrue(errors.isEmpty());
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void translateSingleRuleMultipleCopyActionsAddSnmpHeader() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\","
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+
+ MappingRules mr = new MappingRules(buildRuleWithMultipleCopyActions());
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(mr);
+ assertTrue(errors.isEmpty());
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void translateMultipleRulesMultipleCopyActionsAddSnmpHeader() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\","
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\","
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+
+ MappingRules mr = new MappingRules(buildRuleWithMultipleCopyActions());
+ mr.addOrReplaceRule(buildRuleWithMultipleCopyActions());
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void emptyStringTest() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"map\":{\"\":\"\"},\"field\":\"\",\"toField\":\"mapTargetField\",\"default\":\"\",\"class\":\"MapAlarmValues\"}]},"
+ + "{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+ String ruleRequestBody = "{version:4.1,eventType:syslogFields,description:description,actions:[{actionType:map,from:{value:'\"\"'},target:mapTargetField,map:{values:[{key:'\"\"',value:'\"\"'}],haveDefault:true,default:'\"\"'}}]}";
+ Rule myRule = gson.fromJson(ruleRequestBody, Rule.class);
+ MappingRules mr = new MappingRules(myRule);
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(mr);
+ assertTrue(errors.isEmpty());
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void singleStringConditionTranslationTest() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"syslog_map\",\"processors\":[{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\",\"filter\":{\"string\":\"left\",\"value\":\"right\",\"class\":\"Contains\"},"
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+ String input = "{operator:contains,left:left,right:[right]}";
+ Rule rule = buildRuleWithMultipleCopyActions();
+ rule.setCondition(gson.fromJson(input, BaseCondition.class));
+ MappingRules mr = new MappingRules(rule);
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "syslog_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void multiStringConditionTranslationTest() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"foi_map\",\"processors\":[{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},"
+ + "{\"phase\":\"phase_1\",\"filter\":{\"filters\":[{\"string\":\"left\",\"value\":\"right1\",\"class\":\"Contains\"},{\"string\":\"left\",\"value\":\"right2\",\"class\":\"Contains\"}],\"class\":\"Or\"},"
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+ String input = "{operator:contains,left:left,right:[right1, right2]}";
+ Rule rule = buildRuleWithMultipleCopyActions();
+ rule.setCondition(gson.fromJson(input, BaseCondition.class));
+ MappingRules mr = new MappingRules(rule);
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "foi_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void singleFieldConditionTranslationTest() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\",\"filter\":{\"field\":\"left\",\"value\":\"right\",\"class\":\"Equals\"},"
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+ String input = "{operator:equals,left:left,right:[right]}";
+ Rule rule = buildRuleWithMultipleCopyActions();
+ rule.setCondition(gson.fromJson(input, BaseCondition.class));
+ MappingRules mr = new MappingRules(rule);
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void multiFieldConditionTranslationTest() throws Exception {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"snmp_map\",\"processors\":[{\"array\":\"varbinds\",\"datacolumn\":\"varbind_value\",\"keycolumn\":\"varbind_oid\",\"class\":\"SnmpConvertor\"},"
+ + "{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},{\"phase\":\"phase_1\",\"filter\":{\"field\":\"left\",\"values\":[\"right1\",\"right2\"],\"class\":\"NotOneOf\"},"
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\",\"event.commonEventHeader.eventId\":\"${event.commonEventHeader.sourceName}_${eventGroup}\"},\"class\":\"Set\"},"
+ + "{\"regex\":\"([^:]*):.*\",\"field\":\"targetField\",\"value\":\"extractFromHere\",\"class\":\"ExtractText\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+ String input = "{operator:notequal,left:left,right:[right1,right2]}";
+ Rule rule = buildRuleWithMultipleCopyActions();
+ rule.setCondition(gson.fromJson(input, BaseCondition.class));
+ MappingRules mr = new MappingRules(rule);
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(mr, "snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void reorderRuleActionsDuringValidationSuccessTest() {
+ Rule rule1 = buildValidRuleWithDependentActions();
+ Rule rule2 = buildValidRuleWithDependentActions();
+ assertEquals(rule1, rule2);
+ List<ServiceException> errors = rulesBusinessLogic.validateRule(rule1);
+ assertTrue(errors.isEmpty());
+ assertNotEquals(rule1, rule2);
+ //after validation actions are reordered: 1, 3, 4, 2, 5
+ rule2.getActions().add(1, rule2.getActions().get(2)); // 1, 2, 3, 4, 5 -> 1, 3, 2, 3, 4, 5
+ rule2.getActions().remove(3); // 1, 3, 2, 3, 4, 5 -> 1, 3, 2, 4, 5
+ rule2.getActions().add(2, rule2.getActions().get(3)); // 1, 3, 2, 4, 5 -> 1, 3, 4, 2, 4, 5
+ rule2.getActions().remove(4); // 1, 3, 4, 2, 4, 5 -> 1, 3, 4, 2, 5
+ assertEquals(rule1, rule2);
+ }
+
+ @Test
+ public void reorderRuleActionsDuringValidationFailureTest() {
+ String expectedError = "A circular dependency was detected between actions. The following fields should be resolved: event.commonEventHeader.eventId, event.commonEventHeader.sourceName, invalidSelfDependency, circularDependencyTarget_3";
+ Rule rule1 = buildRuleWithCircularActionDependencies();
+ List<ServiceException> errors = rulesBusinessLogic.validateRule(rule1);
+ assertEquals(expectedError, errors.get(0).getFormattedErrorMessage());
+ }
+
+
+ @Test
+ public void reorderMappingRulesByDependencySuccessTest() {
+ MappingRules mr = new MappingRules(buildRuleWithMultipleCopyActions());
+ Rule rule = new Rule();
+ rule.setDescription("description");
+ rule.setActions(new ArrayList<>());
+ // create a dependency between rules
+ rule.getActions().add(buildCopyAction("${event.commonEventHeader.someField}","event.commonEventHeader.sourceName"));
+ mr.addOrReplaceRule(rule);
+ List<String> ruleUids = new ArrayList<>(mr.getRules().keySet());
+ String translateBefore = rulesBusinessLogic.translateRules(mr,"snmp_map", "map_publish", "phase_1");
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(mr);
+ assertTrue(errors.isEmpty());
+ List<String> ruleUidsMod = new ArrayList<>(mr.getRules().keySet());
+ assertEquals(ruleUids.get(0), ruleUidsMod.get(1));
+ assertEquals(ruleUids.get(1), ruleUidsMod.get(0));
+ assertNotEquals(translateBefore, rulesBusinessLogic.translateRules(mr,"snmp_map", "map_publish", "phase_1"));
+ }
+
+ @Test
+ public void reorderMappingRulesCircularDependencyFailureTest() {
+
+ MappingRules mr = new MappingRules(buildRuleWithMultipleCopyActions());
+ List<ServiceException> errors = rulesBusinessLogic.validateRules(mr);
+ assertTrue(errors.isEmpty());
+ Rule rule = new Rule();
+ rule.setDescription("description");
+ rule.setActions(new ArrayList<>());
+ // create a circular dependency between rules
+ rule.getActions().add(buildCopyAction("${event.commonEventHeader.version}","event.commonEventHeader.sourceName"));
+ String input = "{operator:equals,left:\"${event.commonEventHeader.version}\",right:[\"${event.commonEventHeader.eventId}\"]}";
+ rule.setCondition(gson.fromJson(input, BaseCondition.class));
+ assertTrue(rulesBusinessLogic.addOrEditRule(mr, rule));
+ errors = rulesBusinessLogic.validateRules(mr);
+ assertFalse(errors.isEmpty());
+ String expectedError = String.format("A circular dependency was detected between rules: %s, %s within fields: event.commonEventHeader.sourceName, event.commonEventHeader.version, event.commonEventHeader.eventId", mr.getRules().keySet().toArray());
+ assertEquals(expectedError, errors.get(0).getFormattedErrorMessage());
+ }
+
+
+ @Test
+ public void translateNestedComplexConditionSuccessTest() {
+ String expectedTranslation = "{\"processing\":[{\"phase\":\"foi_map\",\"processors\":[{\"phase\":\"phase_1\",\"class\":\"RunPhase\"}]},"
+ + "{\"phase\":\"phase_1\",\"filter\":{\"filters\":[{\"field\":\"${event.commonEventHeader.version}\",\"value\":\"${event.commonEventHeader.eventId}\",\"class\":\"Equals\"},"
+ + "{\"filters\":[{\"field\":\"left\",\"value\":\"right\",\"class\":\"NotEqual\"},{\"string\":\"${XXX}\",\"value\":\"right1\",\"class\":\"Contains\"},"
+ + "{\"string\":\"${XXX}\",\"value\":\"right2\",\"class\":\"Contains\"}],\"class\":\"Or\"}],\"class\":\"And\"},"
+ + "\"processors\":[{\"updates\":{\"event.commonEventHeader.version\":\"2.0\"},\"class\":\"Set\"}]},{\"phase\":\"phase_1\",\"processors\":[{\"phase\":\"map_publish\",\"class\":\"RunPhase\"}]}]}";
+
+ Rule rule = new Rule();
+ rule.setActions(new ArrayList<>());
+ rule.getActions().add(buildCopyAction("2.0","event.commonEventHeader.version"));
+ rule.setDescription("description");
+ String condition = "{type:All,children:[{operator:equals,left:\"${event.commonEventHeader.version}\",right:[\"${event.commonEventHeader.eventId}\"]},"
+ + "{type:Any,children:[{operator:contains,left:\"${XXX}\",right:[right1,right2]},{operator:notEqual,left:left,right:[right]}]}]}";
+ rule.setCondition(gson.fromJson(condition, BaseCondition.class));
+ List<ServiceException> errors = rulesBusinessLogic.validateRule(rule);
+ assertTrue(errors.isEmpty());
+ assertEquals(expectedTranslation, rulesBusinessLogic.translateRules(new MappingRules(rule),"foi_map", "map_publish", "phase_1"));
+ }
+
+ private Rule buildRuleWithMultipleCopyActions() {
+ Rule rule = new Rule();
+ rule.setDescription("description");
+ List<BaseAction> actions = new ArrayList<>();
+ actions.add(buildCopyAction("2.0","event.commonEventHeader.version"));
+ actions.add(buildConcatAction(Arrays.asList("${event.commonEventHeader.sourceName}","_","${eventGroup}"), "event.commonEventHeader.eventId"));
+ actions.add(buildRegexAction("extractFromHere", "targetField", "([^:]*):.*"));
+ rule.setActions(actions);
+ return rule;
+ }
+
+ private Rule buildValidRuleWithDependentActions() {
+ Rule rule = buildRuleWithMultipleCopyActions();
+ rule.getActions().add(buildConcatAction(Arrays.asList("${targetField}","_","${circularDependencyTarget_3}"), "event.commonEventHeader.sourceName"));
+ rule.getActions().add(buildConcatAction(Arrays.asList("${validSelfDependency}","_","${event.commonEventHeader.version}"), "validSelfDependency"));
+ return rule;
+ }
+
+ private Rule buildRuleWithCircularActionDependencies() {
+ Rule rule = buildValidRuleWithDependentActions();
+ rule.getActions().add(buildCopyAction("${invalidSelfDependency}", "invalidSelfDependency"));
+ rule.getActions().add(buildCopyAction("${event.commonEventHeader.eventId}", "circularDependencyTarget_3"));
+ return rule;
+ }
+
+ private BaseAction buildCopyAction(String from, String to) {
+ BaseAction action = new BaseAction();
+ action.setActionType("copy");
+ action.setFrom(from);
+ action.setTarget(to);
+ return action;
+ }
+
+ private BaseAction buildConcatAction(List<String> from, String to) {
+ BaseAction action = new BaseAction();
+ action.setActionType("concat");
+ action.setFrom(from);
+ action.setTarget(to);
+ return action;
+ }
+
+ private BaseAction buildRegexAction(String from, String to, String regex) {
+ BaseAction action = new BaseAction();
+ action.setActionType("copy");
+ action.setFrom(from, regex);
+ action.setTarget(to);
+ return action;
+ }
+
+ private DateFormatterAction buildDateFormatterAction() {
+ DateFormatterAction action = new DateFormatterAction();
+ action.setActionType("date formatter");
+ action.setFrom("fromField");
+ action.setTarget("targetField");
+ action.setFromFormat("fromFormat");
+ action.setToFormat("toFormat");
+ action.setFromTz("fromTZ");
+ action.setToTz("toTz");
+ return action;
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/services/GetServicesTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/services/GetServicesTest.java
new file mode 100644
index 0000000..68f055f
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/services/GetServicesTest.java
@@ -0,0 +1,143 @@
+package org.onap.sdc.dcae.services;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import org.onap.sdc.dcae.composition.restmodels.DcaeMinimizedService;
+import org.onap.sdc.dcae.composition.controller.ServicesController;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants.LifecycleStateEnum;
+import org.testng.annotations.Test;
+
+public class GetServicesTest {
+
+
+ @Test
+ public void parseAndFliterServicesByUser_nullServices_TBD() {
+// fail("TODO Auto-generated method stub");
+ }
+
+
+ @Test
+ public void parseAndFliterServicesByUser_emptyList_emptyList() {
+ // arrange
+ ServicesController target = new ServicesController();
+ String user_id = "test";
+ String lastUpdaterUserId = "test";
+ List<LinkedHashMap<String, String>> services = new ArrayList<LinkedHashMap<String, String>>();
+ // act
+ List<DcaeMinimizedService> result = target.parseAndFilterServicesByUser(lastUpdaterUserId, services, user_id);
+ // assert
+ assertThat(result).isEqualTo(new ArrayList<DcaeMinimizedService>());
+ }
+
+
+ @Test
+ public void parseAndFliterServicesByUser_singleServicesAsMap_singleServiceParsed() {
+ // arrange
+ String user_id = "test";
+ String lastUpdaterUserId = user_id;
+ String uuid = "a";
+ String invariantUUID = "1";
+ String lifecycleState = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name();
+ String version = "0.1";
+ String serviceName = "TestService";
+
+ ServicesController target = new ServicesController();
+ LinkedHashMap<String, String> service = createServiceAsMap(lastUpdaterUserId, uuid, invariantUUID,
+ lifecycleState, version, serviceName);
+ List<LinkedHashMap<String, String>> services = new ArrayList<LinkedHashMap<String, String>>(
+ Arrays.asList(service));
+
+ DcaeMinimizedService expected = new DcaeMinimizedService(uuid, serviceName, lastUpdaterUserId, lifecycleState,
+ version, invariantUUID);
+ // act
+ List<DcaeMinimizedService> result = target.parseAndFilterServicesByUser(lastUpdaterUserId, services, user_id);
+ // assert
+ assertThat(result).usingRecursiveFieldByFieldElementComparator().contains(expected);
+ }
+
+
+ @Test
+ public void parseAndFliterServicesByUser_unsortedServices_sortedServices() {
+ // arrange
+ String user_id = "test";
+ String lastUpdaterUserId = user_id;
+ String uuid = "a";
+ String lifecycleState = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name();
+ String version = "0.1";
+
+ List<LinkedHashMap<String, String>> unsortedServices = Arrays.asList("d", "a", "c", "b").stream()
+ .map(x -> createServiceAsMap(lastUpdaterUserId, uuid, UUID.randomUUID().toString(), lifecycleState, version, x))
+ .collect(Collectors.toList());
+
+ ServicesController target = new ServicesController();
+
+ // act
+ List<DcaeMinimizedService> result = target.parseAndFilterServicesByUser(lastUpdaterUserId, unsortedServices,
+ user_id);
+ // assert
+ assertThat(result).extracting("name").containsExactly("a","b","c","d");
+ }
+
+
+ @Test
+ public void parseAndFliterServicesByUser_allOptionsForLastUpdaterAndIsCheckout_allOptionsButIsCheckoutAndNotLastUpdater() {
+ // ------------user == last_updater
+ // -----------------True----False--
+ // isCheckout----------------------
+ // --------True------V--------X----
+ // --------False-----V--------V----
+ // --------------------------------
+// fail("TODO Auto-generated method stub");
+ }
+
+
+ @Test
+ public void parseAndFliterServicesByUser_singleServiceWithMultiVersions_singleServiceWithLatestVersion() {
+ // arrange
+ String user_id = "test";
+ String lastUpdaterUserId = user_id;
+ String uuid = "a";
+ String invariantUUID = "1";
+ String lifecycleState = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name();
+ String serviceName = "TestService";
+
+ List<LinkedHashMap<String, String>> singleServiceWithMultiVersions = Arrays.asList("1.0", "0.3", "11.0", "2.0", "1.8").stream()
+ .map(x -> createServiceAsMap(lastUpdaterUserId, uuid, invariantUUID, lifecycleState, x, serviceName))
+ .collect(Collectors.toList());
+
+ ServicesController target = new ServicesController();
+
+ // act
+ List<DcaeMinimizedService> result = target.parseAndFilterServicesByUser(lastUpdaterUserId, singleServiceWithMultiVersions, user_id);
+
+ // assert
+ assertThat(result).extracting("version").containsExactly("11.0");
+ }
+
+
+ private static LinkedHashMap<String, String> createServiceAsMap(String lastUpdaterUserId, String uuid,
+ String invariantUUID, String lifecycleState, String version, String serviceName) {
+
+ LinkedHashMap<String, String> service = new LinkedHashMap<String, String>() {
+ {
+ put("invariantUUID", invariantUUID);
+ put("uuid", uuid);
+ put("name", serviceName);
+ put("lastUpdaterUserId", lastUpdaterUserId);
+ put("lifecycleState", lifecycleState);
+ put("version", version);
+ }
+ };
+
+ return service;
+ }
+
+}
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/EventListenerDefinitionTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/EventListenerDefinitionTest.java
new file mode 100644
index 0000000..3e9edf5
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/EventListenerDefinitionTest.java
@@ -0,0 +1,61 @@
+package org.onap.sdc.dcae.ves;
+
+import org.apache.commons.lang.StringUtils;
+import org.junit.Test;
+import org.onap.sdc.dcae.VesStructureLoaderMock;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class EventListenerDefinitionTest {
+ VesStructureLoaderMock loader = new VesStructureLoaderMock(false);
+
+ @Test
+ public void resolveRefTypesSimpleTest() throws Exception {
+ EventListenerDefinition eventListenerDefinition = loader.getEventListeners().get("4.1");
+ assertTrue(eventListenerDefinition.propertiesContainReference());
+ eventListenerDefinition.resolveRefTypes();
+ assertFalse(eventListenerDefinition.propertiesContainReference());
+ }
+
+ @Test
+ public void resolveRefTypesSimpleUnresolvableTest() throws Exception {
+ EventListenerDefinition eventListenerDefinition = loader.getEventListeners().get("Unresolvable");
+ assertTrue(eventListenerDefinition.propertiesContainReference());
+ String resolverError = eventListenerDefinition.resolveRefTypes();
+ assertTrue(eventListenerDefinition.propertiesContainReference());
+ assertEquals("the following definitions containing unresolvable references: [\"otherFields\",\"stateChangeFields\",\"syslogFields\",\"thresholdCrossingAlertFields\"]",resolverError);
+ }
+
+ @Test
+ public void validateSuccessTest() throws Exception {
+ EventListenerDefinition eventListenerDefinition = loader.getEventListeners().get("4.1");
+ assertTrue(StringUtils.isBlank(eventListenerDefinition.validate()));
+ }
+
+ @Test
+ public void validateTypesFailureTest() throws Exception {
+ EventListenerDefinition eventListenerDefinition = loader.getEventListeners().get("InvalidType");
+ String error = eventListenerDefinition.validate();
+ assertEquals("invalid type declaration: invalid", error);
+ }
+
+ @Test
+ public void validateRequiredFailureTest() throws Exception {
+ EventListenerDefinition eventListenerDefinition = loader.getEventListeners().get("InvalidRequiredEntry");
+ String error = eventListenerDefinition.validate();
+ assertEquals("invalid required entry: codecIdentifier(invalid)", error);
+ }
+
+ @Test
+ public void validateEventPropertyFailureTest() throws Exception {
+ EventListenerDefinition eventListenerDefinition = loader.getEventListeners().get("NoEventProperty");
+ String error = eventListenerDefinition.validate();
+ assertEquals("schema not containing property: event", error);
+ }
+
+
+
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/VesStructureLoaderTest.java b/dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/VesStructureLoaderTest.java
new file mode 100644
index 0000000..3172eec
--- /dev/null
+++ b/dcaedt_be/src/test/java/org/onap/sdc/dcae/ves/VesStructureLoaderTest.java
@@ -0,0 +1,129 @@
+package org.onap.sdc.dcae.ves;
+
+import org.junit.Test;
+import org.onap.sdc.dcae.VesStructureLoaderMock;
+
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class VesStructureLoaderTest {
+
+ // the file names of test schema files
+ private final String UNRESOLVABLE_REFERENCES = "CommonEventFormat_vUnresolvable.json";
+ private final String VALID_VERSION_4_1 = "CommonEventFormat_v4.1.json";
+ private final String VALID_VERSION_5_3 = "CommonEventFormat_v5.3.json";
+ private final String INVALID_JSON = "CommonEventFormat_vInvalidJson.json";
+ private final String UNSUPPORTED_FILENAME = "unsupportedFilename.json";
+ private final String INVALID_SCHEMA_STRUCTURE = "CommonEventFormat_vInvalidSchemaStructure.json";
+ private final String INVALID_TYPE = "CommonEventFormat_vInvalidType.json";
+ private final String INVALID_REQUIRED_ENTRY = "CommonEventFormat_vInvalidRequiredEntry.json";
+ private final String NO_EVENT_PROPERTY = "CommonEventFormat_vNoEventProperty.json";
+ private final String NO_COMMON_EVENT_HEADER = "CommonEventFormat_v4.1WithoutCommonEventHeader.json";
+
+ // schema directory test paths
+ private final String EMPTY_SCHEMA_DIR = System.getProperty("user.dir") + "/src/test/resources/ves-schema/empty";
+ private final String NONE_EXISTING_DIR = EMPTY_SCHEMA_DIR + "/null";
+
+ private final String ERROR_TEXT = "Error: parsing VES schema file ";
+
+ // files loaded from default path, only valid files are kept, errors logged for invalid files (initError);
+ @Test
+ public void defaultInit() {
+ VesStructureLoaderMock loader = new VesStructureLoaderMock();
+ Set<String> expectedAvailableVersions = new HashSet<>();
+ expectedAvailableVersions.add(loader.getVersionFromFileName(VALID_VERSION_4_1));
+ expectedAvailableVersions.add(loader.getVersionFromFileName(VALID_VERSION_5_3));
+ expectedAvailableVersions.add(loader.getVersionFromFileName(NO_COMMON_EVENT_HEADER));
+ assertEquals(expectedAvailableVersions, loader.getAvailableVersionsList());
+ List<String> expectedLoggedErrors = Arrays
+ .asList(getExpectedInvalidJsonError(), getExpectedInvalidRequiredEntryError(), getExpectedInvalidStructureError(), getExpectedInvalidTypeError(), getExpectedNoEventDefinitionError(), getExpectedUnresolvableError());
+ assertTrue(loader.getInitErrors().containsAll(expectedLoggedErrors));
+ assertEquals(expectedLoggedErrors.size(), loader.getInitErrors().size());
+ }
+
+ @Test
+ public void initWithEmptyDir() {
+ VesStructureLoaderMock loader = new VesStructureLoaderMock(true, EMPTY_SCHEMA_DIR);
+ assertTrue(loader.getAvailableVersionsList().isEmpty());
+ assertEquals("No VES schema files found", loader.getInitErrors().get(0));
+ }
+
+ @Test
+ public void initWithNoneExistingDir() {
+ VesStructureLoaderMock loader = new VesStructureLoaderMock(true, NONE_EXISTING_DIR);
+ assertTrue(loader.getAvailableVersionsList().isEmpty());
+ assertEquals("No VES schema files found", loader.getInitErrors().get(0));
+ }
+
+ @Test
+ public void complexDataTypeLoaderOutputTest() {
+ VesStructureLoaderMock loader = new VesStructureLoaderMock();
+ VesDataTypeDefinition loaded = loader.getEventListenerDefinitionByVersion("5.3").get("stateChangeFields");
+ assertEquals(buildStateChangeFieldsDefinition(), loaded);
+ }
+
+ private String getExpectedInvalidJsonError() {
+ return ERROR_TEXT + INVALID_JSON + " failed due to java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at path $";
+ }
+
+ private String getExpectedUnresolvableError() {
+ return ERROR_TEXT + UNRESOLVABLE_REFERENCES + " failed due to the following definitions containing unresolvable references: [\"otherFields\",\"stateChangeFields\",\"syslogFields\",\"thresholdCrossingAlertFields\"]";
+ }
+
+ private String getExpectedInvalidStructureError() {
+ return ERROR_TEXT + INVALID_SCHEMA_STRUCTURE + " failed due to java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 8 column 20 path $.definitions..properties[0]";
+ }
+
+ private String getExpectedInvalidTypeError() {
+ return ERROR_TEXT + INVALID_TYPE + " failed due to invalid type declaration: invalid";
+ }
+
+ private String getExpectedInvalidRequiredEntryError() {
+ return ERROR_TEXT + INVALID_REQUIRED_ENTRY + " failed due to invalid required entry: codecIdentifier(invalid)";
+ }
+
+ private String getExpectedNoEventDefinitionError() {
+ return ERROR_TEXT + NO_EVENT_PROPERTY + " failed due to schema not containing property: event";
+ }
+
+ private VesDataTypeDefinition buildFieldDefinition() {
+ Map<String, VesDataTypeDefinition> propsMap = new HashMap<>();
+ VesDataTypeDefinition prop = buildVesDataType(null, VesSimpleTypesEnum.STRING.getType(), new ArrayList<>(), null, null);
+ propsMap.put("name", prop);
+ propsMap.put("value", prop);
+ return buildVesDataType("name value pair", VesSimpleTypesEnum.OBJECT.getType(), Arrays.asList("name", "value"), propsMap, null);
+ }
+
+ private VesDataTypeDefinition buildStateChangeFieldsDefinition() {
+
+ VesDataItemsDefinition items = new VesDataItemsDefinition();
+ items.add(buildFieldDefinition());
+ VesDataTypeDefinition prop = buildVesDataType("additional stateChange fields if needed", VesSimpleTypesEnum.ARRAY.getType(), new ArrayList<>(), null, null);
+ prop.setItems(items);
+ Map<String, VesDataTypeDefinition> propsMap = new HashMap<>();
+ propsMap.put("additionalFields", prop);
+ prop = buildVesDataType("new state of the entity", VesSimpleTypesEnum.STRING.getType(), new ArrayList<>(), null, Arrays.asList("inService", "maintenance", "outOfService"));
+ propsMap.put("newState", prop);
+ prop = buildVesDataType("previous state of the entity", VesSimpleTypesEnum.STRING.getType(), new ArrayList<>(), null, Arrays.asList("inService", "maintenance", "outOfService"));
+ propsMap.put("oldState", prop);
+ prop = buildVesDataType("version of the stateChangeFields block", VesSimpleTypesEnum.NUMBER.getType(), new ArrayList<>(), null, null);
+ propsMap.put("stateChangeFieldsVersion", prop);
+ prop = buildVesDataType("card or port name of the entity that changed state", VesSimpleTypesEnum.STRING.getType(), new ArrayList<>(), null, null);
+ propsMap.put("stateInterface", prop);
+ VesDataTypeDefinition def = buildVesDataType("stateChange fields", VesSimpleTypesEnum.OBJECT.getType(), Arrays.asList("newState", "oldState", "stateChangeFieldsVersion", "stateInterface"), propsMap, null);
+ return def;
+ }
+
+ private VesDataTypeDefinition buildVesDataType(String description, String type, List<String> required, Map<String, VesDataTypeDefinition> properties, List<String> enums) {
+ VesDataTypeDefinition def = new VesDataTypeDefinition();
+ def.setDescription(description);
+ def.setType(type);
+ def.setRequired(required);
+ def.setEnums(enums);
+ def.setProperties(properties);
+ return def;
+ }
+
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1.json
new file mode 100644
index 0000000..2f86c38
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1WithoutCommonEventHeader.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1WithoutCommonEventHeader.json
new file mode 100644
index 0000000..f165818
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v4.1WithoutCommonEventHeader.json
@@ -0,0 +1,1087 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ }
+
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v5.3.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v5.3.json
new file mode 100644
index 0000000..fca55d9
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_v5.3.json
@@ -0,0 +1,2004 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": {
+ "type": "string"
+ },
+ "numberInUse": {
+ "type": "integer"
+ }
+ },
+ "required": ["codecIdentifier",
+ "numberInUse"]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": ["heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"]
+ },
+ "eventDomainThrottleSpecification": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "heartbeatInterval": {
+ "type": "integer"
+ },
+ "measurementInterval": {
+ "type": "integer"
+ }
+ },
+ "required": ["commandType"]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/command"
+ },
+ "minItems": 0
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": ["fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "sipSignaling",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert",
+ "voiceQuality"]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventName": {
+ "description": "unique event name",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "for example - applicationVnf, guestOS, hostOS, platform",
+ "type": "string"
+ },
+ "internalHeaderFields": {
+ "$ref": "#/definitions/internalHeaderFields"
+ },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "nfcNamingCode": {
+ "description": "3 character network function component type, aligned with vfc naming standards",
+ "type": "string"
+ },
+ "nfNamingCode": {
+ "description": "4 character network function type, aligned with vnf naming standards",
+ "type": "string"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": ["High",
+ "Medium",
+ "Normal",
+ "Low"]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an EMS name; may be the same as sourceName",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": ["domain",
+ "eventId",
+ "eventName",
+ "lastEpochMicrosec",
+ "priority",
+ "reportingEntityName",
+ "sequence",
+ "sourceName",
+ "startEpochMicrosec",
+ "version"]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": {
+ "type": "string",
+ "enum": ["CRIT",
+ "MAJ"]
+ },
+ "name": {
+ "type": "string"
+ },
+ "thresholdCrossed": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "required": ["criticality",
+ "name",
+ "thresholdCrossed",
+ "value"]
+ },
+ "cpuUsage": {
+ "description": "usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": {
+ "description": "cpu identifer",
+ "type": "string"
+ },
+ "cpuIdle": {
+ "description": "percentage of CPU time spent in the idle task",
+ "type": "number"
+ },
+ "cpuUsageInterrupt": {
+ "description": "percentage of time spent servicing interrupts",
+ "type": "number"
+ },
+ "cpuUsageNice": {
+ "description": "percentage of time spent running user space processes that have been niced",
+ "type": "number"
+ },
+ "cpuUsageSoftIrq": {
+ "description": "percentage of time spent handling soft irq interrupts",
+ "type": "number"
+ },
+ "cpuUsageSteal": {
+ "description": "percentage of time spent in involuntary wait which is neither user, system or idle time and is effectively time that went missing",
+ "type": "number"
+ },
+ "cpuUsageSystem": {
+ "description": "percentage of time spent on system tasks running the kernel",
+ "type": "number"
+ },
+ "cpuUsageUser": {
+ "description": "percentage of time spent running un-niced user space processes",
+ "type": "number"
+ },
+ "cpuWait": {
+ "description": "percentage of CPU time spent waiting for I/O operations to complete",
+ "type": "number"
+ },
+ "percentUsage": {
+ "description": "aggregate cpu usage of the virtual machine on which the VNFC reporting the event is running",
+ "type": "number"
+ }
+ },
+ "required": ["cpuIdentifier",
+ "percentUsage"]
+ },
+ "diskUsage": {
+ "description": "usage of an identified disk",
+ "type": "object",
+ "properties": {
+ "diskIdentifier": {
+ "description": "disk identifier",
+ "type": "string"
+ },
+ "diskIoTimeAvg": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the average over the measurement interval",
+ "type": "number"
+ },
+ "diskIoTimeLast": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the last value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskIoTimeMax": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the maximum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskIoTimeMin": {
+ "description": "milliseconds spent doing input/output operations over 1 sec; treat this metric as a device load percentage where 1000ms matches 100% load; provide the minimum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadAvg": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadLast": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the last value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadMax": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the maximum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedReadMin": {
+ "description": "number of logical read operations that were merged into physical read operations, e.g., two logical reads were served by one physical disk access; provide the minimum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteAvg": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteLast": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the last value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteMax": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the maximum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskMergedWriteMin": {
+ "description": "number of logical write operations that were merged into physical write operations, e.g., two logical writes were served by one physical disk access; provide the minimum value measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadAvg": {
+ "description": "number of octets per second read from a disk or partition; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadLast": {
+ "description": "number of octets per second read from a disk or partition; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadMax": {
+ "description": "number of octets per second read from a disk or partition; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsReadMin": {
+ "description": "number of octets per second read from a disk or partition; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteAvg": {
+ "description": "number of octets per second written to a disk or partition; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteLast": {
+ "description": "number of octets per second written to a disk or partition; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteMax": {
+ "description": "number of octets per second written to a disk or partition; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOctetsWriteMin": {
+ "description": "number of octets per second written to a disk or partition; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadAvg": {
+ "description": "number of read operations per second issued to the disk; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadLast": {
+ "description": "number of read operations per second issued to the disk; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadMax": {
+ "description": "number of read operations per second issued to the disk; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsReadMin": {
+ "description": "number of read operations per second issued to the disk; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteAvg": {
+ "description": "number of write operations per second issued to the disk; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteLast": {
+ "description": "number of write operations per second issued to the disk; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteMax": {
+ "description": "number of write operations per second issued to the disk; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskOpsWriteMin": {
+ "description": "number of write operations per second issued to the disk; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsAvg": {
+ "description": "queue size of pending I/O operations per second; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsLast": {
+ "description": "queue size of pending I/O operations per second; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsMax": {
+ "description": "queue size of pending I/O operations per second; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskPendingOperationsMin": {
+ "description": "queue size of pending I/O operations per second; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadAvg": {
+ "description": "milliseconds a read operation took to complete; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadLast": {
+ "description": "milliseconds a read operation took to complete; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadMax": {
+ "description": "milliseconds a read operation took to complete; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeReadMin": {
+ "description": "milliseconds a read operation took to complete; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteAvg": {
+ "description": "milliseconds a write operation took to complete; provide the average measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteLast": {
+ "description": "milliseconds a write operation took to complete; provide the last measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteMax": {
+ "description": "milliseconds a write operation took to complete; provide the maximum measurement within the measurement interval",
+ "type": "number"
+ },
+ "diskTimeWriteMin": {
+ "description": "milliseconds a write operation took to complete; provide the minimum measurement within the measurement interval",
+ "type": "number"
+ }
+ },
+ "required": ["diskIdentifier"]
+ },
+ "endOfCallVqmSummaries": {
+ "description": "provides end of call voice quality metrics",
+ "type": "object",
+ "properties": {
+ "adjacencyName": {
+ "description": " adjacency name",
+ "type": "string"
+ },
+ "endpointDescription": {
+ "description": "Either Caller or Callee",
+ "type": "string",
+ "enum": ["Caller",
+ "Callee"]
+ },
+ "endpointJitter": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpOctetsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpOctetsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpOctetsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpPacketsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpPacketsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "endpointRtpPacketsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "localJitter": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpOctetsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpOctetsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpOctetsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpPacketsDiscarded": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpPacketsReceived": {
+ "description": "",
+ "type": "number"
+ },
+ "localRtpPacketsSent": {
+ "description": "",
+ "type": "number"
+ },
+ "mosCqe": {
+ "description": "1-5 1dp",
+ "type": "number"
+ },
+ "packetsLost": {
+ "description": "",
+ "type": "number"
+ },
+ "packetLossPercent": {
+ "description": "Calculated percentage packet loss based on Endpoint RTP packets lost (as reported in RTCP) and Local RTP packets sent. Direction is based on Endpoint description (Caller, Callee). Decimal (2 dp)",
+ "type": "number"
+ },
+ "rFactor": {
+ "description": "0-100",
+ "type": "number"
+ },
+ "roundTripDelay": {
+ "description": "millisecs",
+ "type": "number"
+ }
+ },
+ "required": ["adjacencyName",
+ "endpointDescription"]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": {
+ "$ref": "#/definitions/commonEventHeader"
+ },
+ "faultFields": {
+ "$ref": "#/definitions/faultFields"
+ },
+ "heartbeatFields": {
+ "$ref": "#/definitions/heartbeatFields"
+ },
+ "measurementsForVfScalingFields": {
+ "$ref": "#/definitions/measurementsForVfScalingFields"
+ },
+ "mobileFlowFields": {
+ "$ref": "#/definitions/mobileFlowFields"
+ },
+ "otherFields": {
+ "$ref": "#/definitions/otherFields"
+ },
+ "sipSignalingFields": {
+ "$ref": "#/definitions/sipSignalingFields"
+ },
+ "stateChangeFields": {
+ "$ref": "#/definitions/stateChangeFields"
+ },
+ "syslogFields": {
+ "$ref": "#/definitions/syslogFields"
+ },
+ "thresholdCrossingAlertFields": {
+ "$ref": "#/definitions/thresholdCrossingAlertFields"
+ },
+ "voiceQualityFields": {
+ "$ref": "#/definitions/voiceQualityFields"
+ }
+ },
+ "required": ["commonEventHeader"]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": ["eventDomain"]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": ["normal",
+ "throttled"]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "$ref": "#/definitions/eventDomainThrottleSpecificationList"
+ }
+ },
+ "required": ["eventThrottlingMode"]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventCategory": {
+ "description": "Event category, for example: license, link, routing, security, signaling",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity",
+ "type": "string",
+ "enum": ["CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: card, host, other, port, portThreshold, router, slotThreshold, switch, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": ["Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"]
+ }
+ },
+ "required": ["alarmCondition",
+ "eventSeverity",
+ "eventSourceType",
+ "faultFieldsVersion",
+ "specificProblem",
+ "vfStatus"]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": {
+ "type": "string"
+ },
+ "featureUtilization": {
+ "type": "integer"
+ }
+ },
+ "required": ["featureIdentifier",
+ "featureUtilization"]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "required": ["name",
+ "value"]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": {
+ "type": "number"
+ },
+ "blockIops": {
+ "type": "number"
+ },
+ "blockUsed": {
+ "type": "number"
+ },
+ "ephemeralConfigured": {
+ "type": "number"
+ },
+ "ephemeralIops": {
+ "type": "number"
+ },
+ "ephemeralUsed": {
+ "type": "number"
+ },
+ "filesystemName": {
+ "type": "string"
+ }
+ },
+ "required": ["blockConfigured",
+ "blockIops",
+ "blockUsed",
+ "ephemeralConfigured",
+ "ephemeralIops",
+ "ephemeralUsed",
+ "filesystemName"]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [{
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [{
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [{
+ "type": "string"
+ },
+ {
+ "type": "number"
+ }]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": ["avgBitErrorRate",
+ "avgPacketDelayVariation",
+ "avgPacketLatency",
+ "avgReceiveThroughput",
+ "avgTransmitThroughput",
+ "flowActivationEpoch",
+ "flowActivationMicrosec",
+ "flowDeactivationEpoch",
+ "flowDeactivationMicrosec",
+ "flowDeactivationTime",
+ "flowStatus",
+ "maxPacketDelayVariation",
+ "numActivationFailures",
+ "numBitErrors",
+ "numBytesReceived",
+ "numBytesTransmitted",
+ "numDroppedPackets",
+ "numL7BytesReceived",
+ "numL7BytesTransmitted",
+ "numLostPackets",
+ "numOutOfOrderPackets",
+ "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries",
+ "numTimeouts",
+ "numTunneledL7BytesReceived",
+ "roundTripTime",
+ "timeToFirstByte"]
+ },
+ "heartbeatFields": {
+ "description": "optional field block for fields specific to heartbeat events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional heartbeat fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "heartbeatFieldsVersion": {
+ "description": "version of the heartbeatFields block",
+ "type": "number"
+ },
+ "heartbeatInterval": {
+ "description": "current heartbeat interval in seconds",
+ "type": "integer"
+ }
+ },
+ "required": ["heartbeatFieldsVersion",
+ "heartbeatInterval"]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "jsonObject": {
+ "description": "json object schema, name and other meta-information along with one or more object instances",
+ "type": "object",
+ "properties": {
+ "objectInstances": {
+ "description": "one or more instances of the jsonObject",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/jsonObjectInstance"
+ }
+ },
+ "objectName": {
+ "description": "name of the JSON Object",
+ "type": "string"
+ },
+ "objectSchema": {
+ "description": "json schema for the object",
+ "type": "string"
+ },
+ "objectSchemaUrl": {
+ "description": "Url to the json schema for the object",
+ "type": "string"
+ },
+ "nfSubscribedObjectName": {
+ "description": "name of the object associated with the nfSubscriptonId",
+ "type": "string"
+ },
+ "nfSubscriptionId": {
+ "description": "identifies an openConfig telemetry subscription on a network function, which configures the network function to send complex object data associated with the jsonObject",
+ "type": "string"
+ }
+ },
+ "required": ["objectInstances",
+ "objectName"]
+ },
+ "jsonObjectInstance": {
+ "description": "meta-information about an instance of a jsonObject along with the actual object instance",
+ "type": "object",
+ "properties": {
+ "objectInstance": {
+ "description": "an instance conforming to the jsonObject schema",
+ "type": "object"
+ },
+ "objectInstanceEpochMicrosec": {
+ "description": "the unix time aka epoch time associated with this objectInstance--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "objectKeys": {
+ "description": "an ordered set of keys that identifies this particular instance of jsonObject",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/key"
+ }
+ }
+ },
+ "required": ["objectInstance"]
+ },
+ "key": {
+ "description": "tuple which provides the name of a key along with its value and relative order",
+ "type": "object",
+ "properties": {
+ "keyName": {
+ "description": "name of the key",
+ "type": "string"
+ },
+ "keyOrder": {
+ "description": "relative sequence or order of the key with respect to other keys",
+ "type": "integer"
+ },
+ "keyValue": {
+ "description": "value of the key",
+ "type": "string"
+ }
+ },
+ "required": ["keyName"]
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": {
+ "type": "number"
+ },
+ "highEndOfLatencyBucket": {
+ "type": "number"
+ },
+ "lowEndOfLatencyBucket": {
+ "type": "number"
+ }
+ },
+ "required": ["countsInTheBucket"]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional name-value-pair fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalMeasurements": {
+ "description": "array of named name-value-pair arrays",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/namedArrayOfFields"
+ }
+ },
+ "additionalObjects": {
+ "description": "array of JSON objects described by name, schema and other meta-information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/jsonObject"
+ }
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "integer"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "integer"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "diskUsageArray": {
+ "description": "usage of an array of disks",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/diskUsage"
+ }
+ },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryUsageArray": {
+ "description": "memory usage of an array of VMs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/memoryUsage"
+ }
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "integer"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "integer"
+ },
+ "vNicPerformanceArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicPerformance"
+ }
+ }
+ },
+ "required": ["measurementInterval",
+ "measurementsForVfScalingVersion"]
+ },
+ "memoryUsage": {
+ "description": "memory usage of an identified virtual machine",
+ "type": "object",
+ "properties": {
+ "memoryBuffered": {
+ "description": "kibibytes of temporary storage for raw disk blocks",
+ "type": "number"
+ },
+ "memoryCached": {
+ "description": "kibibytes of memory used for cache",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "kibibytes of memory configured in the virtual machine on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryFree": {
+ "description": "kibibytes of physical RAM left unused by the system",
+ "type": "number"
+ },
+ "memorySlabRecl": {
+ "description": "the part of the slab that can be reclaimed such as caches measured in kibibytes",
+ "type": "number"
+ },
+ "memorySlabUnrecl": {
+ "description": "the part of the slab that cannot be reclaimed even when lacking memory measured in kibibytes",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "total memory minus the sum of free, buffered, cached and slab memory measured in kibibytes",
+ "type": "number"
+ },
+ "vmIdentifier": {
+ "description": "virtual machine identifier associated with the memory metrics",
+ "type": "string"
+ }
+ },
+ "required": ["memoryFree",
+ "memoryUsed",
+ "vmIdentifier"]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": {
+ "$ref": "#/definitions/gtpPerFlowMetrics"
+ },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "integer"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "integer"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "integer"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": ["flowDirection",
+ "gtpPerFlowMetrics",
+ "ipProtocolType",
+ "ipVersion",
+ "mobileFlowFieldsVersion",
+ "otherEndpointIpAddress",
+ "otherEndpointPort",
+ "reportingEndpointIpAddr",
+ "reportingEndpointPort"]
+ },
+ "namedArrayOfFields": {
+ "description": "an array of name value pairs along with a name for the array",
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "arrayOfFields": {
+ "description": "array of name value pairs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": ["name",
+ "arrayOfFields"]
+ },
+ "otherFields": {
+ "description": "fields for events belonging to the 'other' domain of the commonEventHeader domain enumeration",
+ "type": "object",
+ "properties": {
+ "hashOfNameValuePairArrays": {
+ "description": "array of named name-value-pair arrays",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/namedArrayOfFields"
+ }
+ },
+ "jsonObjects": {
+ "description": "array of JSON objects described by name, schema and other meta-information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/jsonObject"
+ }
+ },
+ "nameValuePairs": {
+ "description": "array of name-value pairs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "otherFieldsVersion": {
+ "description": "version of the otherFields block",
+ "type": "number"
+ }
+ },
+ "required": ["otherFieldsVersion"]
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": ["messageId",
+ "text"]
+ },
+ "sipSignalingFields": {
+ "description": "sip signaling fields",
+ "type": "object",
+ "properties": {
+ "additionalInformation": {
+ "description": "additional sip signaling fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "compressedSip": {
+ "description": "the full SIP request/response including headers and bodies",
+ "type": "string"
+ },
+ "correlator": {
+ "description": "this is the same for all events on this call",
+ "type": "string"
+ },
+ "localIpAddress": {
+ "description": "IP address on VNF",
+ "type": "string"
+ },
+ "localPort": {
+ "description": "port on VNF",
+ "type": "string"
+ },
+ "remoteIpAddress": {
+ "description": "IP address of peer endpoint",
+ "type": "string"
+ },
+ "remotePort": {
+ "description": "port of peer endpoint",
+ "type": "string"
+ },
+ "sipSignalingFieldsVersion": {
+ "description": "version of the sipSignalingFields block",
+ "type": "number"
+ },
+ "summarySip": {
+ "description": "the SIP Method or Response (‘INVITE’, ‘200 OK’, ‘BYE’, etc)",
+ "type": "string"
+ },
+ "vendorVnfNameFields": {
+ "$ref": "#/definitions/vendorVnfNameFields"
+ }
+ },
+ "required": ["correlator",
+ "localIpAddress",
+ "localPort",
+ "remoteIpAddress",
+ "remotePort",
+ "sipSignalingFieldsVersion",
+ "vendorVnfNameFields"]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": ["inService",
+ "maintenance",
+ "outOfService"]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": ["inService",
+ "maintenance",
+ "outOfService"]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": ["newState",
+ "oldState",
+ "stateChangeFieldsVersion",
+ "stateInterface"]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": ["nvPairFieldName",
+ "suppressedNvPairNames"]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed provided as name=value delimited by a pipe ‘|’ symbol, for example: 'name1=value1|name2=value2|…'",
+ "type": "string"
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "integer"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "integer"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string",
+ "enum": ["Alert",
+ "Critical",
+ "Debug",
+ "Emergency",
+ "Error",
+ "Info",
+ "Notice",
+ "Warning"]
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": ["eventSourceType",
+ "syslogFieldsVersion",
+ "syslogMsg",
+ "syslogTag"]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": ["CLEAR",
+ "CONT",
+ "SET"]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": ["CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": ["CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": ["additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp",
+ "thresholdCrossingFieldsVersion"]
+ },
+ "vendorVnfNameFields": {
+ "description": "provides vendor, vnf and vfModule identifying information",
+ "type": "object",
+ "properties": {
+ "vendorName": {
+ "description": "VNF vendor name",
+ "type": "string"
+ },
+ "vfModuleName": {
+ "description": "ASDC vfModuleName for the vfModule generating the event",
+ "type": "string"
+ },
+ "vnfName": {
+ "description": "ASDC modelName for the VNF generating the event",
+ "type": "string"
+ }
+ },
+ "required": ["vendorName"]
+ },
+ "vNicPerformance": {
+ "description": "describes the performance and errors of an identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "receivedBroadcastPacketsAccumulated": {
+ "description": "Cumulative count of broadcast packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedBroadcastPacketsDelta": {
+ "description": "Count of broadcast packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedDiscardedPacketsAccumulated": {
+ "description": "Cumulative count of discarded packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedDiscardedPacketsDelta": {
+ "description": "Count of discarded packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedErrorPacketsAccumulated": {
+ "description": "Cumulative count of error packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedErrorPacketsDelta": {
+ "description": "Count of error packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedMulticastPacketsAccumulated": {
+ "description": "Cumulative count of multicast packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedMulticastPacketsDelta": {
+ "description": "Count of multicast packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedOctetsAccumulated": {
+ "description": "Cumulative count of octets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedOctetsDelta": {
+ "description": "Count of octets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedTotalPacketsAccumulated": {
+ "description": "Cumulative count of all packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedTotalPacketsDelta": {
+ "description": "Count of all packets received within the measurement interval",
+ "type": "number"
+ },
+ "receivedUnicastPacketsAccumulated": {
+ "description": "Cumulative count of unicast packets received as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "receivedUnicastPacketsDelta": {
+ "description": "Count of unicast packets received within the measurement interval",
+ "type": "number"
+ },
+ "transmittedBroadcastPacketsAccumulated": {
+ "description": "Cumulative count of broadcast packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedBroadcastPacketsDelta": {
+ "description": "Count of broadcast packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedDiscardedPacketsAccumulated": {
+ "description": "Cumulative count of discarded packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedDiscardedPacketsDelta": {
+ "description": "Count of discarded packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedErrorPacketsAccumulated": {
+ "description": "Cumulative count of error packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedErrorPacketsDelta": {
+ "description": "Count of error packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedMulticastPacketsAccumulated": {
+ "description": "Cumulative count of multicast packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedMulticastPacketsDelta": {
+ "description": "Count of multicast packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedOctetsAccumulated": {
+ "description": "Cumulative count of octets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedOctetsDelta": {
+ "description": "Count of octets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedTotalPacketsAccumulated": {
+ "description": "Cumulative count of all packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedTotalPacketsDelta": {
+ "description": "Count of all packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "transmittedUnicastPacketsAccumulated": {
+ "description": "Cumulative count of unicast packets transmitted as read at the end of the measurement interval",
+ "type": "number"
+ },
+ "transmittedUnicastPacketsDelta": {
+ "description": "Count of unicast packets transmitted within the measurement interval",
+ "type": "number"
+ },
+ "valuesAreSuspect": {
+ "description": "Indicates whether vNicPerformance values are likely inaccurate due to counter overflow or other condtions",
+ "type": "string",
+ "enum": ["true",
+ "false"]
+ },
+ "vNicIdentifier": {
+ "description": "vNic identification",
+ "type": "string"
+ }
+ },
+ "required": ["valuesAreSuspect",
+ "vNicIdentifier"]
+ },
+ "voiceQualityFields": {
+ "description": "provides statistics related to customer facing voice products",
+ "type": "object",
+ "properties": {
+ "additionalInformation": {
+ "description": "additional voice quality fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "calleeSideCodec": {
+ "description": "callee codec for the call",
+ "type": "string"
+ },
+ "callerSideCodec": {
+ "description": "caller codec for the call",
+ "type": "string"
+ },
+ "correlator": {
+ "description": "this is the same for all events on this call",
+ "type": "string"
+ },
+ "endOfCallVqmSummaries": {
+ "$ref": "#/definitions/endOfCallVqmSummaries"
+ },
+ "phoneNumber": {
+ "description": "phone number associated with the correlator",
+ "type": "string"
+ },
+ "midCallRtcp": {
+ "description": "Base64 encoding of the binary RTCP data excluding Eth/IP/UDP headers",
+ "type": "string"
+ },
+ "vendorVnfNameFields": {
+ "$ref": "#/definitions/vendorVnfNameFields"
+ },
+ "voiceQualityFieldsVersion": {
+ "description": "version of the voiceQualityFields block",
+ "type": "number"
+ }
+ },
+ "required": ["calleeSideCodec",
+ "callerSideCodec",
+ "correlator",
+ "midCallRtcp",
+ "vendorVnfNameFields",
+ "voiceQualityFieldsVersion"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {
+ "$ref": "#/definitions/event"
+ }
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidJson.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidJson.json
new file mode 100644
index 0000000..4b5524c
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidJson.json
@@ -0,0 +1,288 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items":
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidRequiredEntry.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidRequiredEntry.json
new file mode 100644
index 0000000..3e3d3a2
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidRequiredEntry.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier(invalid)", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidSchemaStructure.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidSchemaStructure.json
new file mode 100644
index 0000000..469bf1a
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidSchemaStructure.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": [{
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }]
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidType.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidType.json
new file mode 100644
index 0000000..c925f63
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vInvalidType.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "invalid",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vNoEventProperty.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vNoEventProperty.json
new file mode 100644
index 0000000..bd4ba59
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vNoEventProperty.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "events": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vUnresolvable.json b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vUnresolvable.json
new file mode 100644
index 0000000..5439966
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/CommonEventFormat_vUnresolvable.json
@@ -0,0 +1,288 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file
diff --git a/dcaedt_be/src/test/resources/ves-schema/unsupportedFilename.json b/dcaedt_be/src/test/resources/ves-schema/unsupportedFilename.json
new file mode 100644
index 0000000..2f86c38
--- /dev/null
+++ b/dcaedt_be/src/test/resources/ves-schema/unsupportedFilename.json
@@ -0,0 +1,1165 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+
+ "definitions": {
+ "attCopyrightNotice": {
+ "description": "Copyright (c) <2016>, AT&T Intellectual Property. All other rights reserved",
+ "type": "object",
+ "properties": {
+ "useAndRedistribution": {
+ "description": "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:",
+ "type": "string"
+ },
+ "condition1": {
+ "description": "Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.",
+ "type": "string"
+ },
+ "condition2": {
+ "description": "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.",
+ "type": "string"
+ },
+ "condition3": {
+ "description": "All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the AT&T.",
+ "type": "string"
+ },
+ "condition4": {
+ "description": "Neither the name of AT&T nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.",
+ "type": "string"
+ },
+ "disclaimerLine1": {
+ "description": "THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS",
+ "type": "string"
+ },
+ "disclaimerLine2": {
+ "description": "FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
+ "type": "string"
+ },
+ "disclaimerLine3": {
+ "description": "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
+ "type": "string"
+ },
+ "disclaimerLine4": {
+ "description": "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
+ "type": "string"
+ }
+ }
+ },
+ "codecsInUse": {
+ "description": "number of times an identified codec was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "codecIdentifier": { "type": "string" },
+ "numberInUse": { "type": "number" }
+ },
+ "required": [ "codecIdentifier", "numberInUse" ]
+ },
+ "command": {
+ "description": "command from an event collector toward an event source",
+ "type": "object",
+ "properties": {
+ "commandType": {
+ "type": "string",
+ "enum": [
+ "heartbeatIntervalChange",
+ "measurementIntervalChange",
+ "provideThrottlingState",
+ "throttlingSpecification"
+ ]
+ },
+ "eventDomainThrottleSpecification": { "$ref": "#/definitions/eventDomainThrottleSpecification" },
+ "measurementInterval": { "type": "number" }
+ },
+ "required": [ "commandType" ]
+ },
+ "commandList": {
+ "description": "array of commands from an event collector toward an event source",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/commandListEntry"
+ },
+ "minItems": 0
+ },
+ "commandListEntry": {
+ "description": "reference to a command object",
+ "type": "object",
+ "properties": {
+ "command": {"$ref": "#/definitions/command"}
+ },
+ "required": [ "command" ]
+ },
+ "commonEventHeader": {
+ "description": "fields common to all events",
+ "type": "object",
+ "properties": {
+ "domain": {
+ "description": "the eventing domain associated with the event",
+ "type": "string",
+ "enum": [
+ "fault",
+ "heartbeat",
+ "measurementsForVfScaling",
+ "mobileFlow",
+ "other",
+ "stateChange",
+ "syslog",
+ "thresholdCrossingAlert"
+ ]
+ },
+ "eventId": {
+ "description": "event key that is unique to the event source",
+ "type": "string"
+ },
+ "eventType": {
+ "description": "unique event topic name",
+ "type": "string"
+ },
+ "functionalRole": {
+ "description": "function of the event source e.g., eNodeB, MME, PCRF",
+ "type": "string"
+ },
+ "internalHeaderFields": { "$ref": "#/definitions/internalHeaderFields" },
+ "lastEpochMicrosec": {
+ "description": "the latest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "priority": {
+ "description": "processing priority",
+ "type": "string",
+ "enum": [
+ "High",
+ "Medium",
+ "Normal",
+ "Low"
+ ]
+ },
+ "reportingEntityId": {
+ "description": "UUID identifying the entity reporting the event, for example an OAM VM; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "reportingEntityName": {
+ "description": "name of the entity reporting the event, for example, an OAM VM",
+ "type": "string"
+ },
+ "sequence": {
+ "description": "ordering of events communicated by an event source instance or 0 if not needed",
+ "type": "integer"
+ },
+ "sourceId": {
+ "description": "UUID identifying the entity experiencing the event issue; must be populated by the ATT enrichment process",
+ "type": "string"
+ },
+ "sourceName": {
+ "description": "name of the entity experiencing the event issue",
+ "type": "string"
+ },
+ "startEpochMicrosec": {
+ "description": "the earliest unix time aka epoch time associated with the event from any component--as microseconds elapsed since 1 Jan 1970 not including leap seconds",
+ "type": "number"
+ },
+ "version": {
+ "description": "version of the event header",
+ "type": "number"
+ }
+ },
+ "required": [ "domain", "eventId", "functionalRole", "lastEpochMicrosec",
+ "priority", "reportingEntityName", "sequence",
+ "sourceName", "startEpochMicrosec" ]
+ },
+ "counter": {
+ "description": "performance counter",
+ "type": "object",
+ "properties": {
+ "criticality": { "type": "string", "enum": [ "CRIT", "MAJ" ] },
+ "name": { "type": "string" },
+ "thresholdCrossed": { "type": "string" },
+ "value": { "type": "string"}
+ },
+ "required": [ "criticality", "name", "thresholdCrossed", "value" ]
+ },
+ "cpuUsage": {
+ "description": "percent usage of an identified CPU",
+ "type": "object",
+ "properties": {
+ "cpuIdentifier": { "type": "string" },
+ "percentUsage": { "type": "number" }
+ },
+ "required": [ "cpuIdentifier", "percentUsage" ]
+ },
+ "errors": {
+ "description": "receive and transmit errors for the measurements domain",
+ "type": "object",
+ "properties": {
+ "receiveDiscards": { "type": "number" },
+ "receiveErrors": { "type": "number" },
+ "transmitDiscards": { "type": "number" },
+ "transmitErrors": { "type": "number" }
+ },
+ "required": [ "receiveDiscards", "receiveErrors", "transmitDiscards", "transmitErrors" ]
+ },
+ "event": {
+ "description": "the root level of the common event format",
+ "type": "object",
+ "properties": {
+ "commonEventHeader": { "$ref": "#/definitions/commonEventHeader" },
+ "faultFields": { "$ref": "#/definitions/faultFields" },
+ "measurementsForVfScalingFields": { "$ref": "#/definitions/measurementsForVfScalingFields" },
+ "mobileFlowFields": { "$ref": "#/definitions/mobileFlowFields" },
+ "otherFields": { "$ref": "#/definitions/otherFields" },
+ "stateChangeFields": { "$ref": "#/definitions/stateChangeFields" },
+ "syslogFields": { "$ref": "#/definitions/syslogFields" },
+ "thresholdCrossingAlertFields": { "$ref": "#/definitions/thresholdCrossingAlertFields" }
+ },
+ "required": [ "commonEventHeader" ]
+ },
+ "eventDomainThrottleSpecification": {
+ "description": "specification of what information to suppress within an event domain",
+ "type": "object",
+ "properties": {
+ "eventDomain": {
+ "description": "Event domain enum from the commonEventHeader domain field",
+ "type": "string"
+ },
+ "suppressedFieldNames": {
+ "description": "List of optional field names in the event block that should not be sent to the Event Listener",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "suppressedNvPairsList": {
+ "description": "Optional list of specific NvPairsNames to suppress within a given Name-Value Field",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/suppressedNvPairs"
+ }
+ }
+ },
+ "required": [ "eventDomain" ]
+ },
+ "eventDomainThrottleSpecificationList": {
+ "description": "array of eventDomainThrottleSpecifications",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/eventDomainThrottleSpecification"
+ },
+ "minItems": 0
+ },
+ "eventList": {
+ "description": "array of events",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/event"
+ }
+ },
+ "eventThrottlingState": {
+ "description": "reports the throttling in force at the event source",
+ "type": "object",
+ "properties": {
+ "eventThrottlingMode": {
+ "description": "Mode the event manager is in",
+ "type": "string",
+ "enum": [
+ "normal",
+ "throttled"
+ ]
+ },
+ "eventDomainThrottleSpecificationList": { "$ref": "#/definitions/eventDomainThrottleSpecificationList" }
+ },
+ "required": [ "eventThrottlingMode" ]
+ },
+ "faultFields": {
+ "description": "fields specific to fault events",
+ "type": "object",
+ "properties": {
+ "alarmAdditionalInformation": {
+ "description": "additional alarm information",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "alarmCondition": {
+ "description": "alarm condition reported by the device",
+ "type": "string"
+ },
+ "alarmInterfaceA": {
+ "description": "card, port, channel or interface name of the device generating the alarm",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "faultFieldsVersion": {
+ "description": "version of the faultFields block",
+ "type": "number"
+ },
+ "specificProblem": {
+ "description": "short description of the alarm or problem",
+ "type": "string"
+ },
+ "vfStatus": {
+ "description": "virtual function status enumeration",
+ "type": "string",
+ "enum": [
+ "Active",
+ "Idle",
+ "Preparing to terminate",
+ "Ready to terminate",
+ "Requesting termination"
+ ]
+ }
+ },
+ "required": [ "alarmCondition", "eventSeverity",
+ "eventSourceType", "specificProblem", "vfStatus" ]
+ },
+ "featuresInUse": {
+ "description": "number of times an identified feature was used over the measurementInterval",
+ "type": "object",
+ "properties": {
+ "featureIdentifier": { "type": "string" },
+ "featureUtilization": { "type": "number" }
+ },
+ "required": [ "featureIdentifier", "featureUtilization" ]
+ },
+ "field": {
+ "description": "name value pair",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "value": { "type": "string" }
+ },
+ "required": [ "name", "value" ]
+ },
+ "filesystemUsage": {
+ "description": "disk usage of an identified virtual machine in gigabytes and/or gigabytes per second",
+ "type": "object",
+ "properties": {
+ "blockConfigured": { "type": "number" },
+ "blockIops": { "type": "number" },
+ "blockUsed": { "type": "number" },
+ "ephemeralConfigured": { "type": "number" },
+ "ephemeralIops": { "type": "number" },
+ "ephemeralUsed": { "type": "number" },
+ "filesystemName": { "type": "string" }
+ },
+ "required": [ "blockConfigured", "blockIops", "blockUsed", "ephemeralConfigured",
+ "ephemeralIops", "ephemeralUsed", "filesystemName" ]
+ },
+ "gtpPerFlowMetrics": {
+ "description": "Mobility GTP Protocol per flow metrics",
+ "type": "object",
+ "properties": {
+ "avgBitErrorRate": {
+ "description": "average bit error rate",
+ "type": "number"
+ },
+ "avgPacketDelayVariation": {
+ "description": "Average packet delay variation or jitter in milliseconds for received packets: Average difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "avgPacketLatency": {
+ "description": "average delivery latency",
+ "type": "number"
+ },
+ "avgReceiveThroughput": {
+ "description": "average receive throughput",
+ "type": "number"
+ },
+ "avgTransmitThroughput": {
+ "description": "average transmit throughput",
+ "type": "number"
+ },
+ "durConnectionFailedStatus": {
+ "description": "duration of failed state in milliseconds, computed as the cumulative time between a failed echo request and the next following successful error request, over this reporting interval",
+ "type": "number"
+ },
+ "durTunnelFailedStatus": {
+ "description": "Duration of errored state, computed as the cumulative time between a tunnel error indicator and the next following non-errored indicator, over this reporting interval",
+ "type": "number"
+ },
+ "flowActivatedBy": {
+ "description": "Endpoint activating the flow",
+ "type": "string"
+ },
+ "flowActivationEpoch": {
+ "description": "Time the connection is activated in the flow (connection) being reported on, or transmission time of the first packet if activation time is not available",
+ "type": "number"
+ },
+ "flowActivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowActivationTime": {
+ "description": "time the connection is activated in the flow being reported on, or transmission time of the first packet if activation time is not available; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowDeactivatedBy": {
+ "description": "Endpoint deactivating the flow",
+ "type": "string"
+ },
+ "flowDeactivationEpoch": {
+ "description": "Time for the start of the flow connection, in integer UTC epoch time aka UNIX time",
+ "type": "number"
+ },
+ "flowDeactivationMicrosec": {
+ "description": "Integer microseconds for the start of the flow connection",
+ "type": "number"
+ },
+ "flowDeactivationTime": {
+ "description": "Transmission time of the first packet in the flow connection being reported on; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "flowStatus": {
+ "description": "connection status at reporting time as a working / inactive / failed indicator value",
+ "type": "string"
+ },
+ "gtpConnectionStatus": {
+ "description": "Current connection state at reporting time",
+ "type": "string"
+ },
+ "gtpTunnelStatus": {
+ "description": "Current tunnel state at reporting time",
+ "type": "string"
+ },
+ "ipTosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from the IP Type-of-Service identifiers which range from '0' to '255', and the values are the count of packets that had those ToS identifiers in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "ipTosList": {
+ "description": "Array of unique IP Type-of-Service values observed in the flow where values range from '0' to '255'",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "largePacketRtt": {
+ "description": "large packet round trip time",
+ "type": "number"
+ },
+ "largePacketThreshold": {
+ "description": "large packet threshold being applied",
+ "type": "number"
+ },
+ "maxPacketDelayVariation": {
+ "description": "Maximum packet delay variation or jitter in milliseconds for received packets: Maximum of the difference between the packet timestamp and time received for all pairs of consecutive packets",
+ "type": "number"
+ },
+ "maxReceiveBitRate": {
+ "description": "maximum receive bit rate",
+ "type": "number"
+ },
+ "maxTransmitBitRate": {
+ "description": "maximum transmit bit rate",
+ "type": "number"
+ },
+ "mobileQciCosCountList": {
+ "description": "array of key: value pairs where the keys are drawn from LTE QCI or UMTS class of service strings, and the values are the count of packets that had those strings in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "mobileQciCosList": {
+ "description": "Array of unique LTE QCI or UMTS class-of-service values observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "numActivationFailures": {
+ "description": "Number of failed activation requests, as observed by the reporting node",
+ "type": "number"
+ },
+ "numBitErrors": {
+ "description": "number of errored bits",
+ "type": "number"
+ },
+ "numBytesReceived": {
+ "description": "number of bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numBytesTransmitted": {
+ "description": "number of bytes transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numDroppedPackets": {
+ "description": "number of received packets dropped due to errors per virtual interface",
+ "type": "number"
+ },
+ "numGtpEchoFailures": {
+ "description": "Number of Echo request path failures where failed paths are defined in 3GPP TS 29.281 sec 7.2.1 and 3GPP TS 29.060 sec. 11.2",
+ "type": "number"
+ },
+ "numGtpTunnelErrors": {
+ "description": "Number of tunnel error indications where errors are defined in 3GPP TS 29.281 sec 7.3.1 and 3GPP TS 29.060 sec. 11.1",
+ "type": "number"
+ },
+ "numHttpErrors": {
+ "description": "Http error count",
+ "type": "number"
+ },
+ "numL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, including retransmissions",
+ "type": "number"
+ },
+ "numL7BytesTransmitted": {
+ "description": "number of tunneled layer 7 bytes transmitted, excluding retransmissions",
+ "type": "number"
+ },
+ "numLostPackets": {
+ "description": "number of lost packets",
+ "type": "number"
+ },
+ "numOutOfOrderPackets": {
+ "description": "number of out-of-order packets",
+ "type": "number"
+ },
+ "numPacketErrors": {
+ "description": "number of errored packets",
+ "type": "number"
+ },
+ "numPacketsReceivedExclRetrans": {
+ "description": "number of packets received, excluding retransmission",
+ "type": "number"
+ },
+ "numPacketsReceivedInclRetrans": {
+ "description": "number of packets received, including retransmission",
+ "type": "number"
+ },
+ "numPacketsTransmittedInclRetrans": {
+ "description": "number of packets transmitted, including retransmissions",
+ "type": "number"
+ },
+ "numRetries": {
+ "description": "number of packet retries",
+ "type": "number"
+ },
+ "numTimeouts": {
+ "description": "number of packet timeouts",
+ "type": "number"
+ },
+ "numTunneledL7BytesReceived": {
+ "description": "number of tunneled layer 7 bytes received, excluding retransmissions",
+ "type": "number"
+ },
+ "roundTripTime": {
+ "description": "round trip time",
+ "type": "number"
+ },
+ "tcpFlagCountList": {
+ "description": "array of key: value pairs where the keys are drawn from TCP Flags and the values are the count of packets that had that TCP Flag in the flow",
+ "type": "array",
+ "items": {
+ "type": "array",
+ "items": [
+ { "type": "string" },
+ { "type": "number" }
+ ]
+ }
+ },
+ "tcpFlagList": {
+ "description": "Array of unique TCP Flags observed in the flow",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "timeToFirstByte": {
+ "description": "Time in milliseconds between the connection activation and first byte received",
+ "type": "number"
+ }
+ },
+ "required": [ "avgBitErrorRate", "avgPacketDelayVariation", "avgPacketLatency",
+ "avgReceiveThroughput", "avgTransmitThroughput",
+ "flowActivationEpoch", "flowActivationMicrosec",
+ "flowDeactivationEpoch", "flowDeactivationMicrosec",
+ "flowDeactivationTime", "flowStatus",
+ "maxPacketDelayVariation", "numActivationFailures",
+ "numBitErrors", "numBytesReceived", "numBytesTransmitted",
+ "numDroppedPackets", "numL7BytesReceived",
+ "numL7BytesTransmitted", "numLostPackets",
+ "numOutOfOrderPackets", "numPacketErrors",
+ "numPacketsReceivedExclRetrans",
+ "numPacketsReceivedInclRetrans",
+ "numPacketsTransmittedInclRetrans",
+ "numRetries", "numTimeouts", "numTunneledL7BytesReceived",
+ "roundTripTime", "timeToFirstByte"
+ ]
+ },
+ "internalHeaderFields": {
+ "description": "enrichment fields for internal VES Event Listener service use only, not supplied by event sources",
+ "type": "object"
+ },
+ "latencyBucketMeasure": {
+ "description": "number of counts falling within a defined latency bucket",
+ "type": "object",
+ "properties": {
+ "countsInTheBucket": { "type": "number" },
+ "highEndOfLatencyBucket": { "type": "number" },
+ "lowEndOfLatencyBucket": { "type": "number" }
+ },
+ "required": [ "countsInTheBucket" ]
+ },
+ "measurementGroup": {
+ "description": "measurement group",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "measurements": {
+ "description": "array of name value pair measurements",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ }
+ },
+ "required": [ "name", "measurements" ]
+ },
+ "measurementsForVfScalingFields": {
+ "description": "measurementsForVfScaling fields",
+ "type": "object",
+ "properties": {
+ "additionalMeasurements": {
+ "description": "additional measurement fields",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/measurementGroup"
+ }
+ },
+ "aggregateCpuUsage": {
+ "description": "aggregate CPU usage of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "codecUsageArray": {
+ "description": "array of codecs in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/codecsInUse"
+ }
+ },
+ "concurrentSessions": {
+ "description": "peak concurrent sessions for the VM or VNF over the measurementInterval",
+ "type": "number"
+ },
+ "configuredEntities": {
+ "description": "over the measurementInterval, peak total number of: users, subscribers, devices, adjacencies, etc., for the VM, or subscribers, devices, etc., for the VNF",
+ "type": "number"
+ },
+ "cpuUsageArray": {
+ "description": "usage of an array of CPUs",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cpuUsage"
+ }
+ },
+ "errors": { "$ref": "#/definitions/errors" },
+ "featureUsageArray": {
+ "description": "array of features in use",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/featuresInUse"
+ }
+ },
+ "filesystemUsageArray": {
+ "description": "filesystem usage of the VM on which the VNFC reporting the event is running",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/filesystemUsage"
+ }
+ },
+ "latencyDistribution": {
+ "description": "array of integers representing counts of requests whose latency in milliseconds falls within per-VNF configured ranges",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/latencyBucketMeasure"
+ }
+ },
+ "meanRequestLatency": {
+ "description": "mean seconds required to respond to each request for the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "measurementInterval": {
+ "description": "interval over which measurements are being reported in seconds",
+ "type": "number"
+ },
+ "measurementsForVfScalingVersion": {
+ "description": "version of the measurementsForVfScaling block",
+ "type": "number"
+ },
+ "memoryConfigured": {
+ "description": "memory in MB configured in the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "memoryUsed": {
+ "description": "memory usage in MB of the VM on which the VNFC reporting the event is running",
+ "type": "number"
+ },
+ "numberOfMediaPortsInUse": {
+ "description": "number of media ports in use",
+ "type": "number"
+ },
+ "requestRate": {
+ "description": "peak rate of service requests per second to the VNF over the measurementInterval",
+ "type": "number"
+ },
+ "vnfcScalingMetric": {
+ "description": "represents busy-ness of the VNF from 0 to 100 as reported by the VNFC",
+ "type": "number"
+ },
+ "vNicUsageArray": {
+ "description": "usage of an array of virtual network interface cards",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/vNicUsage"
+ }
+ }
+ },
+ "required": [ "measurementInterval" ]
+ },
+ "mobileFlowFields": {
+ "description": "mobileFlow fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional mobileFlow fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "applicationType": {
+ "description": "Application type inferred",
+ "type": "string"
+ },
+ "appProtocolType": {
+ "description": "application protocol",
+ "type": "string"
+ },
+ "appProtocolVersion": {
+ "description": "application protocol version",
+ "type": "string"
+ },
+ "cid": {
+ "description": "cell id",
+ "type": "string"
+ },
+ "connectionType": {
+ "description": "Abbreviation referencing a 3GPP reference point e.g., S1-U, S11, etc",
+ "type": "string"
+ },
+ "ecgi": {
+ "description": "Evolved Cell Global Id",
+ "type": "string"
+ },
+ "flowDirection": {
+ "description": "Flow direction, indicating if the reporting node is the source of the flow or destination for the flow",
+ "type": "string"
+ },
+ "gtpPerFlowMetrics": { "$ref": "#/definitions/gtpPerFlowMetrics" },
+ "gtpProtocolType": {
+ "description": "GTP protocol",
+ "type": "string"
+ },
+ "gtpVersion": {
+ "description": "GTP protocol version",
+ "type": "string"
+ },
+ "httpHeader": {
+ "description": "HTTP request header, if the flow connects to a node referenced by HTTP",
+ "type": "string"
+ },
+ "imei": {
+ "description": "IMEI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "imsi": {
+ "description": "IMSI for the subscriber UE used in this flow, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "ipProtocolType": {
+ "description": "IP protocol type e.g., TCP, UDP, RTP...",
+ "type": "string"
+ },
+ "ipVersion": {
+ "description": "IP protocol version e.g., IPv4, IPv6",
+ "type": "string"
+ },
+ "lac": {
+ "description": "location area code",
+ "type": "string"
+ },
+ "mcc": {
+ "description": "mobile country code",
+ "type": "string"
+ },
+ "mnc": {
+ "description": "mobile network code",
+ "type": "string"
+ },
+ "mobileFlowFieldsVersion": {
+ "description": "version of the mobileFlowFields block",
+ "type": "number"
+ },
+ "msisdn": {
+ "description": "MSISDN for the subscriber UE used in this flow, as an integer, if the flow connects to a mobile device",
+ "type": "string"
+ },
+ "otherEndpointIpAddress": {
+ "description": "IP address for the other endpoint, as used for the flow being reported on",
+ "type": "string"
+ },
+ "otherEndpointPort": {
+ "description": "IP Port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "otherFunctionalRole": {
+ "description": "Functional role of the other endpoint for the flow being reported on e.g., MME, S-GW, P-GW, PCRF...",
+ "type": "string"
+ },
+ "rac": {
+ "description": "routing area code",
+ "type": "string"
+ },
+ "radioAccessTechnology": {
+ "description": "Radio Access Technology e.g., 2G, 3G, LTE",
+ "type": "string"
+ },
+ "reportingEndpointIpAddr": {
+ "description": "IP address for the reporting entity, as used for the flow being reported on",
+ "type": "string"
+ },
+ "reportingEndpointPort": {
+ "description": "IP port for the reporting entity, as used for the flow being reported on",
+ "type": "number"
+ },
+ "sac": {
+ "description": "service area code",
+ "type": "string"
+ },
+ "samplingAlgorithm": {
+ "description": "Integer identifier for the sampling algorithm or rule being applied in calculating the flow metrics if metrics are calculated based on a sample of packets, or 0 if no sampling is applied",
+ "type": "number"
+ },
+ "tac": {
+ "description": "transport area code",
+ "type": "string"
+ },
+ "tunnelId": {
+ "description": "tunnel identifier",
+ "type": "string"
+ },
+ "vlanId": {
+ "description": "VLAN identifier used by this flow",
+ "type": "string"
+ }
+ },
+ "required": [ "flowDirection", "gtpPerFlowMetrics", "ipProtocolType",
+ "ipVersion", "otherEndpointIpAddress", "otherEndpointPort",
+ "reportingEndpointIpAddr", "reportingEndpointPort" ]
+ },
+ "otherFields": {
+ "description": "additional fields not reported elsewhere",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "requestError": {
+ "description": "standard request error data structure",
+ "type": "object",
+ "properties": {
+ "messageId": {
+ "description": "Unique message identifier of the format ABCnnnn where ABC is either SVC for Service Exceptions or POL for Policy Exception",
+ "type": "string"
+ },
+ "text": {
+ "description": "Message text, with replacement variables marked with %n, where n is an index into the list of <variables> elements, starting at 1",
+ "type": "string"
+ },
+ "url": {
+ "description": "Hyperlink to a detailed error resource e.g., an HTML page for browser user agents",
+ "type": "string"
+ },
+ "variables": {
+ "description": "List of zero or more strings that represent the contents of the variables used by the message text",
+ "type": "string"
+ }
+ },
+ "required": [ "messageId", "text" ]
+ },
+ "stateChangeFields": {
+ "description": "stateChange fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional stateChange fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "newState": {
+ "description": "new state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "oldState": {
+ "description": "previous state of the entity",
+ "type": "string",
+ "enum": [
+ "inService",
+ "maintenance",
+ "outOfService"
+ ]
+ },
+ "stateChangeFieldsVersion": {
+ "description": "version of the stateChangeFields block",
+ "type": "number"
+ },
+ "stateInterface": {
+ "description": "card or port name of the entity that changed state",
+ "type": "string"
+ }
+ },
+ "required": [ "newState", "oldState", "stateInterface" ]
+ },
+ "suppressedNvPairs": {
+ "description": "List of specific NvPairsNames to suppress within a given Name-Value Field for event Throttling",
+ "type": "object",
+ "properties": {
+ "nvPairFieldName": {
+ "description": "Name of the field within which are the nvpair names to suppress",
+ "type": "string"
+ },
+ "suppressedNvPairNames": {
+ "description": "Array of nvpair names to suppress within the nvpairFieldName",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [ "nvPairFieldName", "suppressedNvPairNames" ]
+ },
+ "syslogFields": {
+ "description": "sysLog fields",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional syslog fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "eventSourceHost": {
+ "description": "hostname of the device",
+ "type": "string"
+ },
+ "eventSourceType": {
+ "description": "type of event source; examples: other, router, switch, host, card, port, slotThreshold, portThreshold, virtualMachine, virtualNetworkFunction",
+ "type": "string"
+ },
+ "syslogFacility": {
+ "description": "numeric code from 0 to 23 for facility--see table in documentation",
+ "type": "number"
+ },
+ "syslogFieldsVersion": {
+ "description": "version of the syslogFields block",
+ "type": "number"
+ },
+ "syslogMsg": {
+ "description": "syslog message",
+ "type": "string"
+ },
+ "syslogPri": {
+ "description": "0-192 combined severity and facility",
+ "type": "number"
+ },
+ "syslogProc": {
+ "description": "identifies the application that originated the message",
+ "type": "string"
+ },
+ "syslogProcId": {
+ "description": "a change in the value of this field indicates a discontinuity in syslog reporting",
+ "type": "number"
+ },
+ "syslogSData": {
+ "description": "syslog structured data consisting of a structured data Id followed by a set of key value pairs",
+ "type": "string"
+ },
+ "syslogSdId": {
+ "description": "0-32 char in format name@number for example ourSDID@32473",
+ "type": "string"
+ },
+ "syslogSev": {
+ "description": "numerical Code for severity derived from syslogPri as remaider of syslogPri / 8",
+ "type": "string"
+ },
+ "syslogTag": {
+ "description": "msgId indicating the type of message such as TCPOUT or TCPIN; NILVALUE should be used when no other value can be provided",
+ "type": "string"
+ },
+ "syslogVer": {
+ "description": "IANA assigned version of the syslog protocol specification - typically 1",
+ "type": "number"
+ }
+ },
+ "required": [ "eventSourceType", "syslogMsg", "syslogTag" ]
+ },
+ "thresholdCrossingAlertFields": {
+ "description": "fields specific to threshold crossing alert events",
+ "type": "object",
+ "properties": {
+ "additionalFields": {
+ "description": "additional threshold crossing alert fields if needed",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/field"
+ }
+ },
+ "additionalParameters": {
+ "description": "performance counters",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/counter"
+ }
+ },
+ "alertAction": {
+ "description": "Event action",
+ "type": "string",
+ "enum": [
+ "CLEAR",
+ "CONT",
+ "SET"
+ ]
+ },
+ "alertDescription": {
+ "description": "Unique short alert description such as IF-SHUB-ERRDROP",
+ "type": "string"
+ },
+ "alertType": {
+ "description": "Event type",
+ "type": "string",
+ "enum": [
+ "CARD-ANOMALY",
+ "ELEMENT-ANOMALY",
+ "INTERFACE-ANOMALY",
+ "SERVICE-ANOMALY"
+ ]
+ },
+ "alertValue": {
+ "description": "Calculated API value (if applicable)",
+ "type": "string"
+ },
+ "associatedAlertIdList": {
+ "description": "List of eventIds associated with the event being reported",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "collectionTimestamp": {
+ "description": "Time when the performance collector picked up the data; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "dataCollector": {
+ "description": "Specific performance collector instance used",
+ "type": "string"
+ },
+ "elementType": {
+ "description": "type of network element - internal ATT field",
+ "type": "string"
+ },
+ "eventSeverity": {
+ "description": "event severity or priority",
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "MAJOR",
+ "MINOR",
+ "WARNING",
+ "NORMAL"
+ ]
+ },
+ "eventStartTimestamp": {
+ "description": "Time closest to when the measurement was made; with RFC 2822 compliant format: Sat, 13 Mar 2010 11:29:05 -0800",
+ "type": "string"
+ },
+ "interfaceName": {
+ "description": "Physical or logical port or card (if applicable)",
+ "type": "string"
+ },
+ "networkService": {
+ "description": "network name - internal ATT field",
+ "type": "string"
+ },
+ "possibleRootCause": {
+ "description": "Reserved for future use",
+ "type": "string"
+ },
+ "thresholdCrossingFieldsVersion": {
+ "description": "version of the thresholdCrossingAlertFields block",
+ "type": "number"
+ }
+ },
+ "required": [
+ "additionalParameters",
+ "alertAction",
+ "alertDescription",
+ "alertType",
+ "collectionTimestamp",
+ "eventSeverity",
+ "eventStartTimestamp"
+ ]
+ },
+ "vNicUsage": {
+ "description": "usage of identified virtual network interface card",
+ "type": "object",
+ "properties": {
+ "broadcastPacketsIn": { "type": "number" },
+ "broadcastPacketsOut": { "type": "number" },
+ "bytesIn": { "type": "number" },
+ "bytesOut": { "type": "number" },
+ "multicastPacketsIn": { "type": "number" },
+ "multicastPacketsOut": { "type": "number" },
+ "packetsIn": { "type": "number" },
+ "packetsOut": { "type": "number" },
+ "unicastPacketsIn": { "type": "number" },
+ "unicastPacketsOut": { "type": "number" },
+ "vNicIdentifier": { "type": "string" }
+ },
+ "required": [ "bytesIn", "bytesOut", "packetsIn", "packetsOut", "vNicIdentifier"]
+ }
+ },
+ "title": "Event Listener",
+ "type": "object",
+ "properties": {
+ "event": {"$ref": "#/definitions/event"}
+ }
+} \ No newline at end of file