summaryrefslogtreecommitdiffstats
path: root/core/sli
diff options
context:
space:
mode:
authorJessica Wagantall <jwagantall@linuxfoundation.org>2020-12-01 11:48:20 -0800
committerJessica Wagantall <jwagantall@linuxfoundation.org>2020-12-01 11:48:20 -0800
commit32fb53c13342d5ad353c839b7ffd0ca85d14bd48 (patch)
treef1b92068cf7b79d29e96243899e12495abb4795a /core/sli
parent53eacd8519a535f96d8b4231e48925324f1086dd (diff)
Migrate sli-core files
Migrate sli-core repo files into new directory "core". Signed-off-by: Jessica Wagantall <jwagantall@linuxfoundation.org>
Diffstat (limited to 'core/sli')
-rwxr-xr-xcore/sli/.gitignore38
-rwxr-xr-xcore/sli/common/pom.xml129
-rwxr-xr-xcore/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g467
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java41
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java46
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java51
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java38
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java45
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java45
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java100
-rwxr-xr-xcore/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java46
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java281
-rwxr-xr-xcore/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java165
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java123
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java42
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java170
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java151
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java7
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java438
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java92
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java332
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java46
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java271
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java44
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java52
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java75
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java80
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java199
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java30
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java574
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java178
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java457
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java615
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java43
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java30
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java52
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java36
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java100
-rw-r--r--core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java77
-rwxr-xr-xcore/sli/common/src/main/resources/svclogic.xsd339
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java30
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java28
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java56
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java27
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java284
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java400
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java66
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java34
-rwxr-xr-xcore/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java85
-rw-r--r--core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java38
-rw-r--r--core/sli/common/src/test/resources/2dArray.json4
-rw-r--r--core/sli/common/src/test/resources/3dArray.json4
-rw-r--r--core/sli/common/src/test/resources/ArrayMenu.json41
-rw-r--r--core/sli/common/src/test/resources/EmbeddedEscapedJson.json16
-rw-r--r--core/sli/common/src/test/resources/EscapedJson.json1
-rw-r--r--core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml70
-rw-r--r--core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml263
-rw-r--r--core/sli/common/src/test/resources/JsonObject.json5
-rw-r--r--core/sli/common/src/test/resources/ObjectMenu.json43
-rw-r--r--core/sli/common/src/test/resources/QuotedValues.json43
-rw-r--r--core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml89
-rw-r--r--core/sli/common/src/test/resources/Widget.json27
-rw-r--r--core/sli/common/src/test/resources/bad_neutron_logic_v11.xml61
-rwxr-xr-xcore/sli/common/src/test/resources/dblib.properties14
-rwxr-xr-xcore/sli/common/src/test/resources/expression.tests19
-rw-r--r--core/sli/common/src/test/resources/graphs/sliapi/graph.versions1
-rw-r--r--core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml27
-rw-r--r--core/sli/common/src/test/resources/l3sdn_logic_v10.xml208
-rw-r--r--core/sli/common/src/test/resources/log4j2.properties39
-rw-r--r--core/sli/common/src/test/resources/mergetest.xml54
-rw-r--r--core/sli/common/src/test/resources/neutron_logic_v10.xml56
-rw-r--r--core/sli/common/src/test/resources/nonsense.xml24
-rwxr-xr-xcore/sli/common/src/test/resources/parser-bad.tests3
-rwxr-xr-xcore/sli/common/src/test/resources/parser-good.tests3
-rw-r--r--core/sli/common/src/test/resources/simplelogger.properties24
-rw-r--r--core/sli/common/src/test/resources/svclogic.properties27
-rw-r--r--core/sli/common/src/test/resources/svclogic.sh32
-rwxr-xr-xcore/sli/installer/pom.xml144
-rw-r--r--core/sli/installer/src/assembly/assemble_installer_zip.xml59
-rw-r--r--core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml42
-rw-r--r--core/sli/installer/src/main/resources/scripts/install-feature.sh39
-rwxr-xr-xcore/sli/model/pom.xml27
-rwxr-xr-xcore/sli/model/src/main/yang/sliapi.yang123
-rwxr-xr-xcore/sli/model/src/main/yang/test-model@2019-07-23.yang210
-rwxr-xr-xcore/sli/pom.xml30
-rw-r--r--core/sli/provider-base/pom.xml63
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java121
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java71
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java42
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java170
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java242
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java75
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java127
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java76
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java42
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java110
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java100
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java52
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java66
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java72
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java75
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java65
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java74
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java88
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java77
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java94
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java179
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java603
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java28
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java17
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java80
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java180
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java63
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java89
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java75
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java113
-rw-r--r--core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java160
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java56
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java64
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java61
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java51
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java35
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java78
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java113
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java220
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java280
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java49
-rw-r--r--core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java33
-rw-r--r--core/sli/provider-base/src/test/resources/breakGraph.xml26
-rw-r--r--core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml23
-rw-r--r--core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml27
-rw-r--r--core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml23
-rw-r--r--core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml27
-rw-r--r--core/sli/provider-base/src/test/resources/clearSubArrayValues.xml24
-rw-r--r--core/sli/provider-base/src/test/resources/clearValues.xml22
-rw-r--r--core/sli/provider-base/src/test/resources/copyValues.xml16
-rw-r--r--core/sli/provider-base/src/test/resources/expression.tests24
-rwxr-xr-xcore/sli/provider-base/src/test/resources/expressions.xml55
-rw-r--r--core/sli/provider-base/src/test/resources/simplelogger.properties22
-rwxr-xr-xcore/sli/provider/pom.xml144
-rwxr-xr-xcore/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java1274
-rw-r--r--core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java1355
-rw-r--r--core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java98
-rw-r--r--core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java189
-rw-r--r--core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java52
-rwxr-xr-xcore/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java90
-rw-r--r--core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml36
-rw-r--r--core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml36
-rw-r--r--core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java265
-rwxr-xr-xcore/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java763
-rw-r--r--core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java37
-rw-r--r--core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java142
-rw-r--r--core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java51
-rwxr-xr-xcore/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java17
-rwxr-xr-xcore/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java134
-rw-r--r--core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java10
-rw-r--r--core/sli/provider/src/test/resources/EnumerationMapping.properties1
-rwxr-xr-xcore/sli/provider/src/test/resources/executor.tests8
-rw-r--r--core/sli/provider/src/test/resources/l3sdn.properties66
-rw-r--r--core/sli/provider/src/test/resources/l3sdn_logic_v10.xml227
-rwxr-xr-xcore/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang68
-rw-r--r--core/sli/provider/src/test/resources/simplelogger.properties22
-rw-r--r--core/sli/provider/src/test/resources/svclogic.properties27
163 files changed, 18595 insertions, 0 deletions
diff --git a/core/sli/.gitignore b/core/sli/.gitignore
new file mode 100755
index 000000000..3632ac676
--- /dev/null
+++ b/core/sli/.gitignore
@@ -0,0 +1,38 @@
+#####standard .git ignore entries#####
+
+## IDE Specific Files ##
+org.eclipse.core.resources.prefs
+.classpath
+.project
+.settings
+.idea
+.externalToolBuilders
+maven-eclipse.xml
+workspace
+
+## Compilation Files ##
+*.class
+**/target
+target
+target-ide
+MANIFEST.MF
+
+## Misc Ignores (OS specific etc) ##
+bin/
+dist
+*~
+*.ipr
+*.iml
+*.iws
+classes
+out/
+.DS_STORE
+.metadata
+
+## antlr4 generated files ##
+ExprGrammarBaseListener.java
+ExprGrammarLexer.java
+ExprGrammarListener.java
+ExprGrammarParser.java
+ExprGrammar.tokens
+ExprGrammarLexer.tokens
diff --git a/core/sli/common/pom.xml b/core/sli/common/pom.xml
new file mode 100755
index 000000000..201c11bdd
--- /dev/null
+++ b/core/sli/common/pom.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name>
+ <description>The SLI Common package includes common classes used by the various SLI subcomponents, as well as classes used by clients to interface with the service logic interpreter</description>
+
+ <properties>
+ <!-- Ignore deprecated classes in coverage counts -->
+ <sonar.coverage.exclusions>**/MessageWriter.java</sonar.coverage.exclusions>
+
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-model</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.logging-analytics</groupId>
+ <artifactId>logging-slf4j</artifactId>
+ </dependency>
+ <!-- log4j dependencies are needed to test MDC in junit tests -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-impl</artifactId>
+ </dependency>
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.skyscreamer</groupId>
+ <artifactId>jsonassert</artifactId>
+ <version>1.5.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <configuration>
+ <sourceDirectory>${basedir}/src/main/antlr4</sourceDirectory>
+ <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
+ </configuration>
+ <id>antlr</id>
+ <goals>
+ <goal>antlr4</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/core/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g4 b/core/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g4
new file mode 100755
index 000000000..42563168c
--- /dev/null
+++ b/core/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g4
@@ -0,0 +1,67 @@
+
+grammar ExprGrammar;
+
+options {
+ language = Java;
+}
+
+
+COMPAREOP : '==' | '!=' | '>' | '<' | '>=' | '<=';
+
+RELOP : 'and' | 'or';
+
+ADDOP : '+' | '-';
+
+MULTOP : '/' | '*';
+
+NUMBER : ('0'..'9')+;
+
+STRING : '\'' ~[']* '\'';
+
+IDENTIFIER : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
+
+// CONTEXT_VAR : '$' IDENTIFIER;
+
+WS: [ \n\t\r]+ -> skip;
+
+constant : NUMBER | STRING ;
+
+variableLead : ('$')? variableTerm ;
+
+variableTerm : IDENTIFIER ('[' expr ']')? ;
+
+variable : variableLead ('.' variableTerm)* ('.')?;
+
+// variable : CONTEXT_VAR ( '[' expr ']' )? ('.' IDENTIFIER )? ;
+
+atom : constant | variable;
+
+
+expr : atom
+ | parenExpr
+ | multExpr
+ | addExpr
+ | compareExpr
+ | relExpr
+ | funcExpr;
+
+parenExpr : '(' expr ')';
+
+term : atom | parenExpr | funcExpr;
+
+multExpr : term (MULTOP term)*;
+
+addExpr : multExpr (ADDOP multExpr)*;
+
+compareExpr : addExpr COMPAREOP addExpr;
+
+relExpr : compareExpr (RELOP expr)*;
+
+funcExpr : IDENTIFIER '(' expr (',' expr)* ')';
+
+
+
+
+
+
+
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java
new file mode 100644
index 000000000..a1c0eafe8
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java
@@ -0,0 +1,41 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class ActivationEntry {
+ String module;
+ String rpc;
+ String version;
+ String mode;
+
+ public ActivationEntry(String module, String rpc, String version, String mode) {
+ this.module = module;
+ this.rpc = rpc;
+ this.version = version;
+ this.mode = mode;
+ }
+
+ @Override
+ public String toString() {
+ return "ActivationEntry [module=" + module + ", rpc=" + rpc + ", version=" + version + ", mode=" + mode + "]";
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java
new file mode 100644
index 000000000..e1c0e3db5
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class BreakNodeException extends SvcLogicException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public BreakNodeException()
+ {
+ super();
+ }
+
+ public BreakNodeException(String message)
+ {
+ super(message);
+ }
+
+ public BreakNodeException(String message, Throwable t)
+ {
+ super(message, t);
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java
new file mode 100644
index 000000000..9283cf650
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.onap.ccsdk.sli.core.utils.PathValidator;
+
+import javax.xml.bind.DatatypeConverter;
+
+public class CheckSumHelper {
+
+ public static String md5SumFromFile(String pathToFile) throws NoSuchAlgorithmException, IOException {
+ if (!PathValidator.isValidXmlPath(pathToFile)) {
+ throw new IOException("Invalid XML file name");
+ }
+ byte[] b = Files.readAllBytes(Paths.get(pathToFile));
+ return md5SumFromByteArray(b);
+ }
+
+ private static String md5SumFromByteArray(byte[] input) throws NoSuchAlgorithmException {
+ byte[] hash = MessageDigest.getInstance("MD5").digest(input);
+ String hexString = DatatypeConverter.printHexBinary(hash);
+ return hexString.toLowerCase();
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java
new file mode 100644
index 000000000..b1a7320d7
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public interface CommonConstants {
+
+ String SERVICE_LOGIC_STATUS = "SvcLogic.status";
+ String JDBC_CONN_ERR = "no jdbc connection";
+ String JDBC_STATEMENT_ERR = "could not prepare statement ";
+ String SVCLOGIC_TABLE = ".SVC_LOGIC";
+ String JDBC_SELECT_COUNT = "SELECT count(*) FROM ";
+ String RESULTSET_CLOSE_ERR = "ResultSet close error: ";
+ String JDBC_SELECT_GRAPGH = "SELECT graph FROM ";
+ String JDBC_INSERT = "INSERT INTO ";
+ String JDBC_DELETE = "DELETE FROM ";
+ String JDBC_UPDATE = "UPDATE ";
+ String JDBC_GRAPH_QUERY = " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+ String JDBC_ACTIVE_GRAPH_QUERY = " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java
new file mode 100644
index 000000000..144b99a8a
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class ConfigurationException extends SvcLogicException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public ConfigurationException()
+ {
+ super();
+ }
+
+ public ConfigurationException(String msg)
+ {
+ super(msg);
+ }
+
+ public ConfigurationException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java
new file mode 100644
index 000000000..43f4fe53e
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class DuplicateValueException extends SvcLogicException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public DuplicateValueException()
+ {
+ super();
+ }
+
+ public DuplicateValueException(String message)
+ {
+ super(message);
+ }
+
+ public DuplicateValueException(String message, Throwable t)
+ {
+ super(message, t);
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java
new file mode 100644
index 000000000..47f6526e9
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java
@@ -0,0 +1,100 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+public class ErrorLogger {
+ public static final int ERROR_CODE_100 = 100;
+ public static final int ERROR_CODE_200 = 200;
+ public static final int ERROR_CODE_300 = 300;
+ public static final int ERROR_CODE_400 = 400;
+ public static final int ERROR_CODE_500 = 500;
+ public static final int ERROR_CODE_900 = 900;
+
+ private static final String DEFAULT_100_DESCRIPTION = "Permission Error";
+ private static final String DEFAULT_200_DESCRIPTION = "Availability Error or Timeout";
+ private static final String DEFAULT_300_DESCRIPTION = "Data Error";
+ private static final String DEFAULT_400_DESCRIPTION = "Schema Error";
+ private static final String DEFAULT_500_DESCRIPTION = "Business Process Error";
+ private static final String DEFAULT_900_DESCRIPTION = "Unknown Error";
+ private Logger log;
+
+ public ErrorLogger() {
+ this.log = LoggerFactory.getLogger(ErrorLogger.class);
+ }
+
+ public ErrorLogger(Logger log) {
+ this.log = log;
+ }
+
+ public void logError(String message, int errorCode) {
+ createLogEntry(message, errorCode, null, null);
+ }
+
+ public void logError(String message, int errorCode, Exception e) {
+ createLogEntry(message, errorCode, null, e);
+ }
+
+ public void logError(String message, int errorCode, String description) {
+ createLogEntry(message, errorCode, description, null);
+ }
+
+ public void logError(String message, int errorCode, String description, Exception e) {
+ createLogEntry(message, errorCode, description, e);
+ }
+
+ public void createLogEntry(String message, int errorCode, String description, Exception e) {
+ //If the error code isn't valid default it to unknown error code
+ if(!isValidCode(errorCode)) {
+ errorCode = 900;
+ }
+
+ MDC.put(ONAPLogConstants.MDCs.ERROR_CODE, String.valueOf(errorCode));
+
+ if (description == null || description.isEmpty()) {
+ description = getDefaultDescription(errorCode);
+ }
+
+ MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, description);
+ if (e != null) {
+ log.error(message, e);
+ } else {
+ log.error(message);
+ }
+ clearKeys();
+ }
+
+ public boolean isValidCode(int errorCode) {
+ if (errorCode == ERROR_CODE_100 || errorCode == ERROR_CODE_200 || errorCode == ERROR_CODE_300 || errorCode == ERROR_CODE_400 || errorCode == ERROR_CODE_500
+ || errorCode == ERROR_CODE_900) {
+ return true;
+ }
+ return false;
+ }
+
+ public String getDefaultDescription(int errorCode) {
+ if (errorCode == ERROR_CODE_100) {
+ return DEFAULT_100_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_200) {
+ return DEFAULT_200_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_300) {
+ return DEFAULT_300_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_400) {
+ return DEFAULT_400_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_500) {
+ return DEFAULT_500_DESCRIPTION;
+ }
+ return DEFAULT_900_DESCRIPTION;
+ }
+
+ public void clearKeys() {
+ MDC.remove(ONAPLogConstants.MDCs.ERROR_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.ERROR_DESC);
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java
new file mode 100755
index 000000000..f119c1812
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class ExitNodeException extends SvcLogicException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public ExitNodeException()
+ {
+ super();
+ }
+
+ public ExitNodeException(String message)
+ {
+ super(message);
+ }
+
+ public ExitNodeException(String message, Throwable t)
+ {
+ super(message, t);
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java
new file mode 100644
index 000000000..5ededb9eb
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java
@@ -0,0 +1,281 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Properties;
+import javax.sql.rowset.CachedRowSet;
+import org.onap.ccsdk.sli.core.dblib.DbLibService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Deprecated
+public class MessageWriter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MessageWriter.class);
+
+ private static final String DBLIB_SERVICE = "org.onap.ccsdk.sli.core.dblib.DBResourceManager";
+ private static final String SVCLOGIC_PROP_VAR = "SDNC_SLI_PROPERTIES";
+ private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+ private static final String INCOMING_PROPERTY_NAME = "org.onap.ccsdk.sli.MessageWriter.writeIncomingRequests";
+ private static final String OUTGOING_PROPERTY_NAME = "org.onap.ccsdk.sli.MessageWriter.writeOutgoingRequests";
+
+ private static final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ private static DbLibService dbLibService = null;
+
+ private static boolean incomingEnabled = false;
+ private static boolean outgoingEnabled = false;
+
+ private static boolean initialized = false;
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private static void init() {
+ if (initialized)
+ return;
+
+ initialized = true;
+
+ // Read properties
+ Properties props = new Properties();
+ String propPath = System.getenv(SVCLOGIC_PROP_VAR);
+
+ if (propPath == null) {
+ String propDir = System.getenv(SDNC_CONFIG_DIR);
+ if (propDir == null) {
+ propDir = "/opt/sdnc/data/properties";
+ }
+ propPath = propDir + "/svclogic.properties";
+ LOG.warn("Environment variable " + SVCLOGIC_PROP_VAR + " unset - defaulting to " + propPath);
+ }
+
+ File propFile = new File(propPath);
+
+ if (!propFile.exists()) {
+ LOG.warn("Property file does not exist: " + propPath);
+ }
+
+ try {
+ props.load(new FileInputStream(propFile));
+ } catch (Exception e) {
+ LOG.warn("Error loading property file: " + propPath, e);
+ }
+
+ incomingEnabled = Boolean.valueOf(props.getProperty(INCOMING_PROPERTY_NAME, "false"));
+ outgoingEnabled = Boolean.valueOf(props.getProperty(OUTGOING_PROPERTY_NAME, "false"));
+
+ LOG.info(INCOMING_PROPERTY_NAME + ": " + incomingEnabled);
+ LOG.info(OUTGOING_PROPERTY_NAME + ": " + outgoingEnabled);
+ }
+
+ public static void saveOutgoingRequest(
+ String requestId,
+ String serviceInstanceId,
+ String targetUrl,
+ String request) {
+ try {
+ init();
+
+ if (!outgoingEnabled)
+ return;
+
+ if (serviceInstanceId == null || serviceInstanceId.trim().length() == 0)
+ serviceInstanceId = "NA";
+
+ int seqnum = getLastSequenceNumber("OUTGOING_MESSAGE", requestId) + 1;
+ String now = df.format(new Date());
+
+ String sql = "INSERT INTO OUTGOING_MESSAGE (\n" +
+ " request_id, sequence_number, service_instance_id, target_url, request, start_time)\n" +
+ "VALUES (?, ?, ?, ?, ?, ?)";
+
+ ArrayList<String> data = new ArrayList<>();
+ data.add(requestId);
+ data.add(String.valueOf(seqnum));
+ data.add(serviceInstanceId);
+ data.add(targetUrl);
+ data.add(request);
+ data.add(now);
+
+ dbLibService.writeData(sql, data, null);
+
+ } catch (Exception e) {
+ LOG.warn("Failed to save outgoing request for request-id: " + requestId, e);
+ }
+ }
+
+ public static void saveOutgoingResponse(String requestId, int httpResponseCode, String response) {
+ try {
+ init();
+
+ if (!outgoingEnabled)
+ return;
+
+ int seqnum = getLastSequenceNumber("OUTGOING_MESSAGE", requestId);
+ if (seqnum == 0) {
+ LOG.warn("Failed to save outgoing response for request-id: " + requestId +
+ ": Request record not found in OUTGOING_MESSAGE");
+ return;
+ }
+
+ String now = df.format(new Date());
+
+ String sql = "UPDATE OUTGOING_MESSAGE SET http_response_code = ?, response = ?,\n" +
+ " duration = timestampdiff(MICROSECOND, start_time, ?) / 1000\n" +
+ "WHERE request_id = ? AND sequence_number = ?";
+
+ ArrayList<String> data = new ArrayList<>();
+ data.add(String.valueOf(httpResponseCode));
+ data.add(response);
+ data.add(now);
+ data.add(requestId);
+ data.add(String.valueOf(seqnum));
+
+ dbLibService.writeData(sql, data, null);
+
+ } catch (Exception e) {
+ LOG.warn("Failed to save outgoing response for request-id: " + requestId, e);
+ }
+ }
+
+ public static void saveIncomingRequest(
+ String requestId,
+ String serviceInstanceId,
+ String requestHost,
+ String request) {
+ try {
+ init();
+
+ if (!incomingEnabled)
+ return;
+
+ if (serviceInstanceId == null || serviceInstanceId.trim().length() == 0)
+ serviceInstanceId = "NA";
+
+ int seqnum = getLastSequenceNumber("INCOMING_MESSAGE", requestId) + 1;
+ String now = df.format(new Date());
+
+ String sql = "INSERT INTO INCOMING_MESSAGE (\n" +
+ " request_id, sequence_number, service_instance_id, request_host, request, start_time)\n" +
+ "VALUES (?, ?, ?, ?, ?, ?)";
+
+ ArrayList<String> data = new ArrayList<>();
+ data.add(requestId);
+ data.add(String.valueOf(seqnum));
+ data.add(serviceInstanceId);
+ data.add(requestHost);
+ data.add(request);
+ data.add(now);
+
+ dbLibService.writeData(sql, data, null);
+
+ } catch (Exception e) {
+ LOG.warn("Failed to save incoming request for request-id: " + requestId, e);
+ }
+ }
+
+ public static void saveIncomingResponse(String requestId, int httpResponseCode, String response) {
+ try {
+ init();
+
+ if (!incomingEnabled)
+ return;
+
+ int seqnum = getLastSequenceNumber("INCOMING_MESSAGE", requestId);
+ if (seqnum == 0) {
+ LOG.warn("Failed to save response for request-id: " + requestId +
+ ": Request record not found in INCOMING_MESSAGE");
+ return;
+ }
+
+ String now = df.format(new Date());
+
+ String sql = "UPDATE INCOMING_MESSAGE SET http_response_code = ?, response = ?,\n" +
+ " duration = timestampdiff(MICROSECOND, start_time, ?) / 1000\n" +
+ "WHERE request_id = ? AND sequence_number = ?";
+
+ ArrayList<String> data = new ArrayList<>();
+ data.add(String.valueOf(httpResponseCode));
+ data.add(response);
+ data.add(now);
+ data.add(requestId);
+ data.add(String.valueOf(seqnum));
+
+ dbLibService.writeData(sql, data, null);
+
+ } catch (Exception e) {
+ LOG.warn("Failed to save response for request-id: " + requestId, e);
+ }
+ }
+
+ public static String getServiceInstanceId(String requestId) throws SQLException {
+ init();
+
+ String sql = "SELECT service_instance_id FROM OUTGOING_MESSAGE WHERE request_id = '" + requestId +
+ "' ORDER BY sequence_number DESC";
+
+ CachedRowSet rs = null;
+ try {
+ rs = dbLibService.getData(sql, null, null);
+ if (rs.next()) {
+ return rs.getString("service_instance_id");
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (Exception e) {
+ LOG.warn("Failed to close CachedRowSet", e);
+ }
+ }
+ }
+ return null;
+ }
+
+ private static int getLastSequenceNumber(String tableName, String requestId) throws SQLException {
+ String sql = "SELECT sequence_number FROM " + tableName + " WHERE request_id = '" + requestId +
+ "' ORDER BY sequence_number DESC";
+
+ CachedRowSet rs = null;
+ try {
+ rs = dbLibService.getData(sql, null, null);
+ if (rs.next()) {
+ return rs.getInt("sequence_number");
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (Exception e) {
+ LOG.warn("Failed to close CachedRowSet", e);
+ }
+ }
+ }
+ return 0;
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java
new file mode 100755
index 000000000..577b73401
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java
@@ -0,0 +1,165 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+/**
+ * @author dt5972
+ *
+ */
+public class MetricLogger {
+
+ private static final Logger METRIC = LoggerFactory.getLogger("org.onap.ccsdk.sli.core.filters.metric");
+ private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE-RETURN");
+ private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE");
+
+ private String lastMsg = null;
+
+ public String getRequestID() {
+ return MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
+ }
+
+ public MetricLogger() {
+
+ }
+
+ @Deprecated
+ public static String asIso8601(Date date) {
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SS'+00:00'");
+ df.setTimeZone(tz);
+ return df.format(date);
+ }
+
+ @Deprecated
+ public static String asIso8601(long tsInMillis) {
+ return MetricLogger.asIso8601(new Date(tsInMillis));
+ }
+
+ @Deprecated
+ public void logRequest(String svcInstanceId, String svcName, String partnerName, String targetEntity,
+ String targetServiceName, String targetElement, String msg) {
+ logRequest(svcInstanceId, targetEntity, targetServiceName, targetElement, msg);
+ }
+
+ public void logRequest(String svcInstanceId, String targetEntity, String targetServiceName, String targetElement,
+ String msg) {
+ String timeNow = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT);
+ MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, timeNow);
+
+ // If transaction is initialized by an external client this will already be set by the audit servlet filter
+ // If the transaction is initialized by CCSDK this code will handle generating a new UUID
+ String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
+ if (requestId == null || requestId.isEmpty()) {
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, UUID.randomUUID().toString());
+ }
+
+ String randomInvocationId = UUID.randomUUID().toString();
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, randomInvocationId);
+ MDC.put(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID, randomInvocationId);
+
+ if (svcInstanceId != null) {
+ MDC.put(ONAPLogConstants.MDCs.SERVICE_INSTANCE_ID, svcInstanceId);
+ }
+ if (targetEntity != null) {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, targetEntity);
+ }
+
+ if (targetServiceName != null) {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, targetServiceName);
+ }
+
+ if (targetElement != null) {
+ MDC.put(ONAPLogConstants.MDCs.TARGET_ELEMENT, targetElement);
+ }
+ this.lastMsg = msg;
+ //During invoke status will always be INPROGRESS
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+ MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME, "0");
+ METRIC.info(INVOKE, "Invoke");
+ }
+
+ public void logResponse(String statusCode, String responseCode, String responseDescription) {
+ if (statusCode != null) {
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, statusCode);
+ }
+ if (responseCode != null) {
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, responseCode);
+ }
+ if (responseDescription != null) {
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, formatString(responseDescription));
+ }
+ ZonedDateTime endTime = ZonedDateTime.now(ZoneOffset.UTC);
+ MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, endTime.format(DateTimeFormatter.ISO_INSTANT));
+ try {
+ DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
+ ZonedDateTime entryTimestamp =
+ ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP), timeFormatter);
+ String elapedTime = Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTime));
+ MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME,elapedTime);
+ } catch (Exception e) {
+ //pass
+ }
+ METRIC.info(INVOKE_RETURN, formatString(lastMsg));
+ resetContext();
+ }
+
+ protected String formatString(String str) {
+ if (str != null) {
+ str = str.replaceAll("\\R", ""); // this will strip all new line characters
+ str = str.replaceAll("\\|", "%7C"); // log records should not contain a pipe, encode the pipe character
+ str = str.replaceAll("\t", " "); // tabs are not allowed, replace with spaces
+ str = str.replace(",", "\\,"); // comma must be escaped
+ }
+ return str;
+ }
+
+ public static void resetContext() {
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY);
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME);
+ MDC.remove(ONAPLogConstants.MDCs.TARGET_ELEMENT);
+ MDC.remove(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.RESPONSE_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION);
+ MDC.remove(ONAPLogConstants.MDCs.ELAPSED_TIME);
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java
new file mode 100644
index 000000000..e25aed9f8
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java
@@ -0,0 +1,123 @@
+
+package org.onap.ccsdk.sli.core.sli;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.TreeMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SecurePrinter {
+ private static final Logger LOG = LoggerFactory.getLogger(SecurePrinter.class);
+ private static final String DEFAULT_FILTER = "password,pass,pswd";
+ private static final String REDACTED = "***REDACTED***";
+ private static final String FILTER_PROPERTY = "NODE_STRING_FILTER";
+ private static final String SEPERATOR = " = ";
+ private static final String COMMON_ERROR_MESSAGE = "Failed to print properties";
+
+ private static String[] filterArray;
+
+ public SecurePrinter() {
+ String filterProperty = System.getProperty(FILTER_PROPERTY);
+ if (filterProperty != null && !filterProperty.isEmpty() && filterProperty.contains(",")) {
+ filterArray = filterProperty.split(",");
+ } else {
+ filterArray = DEFAULT_FILTER.split(",");
+ }
+ }
+
+ private String filterValue(String key, String value) {
+ String normalizedKey = key.toLowerCase();
+ for (String restrictedKey : filterArray) {
+ if (normalizedKey.contains(restrictedKey)) {
+ return REDACTED;
+ }
+ }
+ return value;
+ }
+
+ public void printAttributes(HashMap<String, String> attributes) {
+ if (LOG.isDebugEnabled()) {
+ for (Entry<String, String> attribute : attributes.entrySet()) {
+ String value = filterValue(attribute.getKey(), attribute.getValue());
+ LOG.debug(attribute.getKey() + SEPERATOR + value);
+ }
+ }
+ }
+
+ public void printAttributes(HashMap<String, String> attributes, String subpath) {
+ if (LOG.isDebugEnabled()) {
+ for (Entry<String, String> attribute : attributes.entrySet()) {
+ if (attribute.getKey().startsWith(subpath)) {
+ String value = filterValue(attribute.getKey(), attribute.getValue());
+ LOG.debug(attribute.getKey() + SEPERATOR + value);
+ }
+ }
+ }
+ }
+
+ public void printProperties(Properties props) {
+ if (LOG.isDebugEnabled()) {
+ try {
+ for (Entry<Object, Object> property : props.entrySet()) {
+ String keyString = (String) property.getKey();
+ String valueString = (String) property.getValue();
+ String value = filterValue(keyString, valueString);
+ LOG.debug(keyString + SEPERATOR + value);
+ }
+ } catch (Exception e) {
+ LOG.error(COMMON_ERROR_MESSAGE, e);
+ }
+ }
+ }
+
+ public void printProperties(Properties props, String subpath) {
+ if (LOG.isDebugEnabled()) {
+ try {
+ for (Entry<Object, Object> property : props.entrySet()) {
+ String keyString = (String) property.getKey();
+ if (keyString.startsWith(subpath)) {
+ String valueString = (String) property.getValue();
+ String value = filterValue(keyString, valueString);
+ LOG.debug(keyString + SEPERATOR + value);
+ }
+ }
+ } catch (Exception e) {
+ LOG.error(COMMON_ERROR_MESSAGE, e);
+ }
+ }
+ }
+
+ public void printPropertiesAlphabetically(Properties props) {
+ if (LOG.isDebugEnabled()) {
+ TreeMap<String, String> sortedMap = new TreeMap(props);
+ try {
+ for (Entry<String, String> entry : sortedMap.entrySet()) {
+ String value = filterValue(entry.getKey(), entry.getValue());
+ LOG.debug(entry.getKey() + SEPERATOR + value);
+ }
+ } catch (Exception e) {
+ LOG.error(COMMON_ERROR_MESSAGE, e);
+ }
+ }
+ }
+
+ public void printAttributesToFile(HashMap<String, String> attributes, String fileName) {
+ try (FileOutputStream fstr = new FileOutputStream(new File(fileName));
+ PrintStream pstr = new PrintStream(fstr, true);) {
+ pstr.println("#######################################");
+ for (Entry<String, String> entry : attributes.entrySet()) {
+ String value = filterValue(entry.getKey(), entry.getValue());
+ pstr.println(entry.getKey() + SEPERATOR + value);
+ }
+ } catch (Exception e) {
+ LOG.error("Cannot write context to file.", e);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java
new file mode 100644
index 000000000..a76b123ca
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.util.Map;
+
+public interface SvcLogicAdaptor {
+
+ public enum ConfigStatus {
+ SUCCESS,
+ ALREADY_ACTIVE,
+ NOT_FOUND,
+ NOT_READY,
+ FAILURE
+ }
+
+ public ConfigStatus configure(String key, Map<String,String> parameters, SvcLogicContext ctx);
+
+ public ConfigStatus activate(String key, SvcLogicContext ctx);
+
+ public ConfigStatus deactivate(String key, SvcLogicContext ctx);
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java
new file mode 100644
index 000000000..b9ad19e25
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class SvcLogicAtom extends SvcLogicExpression {
+
+ public enum AtomType {
+ NUMBER,
+ STRING,
+ IDENTIFIER,
+ CONTEXT_VAR
+
+ }
+
+ private AtomType atomType;
+ private String atom;
+
+
+ public SvcLogicAtom(String atomType, String atom)
+ {
+ this.atomType = AtomType.valueOf(atomType);
+ this.atom = atom;
+
+ }
+
+ public SvcLogicAtom(String atom)
+ {
+
+ if (atom == null)
+ {
+ this.atomType = null;
+ this.atom = null;
+ }
+ else
+ {
+ if (atom.startsWith("$"))
+ {
+ this.atomType = AtomType.CONTEXT_VAR;
+ this.atom = atom.substring(1);
+ }
+ else
+ {
+ if (Character.isDigit(atom.charAt(0)))
+ {
+ this.atomType = AtomType.NUMBER;
+ this.atom = atom;
+ }
+ else if (atom.charAt(0) == '\'')
+ {
+ this.atomType = AtomType.STRING;
+ this.atom = atom.substring(1, atom.length()-1);
+ }
+ else
+ {
+ this.atomType = AtomType.IDENTIFIER;
+ this.atom = atom;
+
+ }
+
+ }
+ }
+ }
+
+ public AtomType getAtomType() {
+ return atomType;
+ }
+
+ public void setAtomType(String newType)
+ {
+ atomType = AtomType.valueOf(newType);
+ }
+
+ public String getAtom() {
+ return atom;
+ }
+
+
+
+ public void setAtomType(AtomType atomType) {
+ this.atomType = atomType;
+ }
+
+ public void setAtom(String atom) {
+ this.atom = atom;
+ }
+
+
+
+ public String toString()
+ {
+ StringBuffer sbuff = new StringBuffer();
+ switch(getAtomType())
+ {
+ case CONTEXT_VAR:
+ sbuff.append("$");
+ case IDENTIFIER:
+ boolean needDot = false;
+ for (SvcLogicExpression term: this.getOperands())
+ {
+ if (needDot)
+ {
+ sbuff.append(".");
+ }
+ sbuff.append(term.toString());
+ needDot = true;
+ }
+ return sbuff.toString();
+ case STRING:
+ case NUMBER:
+ default:
+ return atom;
+ }
+ }
+
+ public String asParsedExpr()
+ {
+ // simplify debugging output for NUMBER type
+ if (atomType == AtomType.NUMBER) {
+ return atom;
+ }
+
+ StringBuffer sbuff = new StringBuffer();
+
+ sbuff.append("(atom");
+ sbuff.append("<");
+ sbuff.append(atomType.toString());
+ sbuff.append(">");
+
+ switch(atomType)
+ {
+ case IDENTIFIER:
+ case CONTEXT_VAR:
+ for (SvcLogicExpression term : getOperands())
+ {
+ sbuff.append(" ");
+ sbuff.append(term.asParsedExpr());
+
+ }
+ break;
+ default:
+ sbuff.append(" ");
+ sbuff.append(atom);
+ }
+
+ sbuff.append(")");
+ return sbuff.toString();
+ }
+
+
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java
new file mode 100644
index 000000000..a990dd950
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class SvcLogicBinaryExpression extends SvcLogicExpression {
+
+
+ public enum OperatorType {
+ addOp("+"),
+ subOp("-"),
+ multOp("*"),
+ divOp("/"),
+ equalOp("=="),
+ ltOp("<"),
+ leOp("<="),
+ gtOp(">"),
+ geOp(">="),
+ neOp("!="),
+ andOp("and"),
+ orOp("or");
+
+ private String text;
+
+ private OperatorType(String text)
+ {
+ this.text = text;
+ }
+
+ public String getText()
+ {
+ return(text);
+ }
+
+ public static OperatorType fromString(String text)
+ {
+ if (text != null)
+ {
+ for (OperatorType t : OperatorType.values())
+ {
+ if (text.equalsIgnoreCase(t.getText())) {
+
+ return(t);
+ }
+ }
+ }
+ return(null);
+ }
+
+ public String toString()
+ {
+ return(text);
+ }
+ }
+ private List<OperatorType> operators;
+
+ public List<OperatorType> getOperators() {
+ return operators;
+ }
+
+ public SvcLogicBinaryExpression()
+ {
+ operators = new LinkedList<>();
+ }
+
+ public void addOperator(String operator)
+ {
+ operators.add(OperatorType.fromString(operator));
+ }
+
+
+ public String toString()
+ {
+
+ List<SvcLogicExpression>operands = getOperands();
+ StringBuffer sbuff = new StringBuffer();
+
+ sbuff.append(operands.get(0).toString());
+ for (int i = 0 ; i < operators.size(); i++)
+ {
+ sbuff.append(" ");
+ sbuff.append(operators.get(i));
+ sbuff.append(" ");
+ if (i + 1 < operands.size()) {
+ sbuff.append(operands.get(i + 1).toString());
+ } else {
+ // expression incomplete; operand not bound yet
+ sbuff.append("?");
+ }
+ }
+
+ return(sbuff.toString());
+
+ }
+
+ public String asParsedExpr() {
+
+ List<SvcLogicExpression> operands = getOperands();
+
+ if (operators.isEmpty()) {
+ return operands.get(0).asParsedExpr();
+ } else {
+ StringBuffer sbuff = new StringBuffer();
+ // operators in reverse order for left associativity
+ for (int i = operators.size() - 1; i >= 0; --i) {
+ sbuff.append("(");
+ sbuff.append(operators.get(i).getText());
+ sbuff.append(" ");
+ }
+ for (int i = 0; i < operators.size() + 1; ++i) {
+ if (i < operands.size()) {
+ sbuff.append(operands.get(i).asParsedExpr());
+ } else {
+ // expression incomplete; operand not bound yet
+ sbuff.append("?");
+ }
+ if (i != 0) {
+ sbuff.append(")");
+ }
+ if (i < operators.size()) {
+ sbuff.append(" ");
+ }
+ }
+ return sbuff.toString();
+ }
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java
new file mode 100644
index 000000000..61bfe7c20
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java
@@ -0,0 +1,7 @@
+package org.onap.ccsdk.sli.core.sli;
+
+public class SvcLogicConstants {
+ public final static String SUCCESS = "success";
+ public final static String FAILURE = "failure";
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java
new file mode 100644
index 000000000..98cf7e05e
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java
@@ -0,0 +1,438 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.util.*;
+
+import com.google.gson.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+
+public class SvcLogicContext {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicContext.class);
+ private final SecurePrinter securePrinter = new SecurePrinter();
+ public static final String CTX_NULL_VALUE="";
+ private static final String LENGTH="_length";
+
+ private HashMap<String, String> attributes;
+
+ private String status = SvcLogicConstants.SUCCESS;
+
+ public SvcLogicContext() {
+ this.attributes = new HashMap<>();
+
+ }
+
+ public SvcLogicContext(Properties props) {
+ this.attributes = new HashMap<>();
+
+ if (props.containsKey(CommonConstants.SERVICE_LOGIC_STATUS)) {
+ this.status = props.getProperty(CommonConstants.SERVICE_LOGIC_STATUS);
+ }
+
+ for (Object nameObj : props.keySet()) {
+ String propName = (String) nameObj;
+ attributes.put(propName, props.getProperty(propName));
+ }
+ }
+
+ public String getAttribute(String name) {
+ if (attributes.containsKey(name)) {
+ return attributes.get(name);
+ } else {
+ return null;
+ }
+ }
+
+ public void setAttribute(String name, String value) {
+ if (value == null) {
+ if (attributes.containsKey(name)) {
+ attributes.remove(name);
+ }
+ } else {
+ attributes.put(name, value);
+ }
+ }
+
+ public Set<String> getAttributeKeySet() {
+ return attributes.keySet();
+ }
+
+ public Boolean isSuccess() {
+ return status.equals(SvcLogicConstants.SUCCESS);
+ }
+
+ @Deprecated
+ public String getStatus() {
+ return status;
+ }
+
+ @Deprecated
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public void markFailed() {
+ this.status = SvcLogicConstants.FAILURE;
+ }
+
+ public void markSuccess() {
+ this.status = SvcLogicConstants.SUCCESS;
+ }
+
+ public Properties toProperties() {
+ Properties props = new Properties();
+
+ if (status != null) {
+ props.setProperty(CommonConstants.SERVICE_LOGIC_STATUS, status);
+ }
+
+ String attrName;
+ String attrVal;
+ for (Map.Entry<String, String> entry : attributes.entrySet()) {
+ attrName = entry.getKey();
+ attrVal = entry.getValue();
+ if (attrVal == null) {
+ LOG.warn("attribute {} value is null - setting to empty string", attrName);
+ props.setProperty(attrName, "");
+ } else {
+ props.setProperty(attrName, attrVal);
+ }
+ }
+
+ return props;
+ }
+
+ public void mergeDocument(String pfx, Document doc) {
+ String prefix = "";
+
+ if (pfx != null) {
+ prefix = pfx;
+ }
+
+ Element root = doc.getDocumentElement();
+
+ mergeElement(prefix, root, null);
+ }
+
+ public void mergeElement(String pfx, Element element, Map<String, Integer> nodeMap) {
+
+ // In XML, cannot tell the difference between containers and lists.
+ // So, have to treat each element as both (ugly but necessary).
+ // We do this by passing a nodeMap to be used to count instance of each tag,
+ // which will be used to set _length and to set index
+
+ LOG.trace("mergeElement({},{},{})", pfx, element.getTagName(), nodeMap);
+
+ String curTagName = element.getTagName();
+ String prefix = curTagName;
+
+ if (pfx != null) {
+ prefix = pfx + "." + prefix;
+ }
+
+ int myIdx = 0;
+
+ if (nodeMap != null) {
+ if (nodeMap.containsKey(curTagName)) {
+ myIdx = nodeMap.get(curTagName);
+ }
+
+ nodeMap.put(curTagName, myIdx + 1);
+ this.setAttribute(prefix + "_length", Integer.toString(myIdx + 1));
+ }
+
+ NodeList children = element.getChildNodes();
+
+ int numChildren = children.getLength();
+
+ Map<String, Integer> childMap = new HashMap<>();
+ Map<String, Integer> idxChildMap = new HashMap<>();
+
+ for (int i = 0; i < numChildren; i++) {
+ Node curNode = children.item(i);
+
+ if (curNode instanceof Text) {
+ Text curText = (Text) curNode;
+ String curTextValue = curText.getTextContent();
+ LOG.trace("Setting ctx variable {} = {}", prefix, curTextValue);
+ this.setAttribute(prefix, curText.getTextContent());
+
+
+ } else if (curNode instanceof Element) {
+ mergeElement(prefix, (Element) curNode, childMap);
+ if (nodeMap != null) {
+
+ mergeElement(prefix + "[" + myIdx + "]", (Element) curNode, idxChildMap);
+
+ }
+ }
+ }
+
+ }
+
+ public void mergeJson(String pfx, String jsonString) {
+
+ JsonParser jp = new JsonParser();
+ JsonElement element = jp.parse(jsonString);
+ String root = "";
+ if ((pfx != null) && (pfx.length() > 0)) {
+ root = pfx + ".";
+ }
+ if (element.isJsonObject()) {
+ writeJsonObject(element.getAsJsonObject(), root);
+ } else if (element.isJsonArray()) {
+ handleJsonArray("", element.getAsJsonArray(), root);
+ }
+ }
+
+
+ protected void writeJsonObject(JsonObject obj, String root) {
+ for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
+ String key = entry.getKey();
+ if (entry.getValue().isJsonObject()) {
+ writeJsonObject(entry.getValue().getAsJsonObject(), root + key + ".");
+ } else if (entry.getValue().isJsonArray()) {
+ JsonArray array = entry.getValue().getAsJsonArray();
+ handleJsonArray(key, array, root);
+ } else {
+ //Handles when a JSON obj is nested within a JSON obj
+ if(!root.endsWith(".")){
+ root = root + ".";
+ }
+ if(entry.getValue().isJsonNull()) {
+ this.setAttribute(root + key, CTX_NULL_VALUE);
+ }else {
+ this.setAttribute(root + key, entry.getValue().getAsString());
+ }
+ }
+ }
+ }
+
+ protected void handleJsonArray(String key, JsonArray array, String root) {
+ this.setAttribute(root + key + LENGTH, String.valueOf(array.size()));
+ Integer arrayIdx = 0;
+ for (JsonElement element : array) {
+ String prefix = root + key + "[" + arrayIdx + "]";
+
+ if (element.isJsonArray()) {
+ handleJsonArray(key, element.getAsJsonArray(), prefix);
+ } else if (element.isJsonObject()) {
+ writeJsonObject(element.getAsJsonObject(), prefix + ".");
+ } else if (element.isJsonNull()) {
+ this.setAttribute(prefix, CTX_NULL_VALUE);
+ } else if (element.isJsonPrimitive()) {
+ this.setAttribute(prefix, element.getAsString());
+ }
+ arrayIdx++;
+ }
+ }
+
+
+ public String resolve(String ctxVarName) {
+
+ if (ctxVarName.indexOf('[') == -1) {
+ // Ctx variable contains no arrays
+ return getAttribute(ctxVarName);
+ }
+
+ // Resolve any array references
+ StringBuilder sbuff = new StringBuilder();
+ String[] ctxVarParts = ctxVarName.split("\\[");
+ sbuff.append(ctxVarParts[0]);
+ for (int i = 1; i < ctxVarParts.length; i++) {
+ if (ctxVarParts[i].startsWith("$")) {
+ int endBracketLoc = ctxVarParts[i].indexOf(']');
+ if (endBracketLoc == -1) {
+ // Missing end bracket ... give up parsing
+ LOG.warn("Variable reference {} seems to be missing a ']'", ctxVarName);
+ return getAttribute(ctxVarName);
+ }
+
+ String idxVarName = ctxVarParts[i].substring(1, endBracketLoc);
+ String remainder = ctxVarParts[i].substring(endBracketLoc);
+
+ sbuff.append("[");
+ sbuff.append(this.getAttribute(idxVarName));
+ sbuff.append(remainder);
+
+ } else {
+ // Index is not a variable reference
+ sbuff.append("[");
+ sbuff.append(ctxVarParts[i]);
+ }
+ }
+
+ return getAttribute(sbuff.toString());
+ }
+
+ public String toJsonString(String pfx) {
+ JsonParser jp = new JsonParser();
+
+ String jsonString = this.toJsonString();
+ JsonObject jsonRoot = (JsonObject) jp.parse(jsonString);
+ JsonObject targetJson = jsonRoot.getAsJsonObject(pfx);
+ if (targetJson == null) {
+ return("");
+ } else {
+ return(targetJson.toString());
+ }
+ }
+
+ public String toJsonString() {
+ JsonObject root = new JsonObject();
+ JsonElement lastJsonObject = root;
+ JsonElement currJsonLeaf = root;
+
+ String attrName = null;
+ String attrVal = null;
+
+ // Sort properties so that arrays will be reconstructed in proper order
+ TreeMap<String, String> sortedAttributes = new TreeMap<>();
+ sortedAttributes.putAll(attributes);
+
+ // Loop through properties, sorted by key
+ for (Map.Entry<String, String> entry : sortedAttributes.entrySet()) {
+ attrName = entry.getKey();
+ attrVal = entry.getValue();
+
+ currJsonLeaf = root;
+ String curFieldName = null;
+ JsonArray curArray = null;
+ lastJsonObject = null;
+ boolean addNeeded = false;
+
+ // Split property names by period and iterate through parts
+ for (String attrNamePart : attrName.split("\\.")) {
+
+ // Add last object found to JSON tree. Need to handle
+ // this way because last element found (leaf) needs to be
+ // assigned the property value.
+ if (lastJsonObject != null) {
+ if (addNeeded) {
+ if (currJsonLeaf.isJsonArray()) {
+ ((JsonArray) currJsonLeaf).add(lastJsonObject);
+ } else {
+ ((JsonObject) currJsonLeaf).add(curFieldName, lastJsonObject);
+ }
+ }
+ currJsonLeaf = (JsonObject) lastJsonObject;
+ }
+ addNeeded = false;
+ // See if current level should be a JsonArray or JsonObject based on
+ // whether name part contains square brackets.
+ if (!attrNamePart.contains("[")) {
+ // This level should be inserted as a JsonObject
+ curFieldName = attrNamePart;
+ lastJsonObject = ((JsonObject) currJsonLeaf).get(curFieldName);
+ if (lastJsonObject == null) {
+ lastJsonObject = new JsonObject();
+ addNeeded = true;
+ } else if (!lastJsonObject.isJsonObject()) {
+ LOG.error("Unexpected condition - expecting to find JsonObject, but found " + lastJsonObject.getClass().getName());
+ lastJsonObject = new JsonObject();
+ addNeeded = true;
+ }
+ } else {
+ // This level should be inserted as a JsonArray.
+
+ String[] curFieldNameParts = attrNamePart.split("[\\[\\]]");
+ curFieldName = curFieldNameParts[0];
+ int curIndex = Integer.parseInt(curFieldNameParts[1]);
+
+
+ curArray = ((JsonObject) currJsonLeaf).getAsJsonArray(curFieldName);
+
+ if (curArray == null) {
+ // This is the first time we see this array.
+ // Create a new JsonArray and add it to current
+ // leaf
+ curArray = new JsonArray();
+ ((JsonObject) currJsonLeaf).add(curFieldName, curArray);
+ }
+
+ // Current leaf should point to the JsonArray for this level.
+ // lastJsonObject should point to the array item entry to append
+ // the next level to - which is a new one if the index value
+ // isn't the end of the current array.
+ currJsonLeaf = curArray;
+ if (curArray.size() == curIndex + 1) {
+ lastJsonObject = curArray.get(curArray.size() - 1);
+ } else {
+ lastJsonObject = new JsonObject();
+ addNeeded = true;
+ }
+ }
+ }
+
+ // Done parsing property name. Add the value of this
+ // property to the current json leaf, either as a property
+ // or as a string (if the current leaf is a JsonArray)
+
+ if (!curFieldName.endsWith("_length")) {
+ if (currJsonLeaf.isJsonArray()) {
+ if ("true".equals(attrVal) || "false".equals(attrVal)) {
+ ((JsonArray) currJsonLeaf).add(Boolean.valueOf(attrVal));
+ } else if ("null".equals(attrVal)) {
+ ((JsonArray) currJsonLeaf).add(new JsonNull());
+ } else {
+ ((JsonArray) currJsonLeaf).add(attrVal);
+ }
+ } else {
+ if (("true".equals(attrVal) || "false".equals(attrVal))) {
+ ((JsonObject) currJsonLeaf).addProperty(curFieldName, Boolean.valueOf(attrVal));
+ } else if ("null".equals(attrVal)){
+
+ ((JsonObject) currJsonLeaf).add(curFieldName, new JsonNull());
+ } else {
+ ((JsonObject) currJsonLeaf).addProperty(curFieldName, attrVal);
+ }
+ }
+ }
+ }
+
+ return (root.toString());
+ }
+
+ public void printProperties(Properties props) {
+ securePrinter.printProperties(props);
+ }
+
+ public void printAttributes() {
+ securePrinter.printAttributes(attributes);
+ }
+
+ public void printProperties(Properties props, String subpath) {
+ securePrinter.printProperties(props, subpath);
+ }
+
+ public void printAttributes(String subpath) {
+ securePrinter.printAttributes(attributes, subpath);
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java
new file mode 100644
index 000000000..c6fd8b6a2
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli;
+
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SvcLogicCrawler extends SimpleFileVisitor<Path> {
+
+ private List<Path> xmlGraphPathList;
+ private List<Path> activationFilePathList;
+
+ public SvcLogicCrawler() {
+ xmlGraphPathList = new ArrayList<>();
+ activationFilePathList = new ArrayList<>();
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
+ if (attr.isRegularFile()) {
+ String fileName = file.getFileName().toString();
+ if (!file.toString().contains(".git") && !fileName.equals("pom.xml") && !fileName.equals("assemble_zip.xml") && !fileName.equals("assemble_zip_less_config.xml") && !fileName.equals("descriptor.xml")) {
+ if (fileName.endsWith(".xml")) {
+ xmlGraphPathList.add(file);
+ }
+ else if (fileName.endsWith(".versions")) {
+ activationFilePathList.add(file);
+ }
+ }
+ }
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file, IOException exc) {
+ System.err.println("Couldn't visitFile");
+ System.err.println(exc.getMessage());
+ return CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+ String[] skipDirectories = {".git"};
+ for (String str : skipDirectories) {
+ if (dir.endsWith(str)) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ }
+ return CONTINUE;
+ }
+
+ public List<Path> getGraphPaths() {
+ return this.xmlGraphPathList;
+ }
+
+ public List<Path> getActivationPaths() {
+ return this.activationFilePathList;
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java
new file mode 100644
index 000000000..dc3a560eb
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java
@@ -0,0 +1,332 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Properties;
+import javax.sql.rowset.CachedRowSet;
+import org.onap.ccsdk.sli.core.dblib.DbLibService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicDblibStore implements SvcLogicStore {
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicDblibStore.class);
+ private DbLibService dbSvc;
+
+ public SvcLogicDblibStore(DbLibService dbsvc) {
+ this.dbSvc = dbsvc;
+ }
+
+ public Connection getConnection() throws SQLException {
+ return(dbSvc.getConnection());
+ }
+
+ @Override
+ public void init(Properties props) throws ConfigurationException {
+ if(dbSvc == null) {
+ LOG.error("SvcLogic cannot acquire DBLIB_SERVICE");
+ return;
+ }
+ try {
+ dbSvc.getData("select 1 from DUAL", new ArrayList<String>(), null);
+ LOG.debug("SQL test was successful");
+ } catch (SQLException e) {
+ LOG.error("Failed SQL test", e);
+ }
+ }
+
+ @Override
+ public boolean hasGraph(String module, String rpc, String version,
+ String mode) throws SvcLogicException {
+ boolean retval = false;
+ CachedRowSet results = null;
+ String hasVersionGraphSql = "SELECT count(*) FROM SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+
+ String hasActiveGraphSql = "SELECT count(*) FROM SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
+
+ ArrayList<String> args = new ArrayList<>();
+ args.add(module);
+ args.add(rpc);
+ args.add(mode);
+
+ try {
+
+ if (version == null) {
+ results = dbSvc.getData(hasActiveGraphSql, args, null);
+ } else {
+ args.add(version);
+ results = dbSvc.getData(hasVersionGraphSql, args, null);
+ }
+
+ if (results.next()) {
+ int cnt = results.getInt(1);
+
+ if (cnt > 0) {
+ retval = true;
+ }
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("SQL query failed", e);
+ } finally {
+ if (results != null) {
+ try {
+ results.close();
+ } catch (SQLException x) {
+ LOG.error("Failed to close CachedRowSet", x);
+ }
+ }
+
+ }
+
+ return retval;
+ }
+
+ public SvcLogicGraph fetch(String module, String rpc, String version,
+ String mode) throws SvcLogicException {
+
+ PreparedStatement fetchGraphStmt = null;
+ Connection dbConn = null;
+ SvcLogicGraph retval = null;
+ ResultSet results = null;
+
+ String fetchVersionGraphSql = "SELECT graph FROM SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+
+ String fetchActiveGraphSql = "SELECT graph FROM SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
+
+
+ try {
+ dbConn = dbSvc.getConnection();
+
+ if (version == null) {
+ fetchGraphStmt = dbConn.prepareStatement(fetchActiveGraphSql);
+ } else {
+ fetchGraphStmt = dbConn.prepareStatement(fetchVersionGraphSql);
+ }
+
+ fetchGraphStmt.setString(1, module);
+ fetchGraphStmt.setString(2, rpc);
+ fetchGraphStmt.setString(3, mode);
+ if (version != null) {
+ fetchGraphStmt.setString(4,version);
+ }
+
+ results = fetchGraphStmt.executeQuery();
+
+ if (results.next()) {
+ Blob graphBlob = results.getBlob("graph");
+
+ ObjectInputStream gStream = new ObjectInputStream(graphBlob.getBinaryStream());
+
+ Object graphObj = gStream.readObject();
+ gStream.close();
+
+ if (graphObj instanceof SvcLogicGraph) {
+ retval = (SvcLogicGraph) graphObj;
+ } else {
+ throw new ConfigurationException("invalid type for graph ("
+ + graphObj.getClass().getName());
+
+ }
+
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ LOG.error("Graph processing failed", e);
+ throw new ConfigurationException("Graph processing failed: " + e.getMessage());
+ } finally {
+ try {
+ if (fetchGraphStmt != null) {
+ fetchGraphStmt.close();
+ }
+ } catch (SQLException e) {
+ LOG.error("PreparedStatement close error", e);
+ }
+ if (results != null) {
+ try {
+ results.close();
+ } catch (SQLException x) {
+ LOG.error("ResultSet close error", x);
+ }
+ }
+ try {
+ if (dbConn != null && !dbConn.isClosed()) {
+ dbConn.close();
+ }
+ } catch (Exception exc) {
+ LOG.error("dbConn close error", exc);
+ } finally {
+ dbConn = null;
+ }
+
+ }
+
+ return retval;
+ }
+
+ public void store(SvcLogicGraph graph) throws SvcLogicException {
+
+
+
+ String storeGraphSql = "INSERT INTO SVC_LOGIC (module, rpc, version, mode, active, graph, md5sum)"
+ + " VALUES(?, ?, ?, ?, ?, ?, ?)";
+
+ if (graph == null) {
+ throw new SvcLogicException("graph cannot be null");
+ }
+
+ byte[] graphBytes = null;
+
+ try (ByteArrayOutputStream byteStr = new ByteArrayOutputStream();
+ ObjectOutputStream goutStr = new ObjectOutputStream(byteStr)) {
+
+ goutStr.writeObject(graph);
+
+ graphBytes = byteStr.toByteArray();
+
+ } catch (Exception e) {
+ throw new SvcLogicException("could not serialize graph", e);
+ }
+
+ // If object already stored in database, delete it
+ if (hasGraph(graph.getModule(), graph.getRpc(), graph.getVersion(),
+ graph.getMode())) {
+ delete(graph.getModule(), graph.getRpc(), graph.getVersion(),
+ graph.getMode());
+ }
+
+ Connection dbConn = null;
+ PreparedStatement storeGraphStmt = null;
+ try {
+ dbConn = dbSvc.getConnection();
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ storeGraphStmt = dbConn.prepareStatement(storeGraphSql);
+ storeGraphStmt.setString(1, graph.getModule());
+ storeGraphStmt.setString(2, graph.getRpc());
+ storeGraphStmt.setString(3, graph.getVersion());
+ storeGraphStmt.setString(4, graph.getMode());
+ storeGraphStmt.setString(5, "N");
+ storeGraphStmt.setBlob(6, new ByteArrayInputStream(graphBytes));
+ storeGraphStmt.setString(7, graph.getMd5sum());
+ storeGraphStmt.executeUpdate();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not write object to database", e);
+ } finally {
+ try {
+ if (storeGraphStmt != null) {
+ storeGraphStmt.close();
+ }
+ } catch (SQLException e) {
+ LOG.error("PreparedStatement close error", e);
+ }
+ try {
+ if (dbConn != null && !dbConn.isClosed()) {
+ dbConn.close();
+ }
+ } catch (Exception exc) {
+ LOG.error("dbConn close error", exc);
+ } finally {
+ dbConn = null;
+ }
+
+ }
+ }
+
+ public void delete(String module, String rpc, String version, String mode)
+ throws SvcLogicException {
+ String deleteGraphSql = "DELETE FROM SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?";
+
+ ArrayList<String> args = new ArrayList<>();
+
+ args.add(module);
+ args.add(rpc);
+ args.add(version);
+ args.add(mode);
+
+ try {
+ dbSvc.writeData(deleteGraphSql, args, null);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not delete object from database", e);
+ }
+ }
+
+ public void activate(SvcLogicGraph graph) throws SvcLogicException {
+ String deactivateSql = "UPDATE SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?";
+ String activateSql = "UPDATE SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+
+ ArrayList<String> args = new ArrayList<>();
+
+ args.add(graph.getModule());
+ args.add(graph.getRpc());
+ args.add(graph.getMode());
+
+ try {
+ dbSvc.writeData(deactivateSql, args, null);
+ args.add(graph.getVersion());
+ dbSvc.writeData(activateSql, args, null);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not activate graph", e);
+ }
+ }
+
+ @Override
+ public void activate(String module, String rpc, String version, String mode) throws SvcLogicException {
+
+ String deactivateSql = "UPDATE SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?";
+
+ String activateSql = "UPDATE SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+
+ ArrayList<String> args = new ArrayList<>();
+
+ args.add(module);
+ args.add(rpc);
+ args.add(mode);
+
+ try {
+
+ dbSvc.writeData(deactivateSql, args, null);
+
+ args.add(version);
+ dbSvc.writeData(activateSql, args, null);
+
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not activate graph", e);
+ }
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java
new file mode 100644
index 000000000..c03ef9787
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class SvcLogicException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public SvcLogicException()
+ {
+ super();
+ }
+
+ public SvcLogicException(String message)
+ {
+ super(message);
+ }
+
+ public SvcLogicException(String message, Throwable t)
+ {
+ super(message, t);
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java
new file mode 100644
index 000000000..a1871951f
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java
@@ -0,0 +1,271 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.AddExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.AtomContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.CompareExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ConstantContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.FuncExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.MultExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ParenExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.RelExprContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.VariableContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.VariableLeadContext;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.VariableTermContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicExprListener extends ExprGrammarBaseListener
+{
+
+
+
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExprListener.class);
+
+ private SvcLogicExpression curExpr;
+ //private SvcLogicExpression topExpr;
+ private LinkedList<SvcLogicExpression> exprStack;
+
+ public SvcLogicExprListener()
+ {
+ exprStack = new LinkedList<>();
+ }
+
+ public SvcLogicExpression getParsedExpr()
+ {
+ return(curExpr);
+ }
+
+ private void pushOperand(SvcLogicExpression operand)
+ {
+ if (curExpr == null)
+ {
+ curExpr = operand;
+ }
+ else
+ {
+ curExpr.addOperand(operand);
+ }
+ }
+
+ private void pushExpr(SvcLogicExpression expr)
+ {
+ if (curExpr != null)
+ {
+ exprStack.push(curExpr);
+ }
+ curExpr = expr;
+ }
+
+ private void popExpr()
+ {
+ if (exprStack.isEmpty())
+ {
+ //topExpr = curExpr;
+ }
+ else
+ {
+ SvcLogicExpression lastExpr = curExpr;
+ curExpr = exprStack.pop();
+ curExpr.addOperand(lastExpr);
+ }
+
+ }
+
+ @Override
+ public void enterAtom(AtomContext ctx) {
+ String atomText = ctx.getText();
+ SvcLogicAtom newAtom = new SvcLogicAtom(atomText);
+ pushExpr(newAtom);
+ }
+
+
+ @Override
+ public void enterMultExpr(MultExprContext ctx) {
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+ List<TerminalNode> opList = ctx.MULTOP();
+
+ for (TerminalNode nd : opList)
+ {
+ curBinExpr.addOperator(nd.getText());
+ }
+
+ }
+
+ @Override
+ public void exitMultExpr(MultExprContext ctx) {
+ popExpr();
+ }
+
+ @Override
+ public void exitAtom(AtomContext ctx) {
+ popExpr();
+ }
+
+ @Override
+ public void enterAddExpr(AddExprContext ctx) {
+ List<TerminalNode> opList = ctx.ADDOP();
+
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+
+ for (TerminalNode nd : opList)
+ {
+ curBinExpr.addOperator(nd.getText());
+ }
+
+ }
+
+ @Override
+ public void exitAddExpr(AddExprContext ctx) {
+ popExpr();
+ }
+
+ @Override
+ public void enterFuncExpr(FuncExprContext ctx) {
+ LOG.trace("enterFuncExpr: text = "+ctx.getText());
+ LOG.trace("enterFuncExpr - IDENTIFIER : "+ctx.IDENTIFIER().getText());
+
+ for (ExprContext expr: ctx.expr())
+ {
+ LOG.trace("enterFuncExpr - expr = "+expr.getText());
+ }
+
+
+ pushExpr(new SvcLogicFunctionCall(ctx.IDENTIFIER().getText()));
+ }
+
+ @Override
+ public void exitFuncExpr(FuncExprContext ctx) {
+ popExpr();
+ }
+
+ @Override
+ public void enterParenExpr(ParenExprContext ctx) {
+ LOG.trace("enterParenExpr: text = "+ctx.getText());
+ LOG.trace("enterParenExpr: expr = "+ctx.expr().getText());
+ }
+
+ @Override
+ public void exitParenExpr(ParenExprContext ctx) {
+ LOG.trace("exitParenExpr: text = "+ctx.getText());
+ }
+
+ @Override
+ public void enterRelExpr(RelExprContext ctx) {
+ List<TerminalNode> opList = ctx.RELOP();
+
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+
+ for (TerminalNode nd : opList)
+ {
+ curBinExpr.addOperator(nd.getText());
+ }
+
+ }
+
+ @Override
+ public void exitRelExpr(RelExprContext ctx) {
+ popExpr();
+ }
+
+ @Override
+ public void enterCompareExpr(CompareExprContext ctx) {
+
+ TerminalNode nd = ctx.COMPAREOP();
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+ curBinExpr.addOperator(nd.getText());
+
+ }
+
+ @Override
+ public void exitCompareExpr(CompareExprContext ctx) {
+
+ popExpr();
+ }
+
+
+
+ @Override
+ public void enterConstant(ConstantContext ctx) {
+ }
+
+ @Override
+ public void exitConstant(ConstantContext ctx) {
+ }
+
+
+ @Override
+ public void enterVariable(VariableContext ctx) {
+ }
+
+ @Override
+ public void exitVariable(VariableContext ctx) {
+ }
+
+
+ @Override
+ public void enterVariableLead(VariableLeadContext ctx) {
+ }
+
+ @Override
+ public void exitVariableLead(VariableLeadContext ctx) {
+ }
+
+ @Override
+ public void enterVariableTerm(VariableTermContext ctx) {
+ String name = ctx.getText();
+
+ int subscrStart = name.indexOf("[");
+ if (subscrStart > -1)
+ {
+ name = name.substring(0, subscrStart);
+ }
+ SvcLogicVariableTerm vterm = new SvcLogicVariableTerm(name);
+ pushExpr(vterm);
+ }
+
+ @Override
+ public void exitVariableTerm(VariableTermContext ctx) {
+ popExpr();
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java
new file mode 100644
index 000000000..03f2a8b0b
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
+
+public class SvcLogicExprParserErrorListener extends BaseErrorListener {
+
+ private static final SvcLogicExprParserErrorListener instance = new SvcLogicExprParserErrorListener();
+
+ public static SvcLogicExprParserErrorListener getInstance() {
+ return(instance);
+ }
+
+ @Override
+ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
+ String msg, RecognitionException e) throws ParseCancellationException {
+ throw new ParseCancellationException(msg);
+ }
+
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java
new file mode 100644
index 000000000..81aeb6c37
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+
+public abstract class SvcLogicExpression implements Serializable {
+
+ private List<SvcLogicExpression> operands = new LinkedList<>();
+
+
+ public void addOperand(SvcLogicExpression expr)
+ {
+ operands.add(expr);
+ }
+
+ public List<SvcLogicExpression> getOperands() {
+ return operands;
+ }
+
+ public int numOperands()
+ {
+ return(operands.size());
+ }
+
+ public abstract String asParsedExpr();
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java
new file mode 100644
index 000000000..727c84b19
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ExprContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class SvcLogicExpressionFactory {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExpressionFactory.class);
+
+
+ public static SvcLogicExpression parse(String exprStr) throws IOException
+ {
+ InputStream exprStream = new ByteArrayInputStream(exprStr.getBytes());
+ CharStream input = new ANTLRInputStream(exprStream);
+ ExprGrammarLexer lexer = new ExprGrammarLexer(input);
+ CommonTokenStream tokens = new CommonTokenStream(lexer);
+ ExprGrammarParser parser = new ExprGrammarParser(tokens);
+
+ lexer.removeErrorListeners();
+ lexer.addErrorListener(SvcLogicExprParserErrorListener.getInstance());
+ parser.removeErrorListeners();
+ parser.addErrorListener(SvcLogicExprParserErrorListener.getInstance());
+
+ ExprContext expression = null;
+
+ try {
+ expression = parser.expr();
+ } catch (Exception e) {
+ String errorMsg = e.getMessage();
+
+ LOG.error(errorMsg);
+ throw new SvcLogicParserException(errorMsg);
+ }
+
+
+ ParseTreeWalker walker = new ParseTreeWalker();
+ SvcLogicExprListener listener = new SvcLogicExprListener();
+ walker.walk(listener, expression);
+
+
+ return(listener.getParsedExpr());
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java
new file mode 100644
index 000000000..8289f16da
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class SvcLogicFunctionCall extends SvcLogicExpression {
+
+ private String functionName;
+
+ public SvcLogicFunctionCall(String functionName)
+ {
+ this.functionName = functionName;
+ }
+
+ public String getFunctionName() {
+ return functionName;
+ }
+
+ public void setFunctionName(String functionName) {
+ this.functionName = functionName;
+ }
+
+ public String toString()
+ {
+ StringBuffer sbuff = new StringBuffer();
+
+ sbuff.append(functionName);
+ sbuff.append("(");
+ boolean needComma = false;
+ for (SvcLogicExpression operand: getOperands())
+ {
+ if (needComma)
+ {
+ sbuff.append(",");
+ }
+ else
+ {
+ needComma = true;
+ }
+ sbuff.append(operand.toString());
+
+ }
+ sbuff.append(")");
+ return(sbuff.toString());
+ }
+
+ public String asParsedExpr()
+ {
+ StringBuffer sbuff = new StringBuffer();
+
+ sbuff.append("(");
+ sbuff.append(functionName);
+ for (SvcLogicExpression operand: getOperands())
+ {
+ sbuff.append(" ");
+ sbuff.append(operand.asParsedExpr());
+ }
+ sbuff.append(")");
+ return(sbuff.toString());
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java
new file mode 100644
index 000000000..97f2bd7ab
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java
@@ -0,0 +1,199 @@
+/*-
+x * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications 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.ccsdk.sli.core.sli;
+
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SvcLogicGraph implements Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private String module = null;
+ private String rpc = null;
+ private String mode = null;
+ private String version = null;
+
+ private String md5sum = null;
+
+ private Map<String, Serializable> attributes;
+ private Map<String, SvcLogicNode> namedNodes;
+ private SvcLogicNode rootNode;
+
+ public SvcLogicGraph()
+ {
+ attributes = new HashMap<>();
+ namedNodes = new HashMap<>();
+ rootNode = null;
+ }
+
+ public String getMd5sum() {
+ return md5sum;
+ }
+
+
+ public void setMd5sum(String md5sum) {
+ this.md5sum = md5sum;
+ }
+
+
+
+ public String getModule() {
+ return module;
+ }
+
+
+ public void setModule(String module) {
+ this.module = module;
+ }
+
+
+ public String getRpc() {
+ return rpc;
+ }
+
+
+ public void setRpc(String rpc) {
+ this.rpc = rpc;
+ }
+
+
+
+
+ public String getMode() {
+ return mode;
+ }
+
+
+ public void setMode(String mode) {
+ this.mode = mode;
+ }
+
+
+ public String getVersion() {
+ return version;
+ }
+
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+
+ public void setRootNode(SvcLogicNode rootNode)
+ {
+ this.rootNode = rootNode;
+ }
+
+ public SvcLogicNode getRootNode()
+ {
+ return(rootNode);
+ }
+
+ public Serializable getAttribute(String name)
+ {
+ if (attributes.containsKey(name))
+ {
+ return(attributes.get(name));
+ }
+ else
+ {
+ return(null);
+ }
+
+ }
+
+ public void setAttribute(String name, Serializable value) throws DuplicateValueException
+ {
+ if (attributes.containsKey(name))
+ {
+ throw new DuplicateValueException("Duplicate attribute "+name);
+ }
+
+ attributes.put(name, value);
+ }
+
+ public SvcLogicNode getNamedNode(String nodeName)
+ {
+ if (namedNodes.containsKey(nodeName))
+ {
+ return(namedNodes.get(nodeName));
+ }
+ else
+ {
+ return(null);
+ }
+ }
+
+ public void setNamedNode(String nodeName, SvcLogicNode node) throws DuplicateValueException
+ {
+ if (namedNodes.containsKey(nodeName))
+ {
+ throw new DuplicateValueException("Duplicate node name "+nodeName);
+ }
+
+ namedNodes.put(nodeName, node);
+ }
+
+
+
+ public void printAsGv(PrintStream pstr)
+ {
+ pstr.println("digraph g {");
+ pstr.println("START [label=\"START\\n"+module+":"+rpc+"\"];");
+
+ if (rootNode != null)
+ {
+ pstr.println("START -> node"+rootNode.getNodeId()+";");
+ rootNode.setVisited(false, true);
+ rootNode.printAsGv(pstr);
+ }
+ pstr.println("}");
+ }
+
+ public void printAsXml(PrintStream pstr)
+ {
+ pstr.println("<service-logic module='"+getModule()+"' version='"+getVersion()+"'>");
+ pstr.println(" <method rpc='"+getRpc()+"' mode='"+getMode()+"'>");
+ if (rootNode != null)
+ {
+ rootNode.setVisited(false, true);
+ rootNode.printAsXml(pstr, 2);
+ }
+ pstr.println(" </method>");
+ pstr.println("</service-logic>");
+ }
+
+ @Override
+ public String toString() {
+ return "SvcLogicGraph [module=" + module + ", rpc=" + rpc + ", mode=" + mode + ", version=" + version + ", md5sum=" + md5sum + "]";
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java
new file mode 100644
index 000000000..23dff3e6e
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+/**
+ * A marker interface, used to indicate that a class exposes methods that can be
+ * called from an <execute> node. Such methods must have the signature:
+ * void methodName(Map, SvcLogicContext)
+ */
+public interface SvcLogicJavaPlugin {
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java
new file mode 100644
index 000000000..f23456fee
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java
@@ -0,0 +1,574 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicJdbcStore implements SvcLogicStore {
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicJdbcStore.class);
+
+ private String dbUrl = null;
+ private String dbName = null;
+ private String dbUser = null;
+ private String dbPasswd = null;
+ private String dbDriver = null;
+
+ private Connection dbConn;
+ private PreparedStatement hasActiveGraphStmt = null;
+ private PreparedStatement hasVersionGraphStmt = null;
+ private PreparedStatement fetchActiveGraphStmt = null;
+ private PreparedStatement fetchVersionGraphStmt = null;
+ private PreparedStatement storeGraphStmt = null;
+ private PreparedStatement deleteGraphStmt = null;
+
+ private PreparedStatement deactivateStmt = null;
+ private PreparedStatement activateStmt = null;
+
+ private void getConnection() throws ConfigurationException {
+
+ Properties jdbcProps = new Properties();
+
+ jdbcProps.setProperty("user", dbUser);
+ jdbcProps.setProperty("password", dbPasswd);
+
+ try {
+ Driver dvr = new org.mariadb.jdbc.Driver();
+ if (dvr.acceptsURL(dbUrl)) {
+ LOG.debug("Driver com.mysql.jdbc.Driver accepts {}", dbUrl);
+ } else {
+ LOG.warn("Driver com.mysql.jdbc.Driver does not accept {}", dbUrl);
+ }
+ } catch (SQLException e1) {
+ LOG.error("Caught exception trying to load com.mysql.jdbc.Driver", e1);
+ }
+
+ try {
+ this.dbConn = DriverManager.getConnection(dbUrl, jdbcProps);
+ } catch (Exception e) {
+ throw new ConfigurationException("failed to get database connection [" + dbUrl + "]", e);
+ }
+
+ }
+
+ private void createTable() throws ConfigurationException {
+
+ DatabaseMetaData dbm;
+
+ try {
+ dbm = dbConn.getMetaData();
+ } catch (SQLException e) {
+
+ throw new ConfigurationException("could not get databse metadata", e);
+ }
+
+ // See if table SVC_LOGIC exists. If not, create it.
+ Statement stmt = null;
+ try {
+
+ ResultSet tables = dbm.getTables(null, null, "SVC_LOGIC", null);
+ if (tables.next()) {
+ LOG.debug("SVC_LOGIC table already exists");
+ } else {
+ String crTableCmd = "CREATE TABLE " + dbName + ".SVC_LOGIC (" + "module varchar(80) NOT NULL,"
+ + "rpc varchar(80) NOT NULL," + "version varchar(40) NOT NULL," + "mode varchar(5) NOT NULL,"
+ + "active varchar(1) NOT NULL,graph BLOB,"
+ + "modified_timestamp timestamp ,"
+ + "md5sum varchar(128) DEFAULT NULL,"
+ + "CONSTRAINT P_SVC_LOGIC PRIMARY KEY(module, rpc, version, mode))";
+
+ stmt = dbConn.createStatement();
+ stmt.executeUpdate(crTableCmd);
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("could not create SVC_LOGIC table", e);
+ } finally {
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ LOG.error("Statement close error ", e);
+ }
+ }
+ }
+
+ // See if NODE_TYPES table exists and, if not, create it
+ stmt = null;
+ try {
+
+ ResultSet tables = dbm.getTables(null, null, "NODE_TYPES", null);
+ if (tables.next()) {
+ LOG.debug("NODE_TYPES table already exists");
+ } else {
+ String crTableCmd = "CREATE TABLE " + dbName + ".NODE_TYPES (" + "nodetype varchar(80) NOT NULL,"
+ + "CONSTRAINT P_NODE_TYPES PRIMARY KEY(nodetype))";
+
+ stmt = dbConn.createStatement();
+
+ stmt.executeUpdate(crTableCmd);
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("could not create SVC_LOGIC table", e);
+ } finally {
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ LOG.error("Statement close error ", e);
+ }
+ }
+ }
+ }
+
+ private void prepStatements() throws ConfigurationException {
+
+ // Prepare statements
+ String hasVersionGraphSql = CommonConstants.JDBC_SELECT_COUNT + dbName + CommonConstants.SVCLOGIC_TABLE
+ + CommonConstants.JDBC_GRAPH_QUERY;
+
+ try {
+ hasVersionGraphStmt = dbConn.prepareStatement(hasVersionGraphSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + hasVersionGraphSql, e);
+
+ }
+
+ String hasActiveGraphSql = CommonConstants.JDBC_SELECT_COUNT + dbName + CommonConstants.SVCLOGIC_TABLE
+ + CommonConstants.JDBC_ACTIVE_GRAPH_QUERY;
+
+ try {
+ hasActiveGraphStmt = dbConn.prepareStatement(hasActiveGraphSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + hasVersionGraphSql, e);
+
+ }
+
+ String fetchVersionGraphSql = CommonConstants.JDBC_SELECT_GRAPGH + dbName + CommonConstants.SVCLOGIC_TABLE
+ + CommonConstants.JDBC_GRAPH_QUERY;
+
+ try {
+ fetchVersionGraphStmt = dbConn.prepareStatement(fetchVersionGraphSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + fetchVersionGraphSql, e);
+
+ }
+
+ String fetchActiveGraphSql = CommonConstants.JDBC_SELECT_GRAPGH + dbName + CommonConstants.SVCLOGIC_TABLE
+ + CommonConstants.JDBC_ACTIVE_GRAPH_QUERY;
+
+ try {
+ fetchActiveGraphStmt = dbConn.prepareStatement(fetchActiveGraphSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + fetchVersionGraphSql, e);
+
+ }
+
+ String storeGraphSql = CommonConstants.JDBC_INSERT + dbName
+ + ".SVC_LOGIC (module, rpc, version, mode, active, graph, md5sum) VALUES(?, ?, ?, ?, ?, ?, ?)";
+
+ try {
+ storeGraphStmt = dbConn.prepareStatement(storeGraphSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + storeGraphSql, e);
+ }
+
+ String deleteGraphSql = CommonConstants.JDBC_DELETE + dbName
+ + ".SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?";
+
+ try {
+ deleteGraphStmt = dbConn.prepareStatement(deleteGraphSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + deleteGraphSql, e);
+ }
+
+ String deactivateSql = CommonConstants.JDBC_UPDATE + dbName
+ + ".SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?";
+
+ try {
+ deactivateStmt = dbConn.prepareStatement(deactivateSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + deactivateSql, e);
+ }
+
+ String activateSql = CommonConstants.JDBC_UPDATE + dbName
+ + ".SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND version = ? AND mode = ?";
+
+ try {
+ activateStmt = dbConn.prepareStatement(activateSql);
+ } catch (Exception e) {
+ throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + activateSql, e);
+ }
+ }
+
+ private void initDbResources() throws ConfigurationException {
+ if ((dbDriver != null) && (dbDriver.length() > 0)) {
+
+ try {
+ Class.forName(dbDriver);
+ } catch (Exception e) {
+ throw new ConfigurationException("could not load driver class " + dbDriver, e);
+ }
+ }
+ getConnection();
+ createTable();
+ prepStatements();
+ }
+
+
+ @Override
+ public void init(Properties props) throws ConfigurationException {
+
+
+ dbUrl = props.getProperty("org.onap.ccsdk.sli.jdbc.url");
+ if ((dbUrl == null) || (dbUrl.length() == 0)) {
+ throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.url unset");
+ }
+
+ dbName = props.getProperty("org.onap.ccsdk.sli.jdbc.database");
+ if ((dbName == null) || (dbName.length() == 0)) {
+ throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.database unset");
+ }
+
+ dbUser = props.getProperty("org.onap.ccsdk.sli.jdbc.user");
+ if ((dbUser == null) || (dbUser.length() == 0)) {
+ throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.user unset");
+ }
+
+
+ dbPasswd = props.getProperty("org.onap.ccsdk.sli.jdbc.password");
+ if ((dbPasswd == null) || (dbPasswd.length() == 0)) {
+ throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.password unset");
+ }
+
+ dbDriver = props.getProperty("org.onap.ccsdk.sli.jdbc.driver");
+
+
+ initDbResources();
+
+ }
+
+ private boolean isDbConnValid() {
+
+ boolean isValid = false;
+
+ try {
+ if (dbConn != null) {
+ isValid = dbConn.isValid(1);
+ }
+ } catch (SQLException e) {
+ LOG.error("Not a valid db connection: ", e);
+ }
+
+ return isValid;
+ }
+
+ @Override
+ public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException {
+
+ if (!isDbConnValid()) {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid()) {
+ throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR);
+ }
+ }
+
+ boolean retval = false;
+ ResultSet results = null;
+
+ PreparedStatement hasGraphStmt;
+ if (version == null) {
+ hasGraphStmt = hasActiveGraphStmt;
+ } else {
+ hasGraphStmt = hasVersionGraphStmt;
+ }
+
+ try {
+ hasGraphStmt.setString(1, module);
+ hasGraphStmt.setString(2, rpc);
+ hasGraphStmt.setString(3, mode);
+
+
+ if (version != null) {
+ hasGraphStmt.setString(4, version);
+ }
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ results = hasGraphStmt.executeQuery();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+
+ if (results.next()) {
+ int cnt = results.getInt(1);
+
+ if (cnt > 0) {
+ retval = true;
+ }
+
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("SQL query failed", e);
+ } finally {
+ if (results != null) {
+ try {
+ results.close();
+ } catch (SQLException x) {
+ LOG.error(CommonConstants.RESULTSET_CLOSE_ERR, x);
+ }
+ }
+
+ }
+
+ return retval;
+
+ }
+
+ @Override
+ public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException {
+
+
+ if (!isDbConnValid()) {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid()) {
+ throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR);
+ }
+ }
+
+ SvcLogicGraph retval = null;
+ ResultSet results = null;
+
+ PreparedStatement fetchGraphStmt;
+ if (version == null) {
+ fetchGraphStmt = fetchActiveGraphStmt;
+ } else {
+ fetchGraphStmt = fetchVersionGraphStmt;
+ }
+ try {
+ fetchGraphStmt.setString(1, module);
+ fetchGraphStmt.setString(2, rpc);
+ fetchGraphStmt.setString(3, mode);
+
+
+ if (version != null) {
+ fetchGraphStmt.setString(4, version);
+ }
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ results = fetchGraphStmt.executeQuery();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+
+ if (results.next()) {
+ Blob graphBlob = results.getBlob("graph");
+
+ ObjectInputStream gStream = new ObjectInputStream(graphBlob.getBinaryStream());
+
+ Object graphObj = gStream.readObject();
+ gStream.close();
+
+ if (graphObj instanceof SvcLogicGraph) {
+ retval = (SvcLogicGraph) graphObj;
+ } else {
+ throw new ConfigurationException("invalid type for graph (" + graphObj.getClass().getName());
+
+ }
+ }
+
+ } catch (Exception e) {
+ throw new ConfigurationException("SQL query failed", e);
+ } finally {
+ if (results != null) {
+ try {
+ results.close();
+ } catch (SQLException x) {
+ LOG.error(CommonConstants.RESULTSET_CLOSE_ERR, x);
+ }
+ }
+
+ }
+
+ return retval;
+ }
+
+ public void store(SvcLogicGraph graph) throws SvcLogicException {
+
+
+ if (!isDbConnValid()) {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid()) {
+ throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR);
+ }
+ }
+
+ if (graph == null) {
+ throw new SvcLogicException("graph cannot be null");
+ }
+
+ byte[] graphBytes;
+
+ try (ByteArrayOutputStream byteStr = new ByteArrayOutputStream();
+ ObjectOutputStream goutStr = new ObjectOutputStream(byteStr)) {
+
+ goutStr.writeObject(graph);
+
+ graphBytes = byteStr.toByteArray();
+
+ } catch (Exception e) {
+ throw new SvcLogicException("could not serialize graph", e);
+ }
+
+ // If object already stored in database, delete it
+ if (hasGraph(graph.getModule(), graph.getRpc(), graph.getVersion(), graph.getMode())) {
+ delete(graph.getModule(), graph.getRpc(), graph.getVersion(), graph.getMode());
+ }
+
+ try {
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ storeGraphStmt.setString(1, graph.getModule());
+ storeGraphStmt.setString(2, graph.getRpc());
+ storeGraphStmt.setString(3, graph.getVersion());
+ storeGraphStmt.setString(4, graph.getMode());
+ storeGraphStmt.setString(5, "N");
+ storeGraphStmt.setBlob(6, new ByteArrayInputStream(graphBytes));
+ storeGraphStmt.setString(7, graph.getMd5sum());
+
+ storeGraphStmt.executeUpdate();
+ dbConn.commit();
+
+ dbConn.setAutoCommit(oldAutoCommit);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not write object to database", e);
+ }
+ }
+
+ @Override
+ public void delete(String module, String rpc, String version, String mode) throws SvcLogicException {
+ if (!isDbConnValid()) {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid()) {
+ throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR);
+ }
+ }
+
+ try {
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ deleteGraphStmt.setString(1, module);
+ deleteGraphStmt.setString(2, rpc);
+ deleteGraphStmt.setString(3, version);
+ deleteGraphStmt.setString(4, mode);
+
+
+ deleteGraphStmt.executeUpdate();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not delete object from database", e);
+ }
+ }
+
+ @Override
+ public void activate(SvcLogicGraph graph) throws SvcLogicException {
+ try {
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+
+ dbConn.setAutoCommit(false);
+
+ // Deactivate any current active version
+ deactivateStmt.setString(1, graph.getModule());
+ deactivateStmt.setString(2, graph.getRpc());
+ deactivateStmt.setString(3, graph.getMode());
+ deactivateStmt.executeUpdate();
+
+ // Activate this version
+ activateStmt.setString(1, graph.getModule());
+ activateStmt.setString(2, graph.getRpc());
+ activateStmt.setString(3, graph.getVersion());
+ activateStmt.setString(4, graph.getMode());
+ activateStmt.executeUpdate();
+
+ dbConn.commit();
+
+ dbConn.setAutoCommit(oldAutoCommit);
+
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not activate graph", e);
+ }
+ }
+
+ @Override
+ public void activate(String module, String rpc, String version, String mode) throws SvcLogicException {
+ try {
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+
+ dbConn.setAutoCommit(false);
+
+ // Deactivate any current active version
+ deactivateStmt.setString(1, module);
+ deactivateStmt.setString(2, rpc);
+ deactivateStmt.setString(3, mode);
+ deactivateStmt.executeUpdate();
+
+ // Activate this version
+ activateStmt.setString(1, module);
+ activateStmt.setString(2, rpc);
+ activateStmt.setString(3, version);
+ activateStmt.setString(4, mode);
+ activateStmt.executeUpdate();
+
+ dbConn.commit();
+
+ dbConn.setAutoCommit(oldAutoCommit);
+
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not activate graph", e);
+ }
+ }
+
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java
new file mode 100644
index 000000000..433b723e7
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java
@@ -0,0 +1,178 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicLoader {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SvcLogicLoader.class);
+ protected SvcLogicStore store;
+ protected String directoryRoot;
+ protected SvcLogicParser parser;
+
+ public SvcLogicLoader(String directoryRoot, SvcLogicStore store) {
+ this.store = store;
+ this.directoryRoot = directoryRoot;
+ this.parser = new SvcLogicParser();
+ }
+
+ public SvcLogicLoader(String directoryRoot, String propFile) {
+ this.store = SvcLogicParser.getStore(propFile);
+ this.directoryRoot = directoryRoot;
+ this.parser = new SvcLogicParser();
+ }
+
+ public void loadAndActivate() throws IOException {
+ SvcLogicCrawler slc = new SvcLogicCrawler();
+ Files.walkFileTree(Paths.get(directoryRoot), slc);
+ loadGraphs(slc.getGraphPaths(), directoryRoot);
+ List<ActivationEntry> activationEntries = processActivationFiles(slc.getActivationPaths());
+ activateGraphs(activationEntries);
+ }
+
+ protected List<ActivationEntry> processActivationFiles(List<Path> activationPaths) {
+ List<ActivationEntry> activationEntries = new ArrayList<>();
+ for (Path activationFile : activationPaths) {
+ activationEntries.addAll(getActivationEntries(activationFile));
+ }
+ return activationEntries;
+ }
+
+ protected void activateGraphs(List<ActivationEntry> activationEntries) {
+ for (ActivationEntry entry : activationEntries) {
+ try {
+ if (store.hasGraph(entry.module, entry.rpc, entry.version, entry.mode)) {
+ LOGGER.info("Activating SvcLogicGraph [module=" + entry.module + ", rpc=" + entry.rpc + ", mode="
+ + entry.mode + ", version=" + entry.version + "]");
+ store.activate(entry.module, entry.rpc, entry.version, entry.mode);
+ } else {
+ LOGGER.error("hasGraph returned false for " + entry.toString());
+ }
+ } catch (SvcLogicException e) {
+ LOGGER.error("Failed to call hasGraph for " + entry.toString(), e);
+ }
+ }
+ }
+
+ protected List<ActivationEntry> getActivationEntries(Path activationFilePath) {
+ List<ActivationEntry> activationEntries = new ArrayList<>();
+ int lineNumber = 1;
+ try (BufferedReader br = Files.newBufferedReader(activationFilePath, StandardCharsets.US_ASCII)) {
+ String fileRead = br.readLine();
+ while (fileRead != null) {
+ String[] fields = fileRead.split("\\s");
+ if (fields.length == 4) {
+ activationEntries.add(parseActivationEntry(fields));
+ } else {
+ LOGGER.error("Activation entry [" + fileRead + "] is declared at line number " + lineNumber
+ + " in the file " + activationFilePath + " and is invalid.");
+ }
+ fileRead = br.readLine();
+ lineNumber++;
+ }
+ return activationEntries;
+ } catch (IOException ioe) {
+ LOGGER.error("Couldn't read the activation file at " + activationFilePath, ioe);
+ return new ArrayList<>();
+ }
+ }
+
+ protected void loadGraphs(List<Path> graphPaths, String directoryRoot) {
+ for (Path graphPath : graphPaths) {
+ try {
+ saveGraph(graphPath.toString());
+ } catch (Exception e) {
+ LOGGER.error("Couldn't load graph at " + graphPath, e);
+ }
+ }
+ }
+
+ protected void saveGraph(String xmlFile) throws SvcLogicException {
+ File f = new File(xmlFile);
+ if (!f.canRead()) {
+ throw new ConfigurationException("Cannot read xml file (" + xmlFile + ")");
+ }
+
+ LinkedList<SvcLogicGraph> graphs = null;
+
+ try {
+ graphs = parser.parse(xmlFile);
+ } catch (Exception e) {
+ throw new SvcLogicException(e.getMessage(), e);
+ }
+
+ if (graphs == null) {
+ throw new SvcLogicException("Could not parse " + xmlFile);
+ }
+
+ for (Iterator<SvcLogicGraph> iter = graphs.iterator(); iter.hasNext();) {
+ SvcLogicGraph graph = iter.next();
+ try {
+ LOGGER.info("Saving " + graph.toString() + " to database");
+ store.store(graph);
+ } catch (Exception e) {
+ throw new SvcLogicException(e.getMessage(), e);
+ }
+ }
+ }
+
+ protected ActivationEntry parseActivationEntry(String[] fileInput) {
+ return new ActivationEntry(fileInput[0], fileInput[1], fileInput[2], fileInput[3]);
+ }
+
+ protected String getValue(String raw, String attributeName) {
+ raw = raw.substring(attributeName.length() + 1);
+ if (raw.contains(">")) {
+ raw = raw.substring(0, raw.lastIndexOf('>'));
+ }
+ if (raw.endsWith("'")) {
+ raw = raw.substring(0, raw.lastIndexOf('\''));
+ }
+ if (raw.endsWith("\"")) {
+ raw = raw.substring(0, raw.lastIndexOf('"'));
+ }
+ return raw;
+ }
+
+ public void bulkActivate() {
+ Path activationFile = Paths.get(directoryRoot);
+ List<Path> pathList = new ArrayList<>(1);
+ pathList.add(activationFile);
+ List<ActivationEntry> activationEntries = processActivationFiles(pathList);
+ activateGraphs(activationEntries);
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java
new file mode 100644
index 000000000..b0d4fc058
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java
@@ -0,0 +1,457 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ *
+ */
+package org.onap.ccsdk.sli.core.sli;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.TreeMap;
+
+import org.apache.commons.text.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicNode implements Serializable {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExprListener.class);
+
+ private static final long serialVersionUID = 2L;
+
+ private String nodeName;
+ private int nodeId;
+ private String nodeType;
+ private boolean visited;
+ private SvcLogicGraph graph;
+
+
+ private HashMap<String, SvcLogicExpression> attributes;
+ private HashMap<String, SvcLogicNode> outcomes;
+ private HashMap<String, SvcLogicExpression> parameters;
+
+ public SvcLogicNode(int nodeId, String nodeType, SvcLogicGraph graph)
+ {
+ this.nodeId = nodeId;
+ nodeName = "";
+ this.nodeType = nodeType;
+ this.graph = graph;
+ attributes = new HashMap<> ();
+ parameters = new HashMap<> ();
+ outcomes = null;
+
+ }
+
+ public SvcLogicNode(int nodeId, String nodeType, String nodeName, SvcLogicGraph graph) throws DuplicateValueException
+ {
+ this.nodeId = nodeId;
+ this.nodeName = nodeName;
+ this.nodeType = nodeType;
+ this.graph = graph;
+ attributes = new HashMap<> ();
+ parameters = new HashMap<> ();
+ outcomes = null;
+ graph.setNamedNode(nodeName, this);
+ }
+
+
+ public int getNodeId()
+ {
+ return nodeId;
+ }
+
+ public String getNodeName()
+ {
+ return nodeName;
+ }
+
+ public String getNodeType()
+ {
+ return nodeType;
+ }
+
+ public SvcLogicGraph getGraph()
+ {
+ return graph;
+ }
+
+ public int getNumOutcomes()
+ {
+ if (outcomes == null)
+ {
+ return 0;
+ }
+ else
+ {
+ return outcomes.size();
+ }
+ }
+
+ public SvcLogicExpression getAttribute(String name)
+ {
+ if (attributes.containsKey(name))
+ {
+ return attributes.get(name);
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+ public void setAttribute(String name, String value) throws SvcLogicException
+ {
+ setAttribute(name, new SvcLogicAtom("STRING", value));
+ }
+
+ public void setAttribute(String name, SvcLogicExpression value) throws SvcLogicException
+ {
+ if (attributes.containsKey(name))
+ {
+ throw new DuplicateValueException("Duplicate attribute "+name);
+ }
+
+ attributes.put(name, value);
+ }
+
+
+ public void mapParameter(String name, String value) throws SvcLogicException
+ {
+
+ if (parameters.containsKey(name))
+ {
+ throw new DuplicateValueException("Duplicate parameter "+name);
+ }
+ try
+ {
+ SvcLogicExpression parmValue;
+ if (value == null || value.length() == 0)
+ {
+ parmValue = new SvcLogicAtom("STRING", "");
+ }
+ else if (value.trim().startsWith("`"))
+ {
+ int lastParen = value.lastIndexOf("`");
+ String evalExpr = value.trim().substring(1, lastParen);
+ parmValue = SvcLogicExpressionFactory.parse(evalExpr);
+
+ }
+ else
+ {
+ if (Character.isDigit(value.charAt(0)))
+ {
+ parmValue = new SvcLogicAtom("NUMBER", value);
+ }
+ else
+ {
+ parmValue = new SvcLogicAtom("STRING", value);
+ }
+ }
+ LOG.debug("Setting parameter "+name+" = "+value+" = "+parmValue.asParsedExpr());
+ parameters.put(name, parmValue);
+ }
+ catch (IOException e) {
+
+ LOG.error("Invalid parameter value expression ("+value+")");
+ throw new SvcLogicException(e.getMessage());
+ }
+ }
+
+ public SvcLogicExpression getParameter(String name)
+ {
+ if (parameters.containsKey(name))
+ {
+ return parameters.get(name);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public boolean isVisited() {
+ return visited;
+ }
+
+ public void setVisited(boolean visited, boolean recursive) {
+ this.visited = visited;
+
+ if (recursive)
+ {
+ Set<Map.Entry<String, SvcLogicNode>> outcomeSet = getOutcomeSet();
+
+ if (outcomeSet == null)
+ {
+ return;
+ }
+
+ for (Iterator<Map.Entry<String, SvcLogicNode>> iter = outcomeSet.iterator(); iter.hasNext();)
+ {
+ Map.Entry<String, SvcLogicNode> curOutcome = iter.next();
+ SvcLogicNode outNode = curOutcome.getValue();
+ outNode.setVisited(visited, recursive);
+ }
+ }
+ }
+
+ public void addOutcome(String outcomeValue, SvcLogicNode node) throws SvcLogicException
+ {
+ if (outcomes == null)
+ {
+ outcomes = new HashMap<>();
+ }
+
+ if (outcomeValue.length() == 0) {
+ outcomeValue = "\"\"";
+ }
+ if (outcomes.containsKey(outcomeValue))
+ {
+ throw new DuplicateValueException("Duplicate outcome value "+outcomeValue);
+ }
+
+ outcomes.put(outcomeValue, node);
+ }
+
+ public Set<Map.Entry<String, SvcLogicNode>> getOutcomeSet()
+ {
+ if (outcomes == null)
+ {
+ return new HashSet<>();
+ }
+
+ return outcomes.entrySet();
+
+ }
+
+ public Set<Map.Entry<String, SvcLogicExpression>> getParameterSet()
+ {
+ if (parameters == null)
+ {
+ return new HashSet<>();
+ }
+
+ return parameters.entrySet();
+
+ }
+
+ public void printAsGv(PrintStream pstr)
+ {
+
+ if (visited)
+ {
+ return;
+ }
+ else
+ {
+ visited = true;
+ }
+
+ StringBuffer sbuff = new StringBuffer();
+
+ sbuff.append("node");
+ sbuff.append(nodeId);
+ sbuff.append(" [ shape=none, margin=0, label=<<table border=\"0\" cellborder=\"1\" align=\"left\">");
+ sbuff.append("<tr><td colspan=\"2\"><b>");
+ sbuff.append(nodeId);
+ sbuff.append(" : ");
+ sbuff.append(nodeType);
+ sbuff.append("</b></td></tr><th><td><i>Attribute</i></td><td><i>Value</i></td></th>");
+
+ if (nodeName.length() > 0)
+ {
+ sbuff.append("<tr><td>name</td><td>");
+ sbuff.append(nodeName);
+ sbuff.append("</td></tr>");
+ }
+
+ Set<Map.Entry<String, SvcLogicExpression>> attrSet = attributes.entrySet();
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = attrSet.iterator() ; iter.hasNext();)
+ {
+ Map.Entry<String, SvcLogicExpression> curAttr = iter.next();
+ sbuff.append("<tr><td>");
+ sbuff.append(curAttr.getKey());
+ sbuff.append("</td><td>");
+ sbuff.append(StringEscapeUtils.escapeHtml3(curAttr.getValue().toString()));
+ sbuff.append("</td></tr>");
+ }
+ sbuff.append("</table>>];");
+
+ pstr.println(sbuff.toString());
+
+
+ if (outcomes != null)
+ {
+ TreeMap<String, SvcLogicNode> sortedOutcomes = new TreeMap<>(outcomes);
+ Set<Map.Entry<String, SvcLogicNode>> outcomeSet = sortedOutcomes.entrySet();
+
+ for (Iterator<Map.Entry<String, SvcLogicNode>> iter = outcomeSet.iterator(); iter.hasNext();)
+ {
+ Map.Entry<String, SvcLogicNode> curOutcome = iter.next();
+ String outValue = curOutcome.getKey();
+ SvcLogicNode outNode = curOutcome.getValue();
+ pstr.println("node"+nodeId+" -> node"+outNode.getNodeId()+" [label=\""+outValue+"\"];");
+ outNode.printAsGv(pstr);
+ }
+ }
+ }
+
+ public void printAsXml(PrintStream pstr, int indentLvl)
+ {
+ if (visited)
+ {
+ return;
+ }
+ // Print node tag
+ for (int i = 0 ; i < indentLvl ; i++)
+ {
+ pstr.print(" ");
+ }
+ pstr.print("<");
+ pstr.print(this.getNodeType());
+
+ Set<Map.Entry<String, SvcLogicExpression>> attrSet = attributes.entrySet();
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = attrSet.iterator() ; iter.hasNext();)
+ {
+ Map.Entry<String, SvcLogicExpression> curAttr = iter.next();
+ pstr.print(" ");
+ pstr.print(curAttr.getKey());
+ pstr.print("='`");
+ pstr.print(curAttr.getValue());
+ pstr.print("'`");
+ }
+
+ if ((parameters == null || parameters.isEmpty()) &&
+ (outcomes == null || outcomes.isEmpty()))
+ {
+ pstr.print("/>\n");
+ pstr.flush();
+ return;
+ }
+ else
+ {
+ pstr.print(">\n");
+ }
+
+ // Print parameters (if any)
+ if (parameters != null)
+ {
+ Set<Map.Entry<String, SvcLogicExpression>> paramSet = parameters.entrySet();
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = paramSet.iterator() ; iter.hasNext();)
+ {
+ for (int i = 0 ; i < indentLvl+1 ; i++)
+ {
+ pstr.print(" ");
+ }
+ pstr.print("<parameter");
+ Map.Entry<String, SvcLogicExpression> curAttr = iter.next();
+ pstr.print(" name='");
+ pstr.print(curAttr.getKey());
+ pstr.print("' value='`");
+ pstr.print(curAttr.getValue().toString());
+ pstr.print("`'/>\n");
+ }
+ }
+
+ // Print outcomes (if any)
+ if (outcomes != null)
+ {
+ Set<Map.Entry<String, SvcLogicNode>> outcomeSet = outcomes.entrySet();
+ for (Iterator<Map.Entry<String, SvcLogicNode>> iter = outcomeSet.iterator() ; iter.hasNext();)
+ {
+ for (int i = 0 ; i < indentLvl+1 ; i++)
+ {
+ pstr.print(" ");
+ }
+ pstr.print("<outcome");
+ Map.Entry<String, SvcLogicNode> curAttr = iter.next();
+ pstr.print(" value='");
+ pstr.print(curAttr.getKey());
+ pstr.print("'>\n");
+ SvcLogicNode outNode = curAttr.getValue();
+ outNode.printAsXml(pstr, indentLvl+2);
+ for (int i = 0 ; i < indentLvl+1 ; i++)
+ {
+ pstr.print(" ");
+ }
+ pstr.print("</outcome>\n");
+ }
+ }
+
+ // Print node end tag
+ for (int i = 0 ; i < indentLvl ; i++)
+ {
+ pstr.print(" ");
+ }
+ pstr.print("</");
+ pstr.print(this.getNodeType());
+ pstr.print(">\n");
+ pstr.flush();
+
+ }
+
+
+ public SvcLogicNode getOutcomeValue(String value)
+ {
+
+ if (value.length() == 0) {
+ value = "\"\"";
+ }
+ if (outcomes == null)
+ {
+ return null;
+ }
+
+ if (outcomes.containsKey(value))
+ {
+ return outcomes.get(value);
+ }
+ else
+ {
+ StringBuffer keyBuffer = new StringBuffer();
+ keyBuffer.append("{");
+ for (String key : outcomes.keySet()) {
+ keyBuffer.append(" ("+key+")");
+ }
+ keyBuffer.append("}");
+ LOG.info("Outcome (" + value + ") not found, keys are " + keyBuffer.toString());
+
+ if (outcomes.containsKey("Other"))
+ {
+ return outcomes.get("Other");
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java
new file mode 100644
index 000000000..adec7b27d
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java
@@ -0,0 +1,615 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.LinkedList;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.*;
+import org.xml.sax.helpers.DefaultHandler;
+import org.onap.ccsdk.sli.core.utils.PathValidator;
+
+/**
+ * @author dt5972
+ *
+ */
+public class SvcLogicParser {
+
+ static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+ static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
+ static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
+ static final String JAXP_DYNAMIC_VALIDATION = "http://apache.org/xml/features/validation/dynamic";
+ static final String JAXP_SCHEMA_VALIDATION = "http://apache.org/xml/features/validation/schema";
+
+ private static final String LOAD_MESSAGE = "Getting SvcLogicGraph from database - {}";
+ private static final String LOAD_ERROR_MESSAGE = "SvcLogicGraph not found - {}";
+ private static final String ACTIVATION_ERROR_MESSAGE = "Could not activate SvcLogicGraph - {}";
+ private static final String PRINT_ERROR_MESSAGE = "Could not print SvcLogicGraph - {}";
+ private static final String SVC_LOGIC_STORE_ERROR = "Could not get service logic store";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SvcLogicParser.class);
+ private static final String SLI_VALIDATING_PARSER = "org.onap.ccsdk.sli.parser.validate";
+ private static final String SVCLOGIC_XSD = "/svclogic.xsd";
+ private SAXParser saxParser;
+
+ private class SvcLogicHandler extends DefaultHandler {
+ private Locator locator = null;
+ private String module = null;
+ private String version = null;
+ private LinkedList<SvcLogicGraph> graphs = null;
+ private SvcLogicGraph curGraph = null;
+ private SvcLogicNode curNode = null;
+ private LinkedList<SvcLogicNode> nodeStack = null;
+ private int curNodeId = 0;
+ private String outcomeValue = null;
+ private LinkedList<String> outcomeStack = null;
+
+ public SvcLogicHandler(LinkedList<SvcLogicGraph> graphs) {
+ this.graphs = graphs;
+ this.curNode = null;
+ this.nodeStack = new LinkedList<>();
+ this.outcomeStack = new LinkedList<>();
+ this.curNodeId = 1;
+ this.outcomeValue = null;
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException {
+
+ // Handle service-logic (graph) tag
+ if ("service-logic".equalsIgnoreCase(qName)) {
+
+ module = attributes.getValue("module");
+ if (module == null || module.length() == 0) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "Missing 'module' attribute from service-logic tag");
+ }
+
+ version = attributes.getValue("version");
+ if (version == null || version.length() == 0) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "Missing 'version' attribute from service-logic tag");
+ }
+
+ return;
+ }
+
+ if ("method".equalsIgnoreCase(qName)) {
+
+ if (curGraph != null) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "Cannot nest module tags");
+ }
+
+ curGraph = new SvcLogicGraph();
+ curGraph.setModule(module);
+ curGraph.setVersion(version);
+ this.curNodeId = 1;
+
+ String attrValue = attributes.getValue("rpc");
+ if (attrValue == null || attrValue.length() == 0) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "Missing 'rpc' attribute for method tag");
+ }
+ curGraph.setRpc(attrValue);
+
+ attrValue = attributes.getValue("mode");
+ if (attrValue == null || attrValue.length() == 0) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "Missing 'mode' attribute for method tag");
+ }
+ curGraph.setMode(attrValue);
+
+ return;
+ }
+
+ // Handle outcome (edge) tag
+ if ("outcome".equalsIgnoreCase(qName)) {
+ String refValue = attributes.getValue("ref");
+
+ if (refValue != null) {
+ SvcLogicNode refNode = curGraph.getNamedNode(refValue);
+
+ if (refNode != null) {
+ try {
+ curNode.addOutcome(attributes.getValue("value"), refNode);
+ } catch (SvcLogicException e) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber()
+ + " " + "Cannot add outcome", e);
+ }
+ } else {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "ref to unknown node " + refValue);
+ }
+ return;
+ }
+
+ if (outcomeValue != null) {
+ outcomeStack.push(outcomeValue);
+ }
+ outcomeValue = attributes.getValue("value");
+
+ return;
+ }
+
+ // Handle parameter tag
+ if ("parameter".equalsIgnoreCase(qName)) {
+ String parmName = attributes.getValue("name");
+ String parmValue = attributes.getValue("value");
+
+ if (parmName != null && parmName.length() > 0 && parmValue != null) {
+ try {
+
+ curNode.mapParameter(parmName, parmValue);
+ } catch (Exception e) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + " cannot set parameter " + parmName + " to " + parmValue + " [" + e.getMessage()
+ + "]");
+ }
+ }
+
+ return;
+ }
+
+ // Handle node tags
+ String nodeName = attributes.getValue("name");
+ SvcLogicNode thisNode;
+
+
+ try {
+ if (nodeName != null && nodeName.length() > 0) {
+ thisNode = new SvcLogicNode(curNodeId++, qName, nodeName, curGraph);
+ } else {
+ thisNode = new SvcLogicNode(curNodeId++, qName, curGraph);
+ }
+
+ if (curGraph.getRootNode() == null) {
+ curGraph.setRootNode(thisNode);
+ }
+ } catch (SvcLogicException e) {
+ throw new SAXException(
+ "line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage());
+
+ }
+
+ int numAttributes = attributes.getLength();
+
+ for (int i = 0; i < numAttributes; i++) {
+ String attrName = attributes.getQName(i);
+ if (!"name".equalsIgnoreCase(attrName)) {
+ try {
+
+ String attrValueStr = attributes.getValue(i);
+ SvcLogicExpression attrValue;
+ if (attrValueStr.trim().startsWith("`")) {
+ int lastParen = attrValueStr.lastIndexOf('`');
+ String evalExpr = attrValueStr.trim().substring(1, lastParen);
+ attrValue = SvcLogicExpressionFactory.parse(evalExpr);
+
+ } else {
+ if (Character.isDigit(attrValueStr.charAt(0))) {
+ attrValue = new SvcLogicAtom("NUMBER", attrValueStr);
+ } else {
+ attrValue = new SvcLogicAtom("STRING", attrValueStr);
+ }
+ }
+ thisNode.setAttribute(attrName, attrValue);
+ } catch (Exception e) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " "
+ + "Cannot set attribute " + attrName, e);
+ }
+ }
+ }
+
+ if (curNode != null) {
+ try {
+ if ("block".equalsIgnoreCase(curNode.getNodeType()) || "for".equalsIgnoreCase(curNode.getNodeType())
+ || "while".equalsIgnoreCase(curNode.getNodeType())) {
+ curNode.addOutcome(Integer.toString(curNode.getNumOutcomes() + 1), thisNode);
+ } else {
+ if (outcomeValue == null) {
+ throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber()
+ + " " + curNode.getNodeType() + " node expects outcome, instead found "
+ + thisNode.getNodeType());
+ }
+ curNode.addOutcome(outcomeValue, thisNode);
+ }
+ } catch (SvcLogicException e) {
+ throw new SAXException(
+ "line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage());
+ }
+ nodeStack.push(curNode);
+ }
+ curNode = thisNode;
+
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+
+ // Handle close of service-logic tag
+ if ("service-logic".equalsIgnoreCase(qName)) {
+ // Nothing more to do
+ return;
+ }
+
+ // Handle close of method tag
+ if ("method".equalsIgnoreCase(qName)) {
+ graphs.add(curGraph);
+ curGraph = null;
+ return;
+ }
+
+ // Handle close of outcome tag
+ if ("outcome".equalsIgnoreCase(qName)) {
+ // Finished this outcome - pop the outcome stack
+ if (outcomeStack.isEmpty()) {
+ outcomeValue = null;
+ } else {
+ outcomeValue = outcomeStack.pop();
+ }
+ return;
+ }
+
+ // Handle close of parameter tag - do nothing
+ if ("parameter".equalsIgnoreCase(qName)) {
+ return;
+ }
+
+ // Handle close of a node tag
+ if (nodeStack.isEmpty()) {
+ curNode = null;
+ } else {
+ curNode = nodeStack.pop();
+ }
+ }
+
+ @Override
+ public void error(SAXParseException arg0) throws SAXException {
+ throw new SAXException(
+ "line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + arg0.getMessage());
+ }
+
+ }
+
+ public LinkedList<SvcLogicGraph> parse(String fileName) throws SvcLogicException {
+ LinkedList<SvcLogicGraph> graphs;
+
+ try {
+ if (saxParser == null) {
+ saxParser = initParser();
+ }
+
+ graphs = new LinkedList<>();
+ saxParser.parse(fileName, new SvcLogicHandler(graphs));
+
+ try {
+ for (SvcLogicGraph graph : graphs) {
+ graph.setMd5sum(CheckSumHelper.md5SumFromFile(fileName));
+ }
+ } catch (Exception exc) {
+ LOGGER.error("Couldn't set md5sum on graphs", exc);
+ }
+ } catch (Exception e) {
+ LOGGER.error("Parsing failed ", e);
+ String msg = e.getMessage();
+ if (msg != null) {
+ throw new SvcLogicException("Compiler error: " + fileName + " @ " + msg);
+ } else {
+ throw new SvcLogicException("Compiler error: " + fileName, e);
+ }
+ }
+ return graphs;
+ }
+
+ public static void main(String argv[]) {
+
+ if (argv.length == 0) {
+ SvcLogicParser.usage();
+ }
+
+ if ("load".equalsIgnoreCase(argv[0])) {
+ if (argv.length == 3) {
+ String xmlfile = argv[1];
+ String propfile = argv[2];
+
+ SvcLogicStore store = SvcLogicParser.getStore(propfile);
+ try {
+ SvcLogicParser.load(xmlfile, store);
+ } catch (Exception e) {
+ LOGGER.error("Load failed ", e);
+ }
+ } else {
+ SvcLogicParser.usage();
+ }
+ } else if ("print".equalsIgnoreCase(argv[0])) {
+ String version = null;
+ String propfile = null;
+
+ switch (argv.length) {
+ case 6:
+ version = argv[4];
+ propfile = argv[5];
+ case 5:
+ if (propfile == null) {
+ propfile = argv[4];
+ }
+ SvcLogicStore store = SvcLogicParser.getStore(propfile);
+ SvcLogicParser.print(argv[1], argv[2], argv[3], version, store);
+ break;
+ default:
+ SvcLogicParser.usage();
+ }
+ } else if ("get-source".equalsIgnoreCase(argv[0])) {
+
+ if (argv.length == 6) {
+ SvcLogicStore store = SvcLogicParser.getStore(argv[5]);
+ SvcLogicParser.getSource(argv[1], argv[2], argv[3], argv[4], store);
+ } else {
+ SvcLogicParser.usage();
+ }
+ } else if ("activate".equalsIgnoreCase(argv[0])) {
+ if (argv.length == 6) {
+ SvcLogicStore store = SvcLogicParser.getStore(argv[5]);
+ SvcLogicParser.activate(argv[1], argv[2], argv[3], argv[4], store);
+ } else {
+ SvcLogicParser.usage();
+ }
+ } else if ("validate".equalsIgnoreCase(argv[0])) {
+ if (argv.length == 3) {
+ String xmlfile = argv[1];
+ String propfile = argv[2];
+
+ System.setProperty(SLI_VALIDATING_PARSER, "true");
+ SvcLogicStore store = SvcLogicParser.getStore(propfile);
+ try {
+ SvcLogicParser.validate(xmlfile, store);
+ } catch (Exception e) {
+ LOGGER.error("Validate failed", e);
+ }
+ } else {
+ SvcLogicParser.usage();
+ }
+ } else if ("install".equalsIgnoreCase(argv[0])) {
+ if (argv.length == 3) {
+ SvcLogicLoader loader = new SvcLogicLoader(argv[1], argv[2]);
+ try {
+ loader.loadAndActivate();
+ } catch (IOException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ } else {
+ SvcLogicParser.usage();
+ }
+ } else if ("bulkActivate".equalsIgnoreCase(argv[0])) {
+ if (argv.length == 3) {
+ SvcLogicLoader loader = new SvcLogicLoader(argv[1], argv[2]);
+ try {
+ loader.bulkActivate();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ } else {
+ SvcLogicParser.usage();
+ }
+ }
+
+ System.exit(0);
+ }
+
+ protected static SvcLogicStore getStore(String propfile) {
+
+ SvcLogicStore store = null;
+
+ try {
+ store = SvcLogicStoreFactory.getSvcLogicStore(propfile);
+ } catch (Exception e) {
+ LOGGER.error(SVC_LOGIC_STORE_ERROR, e);
+ System.exit(1);
+ }
+
+ return store;
+
+ }
+
+
+ public static void load(String xmlfile, SvcLogicStore store) throws SvcLogicException {
+ if (!PathValidator.isValidXmlPath(xmlfile)) {
+ throw new ConfigurationException("Invalid xml file name ("+ xmlfile + ")");
+ }
+ File xmlFile = new File(xmlfile);
+ if (!xmlFile.canRead()) {
+ throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");
+ }
+
+ SvcLogicParser parser = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graphs;
+ try {
+ LOGGER.info("Loading {}", xmlfile);
+ graphs = parser.parse(xmlfile);
+ } catch (Exception e) {
+ throw new SvcLogicException(e.getMessage(), e);
+ }
+
+ if (graphs == null) {
+ throw new SvcLogicException("Could not parse " + xmlfile);
+ }
+
+ for (SvcLogicGraph graph : graphs) {
+
+ try {
+ LOGGER.info("Saving " + graph.toString() + " to database.");
+ store.store(graph);
+ } catch (Exception e) {
+ throw new SvcLogicException(e.getMessage(), e);
+ }
+
+ }
+
+ }
+
+ public static void validate(String xmlfile, SvcLogicStore store) throws SvcLogicException {
+ if (!PathValidator.isValidXmlPath(xmlfile)) {
+ throw new ConfigurationException("Invalid xml file name ("+ xmlfile + ")");
+ }
+ File xmlFile = new File(xmlfile);
+ if (!xmlFile.canRead()) {
+ throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");
+ }
+
+ SvcLogicParser parser = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graphs;
+ try {
+ LOGGER.info("Validating {}", xmlfile);
+ graphs = parser.parse(xmlfile);
+ } catch (Exception e) {
+ throw new SvcLogicException(e.getMessage(), e);
+ }
+
+ if (graphs == null) {
+ throw new SvcLogicException("Could not parse " + xmlfile);
+ } else {
+ LOGGER.info("Compilation successful for {}", xmlfile);
+ }
+
+ }
+
+ private static void print(String module, String rpc, String mode, String version, SvcLogicStore store) {
+ String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";
+
+ try {
+ LOGGER.info(LOAD_MESSAGE, details);
+
+ SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
+ if (graph == null) {
+ LOGGER.error(LOAD_ERROR_MESSAGE, details);
+ System.exit(1);
+ }
+ graph.printAsGv(System.out);
+ } catch (Exception e) {
+ LOGGER.error(PRINT_ERROR_MESSAGE, details, e);
+ System.exit(1);
+ }
+
+ }
+
+ private static void getSource(String module, String rpc, String mode, String version, SvcLogicStore store) {
+ String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";
+
+ try {
+ LOGGER.info(LOAD_MESSAGE, details);
+
+ SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
+ if (graph == null) {
+ LOGGER.error(LOAD_ERROR_MESSAGE, details);
+ System.exit(1);
+ }
+ graph.printAsXml(System.out);
+ } catch (Exception e) {
+ LOGGER.error(PRINT_ERROR_MESSAGE, details, e);
+ System.exit(1);
+ }
+
+ }
+
+ public static void activate(String module, String rpc, String version, String mode, SvcLogicStore store) {
+ String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")";
+
+ try {
+ LOGGER.info(LOAD_MESSAGE, details);
+
+ SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
+ if (graph == null) {
+ LOGGER.error(LOAD_ERROR_MESSAGE, details);
+ System.exit(1);
+ }
+ store.activate(graph);
+ } catch (Exception e) {
+ LOGGER.error(ACTIVATION_ERROR_MESSAGE, details, e);
+ System.exit(1);
+ }
+
+ }
+
+ private static void usage() {
+ System.err.println("Usage: SvcLogicParser load <xml-file> <prop-file>");
+ System.err.println(" OR SvcLogicParser print <module> <rpc> <mode> [<version>] <prop-file>");
+ System.err.println(" OR SvcLogicParser get-source <module> <rpc> <mode> <version> <prop-file>");
+ System.err.println(" OR SvcLogicParser activate <module> <rpc> <version> <mode>");
+ System.err.println(" OR SvcLogicParser validate <file path to graph> <prop-file>");
+ System.err.println(" OR SvcLogicParser install <service-logic directory path> <prop-file>");
+ System.err.println(" OR SvcLogicParser bulkActivate <path to activation file> <prop-file>");
+ System.exit(1);
+ }
+
+ protected SAXParser initParser() throws ParserConfigurationException, SAXException {
+ URL xsdUrl = null;
+ Schema schema = null;
+ String validateSchema = System.getProperty(SLI_VALIDATING_PARSER, "true");
+
+ if ("true".equalsIgnoreCase(validateSchema)) {
+ xsdUrl = getClass().getResource(SVCLOGIC_XSD);
+ }
+
+ if (xsdUrl != null) {
+ try {
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ schema = schemaFactory.newSchema(xsdUrl);
+ LOGGER.info("Schema path {}", xsdUrl.getPath());
+ } catch (Exception e) {
+ LOGGER.warn("Could not validate using schema {}", xsdUrl.getPath(), e);
+ }
+ } else {
+ LOGGER.warn("Could not find resource {}", SVCLOGIC_XSD);
+ }
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+
+ if (schema != null) {
+ factory.setNamespaceAware(true);
+ factory.setSchema(schema);
+ }
+
+ SAXParser saxParser = factory.newSAXParser();
+ if (saxParser.isValidating()) {
+ LOGGER.info("Parser configured to validate XML {}", (xsdUrl != null ? xsdUrl.getPath() : null));
+ }
+ return saxParser;
+ }
+
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java
new file mode 100644
index 000000000..61f80f7e2
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.IOException;
+
+public class SvcLogicParserException extends IOException {
+
+ public SvcLogicParserException() {
+ super();
+ }
+
+ public SvcLogicParserException(String msg) {
+ super(msg);
+ }
+
+ public SvcLogicParserException(Throwable t) {
+ super(t);
+ }
+
+ public SvcLogicParserException(String msg, Throwable t) {
+ super(msg, t);
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java
new file mode 100644
index 000000000..ca13536bb
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.util.Map;
+
+public interface SvcLogicRecorder {
+
+ void record(Map<String, String> parmMap) throws SvcLogicException;
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java
new file mode 100644
index 000000000..0e2c42574
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.util.Map;
+
+public interface SvcLogicResource {
+
+ public enum QueryStatus {
+ SUCCESS,
+ NOT_FOUND,
+ FAILURE
+ }
+
+ public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException;
+
+ public QueryStatus update(String resource, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) throws SvcLogicException;
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java
new file mode 100644
index 000000000..2eda67f11
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.util.Properties;
+
+public interface SvcLogicStore {
+
+ public void init(Properties props) throws SvcLogicException;
+ public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException;
+ public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException;
+ public void store(SvcLogicGraph graph) throws SvcLogicException;
+ public void delete(String module, String rpc, String version, String mode) throws SvcLogicException;
+ public void activate(SvcLogicGraph graph) throws SvcLogicException;
+ public void activate(String module, String rpc, String version, String mode) throws SvcLogicException;
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java
new file mode 100644
index 000000000..e0eb57304
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Properties;
+import org.onap.ccsdk.sli.core.dblib.DBResourceManager;
+import org.onap.ccsdk.sli.core.utils.PathValidator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicStoreFactory {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicStoreFactory.class);
+
+ public static SvcLogicStore getSvcLogicStore(String propfile)
+ throws SvcLogicException {
+ if (!PathValidator.isValidPropertiesPath(propfile)) {
+ throw new ConfigurationException("Invalid property file name ("+propfile+")");
+ }
+ File propFile = new File(propfile);
+ if (!propFile.canRead()) {
+ throw new ConfigurationException("Cannot read property file "
+ + propfile);
+
+ }
+
+ try {
+ return getSvcLogicStore(new FileInputStream(propFile));
+ } catch (Exception e) {
+ throw new ConfigurationException(
+ "Could load service store from properties file " + propfile,
+ e);
+ }
+
+ }
+
+ public static SvcLogicStore getSvcLogicStore(InputStream inStr) throws SvcLogicException
+ {
+ Properties props = new Properties();
+
+ try {
+ props.load(inStr);
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not get load properties from input stream", e);
+ }
+
+ return getSvcLogicStore(props);
+ }
+
+ public static SvcLogicStore getSvcLogicStore(Properties props)
+ throws SvcLogicException {
+ String storeType = props.getProperty("org.onap.ccsdk.sli.dbtype");
+ if ((storeType == null) || (storeType.length() == 0)) {
+ throw new ConfigurationException(
+ "property org.onap.ccsdk.sli.dbtype unset");
+
+ }
+
+ SvcLogicStore retval;
+ LOG.debug("Using org.onap.ccsdk.sli.dbtype={}", storeType);
+
+ if ("jdbc".equalsIgnoreCase(storeType)) {
+ retval = new SvcLogicJdbcStore();
+
+ } else if ("dblib".equalsIgnoreCase(storeType)) {
+ retval = new SvcLogicDblibStore(new DBResourceManager(props));
+ } else {
+ throw new ConfigurationException("unsupported dbtype (" + storeType
+ + ")");
+
+ }
+
+
+ retval.init(props);
+ return retval;
+ }
+
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java
new file mode 100644
index 000000000..4edf3ecbe
--- /dev/null
+++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+public class SvcLogicVariableTerm extends SvcLogicExpression {
+
+ private String name = null;
+
+ public String getName() {
+ return name;
+ }
+
+
+ public SvcLogicVariableTerm(String identifier)
+ {
+ this.name = identifier;
+ }
+
+ public SvcLogicExpression getSubscript()
+ {
+ if (numOperands() > 0)
+ {
+ return(getOperands().get(0));
+ }
+ else
+ {
+ return(null);
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ String retval;
+
+ if (numOperands() > 0)
+ {
+ retval = name + "[" + getSubscript().toString() + "]";
+ }
+ else
+ {
+ retval = name;
+ }
+ return(retval);
+ }
+
+ @Override
+ public String asParsedExpr() {
+ if (numOperands() == 0) {
+ return("(variable-term "+name+")");
+ }
+ else
+ {
+ return("(variable-term "+name+" "+getSubscript().asParsedExpr()+")");
+ }
+ }
+
+}
diff --git a/core/sli/common/src/main/resources/svclogic.xsd b/core/sli/common/src/main/resources/svclogic.xsd
new file mode 100755
index 000000000..c9beae83e
--- /dev/null
+++ b/core/sli/common/src/main/resources/svclogic.xsd
@@ -0,0 +1,339 @@
+<?xml version = "1.0" encoding = "UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.onap.org/sdnc/svclogic" xmlns="http://www.onap.org/sdnc/svclogic">
+
+ <xsd:simpleType name="modeType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="sync" />
+ <xsd:enumeration value="async" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:group name="node">
+ <xsd:choice>
+ <xsd:element ref="block" />
+ <xsd:element ref="is-available" />
+ <xsd:element ref="exists" />
+ <xsd:element ref="reserve" />
+ <xsd:element ref="release" />
+ <xsd:element ref="allocate" />
+ <xsd:element ref="get-resource" />
+ <xsd:element ref="configure" />
+ <xsd:element ref="return" />
+ <xsd:element ref="switch" />
+ <xsd:element ref="record" />
+ <xsd:element ref="save" />
+ <xsd:element ref="for" />
+ <xsd:element ref="set" />
+ <xsd:element ref="execute" />
+ <xsd:element ref="delete" />
+ <xsd:element ref="update" />
+ <xsd:element ref="call" />
+ <xsd:element ref="notify" />
+ <xsd:element ref="break" />
+ <xsd:element ref="while" />
+ <xsd:element ref="exit" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:element name="service-logic">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="method" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="module" use="required" type="xsd:string" />
+ <xsd:attribute name="version" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="method">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="node" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="rpc" use="required" type="xsd:string" />
+ <xsd:attribute name="mode" use="optional" type="modeType" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="block">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="node" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="atomic" use="optional" type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="is-available">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="exists">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="outcome">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="node" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="ref" use="optional" type="xsd:string" />
+ <xsd:attribute name="value" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="reserve">
+ <xsd:complexType>
+ <xsd:sequence>
+ <!-- This node does not actually read from parameters -->
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <xsd:attribute name="select" use="optional" type="xsd:string" />
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="release">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="record">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="allocate">
+ <xsd:complexType>
+ <xsd:sequence>
+ <!-- This node does not actually read from parameters -->
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="required" type="xsd:string" />
+ <xsd:attribute name="pfx" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="get-resource">
+ <xsd:complexType>
+ <xsd:sequence>
+ <!-- This node does not actually read from parameters -->
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <xsd:attribute name="local-only" use="optional" type="xsd:boolean" />
+ <xsd:attribute name="order-by" use="optional" type="xsd:string" />
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ <!-- force is retired and does not do anything -->
+ <xsd:attribute name="force" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="configure">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="adaptor" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="required" type="xsd:string" />
+ <xsd:attribute name="activate" use="optional" type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <xsd:element name="parameter">
+ <xsd:complexType>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="value" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <xsd:element name="return">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="status" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="switch">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="test" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="save">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <xsd:attribute name="force" use="optional" type="xsd:boolean" />
+ <xsd:attribute name="local-only" use="optional" type="xsd:boolean" />
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="delete">
+ <xsd:complexType>
+ <xsd:sequence>
+ <!-- This node does not actually read from parameters -->
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <!-- force is retired and does not do anything -->
+ <xsd:attribute name="force" use="optional" type="xsd:string" />
+ <!-- local-only is retired and does not do anything -->
+ <xsd:attribute name="local-only" use="optional" type="xsd:string" />
+ <!-- pfx is retired and does not do anything -->
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="for">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="node" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="atomic" use="optional" type="xsd:boolean" />
+ <xsd:attribute name="index" use="required" type="xsd:string" />
+ <xsd:attribute name="start" use="required" type="xsd:string" />
+ <xsd:attribute name="end" use="required" type="xsd:string" />
+ <xsd:attribute name="silentFailure" use="optional" type="xsd:boolean" default="false" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="set">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="only-if-unset" use="optional"
+ type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="execute">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="method" use="required" type="xsd:string" />
+ <xsd:attribute name="emitsOutcome" use="optional" type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="update">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="required" type="xsd:string" />
+ <xsd:attribute name="resource" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <xsd:attribute name="force" use="optional" type="xsd:boolean" />
+ <xsd:attribute name="local-only" use="optional" type="xsd:boolean" />
+ <xsd:attribute name="pfx" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="call">
+ <xsd:complexType>
+ <xsd:sequence>
+ <!-- This node does not actually read from parameters -->
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="module" use="optional" type="xsd:string" />
+ <xsd:attribute name="rpc" use="required" type="xsd:string" />
+ <xsd:attribute name="version" use="optional" type="xsd:string" />
+ <xsd:attribute name="mode" use="required" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="notify">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="plugin" use="optional" type="xsd:string" />
+ <xsd:attribute name="resource" use="optional" type="xsd:string" />
+ <xsd:attribute name="action" use="required" type="xsd:string" />
+ <xsd:attribute name="key" use="optional" type="xsd:string" />
+ <!-- force is retired and does not do anything -->
+ <xsd:attribute name="force" use="optional" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="break">
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:element name="exit">
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:element name="while">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="node" minOccurs="0" maxOccurs="100" />
+ </xsd:sequence>
+ <xsd:attribute name="test" use="required" type="xsd:string" />
+ <xsd:attribute name="do" use="optional" type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java
new file mode 100644
index 000000000..ef7492366
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java
@@ -0,0 +1,30 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class ConfigurationExceptionTestt {
+
+
+ @Test
+ public void ConfigurationExceptionTest() {
+ assertNotNull(new ConfigurationException());
+
+ }
+
+ @Test
+ public void ConfigurationExceptionTestString() {
+ assertNotNull(new ConfigurationException("JUnit Test"));
+
+ }
+
+ @Test
+ public void ConfigurationExceptionTestStringThrowable() {
+ assertNotNull(new ConfigurationException("JUnit Test", new Exception("JUnit Test")));
+
+ }
+
+
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java
new file mode 100644
index 000000000..387873557
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java
@@ -0,0 +1,28 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class DuplicatevalueExceptionTest {
+
+
+ @Test
+ public void DuplicateValueExceptionTest() {
+ assertNotNull(new DuplicateValueException());
+
+ }
+
+ @Test
+ public void DuplicateValueExceptionTestString() {
+ assertNotNull(new DuplicateValueException("JUnit Test"));
+
+ }
+
+ @Test
+ public void DuplicateValueExceptionTestStringThrowable() {
+ assertNotNull(new DuplicateValueException("JUnit Test", new Exception("JUnit Test")));
+
+ }
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java
new file mode 100644
index 000000000..d95ff3075
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java
@@ -0,0 +1,56 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ErrorLoggerTest {
+ private Logger log = LoggerFactory.getLogger(ErrorLoggerTest.class);
+
+ @Test
+ public void testOverloads() throws Exception {
+ ErrorLogger e = new ErrorLogger();
+ Exception exc = new Exception();
+ e.logError("failure", 200);
+ e.logError("failure", 200, exc);
+ e.logError("failure", 200, "Timeout during HTTP operation");
+ e.logError("failure", 200, "Timeout during HTTP operation", exc);
+ }
+
+ @Test
+ public void testInvalidErrorCode() throws Exception {
+ ErrorLogger e = new ErrorLogger();
+ e.logError("failure", 0);
+ }
+
+ @Test
+ public void testDescriptionMapping() throws Exception {
+ ErrorLogger e = new ErrorLogger();
+ e.logError("failure", 100);
+ e.logError("failure", 200);
+ e.logError("failure", 300);
+ e.logError("failure", 400);
+ e.logError("failure", 500);
+ e.logError("failure", 900);
+ }
+
+ @Test
+ public void testIsValidCode() throws Exception {
+ ErrorLogger e = new ErrorLogger(log);
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_100));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_200));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_300));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_400));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_500));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_900));
+
+ assertFalse(e.isValidCode(0));
+ assertFalse(e.isValidCode(204));
+ assertFalse(e.isValidCode(404));
+ assertFalse(e.isValidCode(501));
+ }
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java
new file mode 100644
index 000000000..039b9f5ca
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java
@@ -0,0 +1,27 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class ExitNodeExceptionTest {
+
+ @Test
+ public void ExitNodeExceptionTest() {
+ assertNotNull(new ExitNodeException());
+
+ }
+
+ @Test
+ public void ExitNodeExceptionTestString() {
+ assertNotNull(new ExitNodeException("JUnit Test"));
+
+ }
+
+ @Test
+ public void ExitNodeExceptionTestStringThrowable() {
+ assertNotNull(new ExitNodeException("JUnit Test", new Exception("JUnit Test")));
+
+ }
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java
new file mode 100644
index 000000000..50eb917f8
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java
@@ -0,0 +1,284 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.dblib.DBResourceManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author dt5972
+ *
+ */
+public class ITCaseSvcLogicParser {
+
+ private static SvcLogicStore store;
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicJdbcStore.class);
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+
+ LOG.info("before class");
+
+ URL propUrl = ITCaseSvcLogicParser.class.getResource("/svclogic.properties");
+
+ InputStream propStr = ITCaseSvcLogicParser.class.getResourceAsStream("/svclogic.properties");
+
+ Properties props = new Properties();
+
+ props.load(propStr);
+
+ store = SvcLogicStoreFactory.getSvcLogicStore(props);
+
+ assertNotNull(store);
+
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ LOG.info("after class");
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ LOG.info("before");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ LOG.info("after");
+ }
+
+ /**
+ * Test method for {@link org.onap.ccsdk.sli.core.sli.SvcLogicParser#parse(java.lang.String)}.
+ */
+ @Test
+ public void testParseValidXml() {
+
+ try {
+ InputStream testStr = getClass().getResourceAsStream("/parser-good.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+ String testCaseFile = null;
+ while ((testCaseFile = testsReader.readLine()) != null) {
+
+ testCaseFile = testCaseFile.trim();
+
+ if (testCaseFile.length() > 0) {
+ if (!testCaseFile.startsWith("/")) {
+ testCaseFile = "/" + testCaseFile;
+ }
+ URL testCaseUrl = getClass().getResource(testCaseFile);
+ if (testCaseUrl == null) {
+ fail("Could not resolve test case file " + testCaseFile);
+ }
+
+ // Test parsing and printing
+ try {
+ SvcLogicParser parser = new SvcLogicParser();
+
+ for (SvcLogicGraph graph : parser.parse(testCaseUrl.getPath())) {
+ System.out.println("XML for graph "+graph.getModule()+":"+graph.getRpc());
+ graph.printAsXml(System.out);
+ System.out.println("GV for graph "+graph.getModule()+":"+graph.getRpc());
+ graph.printAsGv(System.out);
+ }
+ } catch (Exception e) {
+
+ fail("Validation failure [" + e.getMessage() + "]");
+ }
+
+ try {
+ SvcLogicParser.load(testCaseUrl.getPath(), store);
+ } catch (Exception e) {
+
+ fail("Validation failure [" + e.getMessage() + "]");
+ }
+ }
+ }
+ } catch (SvcLogicParserException e) {
+ fail("Parser error : " + e.getMessage());
+ } catch (Exception e) {
+ LOG.error("", e);
+ fail("Caught exception processing test cases");
+ }
+ }
+
+ @Test
+ public void testDblibLoadValidXml() throws IOException, SQLException, ConfigurationException {
+
+ URL propUrl = ITCaseSvcLogicParser.class.getResource("/dblib.properties");
+
+ InputStream propStr = ITCaseSvcLogicParser.class.getResourceAsStream("/dblib.properties");
+
+ Properties props = new Properties();
+
+ props.load(propStr);
+
+ SvcLogicDblibStore dblibStore = new SvcLogicDblibStore(new DBResourceManager(props));
+
+ Connection dbConn = dblibStore.getConnection();
+
+ String dbName = props.getProperty("org.onap.ccsdk.sli.jdbc.database", "sdnctl");
+
+ DatabaseMetaData dbm;
+
+ try {
+ dbm = dbConn.getMetaData();
+ } catch (SQLException e) {
+
+ throw new ConfigurationException("could not get databse metadata", e);
+ }
+
+ // See if table SVC_LOGIC exists. If not, create it.
+ Statement stmt = null;
+ try {
+
+ ResultSet tables = dbm.getTables(null, null, "SVC_LOGIC", null);
+ if (tables.next()) {
+ LOG.debug("SVC_LOGIC table already exists");
+ } else {
+ String crTableCmd = "CREATE TABLE " + dbName + ".SVC_LOGIC (" + "module varchar(80) NOT NULL,"
+ + "rpc varchar(80) NOT NULL," + "version varchar(40) NOT NULL," + "mode varchar(5) NOT NULL,"
+ + "active varchar(1) NOT NULL,graph BLOB,"
+ + "modified_timestamp timestamp DEFAULT NULL,"
+ + "md5sum varchar(128) DEFAULT NULL,"
+ + "CONSTRAINT P_SVC_LOGIC PRIMARY KEY(module, rpc, version, mode))";
+
+ stmt = dbConn.createStatement();
+ stmt.executeUpdate(crTableCmd);
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("could not create SVC_LOGIC table", e);
+ } finally {
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ LOG.error("Statement close error ", e);
+ }
+ }
+ }
+
+ // See if NODE_TYPES table exists and, if not, create it
+ stmt = null;
+ try {
+
+ ResultSet tables = dbm.getTables(null, null, "NODE_TYPES", null);
+ if (tables.next()) {
+ LOG.debug("NODE_TYPES table already exists");
+ } else {
+ String crTableCmd = "CREATE TABLE " + dbName + ".NODE_TYPES (" + "nodetype varchar(80) NOT NULL,"
+ + "CONSTRAINT P_NODE_TYPES PRIMARY KEY(nodetype))";
+
+ stmt = dbConn.createStatement();
+
+ stmt.executeUpdate(crTableCmd);
+ }
+ } catch (Exception e) {
+ throw new ConfigurationException("could not create SVC_LOGIC table", e);
+ } finally {
+ if (stmt != null) {
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ LOG.error("Statement close error ", e);
+ }
+ }
+ }
+
+ try {
+ InputStream testStr = getClass().getResourceAsStream("/parser-good.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+ String testCaseFile = null;
+ while ((testCaseFile = testsReader.readLine()) != null) {
+
+ testCaseFile = testCaseFile.trim();
+
+ if (testCaseFile.length() > 0) {
+ if (!testCaseFile.startsWith("/")) {
+ testCaseFile = "/" + testCaseFile;
+ }
+ URL testCaseUrl = getClass().getResource(testCaseFile);
+ if (testCaseUrl == null) {
+ fail("Could not resolve test case file " + testCaseFile);
+ }
+
+ try {
+ SvcLogicParser.load(testCaseUrl.getPath(), dblibStore);
+ } catch (Exception e) {
+
+ fail("Validation failure [" + e.getMessage() + "]");
+ }
+ }
+ }
+ } catch (SvcLogicParserException e) {
+ fail("Parser error : " + e.getMessage());
+ } catch (Exception e) {
+ LOG.error("", e);
+ fail("Caught exception processing test cases");
+ }
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void testParseInvalidXml() throws SvcLogicException, IOException {
+
+ InputStream testStr = getClass().getResourceAsStream("/parser-bad.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+ String testCaseFile;
+ while ((testCaseFile = testsReader.readLine()) != null) {
+
+ testCaseFile = testCaseFile.trim();
+
+ if (testCaseFile.length() > 0) {
+ if (!testCaseFile.startsWith("/")) {
+ testCaseFile = "/" + testCaseFile;
+ }
+ URL testCaseUrl = getClass().getResource(testCaseFile);
+ if (testCaseUrl == null) {
+ fail("Could not resolve test case file " + testCaseFile);
+ }
+ SvcLogicParser.validate(testCaseUrl.getPath(), store);
+ }
+ }
+ }
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java
new file mode 100644
index 000000000..43e7a862b
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java
@@ -0,0 +1,400 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import com.google.gson.*;
+import org.apache.commons.lang3.builder.ToStringExclude;
+import org.checkerframework.checker.units.qual.A;
+import org.json.JSONException;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import junit.framework.TestCase;
+
+import static org.junit.Assert.assertEquals;
+
+public class SvcLogicContextTest extends TestCase {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicContextTest.class);
+
+ @Test
+ public void testMerge() {
+
+ try {
+ InputStream testStr = getClass().getResourceAsStream("/mergetest.xml");
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = dbf.newDocumentBuilder();
+
+ Document theDocument = db.parse(testStr);
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.mergeDocument("test-merge", theDocument);
+ Properties props = ctx.toProperties();
+ LOG.info("SvcLogicContext contains the following : ");
+ for (Enumeration e = props.propertyNames(); e.hasMoreElements() ; ) {
+ String propName = (String) e.nextElement();
+ LOG.info(propName+" = "+props.getProperty(propName));
+
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to merge", e);
+ fail("Caught exception trying to merge");
+ }
+
+ }
+
+ @Test
+ public void testIsSuccess() {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.setStatus(SvcLogicConstants.SUCCESS);
+ assertTrue(ctx.isSuccess());
+ ctx.setStatus(SvcLogicConstants.FAILURE);
+ assertFalse(ctx.isSuccess());
+ }
+
+ @Test
+ public void testMarkSuccess() {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.markSuccess();
+ assertTrue(ctx.isSuccess());
+ assertEquals(SvcLogicConstants.SUCCESS, ctx.getStatus());
+ }
+
+ @Test
+ public void testMarkFailed() {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.markFailed();
+ assertFalse(ctx.isSuccess());
+ assertEquals(SvcLogicConstants.FAILURE, ctx.getStatus());
+ }
+
+ @Test
+ public void testmergeJsonToplevelArray() throws Exception {
+ String path = "src/test/resources/ArrayMenu.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.mergeJson("testPath", content);
+
+
+ assertEquals("1000", ctx.getAttribute("testPath.[0].calories"));
+ assertEquals("1", ctx.getAttribute("testPath.[0].id"));
+ assertEquals("plain", ctx.getAttribute("testPath.[0].name"));
+ assertEquals("pizza", ctx.getAttribute("testPath.[0].type"));
+ assertEquals("true", ctx.getAttribute("testPath.[0].vegetarian"));
+ assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.[1].calories"));
+ assertEquals("2", ctx.getAttribute("testPath.[1].id"));
+ assertEquals("Tuesday Special", ctx.getAttribute("testPath.[1].name"));
+ assertEquals("1", ctx.getAttribute("testPath.[1].topping[0].id"));
+ assertEquals("onion", ctx.getAttribute("testPath.[1].topping[0].name"));
+ assertEquals("2", ctx.getAttribute("testPath.[1].topping[1].id"));
+ assertEquals("pepperoni", ctx.getAttribute("testPath.[1].topping[1].name"));
+ assertEquals("2", ctx.getAttribute("testPath.[1].topping_length"));
+ assertEquals("pizza", ctx.getAttribute("testPath.[1].type"));
+ assertEquals("false", ctx.getAttribute("testPath.[1].vegetarian"));
+ assertEquals("1500", ctx.getAttribute("testPath.[2].calories"));
+ assertEquals("3", ctx.getAttribute("testPath.[2].id"));
+ assertEquals("House Special", ctx.getAttribute("testPath.[2].name"));
+ assertEquals("3", ctx.getAttribute("testPath.[2].topping[0].id"));
+ assertEquals("basil", ctx.getAttribute("testPath.[2].topping[0].name"));
+ assertEquals("4", ctx.getAttribute("testPath.[2].topping[1].id"));
+ assertEquals("fresh mozzarella", ctx.getAttribute("testPath.[2].topping[1].name"));
+ assertEquals("5", ctx.getAttribute("testPath.[2].topping[2].id"));
+ assertEquals("tomato", ctx.getAttribute("testPath.[2].topping[2].name"));
+ assertEquals("3", ctx.getAttribute("testPath.[2].topping_length"));
+ assertEquals("pizza", ctx.getAttribute("testPath.[2].type"));
+ assertEquals("true", ctx.getAttribute("testPath.[2].vegetarian"));
+ assertEquals("3", ctx.getAttribute("testPath._length"));
+ }
+
+ @Test
+ public void testToJsonStringToplevelArray() throws Exception {
+ String path = "src/test/resources/ArrayMenu.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.mergeJson("testPath", content);
+
+ String ctxContent = ctx.toJsonString("testPath");
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+
+ try {
+ assertEquals(jsonIn, jsonOut);
+ } catch (AssertionError e) {
+ LOG.warn("Top level array not working - error is {}", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testMergeJson() throws Exception {
+ String path = "src/test/resources/ObjectMenu.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ ctx.mergeJson("testPath", content);
+
+
+ assertEquals("1000", ctx.getAttribute("testPath.menu[0].calories"));
+ assertEquals("1", ctx.getAttribute("testPath.menu[0].id"));
+ assertEquals("plain", ctx.getAttribute("testPath.menu[0].name"));
+ assertEquals("pizza", ctx.getAttribute("testPath.menu[0].type"));
+ assertEquals("true", ctx.getAttribute("testPath.menu[0].vegetarian"));
+ assertEquals("2000", ctx.getAttribute("testPath.menu[1].calories"));
+ assertEquals("2", ctx.getAttribute("testPath.menu[1].id"));
+ assertEquals("Tuesday Special", ctx.getAttribute("testPath.menu[1].name"));
+ assertEquals("1", ctx.getAttribute("testPath.menu[1].topping[0].id"));
+ assertEquals("onion", ctx.getAttribute("testPath.menu[1].topping[0].name"));
+ assertEquals("2", ctx.getAttribute("testPath.menu[1].topping[1].id"));
+ assertEquals("pepperoni", ctx.getAttribute("testPath.menu[1].topping[1].name"));
+ assertEquals("2", ctx.getAttribute("testPath.menu[1].topping_length"));
+ assertEquals("pizza", ctx.getAttribute("testPath.menu[1].type"));
+ assertEquals("false", ctx.getAttribute("testPath.menu[1].vegetarian"));
+ assertEquals("1500", ctx.getAttribute("testPath.menu[2].calories"));
+ assertEquals("3", ctx.getAttribute("testPath.menu[2].id"));
+ assertEquals("House Special", ctx.getAttribute("testPath.menu[2].name"));
+ assertEquals("3", ctx.getAttribute("testPath.menu[2].topping[0].id"));
+ assertEquals("basil", ctx.getAttribute("testPath.menu[2].topping[0].name"));
+ assertEquals("4", ctx.getAttribute("testPath.menu[2].topping[1].id"));
+ assertEquals("fresh mozzarella", ctx.getAttribute("testPath.menu[2].topping[1].name"));
+ assertEquals("5", ctx.getAttribute("testPath.menu[2].topping[2].id"));
+ assertEquals("tomato", ctx.getAttribute("testPath.menu[2].topping[2].name"));
+ assertEquals("3", ctx.getAttribute("testPath.menu[2].topping_length"));
+ assertEquals("pizza", ctx.getAttribute("testPath.menu[2].type"));
+ assertEquals("true", ctx.getAttribute("testPath.menu[2].vegetarian"));
+ assertEquals("3", ctx.getAttribute("testPath.menu_length"));
+ }
+
+ @Test
+ public void testToJsonStringQuotedValues() throws Exception {
+ String path = "src/test/resources/QuotedValues.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ ctx.mergeJson("testPath", content);
+ String ctxContent = ctx.toJsonString("testPath");
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+ assertEquals(jsonIn, jsonOut);
+ }
+
+
+ @Test
+ public void testToJsonString() throws Exception {
+ String path = "src/test/resources/ObjectMenu.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ ctx.mergeJson("testPath", content);
+ String ctxContent = ctx.toJsonString("testPath");
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+
+ try {
+ assertEquals(jsonIn, jsonOut);
+ } catch (AssertionError e) {
+ // Error could be due to quoted numeric values, which we cannot address.
+ LOG.warn("Test failed, but could be known error condition. Error is {}", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testToJsonStringNoArg() throws Exception {
+ String path = "src/test/resources/QuotedValues.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ ctx.mergeJson(null, content);
+ String ctxContent = ctx.toJsonString();
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+ assertEquals(jsonIn, jsonOut);
+ }
+
+ @Test
+ public void test2dMergeJson() throws Exception {
+ String path = "src/test/resources/2dArray.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+
+ ctx.mergeJson("testPath", content);
+ assertEquals("apple", ctx.getAttribute("testPath.[0][0]"));
+ assertEquals("orange", ctx.getAttribute("testPath.[0][1]"));
+ assertEquals("banana", ctx.getAttribute("testPath.[0][2]"));
+ assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.[0][3]"));
+ assertEquals("4", ctx.getAttribute("testPath.[0]_length"));
+ assertEquals("squash", ctx.getAttribute("testPath.[1][0]"));
+ assertEquals("broccoli", ctx.getAttribute("testPath.[1][1]"));
+ assertEquals("cauliflower", ctx.getAttribute("testPath.[1][2]"));
+ assertEquals("3", ctx.getAttribute("testPath.[1]_length"));
+ assertEquals("2", ctx.getAttribute("testPath._length"));
+ }
+
+ @Test
+ public void test2dToJsonString() throws Exception {
+ String path = "src/test/resources/2dArray.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+
+ ctx.mergeJson("testPath", content);
+ String ctxContent = ctx.toJsonString("testPath");
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+
+ try {
+ assertEquals(jsonIn, jsonOut);
+ } catch (AssertionError e) {
+ LOG.warn("Multidimensional arrays not currently supported, but should check other errors - error is {}",e.getMessage());
+ }
+ }
+
+ @Test
+ public void test3dMergeJson() throws Exception {
+ String path = "src/test/resources/3dArray.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ ctx.mergeJson("testPath", content);
+ assertEquals("a", ctx.getAttribute("testPath.[0][0][0]"));
+ assertEquals("b", ctx.getAttribute("testPath.[0][0][1]"));
+ assertEquals("c", ctx.getAttribute("testPath.[0][0][2]"));
+ assertEquals("3", ctx.getAttribute("testPath.[0][0]_length"));
+ assertEquals("d", ctx.getAttribute("testPath.[0][1][0]"));
+ assertEquals("e", ctx.getAttribute("testPath.[0][1][1]"));
+ assertEquals("f", ctx.getAttribute("testPath.[0][1][2]"));
+ assertEquals("3", ctx.getAttribute("testPath.[0][1]_length"));
+ assertEquals("2", ctx.getAttribute("testPath.[0]_length"));
+ assertEquals("x", ctx.getAttribute("testPath.[1][0][0]"));
+ assertEquals("y", ctx.getAttribute("testPath.[1][0][1]"));
+ assertEquals("z", ctx.getAttribute("testPath.[1][0][2]"));
+ assertEquals("3", ctx.getAttribute("testPath.[1][0]_length"));
+ assertEquals("1", ctx.getAttribute("testPath.[1]_length"));
+ assertEquals("2", ctx.getAttribute("testPath._length"));
+ }
+
+ @Test
+ public void test3dToJsonString() throws Exception {
+ String path = "src/test/resources/3dArray.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.mergeJson("testPath", content);
+ String ctxContent = ctx.toJsonString("testPath");
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+
+ try {
+ assertEquals(jsonIn, jsonOut);
+ } catch (AssertionError e) {
+ LOG.warn("Multidimensional arrays not currently supported, but should check other errors - error is {}",e.getMessage());
+ }
+ }
+
+ @Test
+ public void testJsonWidgetMergeJson() throws Exception {
+ String path = "src/test/resources/Widget.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ ctx.mergeJson("testPath", content);
+ assertEquals("false", ctx.getAttribute("testPath.widget.debug"));
+ assertEquals("center", ctx.getAttribute("testPath.widget.image.alignment"));
+ assertEquals("150", ctx.getAttribute("testPath.widget.image.hOffset"));
+ assertEquals("moon", ctx.getAttribute("testPath.widget.image.name"));
+ assertEquals("images/moon.png", ctx.getAttribute("testPath.widget.image.src"));
+ assertEquals("150", ctx.getAttribute("testPath.widget.image.vOffset"));
+ assertEquals("center", ctx.getAttribute("testPath.widget.text.alignment"));
+ assertEquals("Click Me", ctx.getAttribute("testPath.widget.text.data"));
+ assertEquals("350", ctx.getAttribute("testPath.widget.text.hOffset"));
+ assertEquals("text1", ctx.getAttribute("testPath.widget.text.name"));
+ assertEquals("21", ctx.getAttribute("testPath.widget.text.size"));
+ assertEquals("bold", ctx.getAttribute("testPath.widget.text.style"));
+ assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.widget.text.vOffset"));
+ assertEquals("300", ctx.getAttribute("testPath.widget.window.height"));
+ assertEquals("main_window", ctx.getAttribute("testPath.widget.window.name"));
+ assertEquals("ONAP Widget", ctx.getAttribute("testPath.widget.window.title"));
+ assertEquals("200", ctx.getAttribute("testPath.widget.window.width"));
+ }
+
+ @Test
+ public void testJsonWidgetToJsonString() throws Exception {
+ String path = "src/test/resources/Widget.json";
+ String content = new String(Files.readAllBytes(Paths.get(path)));
+
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.mergeJson("testPath", content);
+ String ctxContent = ctx.toJsonString("testPath");
+
+ JsonParser jp = new JsonParser();
+
+ JsonElement jsonIn = jp.parse(content);
+ JsonElement jsonOut = jp.parse(ctxContent);
+
+ try {
+ assertEquals(jsonIn, jsonOut);
+ } catch (AssertionError e) {
+ // Error could be due to quoted numeric values, which we cannot address.
+ LOG.warn("Test failed, but could be known error condition. Error is {}",e.getMessage());
+ }
+ }
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java
new file mode 100644
index 000000000..80df10cee
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import junit.framework.TestCase;
+
+public class SvcLogicExpressionParserTest extends TestCase {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExprListener.class);
+
+ public void testParse() {
+ try
+ {
+ InputStream testStr = getClass().getResourceAsStream("/expression.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+
+ String testExpr = null;
+ while ((testExpr = testsReader.readLine()) != null) {
+
+ SvcLogicExpression parsedExpr = SvcLogicExpressionFactory.parse(testExpr);
+ if (parsedExpr == null)
+ {
+ fail("parse("+testExpr+") returned null");
+ }
+ else
+ {
+ LOG.info("test expression = ["+testExpr+"] ; parsed expression = ["+parsedExpr.asParsedExpr()+"]");
+
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ fail("Caught exception processing test cases");
+ }
+ }
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java
new file mode 100644
index 000000000..f9d33cb16
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java
@@ -0,0 +1,34 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class SvcLogicParserExceptionTest {
+
+ @Test
+ public void SvcLogicParserExceptionTest() {
+ assertNotNull(new SvcLogicParserException());
+
+ }
+
+ @Test
+ public void SvcLogicParserExceptionTestString() {
+ assertNotNull(new SvcLogicParserException("JUnit Test"));
+
+ }
+
+ @Test
+ public void SvcLogicParserExceptionTestThrowable() {
+ assertNotNull(new SvcLogicParserException(new Exception("JUnit Test")));
+
+ }
+
+ @Test
+ public void SvcLogicParserExceptionTestStringThrowable() {
+ assertNotNull(new SvcLogicParserException("JUnit Test", new Exception("JUnit Test")));
+
+ }
+
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java
new file mode 100755
index 000000000..37d2fc8c5
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java
@@ -0,0 +1,85 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.*;
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.MDC;
+
+public class TestMetricLogger {
+
+ MetricLogger logger;
+
+ @Before
+ public void setUp() throws Exception {
+ logger = new MetricLogger();
+ MetricLogger.resetContext();
+ }
+
+ @Test
+ public final void testGetRequestID() {
+ UUID uuid = UUID.randomUUID();
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, uuid.toString());
+ assertEquals(uuid.toString(),logger.getRequestID());
+ }
+
+ @Test
+ public final void testAsIso8601Date() {
+ logger.asIso8601(new Date());
+ }
+
+ @Test
+ public final void testAsIso8601Long() {
+ logger.asIso8601(System.currentTimeMillis());
+ }
+
+ @Test
+ public void formatString() {
+ String output = logger.formatString("\n");
+ assertEquals("",output);
+ output = logger.formatString("|");
+ assertEquals("%7C",output);
+ output = logger.formatString(null);
+ assertEquals(null,output);
+ output = logger.formatString("\t");
+ assertEquals(" ", output);
+ output = logger.formatString("one,two,three,");
+ assertEquals("one\\,two\\,three\\,", output);
+ }
+
+ @Test
+ public void generateInvocationId() {
+ logger.logRequest("svcInstance1", "svcName", "svcPartner", "targetEntity", "targetServiceName", "targetVirtualEntity", "hello-world");
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID));
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID));
+ }
+
+ @Test
+ public void generateRequestId() {
+ logger.logRequest("svcInstance1", "svcName", "svcPartner", "targetEntity", "targetServiceName", "targetVirtualEntity", "hello-world");
+ assertNotNull(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+ }
+
+ @Test
+ public void overrideInvocationId() {
+ String oldUUID = UUID.randomUUID().toString();
+ MDC.put(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID, oldUUID);
+ MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, oldUUID);
+
+ logger.logRequest("svcInstance1", "svcName", "svcPartner", "targetEntity", "targetServiceName", "targetVirtualEntity", "hello-world");
+ String newUUID = MDC.get(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID);
+ assertFalse(oldUUID.equals(newUUID));
+ newUUID = MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID);
+ assertFalse(oldUUID.equals(newUUID));
+ }
+
+ @Test
+ public void persistRequestId() {
+ String oldUUID = UUID.randomUUID().toString();
+ MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, oldUUID);
+ assertEquals(oldUUID, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+ }
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java
new file mode 100644
index 000000000..2dd83e86d
--- /dev/null
+++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java
@@ -0,0 +1,38 @@
+package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Properties;
+import org.junit.Test;
+
+public class TestSvcLogicLoader {
+
+ @Test
+ public void testLoadAndActivate() throws IOException, SvcLogicException {
+ URL propUrl = ITCaseSvcLogicParser.class.getResource("/svclogic.properties");
+
+ InputStream propStr = ITCaseSvcLogicParser.class.getResourceAsStream("/svclogic.properties");
+
+ Properties props = new Properties();
+
+ props.load(propStr);
+
+ SvcLogicStore store = SvcLogicStoreFactory.getSvcLogicStore(props);
+
+ File graphDirectory = new File(getClass().getClassLoader().getResource("graphs").getFile());
+
+ if (graphDirectory == null) {
+ fail("Cannot find graphs directory");
+ }
+ SvcLogicLoader loader = new SvcLogicLoader(graphDirectory.getAbsolutePath(), store);
+ loader.loadAndActivate();
+
+
+ }
+
+
+
+}
diff --git a/core/sli/common/src/test/resources/2dArray.json b/core/sli/common/src/test/resources/2dArray.json
new file mode 100644
index 000000000..2a94b46f4
--- /dev/null
+++ b/core/sli/common/src/test/resources/2dArray.json
@@ -0,0 +1,4 @@
+[
+ ["apple", "orange", "banana", null],
+ ["squash", "broccoli", "cauliflower"]
+] \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/3dArray.json b/core/sli/common/src/test/resources/3dArray.json
new file mode 100644
index 000000000..149955596
--- /dev/null
+++ b/core/sli/common/src/test/resources/3dArray.json
@@ -0,0 +1,4 @@
+[
+ [["a","b","c"], ["d","e","f"]],
+ [["x","y","z"]]
+] \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/ArrayMenu.json b/core/sli/common/src/test/resources/ArrayMenu.json
new file mode 100644
index 000000000..26a24f292
--- /dev/null
+++ b/core/sli/common/src/test/resources/ArrayMenu.json
@@ -0,0 +1,41 @@
+[{
+ "id": "1",
+ "type": "pizza",
+ "name": "plain",
+ "calories": 1000,
+ "vegetarian": true
+ }, {
+ "id": "2",
+ "type": "pizza",
+ "name": "Tuesday Special",
+ "calories": null,
+ "vegetarian": false,
+ "topping":
+ [{
+ "id": "1",
+ "name": "onion"
+ }, {
+ "id": "2",
+ "name": "pepperoni"
+ }
+ ]
+ }, {
+ "id": "3",
+ "type": "pizza",
+ "name": "House Special",
+ "calories": 1500,
+ "vegetarian": true,
+ "topping":
+ [{
+ "id": "3",
+ "name": "basil"
+ }, {
+ "id": "4",
+ "name": "fresh mozzarella"
+ }, {
+ "id": "5",
+ "name": "tomato"
+ }
+ ]
+ }
+]
diff --git a/core/sli/common/src/test/resources/EmbeddedEscapedJson.json b/core/sli/common/src/test/resources/EmbeddedEscapedJson.json
new file mode 100644
index 000000000..dbb6d8d3a
--- /dev/null
+++ b/core/sli/common/src/test/resources/EmbeddedEscapedJson.json
@@ -0,0 +1,16 @@
+{
+ "input": {
+ "parameters":
+ [{
+ "name": "escapedJsonObject",
+ "value": "[{\"id\":\"0.2.0.0\/16\"},{\"id\":\"ge04::\/64\"}]"
+ }, {
+ "name": "password",
+ "value": "Hello\/World"
+ }, {
+ "name": "resourceName",
+ "value": "The\t\"Best\"\tName"
+ }
+ ]
+ }
+} \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/EscapedJson.json b/core/sli/common/src/test/resources/EscapedJson.json
new file mode 100644
index 000000000..a7719e819
--- /dev/null
+++ b/core/sli/common/src/test/resources/EscapedJson.json
@@ -0,0 +1 @@
+{\"widget\":{\"debug\":false,\"window\":{\"title\":\"ONAP Widget\",\"name\":\"main_window\",\"width\":200,\"height\":300},\"image\":{\"src\":\"images\/moon.png\",\"name\":\"moon\",\"hOffset\":150,\"vOffset\":150,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Me\",\"size\":21,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":350,\"vOffset\":200,\"alignment\":\"center\"}}} \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml b/core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml
new file mode 100644
index 000000000..708823efc
--- /dev/null
+++ b/core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="ase" version="1.0.0">
+
+
+ <method rpc="ase-evc-activation" mode="sync">
+ <configure adaptor="org.onap.ccsdl.sli.adaptors.emt.EmtAdaptor"
+ key="$evc-name" activate="true">
+ <parameter name="circuit.name" value="$evc-name" />
+ <parameter name="topology" value="$topology" />
+ <parameter name="leg1.uniCircuitId" value="$evc-leg[0].evc-access-name" />
+ <parameter name="leg2.uniCircuitId" value="$evc-leg[1].evc-access-name" />
+ <outcome value="success">
+ <return status="success" />
+ </outcome>
+ <outcome value="already-active">
+ <return status="failure">
+ <parameter name="error-code" value="1590" />
+ <parameter name="error-message" value="`Circuit already active`" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1542" />
+ <parameter name="error-message" value="Activation failure" />
+ </return>
+ </outcome>
+ </configure>
+ </method>
+
+ <method rpc="ase-evc-disconnect-request" mode="sync">
+ <configure adaptor="org.onap.ccsdk.sli.adaptors.emt.EmtAdaptor"
+ key="$evc-name" activate="false">
+ <outcome value="success">
+ <return status="success" />
+ </outcome>
+
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1542" />
+ <parameter name="error-message" value="De-activation failure" />
+ </return>
+ </outcome>
+ </configure>
+ </method>
+
+
+</service-logic>
diff --git a/core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml b/core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml
new file mode 100644
index 000000000..9a1a14708
--- /dev/null
+++ b/core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="ase" version="1.0.0">
+
+ <!-- Reserve a port. Returns uni-circuit-id of reserved ase-port -->
+ <method rpc="ase-port-reserve" mode="sync">
+ <switch test="$uni-cir-units">
+ <outcome value="Mbps">
+ <reserve plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-port"
+ key="resource-emt-clli == $edge-device-clli and speed >= $uni-cir-value"
+ pfx="asePort">
+
+
+ <outcome value="success">
+ <block>
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder">
+ <parameter name="file" value="/tmp/sample_r1.log" />
+ <parameter name="field1" value="__TIMESTAMP__"/>
+ <parameter name="field2" value="RESERVED"/>
+ <parameter name="field3" value="$asePort.uni_circuit_id"/>
+ </record>
+ <return status="success">
+ <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" />
+ </return>
+ </block>
+
+ </outcome>
+
+ <outcome value="not-found">
+ <return status="failure">
+ <parameter name="error-code" value="1010" />
+ <parameter name="error-message" value="No ports found that match criteria" />
+ </return>
+ </outcome>
+
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1010" />
+ <parameter name="error-message"
+ value="Error encountered trying to reserve port" />
+ </return>
+ </outcome>
+
+ </reserve>
+ </outcome>
+ <outcome value="Gbps">
+ <reserve plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-port"
+ key="resource-emt-clli == $edge-device-clli and speed >= 1000 * $uni-cir-value"
+ pfx="asePort">
+
+
+ <outcome value="success">
+ <block>
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder">
+ <parameter name="file" value="/tmp/sample_r1.log" />
+ <parameter name="field1" value="__TIMESTAMP__"/>
+ <parameter name="field2" value="RESERVED"/>
+ <parameter name="field3" value="$asePort.uni_circuit_id"/>
+ </record>
+ <return status="success">
+ <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" />
+ </return>
+ </block>
+ </outcome>
+
+ <outcome value="not-found">
+ <return status="failure">
+ <parameter name="error-code" value="1010" />
+ <parameter name="error-message" value="No ports found that match criteria" />
+ </return>
+ </outcome>
+ <outcome value="">
+ <return status="failure">
+ <parameter name="error-code" value="1012" />
+ <parameter name="error-message"
+ value="Error encountered trying to reserve port" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1010" />
+ <parameter name="error-message"
+ value="Error encountered trying to reserve port" />
+ </return>
+ </outcome>
+ </reserve>
+ </outcome>
+ </switch>
+ </method>
+
+ <!-- One step provisioning/activation command. Allocates a local resource,
+ then configures it on device -->
+ <method rpc="ase-port-activate-request" mode="sync">
+
+ <allocate plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id" pfx="asePort">
+
+ <outcome value="success">
+ <configure adaptor="org.onap.ccsdk.sli.adaptors.emt.EmtAdaptor"
+ key="$uni-circuit-id" activate="true">
+ <parameter name="circuit.id" value="$uni-circuit-id" />
+ <parameter name="subscriber.name" value="$subscriber-name" />
+ <parameter name="emt.clli" value="$edge-device-clli" />
+ <parameter name="port.tagging" value="$port-tagging" />
+ <parameter name="port.mediaSpeed" value="$media-speed" />
+ <parameter name="location.state" value="$uni-location-state" />
+ <parameter name="location.city" value="$uni-location-city" />
+ <parameter name="cosCategory" value="$cos-category" />
+ <parameter name="gosProfile" value="$gos-profile" />
+ <parameter name="lldp" value="$asePort.resource-lldp" />
+ <parameter name="mtu" value="$asePort.resource-mtu" />
+ <outcome value="success">
+ <block>
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder">
+ <parameter name="file" value="/tmp/sample_r1.log" />
+ <parameter name="field1" value="__TIMESTAMP__"/>
+ <parameter name="field2" value="ACTIVE"/>
+ <parameter name="field3" value="$uni-circuit-id"/>
+ </record>
+ <return status="success">
+ <parameter name="edge-device-clli" value="$asePort.resource-emt-clli" />
+ </return>
+ </block>
+
+ </outcome>
+ <outcome value="already-active">
+ <return status="failure">
+ <parameter name="error-code" value="1590" />
+ <parameter name="error-message" value="Port already active" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1542" />
+ <parameter name="error-message" value="Activation failure" />
+ </return>
+ </outcome>
+ </configure>
+ </outcome>
+
+ <outcome value="not-found">
+
+ <return status="failure">
+ <parameter name="error-code" value="1220" />
+ <parameter name="error-message" value="Circuit not found" />
+ </return>
+
+ </outcome>
+
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1230" />
+ <parameter name="error-message" value="Error occurred trying to find circuit" />
+ </return>
+ </outcome>
+ </allocate>
+ </method>
+
+
+
+ <!-- Change provisioning w/o activation -->
+ <method rpc="ase-change-port-prov-request" mode="sync">
+ <allocate plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id" pfx="asePort">
+
+ <outcome value="success">
+ <return status="success">
+ <parameter name="edge-device-clli" value="$asePort.resource-emt-clli" />
+ </return>
+ </outcome>
+
+ <outcome value="not-found">
+ <return status="failure">
+ <parameter name="error-code" value="1220" />
+ <parameter name="error-message" value="Circuit not found" />
+ </return>
+ </outcome>
+
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1230" />
+ <parameter name="error-message" value="Error occurred trying to find circuit" />
+ </return>
+ </outcome>
+ </allocate>
+ </method>
+
+
+
+
+ <!-- Release port -->
+
+ <method rpc="ase-release-port-request" mode="sync">
+ <exists plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-evc" key="uni-circuit-id == $uni-circuit-id">
+
+ <outcome value="true">
+ <return status="failure">
+ <parameter name="error-code" value="1130" />
+ <parameter name="error-message"
+ value="Cannot release port - used in existing EVC" />
+ </return>
+ </outcome>
+ <outcome value="false">
+ <release plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id">
+ <outcome value="success">
+ <block>
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder">
+ <parameter name="file" value="/tmp/sample_r1.log" />
+ <parameter name="field1" value="__TIMESTAMP__"/>
+ <parameter name="field2" value="RELEASED"/>
+ <parameter name="field3" value="$uni-circuit-id"/>
+ </record>
+ <return status="success"/>
+ </block>
+ </outcome>
+
+ <outcome value="not-found">
+ <return status="failure">
+ <parameter name="error-code" value="1110" />
+ <parameter name="error-message" value="No port found for this uni-circuit-id" />
+ </return>
+ </outcome>
+
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1130" />
+ <parameter name="error-message"
+ value="Error encountered trying to release port" />
+ </return>
+ </outcome>
+ </release>
+ </outcome>
+ </exists>
+ </method>
+
+</service-logic>
+
diff --git a/core/sli/common/src/test/resources/JsonObject.json b/core/sli/common/src/test/resources/JsonObject.json
new file mode 100644
index 000000000..0578368f8
--- /dev/null
+++ b/core/sli/common/src/test/resources/JsonObject.json
@@ -0,0 +1,5 @@
+{
+ "aaa": "123",
+ "bbb": "xyz",
+ "c.d": "abc"
+} \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/ObjectMenu.json b/core/sli/common/src/test/resources/ObjectMenu.json
new file mode 100644
index 000000000..56f842d48
--- /dev/null
+++ b/core/sli/common/src/test/resources/ObjectMenu.json
@@ -0,0 +1,43 @@
+{
+ "menu": [{
+ "id": "1",
+ "type": "pizza",
+ "name": "plain",
+ "calories": 1000,
+ "vegetarian": true
+ }, {
+ "id": "2",
+ "type": "pizza",
+ "name": "Tuesday Special",
+ "calories": 2000,
+ "vegetarian": false,
+ "topping":
+ [{
+ "id": "1",
+ "name": "onion"
+ }, {
+ "id": "2",
+ "name": "pepperoni"
+ }
+ ]
+ }, {
+ "id": "3",
+ "type": "pizza",
+ "name": "House Special",
+ "calories": 1500,
+ "vegetarian": true,
+ "topping":
+ [{
+ "id": "3",
+ "name": "basil"
+ }, {
+ "id": "4",
+ "name": "fresh mozzarella"
+ }, {
+ "id": "5",
+ "name": "tomato"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/sli/common/src/test/resources/QuotedValues.json b/core/sli/common/src/test/resources/QuotedValues.json
new file mode 100644
index 000000000..8bf91c66b
--- /dev/null
+++ b/core/sli/common/src/test/resources/QuotedValues.json
@@ -0,0 +1,43 @@
+{
+ "menu": [{
+ "id": "1",
+ "type": "pizza",
+ "name": "plain",
+ "calories": "1000",
+ "vegetarian": true
+ }, {
+ "id": "2",
+ "type": "pizza",
+ "name": "Tuesday Special",
+ "calories": "2000",
+ "vegetarian": false,
+ "topping":
+ [{
+ "id": "1",
+ "name": "onion"
+ }, {
+ "id": "2",
+ "name": "pepperoni"
+ }
+ ]
+ }, {
+ "id": "3",
+ "type": "pizza",
+ "name": "House Special",
+ "calories": "1500",
+ "vegetarian": true,
+ "topping":
+ [{
+ "id": "3",
+ "name": "basil"
+ }, {
+ "id": "4",
+ "name": "fresh mozzarella"
+ }, {
+ "id": "5",
+ "name": "tomato"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml b/core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml
new file mode 100644
index 000000000..cee027f75
--- /dev/null
+++ b/core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="ase" version="1.0.1">
+
+ <!-- Updated release port logic : deactivate the released port on the EMT -->
+ <method rpc="ase-release-port-request" mode="sync">
+ <exists plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-evc" key="uni-circuit-id == $uni-circuit-id">
+
+ <outcome value="true">
+ <return status="failure">
+ <parameter name="error-code" value="1130" />
+ <parameter name="error-message"
+ value="Cannot release port - used in existing EVC" />
+ </return>
+ </outcome>
+ <outcome value="false">
+ <release plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id">
+ <outcome value="success">
+ <configure adaptor="org.onap.ccsdk.sli.adaptors.emt.EmtAdaptor"
+ key="$uni-circuit-id" activate="false">
+
+ <outcome value="success">
+ <block>
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder">
+ <parameter name="file" value="/tmp/sample_r1.log" />
+ <parameter name="field1" value="__TIMESTAMP__" />
+ <parameter name="field2" value="RELEASED" />
+ <parameter name="field3" value="$uni-circuit-id" />
+ </record>
+ <return status="success">
+ <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" />
+ </return>
+ </block>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1130" />
+ <parameter name="error-message"
+ value="Error encountered trying to de-activate port" />
+ </return>
+ </outcome>
+ </configure>
+ </outcome>
+
+ <outcome value="not-found">
+ <return status="failure">
+ <parameter name="error-code" value="1110" />
+ <parameter name="error-message" value="No port found for this uni-circuit-id" />
+ </return>
+ </outcome>
+
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1130" />
+ <parameter name="error-message"
+ value="Error encountered trying to release port" />
+ </return>
+ </outcome>
+ </release>
+ </outcome>
+ </exists>
+ </method>
+
+</service-logic>
+
diff --git a/core/sli/common/src/test/resources/Widget.json b/core/sli/common/src/test/resources/Widget.json
new file mode 100644
index 000000000..6b90907ce
--- /dev/null
+++ b/core/sli/common/src/test/resources/Widget.json
@@ -0,0 +1,27 @@
+{
+ "widget": {
+ "debug": false,
+ "window": {
+ "title": "ONAP Widget",
+ "name": "main_window",
+ "width": 200,
+ "height": 300
+ },
+ "image": {
+ "src": "images/moon.png",
+ "name": "moon",
+ "hOffset": 150,
+ "vOffset": 150,
+ "alignment": "center"
+ },
+ "text": {
+ "data": "Click Me",
+ "size": 21,
+ "style": "bold",
+ "name": "text1",
+ "hOffset": 350,
+ "vOffset": null,
+ "alignment": "center"
+ }
+ }
+} \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/bad_neutron_logic_v11.xml b/core/sli/common/src/test/resources/bad_neutron_logic_v11.xml
new file mode 100644
index 000000000..e6ec8614b
--- /dev/null
+++ b/core/sli/common/src/test/resources/bad_neutron_logic_v11.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="neutron" version="1.0.0">
+
+ <method rpc="canCreateNetwork" mode="sync">
+ <switch test="true">
+ <return status="success">
+ <parameter name="error-code" value="200" />
+ </return>
+ </switch>
+ </method>
+
+ <method rpc="networkCreated" mode="sync">
+ <switch test="`(length($network.segment[0].provider-physical-network) >= 5) and (substr($network.segment[0].provider-physical-network,0,5) == 'dvspg')`">
+ <outcome value="true">
+ <block>
+ <set>
+ <parameter name="vlanlist" value="`$network.segment[0].provider-segmentation-id`"/>
+ </set>
+ <for index="i" start="1" end="`$network.num-segments`">
+ <set>
+ <parameter name="vlanlist" value="`$vlanlist+','+$network.segment[$i].provider-segmentation-id`"/>
+ </set>
+ </for>
+
+ <switch test="true">
+ <return status="success"/>
+ </switch>
+ </block>
+ </outcome>
+ <outcome value="Other">
+ <return status="success">
+ <parameter name="error-code" value="200"/>
+ </return>
+ </outcome>
+ </switch>
+ </method>
+
+</service-logic>
diff --git a/core/sli/common/src/test/resources/dblib.properties b/core/sli/common/src/test/resources/dblib.properties
new file mode 100755
index 000000000..f08dce7a0
--- /dev/null
+++ b/core/sli/common/src/test/resources/dblib.properties
@@ -0,0 +1,14 @@
+org.onap.ccsdk.sli.dbtype=jdbc
+org.onap.ccsdk.sli.jdbc.hosts=sdnctldb01,sdnctldb02
+org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:test;create=true
+org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
+org.onap.ccsdk.sli.jdbc.database=test
+org.onap.ccsdk.sli.jdbc.user=test
+org.onap.ccsdk.sli.jdbc.password=test
+org.onap.ccsdk.sli.jdbc.connection.name=sdnctldb01
+
+org.onap.ccsdk.sli.jdbc.connection.timeout=50
+org.onap.ccsdk.sli.jdbc.request.timeout=100
+org.onap.ccsdk.sli.jdbc.limit.init=10
+org.onap.ccsdk.sli.jdbc.limit.min=10
+org.onap.ccsdk.sli.jdbc.limit.max=20
diff --git a/core/sli/common/src/test/resources/expression.tests b/core/sli/common/src/test/resources/expression.tests
new file mode 100755
index 000000000..c352e9b08
--- /dev/null
+++ b/core/sli/common/src/test/resources/expression.tests
@@ -0,0 +1,19 @@
+$uni-circuit-id
+$asePort
+length($uni-circuit-id) > 0
+$asePort.uni-circuit-id
+$uni-cir-units * 1000 * 100 / 100
+$uni-cir-units / 1000
+$uni-cir-units - 100
+$uni-cir-units + 100
+(value * 3 - $arg1 > 0) and (length($uni-circuit-id) == 0)
+'pg-'+$network.name
+$network.segment[0].provider-physical-network
+length($network_segment[0].provider-physical-network) >= 5
+substr($network_segment[0].provider-physical-network,0,5) == 'dvspg'
+length($network_segment[0].provider-physical-network) >= 5 and substr($network_segment[0].provider-physical-network,0,5) == 'dvspg'
+(length($network_segment[0].provider-physical-network) >= 5) and (substr($network_segment[0].provider-physical-network,0,5) == 'dvspg')
+4-2-2
+1+1
+1
+1+2*3-4
diff --git a/core/sli/common/src/test/resources/graphs/sliapi/graph.versions b/core/sli/common/src/test/resources/graphs/sliapi/graph.versions
new file mode 100644
index 000000000..d72920a43
--- /dev/null
+++ b/core/sli/common/src/test/resources/graphs/sliapi/graph.versions
@@ -0,0 +1 @@
+sli healthcheck 1.0.0 sync
diff --git a/core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml b/core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml
new file mode 100644
index 000000000..d512f546f
--- /dev/null
+++ b/core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml
@@ -0,0 +1,27 @@
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : SDN-C
+ ================================================================================
+ 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=========================================================
+ -->
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" module='sli' version='1.0.0'><method rpc='healthcheck' mode='sync'>
+<set>
+<parameter name='error-code' value='200' />
+<parameter name='error-message' value='SDN-C is healthy'/>
+<parameter name='ack-final' value='Y'/>
+</set></method></service-logic>
diff --git a/core/sli/common/src/test/resources/l3sdn_logic_v10.xml b/core/sli/common/src/test/resources/l3sdn_logic_v10.xml
new file mode 100644
index 000000000..58a420f9e
--- /dev/null
+++ b/core/sli/common/src/test/resources/l3sdn_logic_v10.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ============LICENSE_START=======================================================
+ ONAP : CCSDK ================================================================================
+ 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========================================================= -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="neutron" version="1.0.0">
+
+ <method rpc="canCreateNetwork" mode="sync">
+ <return status="success">
+ <parameter name="error-code" value="200" />
+ </return>
+ </method>
+
+ <method rpc="switchTester" mode="sync">
+
+ <switch test="`$test-value`">
+ <outcome value="">
+ <return status="success">
+ <parameter name="visited-outcome" value="empty string" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="success">
+ <parameter name="visited-outcome" value="Other" />
+ </return>
+ </outcome>
+ </switch>
+
+
+ </method>
+
+ <method rpc="forRecordTester" mode="sync">
+ <for index="i" start="0" end="1">
+ <record plugin="org.onap.ccsdk.sli.core.sli.provider.DummyRecorder">
+ <parameter name="level" value="INFO"/>
+ <parameter name="field1" value="`forRecordTester message $i`"/>
+ </record>
+ </for>
+ </method>
+
+ <method rpc="whileNodeTester" mode="sync">
+ <while test="`$test-value`">
+ <break/>
+ </while>
+
+ </method>
+
+ <method rpc="resourceTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='resource-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' />
+ </set>
+
+ <save plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'">
+ <parameter name="sample-key" value="resourceTester.status"/>
+ <parameter name="sample-value" value="FAILED"/>
+ </save>
+
+ <update plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'">
+ <parameter name="sample-key" value="resourceTester.status"/>
+ <parameter name="sample-value" value="PASSED"/>
+ </update>
+
+ <get-resource plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'" pfx="sample"/>
+
+ <exists plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <is-available plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <release plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+
+ <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <notify plugin="`$resource-plugin`" resource="sample" action="RESERVE"/>
+
+ <delete plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+
+
+ </block>
+ </method>
+
+ <method rpc="configureTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='configure-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' />
+ </set>
+ <configure adaptor="`$configure-plugin`" key="dummy" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="FAILURE" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="dummy" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="FAILURE" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+
+ </block>
+ </method>
+
+
+ <method rpc="javaPluginTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='java-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' />
+ </set>
+ <execute plugin="`$java-plugin`" method="dummy"/>
+ </block>
+ </method>
+
+ <method rpc="allNodesTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='resource-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' />
+ <parameter name='configure-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' />
+ <parameter name='java-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' />
+
+ </set>
+
+ <call rpc="switchTester" mode="sync" />
+
+ <call rpc="forRecordTester" mode="sync"/>
+
+ <call rpc="resourceTester" mode="sync"/>
+
+ <call rpc="configureTester" mode="sync"/>
+
+ <call rpc="javaPluginTester" mode="sync"/>
+
+ <call rpc="whileNodeTester" mode="sync"/>
+
+ </block>
+ </method>
+
+ <method rpc="networkCreated" mode="sync">
+ <switch
+ test="length($network.segment[0].provider-physical-network) >= 5 and substr($network.segment[0].provider-physical-network,0,5) == 'dvspg'">
+ <outcome value="true">
+ <block>
+ <set>
+ <parameter name="$vlanlist"
+ value="$network.segment[0].provider-segmentation-id" />
+ </set>
+ <for index="i" start="1" end="$network.num-segments">
+ <set>
+ <parameter name="$vlanlist"
+ value="eval($vlanlist+','+$network.segment[i].provider-segmentation-id)" />
+ </set>
+ </for>
+
+ </block>
+ </outcome>
+ <outcome value="Other">
+ <return status="success">
+ <parameter name="error-code" value="200" />
+ </return>
+ </outcome>
+ </switch>
+ </method>
+
+</service-logic>
diff --git a/core/sli/common/src/test/resources/log4j2.properties b/core/sli/common/src/test/resources/log4j2.properties
new file mode 100644
index 000000000..3a5d8ef76
--- /dev/null
+++ b/core/sli/common/src/test/resources/log4j2.properties
@@ -0,0 +1,39 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# Copyright (C) 2020 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=========================================================
+###
+
+status = error
+name = PropertiesConfig
+
+filters = threshold
+
+filter.threshold.type = ThresholdFilter
+filter.threshold.level = debug
+
+appenders = console
+
+appender.console.type = Console
+appender.console.name = STDOUT
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+rootLogger.level = debug
+rootLogger.appenderRefs = stdout
+rootLogger.appenderRef.stdout.ref = STDOUT
diff --git a/core/sli/common/src/test/resources/mergetest.xml b/core/sli/common/src/test/resources/mergetest.xml
new file mode 100644
index 000000000..95c26da27
--- /dev/null
+++ b/core/sli/common/src/test/resources/mergetest.xml
@@ -0,0 +1,54 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+<multicast-parameters xmlns="org.onap.sdnc:test">
+ <vpn-v4-multicast-enabled>Y</vpn-v4-multicast-enabled>
+ <v4-multicast>
+ <v4-pim-ssm-default-range>Y</v4-pim-ssm-default-range>
+ <v4-data-mdt>11.11.11.11</v4-data-mdt>
+ <v4-data-mdt-wildcard-mask>2.2.2.2</v4-data-mdt-wildcard-mask>
+ <max-routes-limit>100</max-routes-limit>
+ <v4-default-mdt>1.1.1.1</v4-default-mdt>
+ <v4-pim-sm-static-override>N</v4-pim-sm-static-override>
+ <v4-pim-ssm-groups>
+ <v4-pim-ssm-group-address>4.4.4.4</v4-pim-ssm-group-address>
+ </v4-pim-ssm-groups>
+ <v4-pim-ssm-groups>
+ <v4-pim-ssm-group-address>3.3.3.3</v4-pim-ssm-group-address>
+ </v4-pim-ssm-groups>
+ <v4-static-rp-triplet>
+ <rp-address>8.8.8.8</rp-address>
+ <c-groups>
+ <c-group-address-prefix>10.10.10.10</c-group-address-prefix>
+ </c-groups>
+ <c-groups>
+ <c-group-address-prefix>9.9.9.9</c-group-address-prefix>
+ </c-groups>
+ </v4-static-rp-triplet>
+ <v4-static-rp-triplet>
+ <rp-address>7.7.7.7</rp-address>
+ <c-groups>
+ <c-group-address-prefix>6.6.6.6</c-group-address-prefix>
+ </c-groups>
+ <c-groups>
+ <c-group-address-prefix>5.5.5.5</c-group-address-prefix>
+ </c-groups>
+ </v4-static-rp-triplet>
+ </v4-multicast>
+</multicast-parameters>
diff --git a/core/sli/common/src/test/resources/neutron_logic_v10.xml b/core/sli/common/src/test/resources/neutron_logic_v10.xml
new file mode 100644
index 000000000..74088036b
--- /dev/null
+++ b/core/sli/common/src/test/resources/neutron_logic_v10.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="neutron" version="1.0.0">
+
+ <method rpc="canCreateNetwork" mode="sync">
+ <return status="success">
+ <parameter name="error-code" value="200" />
+ </return>
+ </method>
+
+ <method rpc="networkCreated" mode="sync">
+ <switch test="`(length($network.segment[0].provider-physical-network) >= 5) and (substr($network.segment[0].provider-physical-network,0,5) == 'dvspg')`">
+ <outcome value="true">
+ <block>
+ <set>
+ <parameter name="vlanlist" value="`$network.segment[0].provider-segmentation-id`"/>
+ </set>
+ <for index="i" start="1" end="`$network.num-segments`">
+ <set>
+ <parameter name="vlanlist" value="`$vlanlist+','+$network.segment[$i].provider-segmentation-id`"/>
+ </set>
+ </for>
+
+ </block>
+ </outcome>
+ <outcome value="Other">
+ <return status="success">
+ <parameter name="error-code" value="200"/>
+ </return>
+ </outcome>
+ </switch>
+ </method>
+
+</service-logic>
diff --git a/core/sli/common/src/test/resources/nonsense.xml b/core/sli/common/src/test/resources/nonsense.xml
new file mode 100644
index 000000000..c30c6bfc6
--- /dev/null
+++ b/core/sli/common/src/test/resources/nonsense.xml
@@ -0,0 +1,24 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+<non>
+<sense>Hello world</sense>
+</non>
diff --git a/core/sli/common/src/test/resources/parser-bad.tests b/core/sli/common/src/test/resources/parser-bad.tests
new file mode 100755
index 000000000..82913afc2
--- /dev/null
+++ b/core/sli/common/src/test/resources/parser-bad.tests
@@ -0,0 +1,3 @@
+bad_neutron_logic_v11.xml
+EvcActivateSvcLogic_v100.xml
+nonsense.xml \ No newline at end of file
diff --git a/core/sli/common/src/test/resources/parser-good.tests b/core/sli/common/src/test/resources/parser-good.tests
new file mode 100755
index 000000000..4147fdb62
--- /dev/null
+++ b/core/sli/common/src/test/resources/parser-good.tests
@@ -0,0 +1,3 @@
+ReleasePortSvcLogic_v101.xml
+neutron_logic_v10.xml
+l3sdn_logic_v10.xml
diff --git a/core/sli/common/src/test/resources/simplelogger.properties b/core/sli/common/src/test/resources/simplelogger.properties
new file mode 100644
index 000000000..73e4d3a99
--- /dev/null
+++ b/core/sli/common/src/test/resources/simplelogger.properties
@@ -0,0 +1,24 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+org.slf4j.simpleLogger.defaultLogLevel=info
+org.slf4j.simplelogger.log.org.onap.ccsdk.sli.core.sli.SvcLogicContext=debug
+org.slf4j.simplelogger.log.SvcLogicContext=debug
diff --git a/core/sli/common/src/test/resources/svclogic.properties b/core/sli/common/src/test/resources/svclogic.properties
new file mode 100644
index 000000000..426960f76
--- /dev/null
+++ b/core/sli/common/src/test/resources/svclogic.properties
@@ -0,0 +1,27 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+org.onap.ccsdk.sli.dbtype = jdbc
+org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:sdnctl;create=true
+org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
+org.onap.ccsdk.sli.jdbc.database = sdnctl
+org.onap.ccsdk.sli.jdbc.user = test
+org.onap.ccsdk.sli.jdbc.password = test
diff --git a/core/sli/common/src/test/resources/svclogic.sh b/core/sli/common/src/test/resources/svclogic.sh
new file mode 100644
index 000000000..67977c3d9
--- /dev/null
+++ b/core/sli/common/src/test/resources/svclogic.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+MYSQL_JDBC_DRIVER=${MYSQL_JDBC_DRIVER:-/home/ubuntu/mysql-connector-java-5.1.38.1.jar}
+SLI_COMMON_TARGETDIR=${SLI_COMMON_TARGETDIR:-/home/ubuntu/opendaylight/plugins}
+#SLI_COMMON_TARGETDIR=${SLI_COMMON_TARGETDIR:-/home/ubuntu/git/sdnctl/sli/common/target}
+SLI_VERSION=${SLI_VERSION:-1.1.0-SNAPSHOT}
+SLI_COMMON_JAR=${SLI_COMMON_JAR:=${SLI_COMMON_TARGETDIR}/sli-common-${SLI_VERSION}.jar}
+
+echo SLI_COMMON_JAR is $SLI_COMMON_JAR
+
+java -cp ${CLASSPATH}:${MYSQL_JDBC_DRIVER}:${SLI_COMMON_JAR} org.onap.ccsdk.sli.core.sli.SvcLogicParser $*
diff --git a/core/sli/installer/pom.xml b/core/sli/installer/pom.xml
new file mode 100755
index 000000000..40776bdcf
--- /dev/null
+++ b/core/sli/installer/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-installer</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name>
+
+ <properties>
+ <application.name>ccsdk-sli</application.name>
+ <features.boot>${application.name}</features.boot>
+ <features.repositories>mvn:org.onap.ccsdk.sli.core/${features.boot}/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>maven-repo-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <attach>true</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>true</appendAssemblyId>
+ </configuration>
+ </execution>
+ <execution>
+ <id>installer-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <attach>true</attach>
+ <finalName>${application.name}-${project.version}-installer</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_installer_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <transitive>false</transitive>
+ <outputDirectory>${project.build.directory}/assembly/system</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <useRepositoryLayout>true</useRepositoryLayout>
+ <addParentPoms>false</addParentPoms>
+ <copyPom>false</copyPom>
+ <includeGroupIds>org.onap.ccsdk.sli.core</includeGroupIds>
+ <excludeArtifactIds>utils-provider,dblib-provider</excludeArtifactIds>
+ <scope>provided</scope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ <executions>
+ <execution>
+ <id>copy-version</id>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals><!-- here the phase you need -->
+ <phase>validate</phase>
+ <configuration>
+ <outputDirectory>${basedir}/target/stage</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources/scripts</directory>
+ <includes>
+ <include>install-feature.sh</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/core/sli/installer/src/assembly/assemble_installer_zip.xml b/core/sli/installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 000000000..2d3c0606d
--- /dev/null
+++ b/core/sli/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,59 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>bin</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>755</fileMode>
+ <includes>
+ <include>*.sh</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>644</fileMode>
+ <excludes>
+ <exclude>*.sh</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml b/core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 000000000..6a21012dc
--- /dev/null
+++ b/core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,42 @@
+<!-- ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ 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========================================================= -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>repo</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level as this
+ file is suppose to be unzip on top of a karaf distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/core/sli/installer/src/main/resources/scripts/install-feature.sh b/core/sli/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 000000000..74b95b5c8
--- /dev/null
+++ b/core/sli/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+INSTALLERDIR=$(dirname $0)
+
+REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip
+
+if [ -f ${REPOZIP} ]
+then
+ unzip -d ${ODL_HOME} ${REPOZIP}
+else
+ echo "ERROR : repo zip ($REPOZIP) not found"
+ exit 1
+fi
+
+${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} feature:install ${features.boot}
diff --git a/core/sli/model/pom.xml b/core/sli/model/pom.xml
new file mode 100755
index 000000000..0b859e7d2
--- /dev/null
+++ b/core/sli/model/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-model</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
+ <artifactId>rfc6991</artifactId>
+ </dependency>
+
+
+ </dependencies>
+</project>
diff --git a/core/sli/model/src/main/yang/sliapi.yang b/core/sli/model/src/main/yang/sliapi.yang
new file mode 100755
index 000000000..a7d52928b
--- /dev/null
+++ b/core/sli/model/src/main/yang/sliapi.yang
@@ -0,0 +1,123 @@
+module SLI-API {
+
+ yang-version 1;
+
+ namespace "org:onap:ccsdk:sli:core:sliapi";
+
+ prefix sample;
+
+ import ietf-inet-types { prefix "inet"; revision-date 2013-07-15; }
+
+ organization "ONAP";
+
+ contact
+ "Dan Timoney";
+
+ description
+ "Defines API to service logic interpreter";
+
+ revision "2016-11-10" {
+ description
+ "REST API to Service Logic Interpreter";
+ }
+
+ grouping parameter-setting {
+ description
+ "Parameter setting";
+
+ leaf parameter-name {
+ type string;
+ description "Parameter name";
+ }
+
+ leaf int-value {
+ type int32;
+ }
+ leaf string-value {
+ type string;
+ }
+ leaf boolean-value {
+ type boolean;
+ }
+ leaf ipaddress-value {
+ type inet:ip-address;
+ }
+ leaf ipprefix-value {
+ type inet:ip-prefix;
+ }
+ leaf port-number {
+ type inet:port-number;
+ }
+ leaf dscp {
+ type inet:dscp;
+ }
+ }
+
+ grouping response-fields {
+ leaf response-code {
+ type string;
+ }
+ leaf ack-final-indicator {
+ type string;
+ }
+ leaf response-message {
+ type string;
+ }
+ leaf context-memory-json {
+ type string;
+ }
+ }
+
+ container test-results {
+ description "Test results";
+
+ list test-result {
+ key "test-identifier";
+
+ leaf test-identifier {
+ type string;
+ }
+
+ leaf-list results {
+ type string;
+ }
+ }
+ }
+
+ rpc execute-graph {
+ description " Method to add a new parameter.";
+ input {
+
+ leaf module-name {
+ type string;
+ }
+
+ leaf rpc-name {
+ type string;
+ }
+
+ leaf mode {
+ type enumeration {
+ enum sync;
+ enum async;
+ }
+ }
+
+ list sli-parameter {
+ key "parameter-name";
+ uses parameter-setting;
+ }
+ }
+
+ output {
+ uses response-fields;
+ }
+ }
+
+ rpc healthcheck {
+ output {
+ uses response-fields;
+ }
+ }
+
+}
diff --git a/core/sli/model/src/main/yang/test-model@2019-07-23.yang b/core/sli/model/src/main/yang/test-model@2019-07-23.yang
new file mode 100755
index 000000000..fc8e8b007
--- /dev/null
+++ b/core/sli/model/src/main/yang/test-model@2019-07-23.yang
@@ -0,0 +1,210 @@
+module test-model {
+
+ yang-version 1;
+
+ namespace "org:onap:ccsdk:sli:core:testmodel";
+
+ prefix sample;
+
+ import ietf-inet-types { prefix "inet"; revision-date 2013-07-15; }
+
+ organization "ONAP";
+
+ contact
+ "Test Author";
+
+ description
+ "A test model not used in business flows";
+
+ revision "2019-07-23" {
+ description
+ "First release of the test model";
+ }
+
+ identity sample-identity {
+ description
+ "Base identity";
+ }
+
+ typedef percentage {
+ type uint8 {
+ range "0 .. 100";
+ }
+ description "represents a percentage";
+ }
+
+ grouping builtin {
+ leaf sample-binary {
+ type binary;
+ }
+ leaf sample-bits {
+ type bits{
+ bit fan-running {
+ position 0;
+ }
+ bit hd-led {
+ position 1;
+ }
+ bit power-led {
+ position 2;
+ }
+ }
+ }
+ leaf sample-boolean {
+ type boolean;
+ }
+ leaf sample-decimal64 {
+ type decimal64{
+ fraction-digits 1;
+ }
+ }
+ leaf sample-empty {
+ type empty;
+ }
+ leaf sample-enumeration {
+ type enumeration{
+ enum "shelf.slot.port";
+ enum "not available";
+ enum "CURRENTLY_AVAILABLE";
+ enum "200OK";
+ enum "hyphen-separated-value";
+ }
+ }
+ leaf sample-identityref {
+ type identityref {
+ base "sample-identity";
+ }
+ }
+ leaf sample-int8 {
+ type int8;
+ }
+ leaf sample-int16 {
+ type int16;
+ }
+ leaf sample-int32 {
+ type int32;
+ }
+ leaf sample-int64 {
+ type int64;
+ }
+ leaf sample-leafref {
+ type leafref {
+ path "../sample-boolean";
+ }
+ }
+ leaf sample-string {
+ type string;
+ }
+ leaf sample-uint8 {
+ type uint8;
+ }
+ leaf sample-uint16 {
+ type uint16;
+ }
+ leaf sample-uint32 {
+ type uint32;
+ }
+ leaf sample-uint64 {
+ type uint64;
+ }
+ leaf sample-union {
+ type union {
+ type int32;
+ type enumeration {
+ enum "unbounded";
+ }
+ }
+ }
+ leaf percent-completed {
+ type percentage;
+ }
+ }
+
+ grouping inet-types-grouping {
+ leaf ip-version {
+ type inet:ip-version;
+ }
+ leaf dscp {
+ type inet:dscp;
+ }
+ leaf port-number {
+ type inet:port-number;
+ }
+ leaf ipv6-flow-label {
+ type inet:ipv6-flow-label;
+ }
+ leaf as-number {
+ type inet:as-number;
+ }
+ leaf ip-address {
+ type inet:ip-address;
+ }
+ leaf ipv4-address {
+ type inet:ipv4-address;
+ }
+ leaf ipv6-address {
+ type inet:ipv6-address;
+ }
+ leaf ip-address-no-zone {
+ type inet:ip-address-no-zone;
+ }
+ leaf ipv4-address-no-zone {
+ type inet:ipv4-address-no-zone;
+ }
+ leaf ipv6-address-no-zone {
+ type inet:ipv6-address-no-zone;
+ }
+ leaf ip-prefix {
+ type inet:ip-prefix;
+ }
+ leaf ipv4-prefix {
+ type inet:ipv4-prefix;
+ }
+ leaf ipv6-prefix {
+ type inet:ipv6-prefix;
+ }
+ leaf domain-name {
+ type inet:domain-name;
+ }
+ leaf host {
+ type inet:host;
+ }
+ leaf uri {
+ type inet:uri;
+ }
+ anyxml data;
+ }
+
+ container sample-container {
+ leaf customer-name {
+ type string;
+ }
+
+ leaf-list customer-nicknames {
+ type string;
+ }
+
+ container login {
+ leaf message {
+ type string;
+ description
+ "Message given at start of login session";
+ }
+
+ list customer-addresses {
+ key "address-name";
+ leaf address-name {
+ type string;
+ }
+ leaf street-address {
+ type string;
+ }
+ leaf state {
+ type string;
+ }
+ }
+ }
+ uses builtin;
+ uses inet-types-grouping;
+ }
+}
diff --git a/core/sli/pom.xml b/core/sli/pom.xml
new file mode 100755
index 000000000..cfb7656d1
--- /dev/null
+++ b/core/sli/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>ccsdk-sli-core :: sli</name>
+ <description>The Service Logic Interpreter (SLI) allows service planners to design the flow of logic within the SDN controller in an XML format, without a need for custom Java code. </description>
+ <organization>
+ <name>ONAP</name>
+ </organization>
+
+ <modules>
+ <module>provider-base</module>
+ <module>model</module>
+ <module>common</module>
+ <module>provider</module>
+ <module>installer</module>
+ </modules>
+</project>
diff --git a/core/sli/provider-base/pom.xml b/core/sli/provider-base/pom.xml
new file mode 100644
index 000000000..eedce9154
--- /dev/null
+++ b/core/sli/provider-base/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-provider-base</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+
+ <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <sonar.coverage.jacoco.xmlReportPaths>${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml,${project.reporting.outputDirectory}/jacoco-it/jacoco.xml,../provider/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java
new file mode 100644
index 000000000..031beba2a
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractSvcLogicNodeExecutor {
+ protected SvcLogicResolver resolver;
+ public abstract SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException;
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractSvcLogicNodeExecutor.class);
+ protected static final String PARAMETER_DEBUG_PATTERN = "Parameter: ({}) resolves to: ({}) which came from the expression: ({})";
+ protected static final String SETTING_DEBUG_PATTERN = "Setting context attribute: ({}) to: ({}) which came from the expression: ({})";
+
+ protected String evaluateNodeTest(SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+ if (node == null) {
+ return null;
+ }
+
+ return (SvcLogicExpressionResolver.evaluate(node.getAttribute("test"),
+ node, ctx));
+
+ }
+
+ public void setResolver(SvcLogicResolver resolver) {
+ this.resolver = resolver;
+ }
+
+ protected SvcLogicAdaptor getAdaptor(String adaptorName) {
+ return resolver.getSvcLogicAdaptor(adaptorName);
+ }
+
+ protected SvcLogicResource getSvcLogicResource(String resourceName) {
+ return resolver.getSvcLogicResource(resourceName);
+ }
+
+ protected SvcLogicRecorder getSvcLogicRecorder(String recorderName) {
+ return resolver.getSvcLogicRecorder(recorderName);
+ }
+
+ protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName){
+ return resolver.getSvcLogicJavaPlugin(pluginName);
+ }
+
+ protected SvcLogicNode getNextNode(SvcLogicNode node, String outValue) {
+ SvcLogicNode nextNode = node.getOutcomeValue(outValue);
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute " + outValue + " branch");
+ }
+ return (nextNode);
+ }
+
+ nextNode = node.getOutcomeValue("Other");
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute Other branch");
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("no " + outValue + " or Other branch found");
+ }
+ }
+ return (nextNode);
+ }
+
+ protected Map<String, String> getResolvedParameters(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException{
+ Map<String, String> parmMap = new HashMap<>();
+
+ Set<Map.Entry<String, SvcLogicExpression>> parmSet = node
+ .getParameterSet();
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parmSet
+ .iterator(); iter.hasNext();) {
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+
+ SvcLogicExpression curExpr = curEnt.getValue();
+ String curExprValue = SvcLogicExpressionResolver.evaluate(curExpr, node, ctx);
+ LOG.trace(PARAMETER_DEBUG_PATTERN, curName, curExprValue, curExpr);
+ parmMap.put(curName, curExprValue);
+ }
+
+ return parmMap;
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java
new file mode 100644
index 000000000..7079e263b
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlockNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(BlockNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ SvcLogicExpression atomicExpr = node.getAttribute("atomic");
+ String atomicStr = SvcLogicExpressionResolver.evaluate(atomicExpr, node, ctx);
+ boolean isAtomic = "true".equalsIgnoreCase(atomicStr);
+
+ // Initialize status to success so that at least one outcome will execute
+ ctx.markSuccess();
+
+ int numOutcomes = node.getNumOutcomes();
+
+ for (int i = 0; i < numOutcomes; i++) {
+ if (SvcLogicConstants.FAILURE.equals(ctx.getStatus()) && isAtomic) {
+ LOG.info("Block - stopped executing nodes due to failure status");
+ return(null);
+ }
+
+ SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1));
+ if (nextNode != null) {
+
+ while (nextNode != null)
+ {
+ nextNode = svc.executeNode(nextNode, ctx);
+ }
+ }
+ }
+
+ return (null);
+ }
+
+
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java
new file mode 100644
index 000000000..603d7abc5
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.BreakNodeException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BreakNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BreakNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ String message = "BreakNodeExecutor encountered break with nodeId " + node.getNodeId();
+ LOG.debug(message);
+ throw new BreakNodeException(message);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java
new file mode 100644
index 000000000..766826f7d
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CallNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(CallNodeExecutor.class);
+ private static final String CURRENT_GRAPH="currentGraph";
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String outValue = "not-found";
+
+ SvcLogicGraph myGraph = node.getGraph();
+
+ if (myGraph == null)
+ {
+ LOG.debug("execute: getGraph returned null");
+ }
+
+ SvcLogicExpression moduleExpr = null;
+
+ String module = null;
+
+ moduleExpr = node.getAttribute("module");
+ if (moduleExpr != null)
+ {
+ module = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx);
+ }
+
+ if ((module == null) || (module.length() == 0))
+ {
+ if (myGraph != null)
+ {
+ module = myGraph.getModule();
+ }
+ }
+
+ SvcLogicExpression rpcExpr = null;
+ String rpc = null;
+ rpcExpr = node.getAttribute("rpc");
+ if (rpcExpr != null)
+ {
+ rpc = SvcLogicExpressionResolver.evaluate(rpcExpr, node, ctx);
+ }
+
+ if ((rpc == null) || (rpc.length() == 0))
+ {
+ if (myGraph != null)
+ {
+ rpc = myGraph.getRpc();
+ }
+ }
+
+ String mode = null;
+
+ moduleExpr = node.getAttribute("mode");
+ if (moduleExpr != null)
+ {
+ mode = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx);
+ }
+
+ if ((mode == null) || (mode.length() == 0))
+ {
+ if (myGraph != null)
+ {
+ mode = myGraph.getMode();
+ }
+ }
+
+ String version = null;
+
+ moduleExpr = node.getAttribute("version");
+ if (moduleExpr != null)
+ {
+ version = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx);
+ }
+
+ String parentGraph = ctx.getAttribute(CURRENT_GRAPH);
+ ctx.setAttribute("parentGraph", parentGraph);
+
+ SvcLogicStore store = svc.getStore();
+ String errorMessage = "Parent " + parentGraph + " failed to call child [" + module + "," + rpc + "," + version + "," + mode + "] because the graph could not be found";
+ boolean graphWasCalled = false;
+ if (store != null) {
+ SvcLogicGraph calledGraph = store.fetch(module, rpc, version, mode);
+ if (calledGraph != null) {
+ LOG.debug("Parent " + parentGraph + " is calling child " + calledGraph.toString());
+ ctx.setAttribute(CURRENT_GRAPH, calledGraph.toString());
+ svc.execute(calledGraph, ctx);
+ outValue = ctx.getStatus();
+ graphWasCalled = true;
+ } else {
+ LOG.debug(errorMessage);
+ }
+ } else {
+ LOG.debug("Could not get SvcLogicStore reference");
+ }
+
+ SvcLogicNode nextNode = node.getOutcomeValue(outValue);
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute " + outValue + " branch");
+ }
+ ctx.setAttribute(CURRENT_GRAPH, parentGraph);
+ return (nextNode);
+ }
+
+ nextNode = node.getOutcomeValue("Other");
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute Other branch");
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("no " + outValue + " or Other branch found");
+ }
+ }
+
+ if (graphWasCalled == false) {
+ if (node.getOutcomeValue("catch") != null) {
+ nextNode = node.getOutcomeValue("catch");
+ LOG.debug("graph could not be called, but catch node was found and will be executed");
+ } else {
+ LOG.debug("graph could not be called and no catch node was found, throwing exception");
+ throw new SvcLogicException(errorMessage);
+ }
+ }
+
+ ctx.setAttribute(CURRENT_GRAPH, parentGraph);
+ ctx.setAttribute("parentGraph", null);
+
+ return (nextNode);
+
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java
new file mode 100644
index 000000000..a0e3af189
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java
@@ -0,0 +1,242 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConfigureNodeExecutor extends AbstractSvcLogicNodeExecutor {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ConfigureNodeExecutor.class);
+ private static final String CAUGHT_EXCEPTION_MSG="Caught exception from ";
+ private static final String ALREADY_ACTIVE= "already-active";
+ private static final String NOT_FOUND= "not-found";
+
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+ String adaptorName = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("adaptor"), node, ctx);
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("configure node encountered - looking for adaptor "
+ + adaptorName);
+ }
+
+ SvcLogicAdaptor adaptor = getAdaptor(adaptorName);
+
+ if (adaptor != null) {
+ String activate = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("activate"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("key"), node, ctx);
+
+ boolean hasParms = false;
+
+ Map<String, String> parmMap = getResolvedParameters(node,ctx);
+ if(!parmMap.isEmpty()) {
+ hasParms = true;
+ }
+
+ if (hasParms) {
+ SvcLogicAdaptor.ConfigStatus confStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+
+ try {
+ confStatus = adaptor.configure(key, parmMap, ctx);
+ } catch (Exception e) {
+ LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".configure", e);
+ confStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+
+ switch (confStatus) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ if ((activate != null) && (activate.length() > 0)) {
+ if ("true".equalsIgnoreCase(activate)) {
+ SvcLogicAdaptor.ConfigStatus activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+
+ try {
+ activateStatus = adaptor.activate(key, ctx);
+ } catch (Exception e) {
+
+ LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".activate", e);
+ activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+ switch (activateStatus) {
+ case SUCCESS:
+ break;
+ case ALREADY_ACTIVE:
+ outValue = ALREADY_ACTIVE;
+ break;
+ case NOT_FOUND:
+ outValue = NOT_FOUND;
+ break;
+ case NOT_READY:
+ outValue = "not-ready";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else if ("false".equalsIgnoreCase(activate)) {
+ SvcLogicAdaptor.ConfigStatus deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+
+ try {
+ deactivateStatus = adaptor.deactivate(key, ctx);
+ } catch (Exception e) {
+
+ LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".deactivate", e);
+ deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+ switch (deactivateStatus) {
+ case SUCCESS:
+ break;
+ case ALREADY_ACTIVE:
+ outValue = ALREADY_ACTIVE;
+ break;
+ case NOT_FOUND:
+ outValue = NOT_FOUND;
+ break;
+ case NOT_READY:
+ outValue = "not-ready";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ }
+ }
+ break;
+ case ALREADY_ACTIVE:
+ outValue = ALREADY_ACTIVE;
+ break;
+ case NOT_FOUND:
+ outValue = NOT_FOUND;
+ break;
+ case NOT_READY:
+ outValue = "not-ready";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ if ((activate != null) && (activate.length() > 0)) {
+ if ("true".equalsIgnoreCase(activate)) {
+ SvcLogicAdaptor.ConfigStatus activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ try {
+ activateStatus = adaptor.activate(key, ctx);
+ } catch (Exception e) {
+ LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".activate", e);
+ activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+ switch (activateStatus) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case ALREADY_ACTIVE:
+ outValue = ALREADY_ACTIVE;
+ break;
+ case NOT_FOUND:
+ outValue = NOT_FOUND;
+ break;
+ case NOT_READY:
+ outValue = "not-ready";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else if ("false".equalsIgnoreCase(activate)) {
+ SvcLogicAdaptor.ConfigStatus deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+
+ try {
+ deactivateStatus = adaptor.deactivate(key, ctx);
+ } catch (Exception e) {
+ LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".deactivate", e);
+ deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+ switch (deactivateStatus) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case ALREADY_ACTIVE:
+ outValue = ALREADY_ACTIVE;
+ break;
+ case NOT_FOUND:
+ outValue = NOT_FOUND;
+ break;
+ case NOT_READY:
+ outValue = "not-ready";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ }
+ } else {
+ LOG.warn("Nothing to configure - no parameters passed, and activate attribute is not set");
+ outValue = SvcLogicConstants.SUCCESS;
+ }
+ }
+ } else {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Adaptor for " + adaptorName + " not found");
+ }
+ }
+
+ SvcLogicNode nextNode = node.getOutcomeValue(outValue);
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute " + outValue + " branch");
+ }
+ return (nextNode);
+ }
+
+ nextNode = node.getOutcomeValue("Other");
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute Other branch");
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("no " + outValue + " or Other branch found");
+ }
+ }
+ return (nextNode);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java
new file mode 100644
index 000000000..00f0629cb
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeleteNodeExecutor.class);
+ private static final String FAILURE=SvcLogicConstants.FAILURE;
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+
+ String outValue = FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("delete node encountered - looking for resource class " + plugin);
+ }
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+ if (resourcePlugin != null) {
+ try {
+ switch (resourcePlugin.delete(resourceType, key, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java
new file mode 100644
index 000000000..b23662a6c
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java
@@ -0,0 +1,127 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ExecuteNodeExecutor extends AbstractSvcLogicNodeExecutor {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ExecuteNodeExecutor.class);
+ private static final String FAILURE=SvcLogicConstants.FAILURE;
+
+ private static final String pluginErrorMessage = "Could not execute plugin. SvcLogic status will be set to failure.";
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+ String pluginName = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("plugin"), node, ctx);
+ String outValue = FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("execute node encountered - looking for plugin "
+ + pluginName);
+ }
+
+ SvcLogicJavaPlugin plugin = getSvcLogicJavaPlugin(pluginName);
+
+ if (plugin == null) {
+ outValue = "not-found";
+ } else {
+
+ String methodName = evaluate(node.getAttribute("method"), node, ctx);
+
+ Class pluginClass = plugin.getClass();
+
+ Method pluginMethod = null;
+
+ try {
+ LOG.debug("executing method {} on plugin {}", methodName, pluginName);
+ pluginMethod = pluginClass.getMethod(methodName, Map.class, SvcLogicContext.class);
+ } catch (NoSuchMethodException e) {
+ LOG.error(pluginErrorMessage, e);
+ }
+
+ if (pluginMethod == null) {
+ outValue = "unsupported-method";
+ } else {
+ try {
+
+
+ Map<String, String> parmMap = getResolvedParameters(node,ctx);
+ Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+ String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx);
+
+ outValue = mapOutcome(o, emitsOutcome);
+
+ } catch (InvocationTargetException e) {
+ if(e.getCause() != null){
+ LOG.error(pluginErrorMessage, e.getCause());
+ }else{
+ LOG.error(pluginErrorMessage, e);
+ }
+ outValue = FAILURE;
+ ctx.markFailed();
+ } catch (IllegalAccessException e) {
+ LOG.error(pluginErrorMessage, e);
+ outValue = FAILURE;
+ ctx.markFailed();
+ } catch (IllegalArgumentException e) {
+ LOG.error(pluginErrorMessage, e);
+ outValue = FAILURE;
+ ctx.markFailed();
+ }
+ }
+
+ }
+ return (getNextNode(node, outValue));
+ }
+
+ protected String evaluate(SvcLogicExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ return SvcLogicExpressionResolver.evaluate(node.getAttribute("method"), node, ctx);
+ }
+
+ public String mapOutcome(Object o, String emitsOutcome) {
+ if (emitsOutcome != null) {
+ Boolean nodeEmitsOutcome = Boolean.valueOf(emitsOutcome);
+ if (nodeEmitsOutcome) {
+ return (String) o;
+ } else {
+ return SvcLogicConstants.SUCCESS;
+ }
+ } else {
+ return SvcLogicConstants.SUCCESS;
+ }
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java
new file mode 100644
index 000000000..ca12e35d8
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ExistsNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ExistsNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+ String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx);
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("exists node encountered - looking for resource class " + plugin);
+ }
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+
+ if (resourcePlugin != null) {
+ try {
+ switch (resourcePlugin.exists(resourceType, key, pfx, ctx)) {
+ case SUCCESS:
+ outValue = "true";
+ break;
+ case NOT_FOUND:
+ outValue = "false";
+ break;
+ case FAILURE:
+ default:
+ outValue = "false";
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java
new file mode 100644
index 000000000..828e10152
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.ExitNodeException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ExitNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ExitNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ String message = "ExitNodeExecutor encountered exit with nodeId " + node.getNodeId();
+ LOG.debug(message);
+ throw new ExitNodeException(message);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java
new file mode 100644
index 000000000..2d9721c7f
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.BreakNodeException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ForNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ForNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+ SvcLogicExpression atomicExpr = node.getAttribute("atomic");
+ String atomicStr = SvcLogicExpressionResolver.evaluate(atomicExpr, node, ctx);
+ boolean isAtomic = !("false".equalsIgnoreCase(atomicStr));
+
+ int numOutcomes = node.getNumOutcomes();
+ String idxVar = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("index"), node, ctx);
+ String startVal = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("start"), node, ctx);
+ String endVal = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("end"), node, ctx);
+
+ LOG.debug("Executing "+ (isAtomic ? "atomic" : "non-atomic") + " for loop - for (int " + idxVar + " = " + startVal
+ + "; " + idxVar + " < " + endVal + "; " + idxVar + "++)");
+
+ int startIdx = 0;
+ int endIdx = 0;
+
+ try {
+ startIdx = Integer.parseInt(startVal);
+ endIdx = Integer.parseInt(endVal);
+ } catch (NumberFormatException e) {
+ SvcLogicExpression silentFailureExpr = node.getAttribute("silentFailure");
+ String silentFailure = SvcLogicExpressionResolver.evaluate(silentFailureExpr, node, ctx);
+ boolean isSilentFailure = Boolean.parseBoolean(silentFailure);
+ String message = "Invalid index values [" + startVal + "," + endVal + "]";
+ if(!isSilentFailure){
+ throw new SvcLogicException(message);
+ }else{
+ LOG.debug(message + ". Not exiting because silentFailure was set to true.");
+ return(null);
+ }
+ }
+
+ try {
+ for (int ctr = startIdx; ctr < endIdx; ctr++) {
+
+ ctx.setAttribute(idxVar, "" + ctr);
+
+ for (int i = 0; i < numOutcomes; i++) {
+
+ if (SvcLogicConstants.FAILURE.equals(ctx.getStatus()) && isAtomic) {
+ LOG.info("For - stopped executing nodes due to failure status");
+ return(null);
+ }
+
+ SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1));
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("For - executing outcome " + (i + 1));
+ }
+ SvcLogicNode innerNextNode = nextNode;
+ while (innerNextNode != null) {
+ innerNextNode = svc.executeNode(innerNextNode, ctx);
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("For - done: no outcome " + (i + 1));
+ }
+ }
+ }
+ }
+ } catch (BreakNodeException br) {
+ LOG.trace("ForNodeExecutor caught break" + br.getMessage());
+ }
+ return (null);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java
new file mode 100644
index 000000000..f7cfc66d2
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GetResourceNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GetResourceNodeExecutor.class);
+
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+ String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx);
+
+ String localOnlyStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("local-only"), node, ctx);
+
+ // Note: for get-resource, only refresh from A&AI if the DG explicitly set
+ // local-only to false. Otherwise, just read from local database.
+ boolean localOnly = true;
+
+ if ("false".equalsIgnoreCase(localOnlyStr)) {
+ localOnly = false;
+ }
+
+ SvcLogicExpression selectExpr = node.getAttribute("select");
+ String select = null;
+
+ if (selectExpr != null) {
+ select = SvcLogicExpressionResolver.evaluateAsKey(selectExpr, node, ctx);
+ }
+
+ SvcLogicExpression orderByExpr = node.getAttribute("order-by");
+ String orderBy = null;
+
+ if (orderByExpr != null) {
+ orderBy = SvcLogicExpressionResolver.evaluateAsKey(orderByExpr, node, ctx);
+ }
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(node.getNodeType() + " node encountered - looking for resource class " + plugin);
+ }
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+
+ if (resourcePlugin != null) {
+ try {
+ switch (resourcePlugin.query(resourceType, localOnly, select, key, pfx, orderBy, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java
new file mode 100644
index 000000000..d33312784
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java
@@ -0,0 +1,52 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+
+public class HashMapResolver implements SvcLogicResolver {
+ Map<String, SvcLogicResource> svcLogicResourceMap = new HashMap<String, SvcLogicResource>();
+ Map<String, SvcLogicJavaPlugin> svcLogicJavaPluginMap = new HashMap<String, SvcLogicJavaPlugin>();
+ Map<String, SvcLogicAdaptor> adaptorMap = new HashMap<String, SvcLogicAdaptor>();
+ Map<String, SvcLogicRecorder> recorderMap = new HashMap<String, SvcLogicRecorder>();
+
+ @Override
+ public SvcLogicResource getSvcLogicResource(String resourceName) {
+ return svcLogicResourceMap.get(resourceName);
+ }
+
+ @Override
+ public SvcLogicRecorder getSvcLogicRecorder(String recorderName) {
+ return recorderMap.get(recorderName);
+ }
+
+ @Override
+ public SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) {
+ return svcLogicJavaPluginMap.get(pluginName);
+ }
+
+ @Override
+ public SvcLogicAdaptor getSvcLogicAdaptor(String adaptorName) {
+ return adaptorMap.get(adaptorName);
+ }
+
+ public void addSvcLogicAdaptor(String adaptorName, SvcLogicAdaptor adaptor) {
+ adaptorMap.put(adaptorName, adaptor);
+ }
+
+ public void addSvcLogicRecorder(String recorderName, SvcLogicRecorder recorder) {
+ recorderMap.put(recorderName, recorder);
+ }
+
+ public void addSvcLogicSvcLogicJavaPlugin(String pluginName, SvcLogicJavaPlugin plugin) {
+ svcLogicJavaPluginMap.put(pluginName, plugin);
+ }
+
+ public void addSvcLogicResource(String resourceName, SvcLogicResource resource) {
+ svcLogicResourceMap.put(resourceName, resource);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java
new file mode 100644
index 000000000..ddf464fe7
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java
@@ -0,0 +1,66 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InMemorySvcLogicStore implements SvcLogicStore {
+ private static final Logger logger = LoggerFactory.getLogger(InMemorySvcLogicStore.class);
+ public Map<String, SvcLogicGraph> graphStore;
+
+ public InMemorySvcLogicStore() {
+ graphStore = new HashMap<String, SvcLogicGraph>();
+ }
+
+ @Override
+ public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException {
+ String storeId = new String(module + ":" + rpc);
+ return graphStore.containsKey(storeId);
+ }
+
+ @Override
+ public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException {
+ String storeId = new String(module + ":" + rpc);
+ return graphStore.get(storeId);
+ }
+
+ @Override
+ public void store(SvcLogicGraph graph) throws SvcLogicException {
+ if (graph != null) {
+ String storeId = new String(graph.getModule() + ":" + graph.getRpc());
+ graphStore.put(storeId, graph);
+ logger.info(graph.toString() + " stored in InMemorySvcLogicStore.");
+ }
+ }
+
+ @Override
+ public void init(Properties props) throws SvcLogicException {
+ // noop
+ }
+
+ @Override
+ public void delete(String module, String rpc, String version, String mode) throws SvcLogicException {
+ String storeId = new String(module + ":" + rpc);
+ if (graphStore.containsKey(storeId)) {
+ graphStore.remove(storeId);
+ }
+ }
+
+ @Override
+ public void activate(SvcLogicGraph graph) throws SvcLogicException {
+ // noop
+ }
+
+ @Override
+ public void activate(String module, String rpc, String version, String mode) throws SvcLogicException {
+ // noop
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java
new file mode 100644
index 000000000..1d6e34e85
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IsAvailableNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IsAvailableNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+ String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx);
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+
+ if (resourcePlugin != null) {
+ try {
+ switch (resourcePlugin.isAvailable(resourceType, key, pfx, ctx)) {
+ case SUCCESS:
+ outValue = "true";
+ break;
+ case NOT_FOUND:
+ outValue = "false";
+ break;
+ case FAILURE:
+ default:
+ outValue = "false";
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java
new file mode 100644
index 000000000..fb560db5f
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NotifyNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NotifyNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String action = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("action"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("release node encountered - looking for resource class " + plugin);
+ }
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+ if (resourcePlugin != null) {
+ try {
+ switch (resourcePlugin.notify(resourceType, action, key, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java
new file mode 100644
index 000000000..2dd5a081e
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RecordNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RecordNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String outValue = SvcLogicConstants.FAILURE;
+
+ Map<String, String> parmMap = getResolvedParameters(node,ctx);
+
+ SvcLogicRecorder recorder = getSvcLogicRecorder(plugin);
+ if (recorder != null) {
+ try {
+ recorder.record(parmMap);
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from recorder plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicRecorder object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java
new file mode 100644
index 000000000..ee06031d6
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReleaseNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ReleaseNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("release node encountered - looking for resource class " + plugin);
+ }
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+ if (resourcePlugin != null) {
+ try {
+ switch (resourcePlugin.release(resourceType, key, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java
new file mode 100644
index 000000000..d22d36ebb
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReserveNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ReserveNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+ String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx);
+
+
+ SvcLogicExpression selectExpr = node.getAttribute("select");
+ String select = null;
+
+ if (selectExpr != null) {
+ select = SvcLogicExpressionResolver.evaluateAsKey(selectExpr, node, ctx);
+ }
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("reserve node encountered - looking for resource class " + plugin);
+ }
+
+
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+
+ if (resourcePlugin != null) {
+
+ try {
+ switch (resourcePlugin.reserve(resourceType, select, key, pfx, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java
new file mode 100644
index 000000000..8ee465774
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReturnNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ReturnNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+ String status = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("status"), node, ctx);
+
+ if (status != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Returning status " + status);
+ }
+ ctx.setStatus(status);
+ } else {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Return node has no status attribute set");
+ }
+ }
+
+ Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node
+ .getParameterSet();
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet
+ .iterator(); iter.hasNext();) {
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ String curValue = SvcLogicExpressionResolver.evaluate(
+ curEnt.getValue(), node, ctx);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(SETTING_DEBUG_PATTERN, curName, curValue, curEnt.getValue());
+ }
+ ctx.setAttribute(curName, curValue);
+ }
+ return null;
+ }
+
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java
new file mode 100644
index 000000000..b0b70f1f2
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SaveNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SaveNodeExecutor.class);
+ private static final String FAILURE= SvcLogicConstants.FAILURE;
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+ String forceStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("force"), node, ctx);
+ String localOnlyStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("local-only"), node, ctx);
+ String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx);
+
+ boolean force = "true".equalsIgnoreCase(forceStr);
+ boolean localOnly = "true".equalsIgnoreCase(localOnlyStr);
+
+ Map<String, String> parmMap = getResolvedParameters(node,ctx);
+
+ String outValue = FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("save node encountered - looking for resource class " + plugin);
+ }
+
+
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+
+ if (resourcePlugin != null) {
+
+ try {
+ switch (resourcePlugin.save(resourceType, force, localOnly, key, parmMap, pfx, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java
new file mode 100644
index 000000000..7e07d29bf
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java
@@ -0,0 +1,179 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpressionFactory;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SetNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SetNodeExecutor.class);
+ protected final String arrayPattern = "\\[\\d*\\]";
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+ execute(node,ctx);
+ return null;
+ }
+
+ public void execute(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ String ifunsetStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("only-if-unset"), node, ctx);
+
+ boolean ifunset = "true".equalsIgnoreCase(ifunsetStr);
+
+ Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node.getParameterSet();
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet.iterator(); iter.hasNext();) {
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ String lhsVarName = curName;
+
+ // Resolve LHS of assignment (could contain index variables)
+ try {
+ // Backticks symbolize the variable should be handled as an expression instead of as a variable
+ if (curName.trim().startsWith("`")) {
+ int lastParen = curName.lastIndexOf("`");
+ String evalExpr = curName.trim().substring(1, lastParen);
+ SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(evalExpr);
+ lhsVarName = SvcLogicExpressionResolver.evaluate(lhsExpr, node, ctx);
+ } else {
+ SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(curName);
+ lhsVarName = SvcLogicExpressionResolver.resolveVariableName(lhsExpr, node, ctx);
+ }
+ } catch (Exception e) {
+ LOG.warn("Caught exception trying to resolve variable name (" + curName + ")", e);
+ }
+
+ boolean setValue = true;
+
+ if (curName.endsWith(".")) {
+ // Copy subtree - value should be a variable name
+ SvcLogicExpression curValue = curEnt.getValue();
+
+ if (curValue != null) {
+ String rhsRoot = curValue.toString();
+
+ if ((rhsRoot != null) && (rhsRoot.length() > 0)) {
+ if (rhsRoot.endsWith(".")) {
+ rhsRoot = rhsRoot.substring(0, rhsRoot.length() - 1);
+ }
+
+ // SDNGC-2321 : rhsRoot is variable name, possibly with subscript(s) to be resolved
+ try {
+ SvcLogicExpression rhsExpr = SvcLogicExpressionFactory.parse(rhsRoot);
+ rhsRoot = SvcLogicExpressionResolver.resolveVariableName(rhsExpr, node, ctx);
+ } catch (Exception e) {
+ LOG.warn("Caught exception trying to resolve variable name (" + rhsRoot + ")", e);
+ }
+
+ // See if the parameters are reversed (copying service-data to input) .. this
+ // was done as a workaround to earlier issue
+ if (curName.endsWith("-input.") && rhsRoot.startsWith("service-data")) {
+ LOG.warn("Arguments appear to be reversed .. will copy input to service-data instead");
+ lhsVarName = rhsRoot + ".";
+ rhsRoot = curName.substring(0, curName.length() - 1);
+ }
+
+ rhsRoot = rhsRoot + ".";
+ String lhsPrefix = lhsVarName;
+
+ if (lhsPrefix.endsWith(".")) {
+ lhsPrefix = lhsPrefix.substring(0, lhsPrefix.length() - 1);
+ }
+
+ HashMap<String, String> parmsToAdd = new HashMap<>();
+
+ for (String sourceVarName : ctx.getAttributeKeySet()) {
+ if (sourceVarName.startsWith(rhsRoot)) {
+ String targetVar = lhsPrefix + "." + sourceVarName.substring(rhsRoot.length());
+ LOG.debug("Copying {} value to {}", sourceVarName, targetVar);
+ parmsToAdd.put(targetVar, ctx.getAttribute(sourceVarName));
+ }
+ }
+ for (String newParmName : parmsToAdd.keySet()) {
+ ctx.setAttribute(newParmName, parmsToAdd.get(newParmName));
+ }
+ } else {
+ // If RHS is empty, unset attributes in LHS
+ LinkedList<String> parmsToRemove = new LinkedList<>();
+ String prefix = lhsVarName + ".";
+ String arrayPrefix = lhsVarName + "[";
+ //Clear length value in case an array exists with this prefix
+ String lengthParamName = lhsVarName + "_length";
+ LOG.debug("Unsetting {} because prefix {} is being cleared.", lengthParamName, prefix);
+
+ for (String curCtxVarname : ctx.getAttributeKeySet()) {
+ String curCtxVarnameMatchingValue = curCtxVarname;
+ //Special handling for reseting array values, strips out brackets and any numbers between the brackets
+ //when testing if a context memory value starts with a prefix
+ if(!prefix.contains("[") && curCtxVarnameMatchingValue.contains("[")) {
+ curCtxVarnameMatchingValue = curCtxVarname.replaceAll(arrayPattern, "") + ".";
+ }
+ if (curCtxVarnameMatchingValue.startsWith(prefix)) {
+ LOG.debug("Unsetting {} because matching value {} starts with the prefix {}", curCtxVarname, curCtxVarnameMatchingValue, prefix);
+ parmsToRemove.add(curCtxVarname);
+ }else if (curCtxVarnameMatchingValue.startsWith(lengthParamName)) {
+ LOG.debug("Unsetting {} because matching value {} starts with the lengthParamName {}", curCtxVarname, curCtxVarnameMatchingValue, lengthParamName);
+ parmsToRemove.add(curCtxVarname);
+ }else if (curCtxVarnameMatchingValue.startsWith(arrayPrefix)) {
+ LOG.debug("Unsetting {} because matching value {} starts with the arrayPrefix {}", curCtxVarname, curCtxVarnameMatchingValue, arrayPrefix);
+ parmsToRemove.add(curCtxVarname);
+ }
+ }
+ for (String parmName : parmsToRemove) {
+ ctx.setAttribute(parmName, null);
+ }
+ }
+ }
+ } else {
+ if (ifunset) {
+ String ctxValue = ctx.getAttribute(lhsVarName);
+ if ((ctxValue != null) && (ctxValue.length() > 0)) {
+ setValue = false;
+ LOG.debug("Attribute {} already set and only-if-unset is true, so not overriding", lhsVarName);
+ }
+ }
+ if (setValue) {
+ String curValue = SvcLogicExpressionResolver.evaluate(curEnt.getValue(), node, ctx);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(SETTING_DEBUG_PATTERN, lhsVarName, curValue, curEnt.getValue());
+ }
+ ctx.setAttribute(lhsVarName, curValue);
+ }
+ }
+ }
+ }
+}
+
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java
new file mode 100644
index 000000000..a3507947f
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java
@@ -0,0 +1,603 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAtom;
+import org.onap.ccsdk.sli.core.sli.SvcLogicBinaryExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicFunctionCall;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicVariableTerm;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAtom.AtomType;
+import org.onap.ccsdk.sli.core.sli.SvcLogicBinaryExpression.OperatorType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicExpressionResolver {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExpressionResolver.class);
+ private static final String INVALID_EXPRESSION_MSG= "Invalid expression (";
+ private static final String EXPRESSION_DEBUG_PATTERN = "Expression: ({}) resolves to: (${}) which has the value: ({})";
+
+ public static String evaluate(SvcLogicExpression expr, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+ if (expr == null) {
+ return (null);
+ }
+
+ if (expr instanceof SvcLogicAtom) {
+ SvcLogicAtom atom = (SvcLogicAtom) expr;
+
+ AtomType atomType = atom.getAtomType();
+ switch (atomType) {
+ case NUMBER:
+ case STRING:
+ return (atom.toString());
+ case CONTEXT_VAR:
+ case IDENTIFIER:
+
+ String varName = resolveVariableName(atom, node, ctx);
+
+ if (atomType == AtomType.CONTEXT_VAR)
+ {
+ String varValue = ctx.getAttribute(varName);
+ if (varValue == null) {
+ LOG.trace("Context variable: ($"+varName+") unset - treating as empty string");
+ varValue = "";
+ }
+ LOG.trace(EXPRESSION_DEBUG_PATTERN, expr, varName, varValue);
+ return (varValue);
+ }
+
+ SvcLogicExpression parm = node.getParameter(varName);
+ if (parm != null) {
+ String value = evaluate(parm, node, ctx);
+ LOG.trace(EXPRESSION_DEBUG_PATTERN, expr, varName, value);
+ return value;
+ }
+ else {
+ LOG.trace(EXPRESSION_DEBUG_PATTERN, expr, varName, varName);
+ return(varName);
+ }
+ default:
+ return(null);
+ }
+
+ } else if (expr instanceof SvcLogicBinaryExpression) {
+ SvcLogicBinaryExpression binExpr = (SvcLogicBinaryExpression) expr;
+ List<OperatorType> operators = binExpr.getOperators();
+ if (operators.isEmpty())
+ {
+ List<SvcLogicExpression> operands = binExpr.getOperands();
+ if (operands.size() == 1)
+ {
+ return(evaluate(operands.get(0), node, ctx));
+ }
+ else
+ {
+ if (operands.isEmpty())
+ {
+ LOG.error("SvcLogicBinaryExpression has no operators and no operands - evaluating value as null");
+ }
+ else
+ {
+ LOG.error("SvcLogicBinaryExpression has no operators and "+operands.size()+" operands - evaluating value as null");
+ }
+ return(null);
+ }
+ }
+ switch (operators.get(0)) {
+ case addOp:
+ case subOp:
+ case multOp:
+ case divOp:
+ return(evalArithExpression(binExpr, node, ctx));
+ case equalOp:
+ case neOp:
+ case ltOp:
+ case leOp:
+ case gtOp:
+ case geOp:
+ return (evalCompareExpression(binExpr, node, ctx));
+ case andOp:
+ case orOp:
+ return(evalLogicExpression(binExpr, node, ctx));
+
+ default:
+ return(null);
+ }
+ }
+ else if (expr instanceof SvcLogicFunctionCall)
+ {
+ return(evalFunctionCall((SvcLogicFunctionCall)expr, node, ctx));
+ }
+ else
+ {
+ throw new SvcLogicException("Unrecognized expression type ["+expr+"]");
+ }
+ }
+
+ private static String evalArithExpression(SvcLogicBinaryExpression binExpr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ List<SvcLogicExpression> operands = binExpr.getOperands();
+ List<OperatorType> operators = binExpr.getOperators();
+ if (operands.size() != (operators.size()+1))
+ {
+ throw new SvcLogicException(INVALID_EXPRESSION_MSG+binExpr+")");
+ }
+ String retval = evaluate(operands.get(0), node, ctx);
+ String retsval = retval;
+ long retlval = 0;
+ boolean valueIsLong = false;
+
+ int i = 1;
+ try
+ {
+
+ if ((retval.length() > 0) && StringUtils.isNumeric(retval))
+ {
+ retlval = Long.parseLong(retval);
+ valueIsLong = true;
+ }
+ for (OperatorType operator: operators)
+ {
+ String curOperandValue = evaluate(operands.get(i++), node, ctx);
+ switch(operator) {
+ case addOp:
+ retsval = retsval + curOperandValue;
+ if (valueIsLong)
+ {
+ if ((curOperandValue.length() > 0) && StringUtils.isNumeric(curOperandValue) )
+ {
+ retlval = retlval + Long.parseLong(curOperandValue);
+ }
+ else
+ {
+ valueIsLong = false;
+ }
+ }
+ break;
+ case subOp:
+ retlval = retlval - Long.parseLong(curOperandValue);
+ break;
+ case multOp:
+ retlval = retlval * Long.parseLong(curOperandValue);
+ break;
+ case divOp:
+ retlval = retlval / Long.parseLong(curOperandValue);
+ break;
+ }
+
+ }
+ }
+ catch (NumberFormatException e1)
+ {
+ throw new SvcLogicException("Illegal value in arithmetic expression", e1);
+ }
+
+ if (valueIsLong)
+ {
+ return("" + retlval);
+ }
+ else
+ {
+ return(retsval);
+ }
+
+ }
+
+
+
+ private static String evalCompareExpression(SvcLogicBinaryExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
+ {
+
+ List<OperatorType> operators = expr.getOperators();
+ List<SvcLogicExpression> operands = expr.getOperands();
+
+ if ((operators.size() != 1) || (operands.size() != 2))
+ {
+ throw new SvcLogicException ("Invalid comparison expression : "+expr);
+ }
+
+ OperatorType operator = operators.get(0);
+ String op1Value = evaluate(operands.get(0), node, ctx);
+ String op2Value = evaluate(operands.get(1), node, ctx);
+
+ if ((StringUtils.isNotEmpty(op1Value) && StringUtils.isNumeric(op1Value) && StringUtils.isNotEmpty(op2Value) && StringUtils.isNumeric(op2Value)))
+ {
+ try
+ {
+ double op1dbl = Double.parseDouble(op1Value);
+ double op2dbl = Double.parseDouble(op2Value);
+
+ switch(operator)
+ {
+ case equalOp:
+ return(Boolean.toString(op1dbl == op2dbl));
+ case neOp:
+ return(Boolean.toString(op1dbl != op2dbl));
+ case ltOp:
+ return(Boolean.toString(op1dbl < op2dbl));
+ case leOp:
+ return(Boolean.toString(op1dbl <= op2dbl));
+ case gtOp:
+ return(Boolean.toString(op1dbl > op2dbl));
+ case geOp:
+ return(Boolean.toString(op1dbl >= op2dbl));
+ default:
+ return(null);
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ throw new SvcLogicException("Caught exception trying to compare numeric values", e);
+ }
+ }
+ else
+ {
+
+ int compResult = 0;
+
+ if (op1Value == null) {
+ compResult = -1;
+ } else if (op2Value == null ) {
+ compResult = 1;
+ } else {
+ compResult = op1Value.compareToIgnoreCase(op2Value);
+ }
+
+ switch(operator)
+ {
+ case equalOp:
+ return(Boolean.toString(compResult == 0));
+ case neOp:
+ return(Boolean.toString(compResult != 0));
+ case ltOp:
+ return(Boolean.toString(compResult < 0));
+ case leOp:
+ return(Boolean.toString(compResult <= 0));
+ case gtOp:
+ return(Boolean.toString(compResult > 0));
+ case geOp:
+ return(Boolean.toString(compResult >= 0));
+ default:
+ return(null);
+ }
+ }
+
+ }
+
+ private static String evalLogicExpression(SvcLogicBinaryExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
+ {
+ boolean retval;
+
+ List<SvcLogicExpression> operands = expr.getOperands();
+ List<OperatorType> operators = expr.getOperators();
+
+ if (operands.size() != (operators.size()+1))
+ {
+ throw new SvcLogicException(INVALID_EXPRESSION_MSG+expr+")");
+ }
+
+ try
+ {
+ retval = Boolean.parseBoolean(evaluate(operands.get(0), node, ctx));
+ int i = 1;
+ for (OperatorType operator : operators)
+ {
+ if (operator == OperatorType.andOp)
+ {
+ retval = retval && Boolean.parseBoolean(evaluate(operands.get(i++), node, ctx));
+ }
+ else
+ {
+
+ retval = retval || Boolean.parseBoolean(evaluate(operands.get(i++), node, ctx));
+ }
+
+ }
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException(INVALID_EXPRESSION_MSG+expr+")");
+ }
+
+
+ return(Boolean.toString(retval));
+ }
+
+ private static String evalFunctionCall(SvcLogicFunctionCall func, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
+ {
+ String funcName = func.getFunctionName();
+ List<SvcLogicExpression> operands = func.getOperands();
+
+ if ("length".equalsIgnoreCase(funcName))
+ {
+
+ if (operands.size() == 1)
+ {
+ String opValue = evaluate(operands.get(0), node, ctx);
+ return(""+opValue.length());
+ }
+ else
+ {
+ throw new SvcLogicException("Invalid call to length() function");
+ }
+ }
+ else if ("substr".equalsIgnoreCase(funcName))
+ {
+ if (operands.size() == 3)
+ {
+ String op1Value = evaluate(operands.get(0), node, ctx);
+ String op2Value = evaluate(operands.get(1), node, ctx);
+ String op3Value = evaluate(operands.get(2), node, ctx);
+
+ if (!StringUtils.isNumeric(op2Value) || !StringUtils.isNumeric(op3Value))
+ {
+ throw new SvcLogicException("Invalid arguments to substr() function");
+ }
+
+ try
+ {
+ return(op1Value.substring(Integer.parseInt(op2Value), Integer.parseInt(op3Value)));
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Caught exception trying to take substring", e);
+ }
+ }
+ else
+ {
+
+ throw new SvcLogicException("Invalid call to substr() function");
+ }
+
+ }
+ else if ("toUpperCase".equalsIgnoreCase(funcName))
+ {
+ if (operands.size() == 1)
+ {
+ String opValue = evaluate(operands.get(0), node, ctx);
+ if (opValue != null) {
+ return(opValue.toUpperCase());
+ } else {
+ return("");
+ }
+ }
+ else
+ {
+ throw new SvcLogicException("Invalid call to toUpperCase() function");
+ }
+ }
+ else if ("toLowerCase".equalsIgnoreCase(funcName))
+ {
+ if (operands.size() == 1)
+ {
+ String opValue = evaluate(operands.get(0), node, ctx);
+ if (opValue != null) {
+ return(opValue.toLowerCase());
+ } else {
+ return("");
+ }
+ }
+ else
+ {
+ throw new SvcLogicException("Invalid call to toLowerCase() function");
+ }
+ }
+ else if ("convertBase".equalsIgnoreCase(funcName)) {
+ int fromBase = 10;
+ int toBase = 10;
+ String srcString = "";
+
+ if (operands.size() == 2)
+ {
+ fromBase = 10;
+ srcString = evaluate(operands.get(0), node, ctx);
+ toBase = Integer.parseInt(evaluate(operands.get(1), node, ctx));
+ } else if (operands.size() == 3) {
+
+ srcString = evaluate(operands.get(0), node, ctx);
+ fromBase = Integer.parseInt(evaluate(operands.get(1), node, ctx));
+ toBase = Integer.parseInt(evaluate(operands.get(2), node, ctx));
+ } else {
+ throw new SvcLogicException("Invalid call to convertBase() function");
+ }
+
+ long srcValue = Long.parseLong(srcString, fromBase);
+ return(Long.toString(srcValue, toBase));
+ }
+ else
+ {
+ throw new SvcLogicException("Unrecognized function ("+funcName+")");
+ }
+
+ }
+
+ public static String evaluateAsKey(SvcLogicExpression expr, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+ if (expr == null) {
+ return (null);
+ }
+
+
+
+ if (expr instanceof SvcLogicAtom) {
+ SvcLogicAtom atom = (SvcLogicAtom) expr;
+
+ AtomType atomType = atom.getAtomType();
+ StringBuffer varNameBuff = new StringBuffer();
+ switch (atomType) {
+ case NUMBER:
+ return (atom.toString());
+ case STRING:
+ return("'"+atom.toString()+"'");
+ case CONTEXT_VAR:
+ case IDENTIFIER:
+ boolean needDot = false;
+ for (SvcLogicExpression term : atom.getOperands())
+ {
+ if (needDot)
+ {
+ varNameBuff.append(".");
+ }
+ if (term instanceof SvcLogicVariableTerm)
+ {
+ SvcLogicVariableTerm vterm = (SvcLogicVariableTerm) term;
+ varNameBuff.append(vterm.getName());
+ if (vterm.numOperands() > 0)
+ {
+ varNameBuff.append("[");
+ varNameBuff.append(evaluate(vterm.getSubscript(), node, ctx));
+ varNameBuff.append("]");
+
+ }
+ }
+ else
+ {
+ varNameBuff.append(term.toString());
+ }
+ needDot = true;
+ }
+
+ String varName = varNameBuff.toString();
+ String ctxValue = ctx.getAttribute(varName);
+ if (ctxValue == null)
+ {
+ return(null);
+ }
+ if (StringUtils.isNumeric(ctxValue))
+ {
+ return(ctxValue);
+ }
+ else
+ {
+ return("'"+ctxValue+"'");
+ }
+
+ default:
+ return(null);
+ }
+
+ } else if (expr instanceof SvcLogicBinaryExpression) {
+ SvcLogicBinaryExpression binExpr = (SvcLogicBinaryExpression) expr;
+ List<OperatorType> operators = binExpr.getOperators();
+ List<SvcLogicExpression> operands = binExpr.getOperands();
+ if (operators.isEmpty())
+ {
+ if (operands.size() == 1)
+ {
+ LOG.debug("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand");
+ return(evaluateAsKey(operands.get(0), node, ctx));
+ }
+ else
+ {
+ if (operands.isEmpty())
+ {
+ LOG.error("SvcLogicBinaryExpression has no operators and no operands - evaluating value as null");
+ }
+ else
+ {
+ LOG.error("SvcLogicBinaryExpression has no operators and "+operands.size()+" operands - evaluating value as null");
+ }
+ return(null);
+ }
+ }
+ StringBuffer sbuff = new StringBuffer();
+ sbuff.append(evaluateAsKey(operands.get(0), node, ctx));
+ int i = 1;
+ for (OperatorType operator : operators)
+ {
+ sbuff.append(" ");
+ sbuff.append(operator.toString());
+ sbuff.append(" ");
+ sbuff.append(evaluateAsKey(operands.get(i++), node,ctx));
+ }
+ return(sbuff.toString());
+ }
+ else if (expr instanceof SvcLogicFunctionCall)
+ {
+ StringBuffer sbuff = new StringBuffer();
+ SvcLogicFunctionCall funcCall = (SvcLogicFunctionCall) expr;
+ sbuff.append(funcCall.getFunctionName());
+ sbuff.append("(");
+ boolean needComma = false;
+ for (SvcLogicExpression operand : funcCall.getOperands())
+ {
+ if (needComma)
+ {
+ sbuff.append(",");
+ }
+ else
+ {
+ needComma = true;
+ }
+ sbuff.append(evaluateAsKey(operand, node, ctx));
+ }
+ sbuff.append(")");
+ return(sbuff.toString());
+ }
+ else
+ {
+ throw new SvcLogicException("Unrecognized expression type ["+expr+"]");
+ }
+ }
+
+ public static String resolveVariableName(SvcLogicExpression atom, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException
+ {
+ StringBuffer varNameBuff = new StringBuffer();
+
+ boolean needDot = false;
+ for (SvcLogicExpression term : atom.getOperands())
+ {
+ if (needDot)
+ {
+ varNameBuff.append(".");
+ }
+ if (term instanceof SvcLogicVariableTerm)
+ {
+ SvcLogicVariableTerm vterm = (SvcLogicVariableTerm) term;
+ varNameBuff.append(vterm.getName());
+ if (vterm.numOperands() > 0)
+ {
+ varNameBuff.append("[");
+ varNameBuff.append(evaluate(vterm.getSubscript(), node, ctx));
+ varNameBuff.append("]");
+ }
+ }
+ else
+ {
+ varNameBuff.append(term.toString());
+ }
+ needDot = true;
+ }
+ return(varNameBuff.toString());
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java
new file mode 100644
index 000000000..fc108f951
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * onap
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 ONAP
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.Properties;
+
+public interface SvcLogicPropertiesProvider {
+
+ public Properties getProperties();;
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java
new file mode 100644
index 000000000..08b675958
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java
@@ -0,0 +1,17 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+
+public interface SvcLogicResolver {
+
+ abstract SvcLogicResource getSvcLogicResource(String resourceName);
+
+ abstract SvcLogicRecorder getSvcLogicRecorder(String recorderName);
+
+ abstract SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName);
+
+ abstract SvcLogicAdaptor getSvcLogicAdaptor(String adaptorName);
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java
new file mode 100644
index 000000000..3bade8132
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.Properties;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+
+public interface SvcLogicServiceBase {
+
+
+ /**
+ * Check for existence of a directed graph
+ * @param module - module name
+ * @param rpc - rpc name
+ * @param version - version. If null, looks for active version
+ * @param mode - mode (sync/async)
+ * @return true if directed graph found, false otherwise
+ * @throws SvcLogicException
+ */
+ boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException;
+
+ /**
+ * Execute a directed graph
+ *
+ * @param module - module name
+ * @param rpc - rpc name
+ * @param version - version. If null, use active version
+ * @param mode - mode (sync/async)
+ * @param parms - parameters, used to set SvcLogicContext attributes
+ * @return final values of attributes from SvcLogicContext, as Properties
+ * @throws SvcLogicException
+ *
+ *
+ */
+ Properties execute(String module, String rpc, String version, String mode, Properties parms) throws SvcLogicException;
+ /**
+ * Execute a directed graph
+ *
+ * @param module - module name
+ * @param rpc - rpc name
+ * @param version - version. If null, use active version
+ * @param mode - mode (sync/async)
+ * @param ctx - parameters, as a SvcLogicContext object
+ * @return final values of attributes from SvcLogicContext, as Properties
+ * @throws SvcLogicException
+ *
+ *
+ */
+ SvcLogicContext execute(String module, String rpc, String version, String mode, SvcLogicContext ctx) throws SvcLogicException;
+
+ SvcLogicStore getStore() throws SvcLogicException;
+
+ SvcLogicContext execute(SvcLogicGraph calledGraph, SvcLogicContext ctx) throws SvcLogicException;
+
+ SvcLogicNode executeNode(SvcLogicNode nextNode, SvcLogicContext ctx) throws SvcLogicException;
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java
new file mode 100644
index 000000000..75673f756
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java
@@ -0,0 +1,180 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import org.onap.ccsdk.sli.core.sli.ExitNodeException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+public class SvcLogicServiceImplBase implements SvcLogicServiceBase {
+ protected SvcLogicResolver resolver;
+ protected static final Map<String, AbstractSvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, AbstractSvcLogicNodeExecutor>() {
+ {
+ put("block", new BlockNodeExecutor());
+ put("call", new CallNodeExecutor());
+ put("configure", new ConfigureNodeExecutor());
+ put("delete", new DeleteNodeExecutor());
+ put("execute", new ExecuteNodeExecutor());
+ put("exists", new ExistsNodeExecutor());
+ put("for", new ForNodeExecutor());
+ put("get-resource", new GetResourceNodeExecutor());
+ put("is-available", new IsAvailableNodeExecutor());
+ put("notify", new NotifyNodeExecutor());
+ put("record", new RecordNodeExecutor());
+ put("release", new ReleaseNodeExecutor());
+ put("reserve", new ReserveNodeExecutor());
+ put("return", new ReturnNodeExecutor());
+ put("save", new SaveNodeExecutor());
+ put("set", new SetNodeExecutor());
+ put("switch", new SwitchNodeExecutor());
+ put("update", new UpdateNodeExecutor());
+ put("break", new BreakNodeExecutor());
+ put("while", new WhileNodeExecutor());
+ put("exit", new ExitNodeExecutor());
+ }
+ };
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicServiceImplBase.class);
+ protected HashMap<String, AbstractSvcLogicNodeExecutor> nodeExecutors = null;
+ protected Properties properties;
+ protected SvcLogicStore store;
+ protected static final String CURRENT_GRAPH="currentGraph";
+
+ public SvcLogicServiceImplBase(SvcLogicStore store, SvcLogicResolver resolver) {
+ this.store = store;
+ this.resolver = resolver;
+ }
+
+ protected void registerExecutors() {
+ for (String nodeType : BUILTIN_NODES.keySet()) {
+ registerExecutor(nodeType, BUILTIN_NODES.get(nodeType));
+ }
+ }
+
+ public void registerExecutor(String nodeName, AbstractSvcLogicNodeExecutor executor) {
+ if (nodeExecutors == null) {
+ nodeExecutors = new HashMap<>();
+ }
+ executor.setResolver(resolver);
+ nodeExecutors.put(nodeName, executor);
+ }
+
+ public void unregisterExecutor(String nodeName) {
+ nodeExecutors.remove(nodeName);
+ }
+
+ public SvcLogicContext execute(SvcLogicGraph graph, SvcLogicContext ctx) throws SvcLogicException {
+ if (nodeExecutors == null) {
+ registerExecutors();
+ }
+
+ MDC.put(CURRENT_GRAPH, graph.toString());
+
+ SvcLogicNode curNode = graph.getRootNode();
+ LOG.info("About to execute graph {}", graph.toString());
+ try {
+ while (curNode != null) {
+ SvcLogicNode nextNode = executeNode(curNode, ctx);
+ curNode = nextNode;
+ }
+ } catch (ExitNodeException e) {
+ LOG.debug("SvcLogicServiceImpl caught ExitNodeException");
+ }
+ MDC.remove("nodeId");
+ MDC.remove(CURRENT_GRAPH);
+
+ return (ctx);
+ }
+
+ public SvcLogicNode executeNode(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+ if (node == null) {
+ return (null);
+ }
+
+ LOG.info("About to execute node #{} {} node in graph {}", node.getNodeId(), node.getNodeType(), node.getGraph().toString());
+
+ AbstractSvcLogicNodeExecutor executor = nodeExecutors.get(node.getNodeType());
+
+ if (executor != null) {
+ MDC.put("nodeId", node.getNodeId() + " (" + node.getNodeType() + ")");
+ return (executor.execute(this, node, ctx));
+ } else {
+ throw new SvcLogicException("Attempted to execute a node of type " + node.getNodeType() + ", but no executor was registered for this type");
+ }
+ }
+
+ @Override
+ public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException {
+ return (store.hasGraph(module, rpc, version, mode));
+ }
+
+ @Override
+ public Properties execute(String module, String rpc, String version, String mode, Properties props)
+ throws SvcLogicException {
+
+ SvcLogicContext ctx = new SvcLogicContext(props);
+
+ return(execute(module, rpc, version, mode, ctx).toProperties());
+ }
+
+ @Override
+ public SvcLogicContext execute(String module, String rpc, String version, String mode, SvcLogicContext ctx) throws SvcLogicException {
+ SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
+
+ if (ctx == null) {
+ ctx = new SvcLogicContext();
+ }
+
+ if (graph == null) {
+ ctx.setAttribute("error-code", "401");
+ ctx.setAttribute("error-message",
+ "No service logic found for [" + module + "," + rpc + "," + version + "," + mode + "]");
+ return (ctx);
+ }
+
+
+
+ ctx.setAttribute(CURRENT_GRAPH, graph.toString());
+ // To support legacy code we should not stop populating X-ECOMP-RequestID
+ ctx.setAttribute("X-ECOMP-RequestID", MDC.get(ONAPLogConstants.MDCs.REQUEST_ID));
+ execute(graph, ctx);
+ return (ctx);
+ }
+
+ @Override
+ public SvcLogicStore getStore() throws SvcLogicException {
+ return this.store;
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java
new file mode 100644
index 000000000..2186a38e0
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SwitchNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SwitchNodeExecutor.class);
+
+ @Override
+
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+
+ String testResult = evaluateNodeTest(node, ctx);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Executing switch node");
+
+
+ LOG.debug("test expression (" + node.getAttribute("test")
+ + ") evaluates to " + testResult);
+ }
+
+ SvcLogicNode nextNode = node.getOutcomeValue(testResult);
+
+ if (LOG.isDebugEnabled()) {
+ if (nextNode != null) {
+ LOG.debug("Next node to execute is node " + nextNode.getNodeId());
+ } else {
+ LOG.debug("No next node found");
+ }
+ }
+ return (nextNode);
+
+ }
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java
new file mode 100644
index 000000000..c22c573cd
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UpdateNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UpdateNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx);
+ String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx);
+ String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx);
+ String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx);
+
+
+ Map<String, String> parmMap = getResolvedParameters(node,ctx);
+
+ String outValue = SvcLogicConstants.FAILURE;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("save node encountered - looking for resource class " + plugin);
+ }
+
+
+ SvcLogicResource resourcePlugin = getSvcLogicResource(plugin);
+
+
+ if (resourcePlugin != null) {
+
+ try {
+ switch (resourcePlugin.update(resourceType, key, parmMap, pfx, ctx)) {
+ case SUCCESS:
+ outValue = SvcLogicConstants.SUCCESS;
+ break;
+ case NOT_FOUND:
+ outValue = "not-found";
+ break;
+ case FAILURE:
+ default:
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from resource plugin", e);
+ outValue = SvcLogicConstants.FAILURE;
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin " + plugin);
+ }
+ return (getNextNode(node, outValue));
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java
new file mode 100644
index 000000000..3078b3437
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import org.onap.ccsdk.sli.core.sli.BreakNodeException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WhileNodeExecutor extends AbstractSvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WhileNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException {
+
+ String testResult = evaluateNodeTest(node, ctx);
+ SvcLogicExpression silentFailureExpr = node.getAttribute("do");
+ String doWhile = SvcLogicExpressionResolver.evaluate(silentFailureExpr, node, ctx);
+ if ("true".equals(doWhile)) {
+ LOG.debug("While loop will execute once regardless of expression because do is set to true");
+ }
+
+ try {
+ while ("true".equals(testResult) || "true".equals(doWhile)) {
+ if (!"true".equals(doWhile)) {
+ LOG.debug("Test expression (" + node.getAttribute("test") + ") evaluates to true, executing loop.");
+ }
+ int numOutcomes = node.getNumOutcomes() + 1;
+ for (int i = 0; i < numOutcomes; i++) {
+ SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1));
+ if (nextNode != null) {
+ while (nextNode != null) {
+ nextNode = svc.executeNode(nextNode, ctx);
+ }
+ } else {
+ if ("true".equals(doWhile)) {
+ LOG.debug("Do executed, will only execute again if test expression is true.");
+ doWhile = "false";
+ }
+ testResult = evaluateNodeTest(node, ctx);
+ LOG.debug("test expression (" + node.getAttribute("test") + ") evaluates to " + testResult);
+ }
+ }
+ }
+ LOG.debug("testResult was " + testResult + " which is not equal to true, exiting while loop.");
+ } catch (BreakNodeException e) {
+ LOG.debug("WhileNodeExecutor caught break" + e.getMessage());
+ }
+ return (null);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java
new file mode 100644
index 000000000..7d690e745
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java
@@ -0,0 +1,113 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.recording;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.onap.ccsdk.sli.core.sli.ConfigurationException;
+import org.onap.ccsdk.sli.core.utils.PathValidator;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+
+
+public class FileRecorder implements SvcLogicRecorder {
+
+ @Override
+ public void record(Map<String, String> parmMap) throws SvcLogicException {
+
+ String fileName = parmMap.get("file");
+ if (fileName == null)
+ {
+ throw new ConfigurationException("No file parameter specified");
+ }
+
+ if (!PathValidator.isValidFilePath(fileName)) {
+ throw new ConfigurationException("Invalid file name ("+fileName+")");
+ }
+
+ String record = parmMap.get("record");
+ if (record == null)
+ {
+ String delimiter = parmMap.get("delimiter");
+ if (delimiter == null)
+ {
+ delimiter = "|";
+ }
+
+ int idx = 1;
+ boolean moreFields = true;
+ while (moreFields)
+ {
+ String curField = parmMap.get("field"+idx++);
+ if (curField == null)
+ {
+ moreFields = false;
+ }
+ else
+ {
+ if (record == null)
+ {
+ record = delimiter;
+ }
+ record = record + curField + delimiter;
+ }
+ }
+ }
+
+ if (record == null)
+ {
+ throw new ConfigurationException("No record/fields passed in record node");
+ }
+
+ File recordFile = new File(fileName);
+ Date now = new Date();
+
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat dateFmt = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss:SS'+00:00'");
+ dateFmt.setTimeZone(tz);
+ if (record.indexOf("__TIMESTAMP__") != -1)
+ {
+ record = record.replaceFirst("__TIMESTAMP__", dateFmt.format(now));
+ }
+
+ try ( FileWriter fileWriter = new FileWriter(recordFile, true);
+ PrintWriter recPrinter = new PrintWriter(fileWriter))
+ {
+ recPrinter.println(record);
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Cannot write record to file", e);
+ }
+ }
+
+}
+
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java
new file mode 100644
index 000000000..4f67c5d9a
--- /dev/null
+++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java
@@ -0,0 +1,160 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.recording;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.onap.ccsdk.sli.core.sli.ConfigurationException;
+import org.onap.ccsdk.sli.core.sli.ErrorLogger;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Slf4jRecorder implements SvcLogicRecorder {
+ protected DateFormat dateFmt;
+ protected static final String messageLogName = "message-log";
+
+ public enum Level {
+ ERROR,
+ WARN,
+ INFO,
+ DEBUG,
+ TRACE
+ }
+
+ protected Logger defaultLogger = LoggerFactory.getLogger(Slf4jRecorder.class);
+ protected Logger messageLogger = LoggerFactory.getLogger(messageLogName);
+
+ public Slf4jRecorder() {
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ dateFmt = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss:SS'+00:00'");
+ dateFmt.setTimeZone(tz);
+ }
+
+ @Override
+ public void record(Map<String, String> parmMap) throws SvcLogicException {
+ String lvl = parmMap.get("level");
+ if (lvl == null) {
+ lvl = "INFO";
+ }
+
+ Level level = Level.INFO;
+
+ try {
+ level = Level.valueOf(lvl.toUpperCase());
+ } catch (Exception e) {}
+
+
+
+ String record = parmMap.get("record");
+ if (record == null)
+ {
+ String delimiter = parmMap.get("delimiter");
+ if (delimiter == null)
+ {
+ delimiter = "|";
+ }
+
+ int idx = 1;
+ boolean moreFields = true;
+ while (moreFields)
+ {
+ String curField = parmMap.get("field"+idx++);
+ if (curField == null)
+ {
+ moreFields = false;
+ }
+ else
+ {
+ if (record == null)
+ {
+ record = delimiter;
+ }
+ record = record + curField + delimiter;
+ }
+ }
+ }
+
+ if (record == null)
+ {
+ throw new ConfigurationException("No record/fields passed in record node");
+ }
+
+ String loggerName = parmMap.get("logger");
+ Logger logger = null;
+ if (loggerName == null) {
+ logger = defaultLogger;
+ }else {
+ if(loggerName.equals(messageLogName)){
+ logger = messageLogger;
+ }else {
+ logger = LoggerFactory.getLogger(loggerName);
+ }
+ }
+
+ Date now = new Date();
+
+ if (record.indexOf("__TIMESTAMP__") != -1)
+ {
+ record = record.replaceFirst("__TIMESTAMP__", dateFmt.format(now));
+ }
+
+ switch (level) {
+ case ERROR:
+ String errorCode = parmMap.get("errorCode");
+ String errorDescription = parmMap.get("errorDescription");
+
+ if ((errorCode != null && !errorCode.isEmpty())
+ || (errorDescription != null && !errorDescription.isEmpty())) {
+ ErrorLogger e = new ErrorLogger(logger);
+
+ Integer integerCode = 0;
+ try {
+ integerCode = Integer.valueOf(errorCode);
+ } catch (NumberFormatException nfe) {
+ // do nothing
+ }
+ e.createLogEntry(record, integerCode, errorDescription, null);
+ } else {
+ logger.error(record);
+ }
+ break;
+ case WARN:
+ logger.warn(record);
+ break;
+ case INFO:
+ logger.info(record);
+ break;
+ case DEBUG:
+ logger.debug(record);
+ break;
+ case TRACE:
+ logger.trace(record);
+ }
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java
new file mode 100644
index 000000000..6c5877ebc
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+
+
+public class BadPlugin implements SvcLogicJavaPlugin {
+ public String selectLunch(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ String day = parameters.get("day");
+ if (day == null || day.length() < 1) {
+ throw new SvcLogicException("What day is it?");
+ }
+ switch (day) {
+ case ("monday"): {
+ return "pizza";
+ }
+ case ("tuesday"): {
+ return "soup";
+ }
+ case ("wednesday"): {
+ return "salad";
+ }
+ case ("thursday"): {
+ return "sushi";
+ }
+ case ("friday"): {
+ return "bbq";
+ }
+ }
+ throw new SvcLogicException("Lunch cannot be served");
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java
new file mode 100644
index 000000000..9a929387f
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.Properties;
+import org.onap.ccsdk.sli.core.sli.DuplicateValueException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import junit.framework.TestCase;
+
+public class ExecuteNodeExecutorTest extends TestCase {
+ public class MockExecuteNodeExecutor extends ExecuteNodeExecutor {
+
+ protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) {
+ return (SvcLogicJavaPlugin) new LunchSelectorPlugin();
+ }
+
+ protected String evaluate(SvcLogicExpression expr, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+ return "selectLunch";
+ }
+ }
+
+ public void testBadPlugin() throws DuplicateValueException, SvcLogicException {
+ LunchSelectorPlugin p = new LunchSelectorPlugin();
+ MockExecuteNodeExecutor execute = new MockExecuteNodeExecutor();
+ SvcLogicNode node = new SvcLogicNode(0, "", "", new SvcLogicGraph());
+ node.setAttribute("method", "selectLunch");
+ SvcLogicPropertiesProvider resourceProvider = new SvcLogicPropertiesProvider() {
+
+ public Properties getProperties() {
+ return new Properties();
+ };
+ };
+
+
+ execute.execute(new SvcLogicServiceImplBase(null, null), new SvcLogicNode(0, "", "", new SvcLogicGraph()),
+ new SvcLogicContext());
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java
new file mode 100644
index 000000000..3534d5f90
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java
@@ -0,0 +1,61 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicParser;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GraphTests {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GraphTests.class);
+ private static final SvcLogicStore store = new InMemorySvcLogicStore();
+ private static final HashMapResolver resolver = new HashMapResolver();
+ private static final SvcLogicServiceBase svc = new SvcLogicServiceImplBase(store, resolver);
+ private static final SvcLogicParser p = new SvcLogicParser();
+ // Write a very simple recorder so record nodes can be used during debugging
+ private static final SvcLogicRecorder recorder = new SvcLogicRecorder() {
+ @Override
+ public void record(Map<String, String> map) throws SvcLogicException {
+ map.remove("level");
+ for (Entry<String, String> entry : map.entrySet()) {
+ LOG.debug(entry.getKey() + " = " + entry.getValue());
+ }
+ }
+ };
+
+ @Test
+ public void testBreakNode() throws Exception {
+ // This graph as a for node that will loop with start 0 and end 999
+ // in the loop idx is printed and variable "a" is incremented by 1
+ // there is an if block in the loop that when a equals 2 a break node should execute and break out of the for
+ // loop
+ SvcLogicContext ctx = executeGraph("src/test/resources/breakGraph.xml");
+ assertTrue(ctx.isSuccess());
+ assertEquals("2", ctx.getAttribute("idx")); // the break should happen when idx equals 2
+ assertEquals("3", ctx.getAttribute("a")); // incrementing a happens before the break so a should be idx + 1
+ }
+
+ public SvcLogicContext executeGraph(String pathToGraph) throws SvcLogicException {
+ return executeGraph(pathToGraph, new SvcLogicContext());
+ }
+
+ public SvcLogicContext executeGraph(String pathToGraph, SvcLogicContext context) throws SvcLogicException {
+ resolver.addSvcLogicRecorder("org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder", recorder);
+ LinkedList<SvcLogicGraph> graphList = p.parse(pathToGraph);
+ SvcLogicGraph graph = graphList.get(0);
+ store.store(graph);
+ store.activate(graph);
+ return svc.execute(graph, context);
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java
new file mode 100644
index 000000000..5a2140696
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java
@@ -0,0 +1,51 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertNotNull;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+
+public class HashMapResolverTest {
+ @Mock
+ SvcLogicResource myResource;
+
+ @Mock
+ SvcLogicRecorder myRecorder;
+
+ @Mock
+ SvcLogicJavaPlugin myJavaPlugin;
+
+ @Mock
+ SvcLogicAdaptor myAdaptor;
+
+ @Rule
+ public MockitoRule mockitoRule = MockitoJUnit.rule();
+
+ @Test
+ public void simpleTest() throws Exception {
+
+ HashMapResolver resolver = new HashMapResolver();
+ String resourceKey = "simple.resource";
+ String recorderKey = "simple.record";
+ String pluginKey = "simple.plugin";
+ String adaptorKey = "simple.adaptor";
+
+ resolver.addSvcLogicAdaptor(adaptorKey, myAdaptor);
+ resolver.addSvcLogicRecorder(recorderKey, myRecorder);
+ resolver.addSvcLogicResource(resourceKey, myResource);
+ resolver.addSvcLogicSvcLogicJavaPlugin(pluginKey, myJavaPlugin);
+
+ assertNotNull(resolver.getSvcLogicAdaptor(adaptorKey));
+ assertNotNull(resolver.getSvcLogicJavaPlugin(pluginKey));
+ assertNotNull(resolver.getSvcLogicRecorder(recorderKey));
+ assertNotNull(resolver.getSvcLogicResource(resourceKey));
+
+
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java
new file mode 100644
index 000000000..5f8757aa2
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java
@@ -0,0 +1,35 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import java.util.Properties;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+
+public class InMemorySvcLogicStoreTest {
+ @Test
+ public void simpleTest() throws Exception {
+ InMemorySvcLogicStore store = new InMemorySvcLogicStore();
+ store.init(new Properties());
+ SvcLogicGraph graph = new SvcLogicGraph();
+ String module = "TEST";
+ String rpc = "NOTIFICATION";
+ String mode = "sync";
+ String version = "1";
+
+ graph.setModule(module);
+ graph.setRpc(rpc);
+ graph.setMode(mode);
+ graph.setVersion(version);
+
+ store.store(graph);
+ assertTrue(store.hasGraph(module, rpc, version, mode));
+ assertNotNull(store.fetch(module, rpc, version, mode));
+ store.activate(graph);
+ store.activate(module, rpc, version, mode);
+
+ store.delete(module, rpc, version, mode);
+ assertNull(store.fetch(module, rpc, version, mode));
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java
new file mode 100644
index 000000000..0f4cab748
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.util.Map;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+
+
+
+public class LunchSelectorPlugin implements SvcLogicJavaPlugin {
+ public class UnknownLunchDayException extends Exception{
+
+ public UnknownLunchDayException(String string) {
+ super(string);
+ }
+
+ }
+ class Sandwhich {
+ String meat;
+ String cheese;
+
+ public Sandwhich(String meat, String cheese) {
+ this.meat = meat;
+ this.cheese = cheese;
+ }
+ }
+
+ public String selectLunch(Map<String, String> parameters, SvcLogicContext ctx) throws Exception {
+ String day = parameters.get("day");
+ if (day == null || day.length() < 1) {
+ throw new UnknownLunchDayException("What day is it?");
+ }
+ switch (day) {
+ case ("monday"): {
+ return "pizza";
+ }
+ case ("tuesday"): {
+ return "soup";
+ }
+ case ("wednesday"): {
+ return "salad";
+ }
+ case ("thursday"): {
+ return "sushi";
+ }
+ case ("friday"): {
+ return "bbq";
+ }
+ }
+ throw new SvcLogicException("Lunch cannot be served");
+ }
+
+ public Sandwhich makeLunch(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ return new Sandwhich("ham", "american");
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java
new file mode 100644
index 000000000..b154ecf01
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java
@@ -0,0 +1,113 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicConstants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.provider.base.ExecuteNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicExpressionResolver;
+
+import junit.framework.TestCase;
+
+public class PluginTest extends TestCase {
+
+ // The existing plugins work just like a VoidDummyPlugin
+ // They will return null simply because they are all void
+ // The attribute emitsOutcome will not be present, the expected outcome is success when no exception is thrown by the plugin
+ public void testOldPlugin() throws Exception {
+ ExecuteNodeExecutor executor = new ExecuteNodeExecutor();
+ SvcLogicJavaPlugin plugin = new SvcLogicJavaPlugin() {
+ public void dummy(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ return;
+ }
+ };
+
+ Class pluginClass = plugin.getClass();
+ Method pluginMethod = pluginClass.getMethod("dummy", Map.class, SvcLogicContext.class);
+ Map<String, String> parmMap = new HashMap<String, String>();
+ SvcLogicContext ctx = new SvcLogicContext();
+ Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+
+ SvcLogicGraph graph = new SvcLogicGraph();
+ SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+ String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx);
+ String outValue = executor.mapOutcome(o, emitsOutcome);
+ assertEquals(SvcLogicConstants.SUCCESS,outValue);
+ }
+
+ //Newer plugins can set the attribute emitsOutcome to true, if so they should return a string
+ //The string represents the outcome value
+ public void testNewPlugin() throws Exception {
+ ExecuteNodeExecutor executor = new ExecuteNodeExecutor();
+ SvcLogicJavaPlugin plugin = new LunchSelectorPlugin();
+
+ Class pluginClass = plugin.getClass();
+ Method pluginMethod = pluginClass.getMethod("selectLunch", Map.class, SvcLogicContext.class);
+
+ Map<String, String> parmMap = new HashMap<String, String>();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ parmMap.put("day", "monday");
+ Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+ SvcLogicGraph graph = new SvcLogicGraph();
+ SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+ node.setAttribute("emitsOutcome", "true");
+ String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx);
+ String outValue = executor.mapOutcome(o, emitsOutcome);
+ assertEquals("pizza", outValue);
+
+ parmMap.put("day", "tuesday");
+ outValue = (String) pluginMethod.invoke(plugin, parmMap, ctx);
+ o = pluginMethod.invoke(plugin, parmMap, ctx);
+ outValue = executor.mapOutcome(o, emitsOutcome);
+ assertEquals("soup",outValue);
+
+ }
+
+ //APPC had some legacy plugins returning objects which should not be treated as outcomes
+ //The attribute emitsOutcome will not be set
+ //The outcome should be success as it has always been
+ public void testObjPlugin() throws Exception{
+ ExecuteNodeExecutor executor = new ExecuteNodeExecutor();
+ SvcLogicJavaPlugin plugin = new LunchSelectorPlugin();
+
+ Class pluginClass = plugin.getClass();
+ Method pluginMethod = pluginClass.getMethod("makeLunch", Map.class, SvcLogicContext.class);
+
+ Map<String, String> parmMap = new HashMap<String, String>();
+ SvcLogicContext ctx = new SvcLogicContext();
+ Object o = pluginMethod.invoke(plugin, parmMap, ctx);
+ SvcLogicGraph graph = new SvcLogicGraph();
+ SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+ String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx);
+ String outValue = executor.mapOutcome(o, emitsOutcome);
+ assertEquals(SvcLogicConstants.SUCCESS,outValue);
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java
new file mode 100644
index 000000000..115989a80
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java
@@ -0,0 +1,220 @@
+package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import java.util.LinkedList;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.SvcLogicParser;
+import org.onap.ccsdk.sli.core.sli.provider.base.SetNodeExecutor;
+
+public class SetNodeExecutorTest {
+ @Test
+ public void clearProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertNull(ctx.getAttribute("si.field1"));
+ assertNull(ctx.getAttribute("si.field2"));
+ assertNull(ctx.getAttribute("si.field3"));
+ assertNull(ctx.getAttribute("si.subarray[0]"));
+ assertNull(ctx.getAttribute("si.subarray[1]"));
+ assertNull(ctx.getAttribute("si.subarray[2]"));
+ assertNull(ctx.getAttribute("si.subarray_length"));
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+ @Test
+ public void clearMultipleArrayProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearMultipleArrayValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertNull(ctx.getAttribute("si[0].field1"));
+ assertNull(ctx.getAttribute("si[1].field2"));
+ assertNull(ctx.getAttribute("si[2].field3"));
+ assertNull(ctx.getAttribute("si_length"));
+ assertNull(ctx.getAttribute("si[0].subarray[0]"));
+ assertNull(ctx.getAttribute("si[0].subarray[1]"));
+ assertNull(ctx.getAttribute("si[0].subarray[2]"));
+ assertNull(ctx.getAttribute("si[0].subarray_length"));
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+ @Test
+ public void clearSingleArrayProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearSingleArrayValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertNull(ctx.getAttribute("si[0].field1"));
+ assertNull(ctx.getAttribute("si[0].subarray[0]"));
+ assertNull(ctx.getAttribute("si[0].subarray[1]"));
+ assertNull(ctx.getAttribute("si[0].subarray[2]"));
+ assertNull(ctx.getAttribute("si[0].subarray_length"));
+
+ // TODO: This is just setting up elements as null but note reducing the size of Array.
+ assertEquals("3",ctx.getAttribute("si_length"));
+
+ assertEquals("2",ctx.getAttribute("si[1].field2"));
+ assertEquals("3", ctx.getAttribute("si[2].field3"));
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+ @Test
+ public void clearSingleSubArrayProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearSingleSubArrayValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertEquals("1",ctx.getAttribute("tmp.si[0].field1"));
+ assertEquals("2",ctx.getAttribute("tmp.si[1].field2"));
+ assertEquals("3", ctx.getAttribute("tmp.si[2].field3"));
+ assertEquals("3", ctx.getAttribute("tmp.si_length"));
+
+ assertEquals("a",ctx.getAttribute("tmp.si[0].subarray[0]"));
+
+ // TODO: This is setting up element as Empty instead null
+ //assertNull(ctx.getAttribute("tmp.si[0].subarray[1]"));
+ assertEquals("", ctx.getAttribute("tmp.si[0].subarray[1]"));
+
+ assertEquals("c", ctx.getAttribute("tmp.si[0].subarray[2]"));
+ assertEquals("3", ctx.getAttribute("tmp.si[0].subarray_length"));
+
+ assertEquals("x",ctx.getAttribute("tmp.si[1].subarray[0]"));
+ assertEquals("y",ctx.getAttribute("tmp.si[1].subarray[1]"));
+ assertEquals("z", ctx.getAttribute("tmp.si[1].subarray[2]"));
+ assertEquals("3", ctx.getAttribute("tmp.si[1].subarray_length"));
+
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+ @Test
+ public void clearSubArrayProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearSubArrayValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertEquals("1", ctx.getAttribute("si[0].field1"));
+ assertEquals("2",ctx.getAttribute("si[1].field2"));
+ assertEquals("3", ctx.getAttribute("si[2].field3"));
+ assertEquals("3", ctx.getAttribute("si_length"));
+ assertNull(ctx.getAttribute("si[0].subarray[0]"));
+ assertNull(ctx.getAttribute("si[0].subarray[1]"));
+ assertNull(ctx.getAttribute("si[0].subarray[2]"));
+ assertNull(ctx.getAttribute("si[0].subarray_length"));
+
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+ @Test
+ public void arrayPattern() {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ String source = "one.two[0].three[0].four";
+ assertEquals("one.two.three.four", source.replaceAll(sne.arrayPattern, ""));
+ }
+
+ @Test
+ public void subtreeCopy() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/copyValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertEquals("1", ctx.getAttribute("si.field1"));
+ assertEquals("2", ctx.getAttribute("si.field2"));
+ assertEquals("3", ctx.getAttribute("si.field3"));
+ assertEquals("1", ctx.getAttribute("rootTwo.field1"));
+ assertEquals("2", ctx.getAttribute("rootTwo.field2"));
+ assertEquals("3", ctx.getAttribute("rootTwo.field3"));
+ }
+
+ @Test
+ public void clearNestedSubArrayProperties() throws Exception {
+ SetNodeExecutor sne = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearNestedSubArrayValues.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+ SvcLogicNode nodeOne = root.getOutcomeValue("1");
+ SvcLogicNode nodeTwo = root.getOutcomeValue("2");
+
+ sne.execute(nodeOne, ctx);
+ sne.execute(nodeTwo, ctx);
+
+ assertEquals("1", ctx.getAttribute("tmp.si[0].field1"));
+ assertEquals("2",ctx.getAttribute("tmp.si[1].field2"));
+ assertEquals("3", ctx.getAttribute("tmp.si[2].field3"));
+ assertEquals("3", ctx.getAttribute("tmp.si_length"));
+
+ assertNull(ctx.getAttribute("tmp.si[0].subarray[0]"));
+ assertNull(ctx.getAttribute("tmp.si[0].subarray[1]"));
+ assertNull(ctx.getAttribute("tmp.si[0].subarray[2]"));
+ assertNull(ctx.getAttribute("tmp.si[0].subarray_length"));
+
+ assertEquals("x", ctx.getAttribute("tmp.si[1].subarray[0]"));
+ assertEquals("y",ctx.getAttribute("tmp.si[1].subarray[1]"));
+ assertEquals("z", ctx.getAttribute("tmp.si[1].subarray[2]"));
+ assertEquals("3", ctx.getAttribute("tmp.si[1].subarray_length"));
+
+ assertEquals("6", ctx.getAttribute("search1"));
+ assertEquals("KeepMe!", ctx.getAttribute("simonSays"));
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java
new file mode 100644
index 000000000..054b38d0f
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java
@@ -0,0 +1,280 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider.base;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExprListener;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpression;
+import org.onap.ccsdk.sli.core.sli.SvcLogicExpressionFactory;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicNode;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicExpressionResolver;
+import org.onap.ccsdk.sli.core.sli.SvcLogicParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class SvcLogicExpressionResolverTest extends TestCase {
+
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExpressionResolver.class);
+
+ public void testEvaluate()
+ {
+ InputStream testStr = getClass().getResourceAsStream("/expression.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+
+ try
+ {
+ SvcLogicContext ctx = new SvcLogicContext();
+ SvcLogicGraph graph = new SvcLogicGraph();
+ SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+ graph.setRootNode(node);
+
+ String line = null;
+ int lineNo = 0;
+ while ((line = testsReader.readLine()) != null) {
+ ++lineNo;
+ if (line.startsWith("#"))
+ {
+ String testExpr = line.trim().substring(1).trim();
+ String[] nameValue = testExpr.split("=");
+ String name = nameValue[0].trim();
+ String value = nameValue[1].trim();
+
+ if (name.startsWith("$"))
+ {
+ LOG.info("Setting context attribute "+name+" = "+value);
+ ctx.setAttribute(name.substring(1), value);
+ }
+ else
+ {
+
+ LOG.info("Setting node attribute "+name+" = "+value);
+ node.setAttribute(name, value);
+
+ }
+ }
+ else
+ {
+ // if the line contains #, what comes before is the expression to evaluate, and what comes after
+ // is the expected value
+ String[] substrings = line.split("#");
+ String expectedValue = substrings.length > 1 ? substrings[1].trim() : null;
+ String testExpr = substrings[0].trim();
+
+ LOG.info("Parsing expression "+testExpr);
+ SvcLogicExpression expr = SvcLogicExpressionFactory.parse(testExpr);
+ if (expr == null)
+ {
+ fail("Unable to parse expression "+testExpr);
+ }
+ else
+ {
+ LOG.info("Evaluating parsed expression "+expr.asParsedExpr());
+ String exprValue = SvcLogicExpressionResolver.evaluate(expr, node, ctx);
+ if (exprValue == null)
+ {
+ fail("Unable to evaluate expression "+testExpr);
+ }
+ else
+ {
+ LOG.info("Expression " + testExpr + " evaluates to " + exprValue);
+ if (expectedValue != null) {
+ Assert.assertEquals("Line " + lineNo + ": " + testExpr, expectedValue, exprValue);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ LOG.error("Caught exception", e);
+ fail("Caught exception");
+ }
+ }
+
+ public void testSvcLogicExpressions() throws Exception {
+ SwitchNodeExecutor switchNodeExecutor = new SwitchNodeExecutor();
+ SetNodeExecutor setNodeExecutor = new SetNodeExecutor();
+ SvcLogicContext ctx = new SvcLogicContext();
+ SvcLogicParser slp = new SvcLogicParser();
+ LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/expressions.xml");
+ SvcLogicNode root = graph.getFirst().getRootNode();
+//Test a set node that makes use of arithmetic operations
+/*
+<set>
+ <parameter name='add' value='`1 + 1`' />
+ <parameter name='sub' value='`2 - 1`' />
+ <parameter name='div' value='`6 / 2`' />
+ <parameter name='multi' value='`2 * 2`' />
+ <parameter name='addDoubleQuotes' value="`1 + 1`" />
+ <parameter name='subDoubleQuotes' value="`2 - 1`" />
+ <parameter name='divDoubleQuotes' value="`6 / 2`" />
+ <parameter name='multiDoubleQuotes' value="`2 * 2`" />
+</set>
+*/
+//the node matching outcome value 1 comes from parsing the block of xml above
+ ctx.setAttribute("a", "5");
+ ctx.setAttribute("b", "3");
+ setNodeExecutor.execute(root.getOutcomeValue("1"), ctx);
+ assertEquals("2", ctx.getAttribute("add"));
+ assertEquals("1", ctx.getAttribute("sub"));
+ assertEquals("3", ctx.getAttribute("div"));
+ assertEquals("4", ctx.getAttribute("multi"));
+ assertEquals("2", ctx.getAttribute("addDoubleQuotes"));
+ assertEquals("1", ctx.getAttribute("subDoubleQuotes"));
+ assertEquals("3", ctx.getAttribute("divDoubleQuotes"));
+ assertEquals("4", ctx.getAttribute("multiDoubleQuotes"));
+
+//Test a set node that makes use of string concatenation
+/*
+<set>
+ <parameter name='varA' value='`$a + $b`' />
+ <parameter name='varB' value='`$a + &apos;literal&apos; `' />
+ <parameter name='varC' value='`&apos;literal&apos; + $b `' />
+ <parameter name='varD' value='`&apos;too&apos; + &apos;literal&apos;`' />
+ <parameter name='varADoubleQuotes' value="`$a + $b`" />
+ <parameter name='varBDoubleQuotes' value="`$a +'literal' `" />
+ <parameter name='varCDoubleQuotes' value="`'literal' + $b `" />
+ <parameter name='varDDoubleQuotes' value="`'too' + 'literal'`" />
+</set>
+*/
+//the node matching outcome value 2 comes from parsing the block of xml above
+ ctx.setAttribute("a", "cat");
+ ctx.setAttribute("b", "dog");
+ setNodeExecutor.execute(root.getOutcomeValue("2"), ctx);
+ assertEquals("catdog", ctx.getAttribute("varA"));
+ assertEquals("catliteral", ctx.getAttribute("varB"));
+ assertEquals("literaldog", ctx.getAttribute("varC"));
+ assertEquals("tooliteral", ctx.getAttribute("varD"));
+ assertEquals("catdog", ctx.getAttribute("varADoubleQuotes"));
+ assertEquals("catliteral", ctx.getAttribute("varBDoubleQuotes"));
+ assertEquals("literaldog", ctx.getAttribute("varCDoubleQuotes"));
+ assertEquals("tooliteral", ctx.getAttribute("varDDoubleQuotes"));
+
+//Shows how backticks interact with + operator
+/*
+<set>
+ <parameter name='testOne' value='`1 + 1`' />
+ <parameter name='testThree' value='"1" +"1"' />
+ <parameter name='testFour' value='`$portNumber + $slot + $shelf`' />
+ <parameter name='testOneDoubleQuotes' value="`1 + 1`" />
+ <parameter name='testThreeDoubleQuotes' value="'1' +'1'" />
+ <parameter name='testFourDoubleQuotes' value="`$portNumber + $slot + $shelf`" />
+</set>
+*/
+//the node matching outcome value 3 comes from parsing the block of xml above
+ ctx.setAttribute("portNumber", "2");
+ ctx.setAttribute("slot", "3");
+ ctx.setAttribute("shelf", "1");
+
+ setNodeExecutor.execute(root.getOutcomeValue("3"), ctx);
+ assertEquals("2", ctx.getAttribute("testOne"));
+ assertEquals("\"1\" +\"1\"", ctx.getAttribute("testThree"));
+ assertEquals("6", ctx.getAttribute("testFour"));
+ assertEquals("2", ctx.getAttribute("testOneDoubleQuotes"));
+ assertEquals("'1' +'1'", ctx.getAttribute("testThreeDoubleQuotes"));
+ assertEquals("6", ctx.getAttribute("testFourDoubleQuotes"));
+
+ ctx.setAttribute("a", "5");
+ ctx.setAttribute("b", "3");
+
+ // series of switch statements showing and or != > < >= == <=
+ // the XML for the node is commented above the line that evaluates that node, the switch statements are single line
+
+ //<switch test="`'PIZZA' == 'NOTPIZZA' or $a != $b`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("4"), ctx));
+
+ //<switch test="`'PIZZA' == 'PIZZA' and $a != $b`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("5"), ctx));
+
+ //<switch test="`'PIZZA' == 'NOTPIZZA' or $a &gt;= $b`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("6"), ctx));
+
+ //<switch test="`'PIZZA' == 'PIZZA' and $b &lt; $a`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("7"), ctx));
+
+ //<switch test="`'PIZZA' == 'PIZZA'`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("8"), ctx));
+
+ //<switch test="`$a == $b`" />
+ assertEquals("false",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("9"), ctx));
+
+ //<switch test="`'PIZZA' == 'NOTPIZZA'`" />
+ assertEquals("false",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("10"), ctx));
+
+ //<switch test="`'PIZZA' != 'PIZZA'`" />
+ assertEquals("false",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("11"), ctx));
+
+ //<switch test="`'PIZZA' != 'NOTPIZZA'`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("12"), ctx));
+
+ //<switch test='`$a != $b`' />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("13"), ctx));
+
+ //<switch test='`1 &lt; 2`' />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("14"), ctx));
+
+ //<switch test='`2 &lt;= 2`' />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("15"), ctx));
+
+ //<switch test='`3 &gt; 2`' />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("16"), ctx));
+
+ //<switch test='`2 &gt;= 2`' />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("17"), ctx));
+
+ // Series of switch statements that show the effect of using backticks
+
+ ctx.setAttribute("literalStartingWithDollarSign", "DONT READ ME!");
+ //<switch test='$literalStartingWithDollarSign'/>
+ assertEquals("$literalStartingWithDollarSign",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("18"), ctx));
+
+ ctx.setAttribute("dollarSignFollowedByVariableSurroundedinBackticks", "README");
+ //<switch test='$literalStartingWithDollarSign'/>
+ assertEquals("README",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("19"), ctx));
+
+ ctx.setAttribute("a", "2");
+ ctx.setAttribute("b", "2");
+ //<switch test='`$a == $b`' />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("20"), ctx));
+
+ //<switch test="`$a == $b`" />
+ assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("21"), ctx));
+
+ //<switch test='$a == $b' />
+ assertEquals("$a == $b",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("22"), ctx));
+
+ //<switch test="$a == $b" />
+ assertEquals("$a == $b",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("23"), ctx));
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java
new file mode 100644
index 000000000..d0cc83182
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java
@@ -0,0 +1,49 @@
+/**
+ *
+ */
+package org.onap.ccsdk.sli.core.sli.recording;
+
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * @author dt5972
+ *
+ */
+public class TestFileRecorder {
+ private FileRecorder recorder;
+
+ @Before
+ public void setUp() {
+ recorder = new FileRecorder();
+ }
+
+ /**
+ * Test method for
+ * {@link org.onap.ccsdk.sli.core.sli.recording.FileRecorder#record(java.util.Map)}.
+ */
+ @Test
+ public void testRecord() {
+ HashMap<String, String> parms = new HashMap<>();
+ parms.put("file", "/dev/null");
+ parms.put("field1", "hi");
+ try {
+ recorder.record(parms);
+ } catch (SvcLogicException e) {
+ fail("Caught SvcLogicException : " + e.getMessage());
+ }
+ }
+
+ @Test(expected = Exception.class)
+ public void testRecordForEmptyFileName() throws Exception {
+ HashMap<String, String> parms = new HashMap<>();
+ parms.put("field1", "hi");
+ recorder.record(parms);
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java
new file mode 100644
index 000000000..c696f25b5
--- /dev/null
+++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java
@@ -0,0 +1,33 @@
+/**
+ *
+ */
+package org.onap.ccsdk.sli.core.sli.recording;
+
+import static org.junit.Assert.*;
+import java.util.HashMap;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * @author dt5972
+ *
+ */
+public class TestSlf4jRecorder {
+
+ /**
+ * Test method for {@link org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder#record(java.util.Map)}.
+ */
+ @Test
+ public void testRecord() {
+ Slf4jRecorder recorder = new Slf4jRecorder();
+
+ HashMap<String,String> parms = new HashMap<>();
+ parms.put("field1","hi");
+ try {
+ recorder.record(parms);
+ } catch (SvcLogicException e) {
+ fail("Caught SvcLogicException : "+e.getMessage());
+ }
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/resources/breakGraph.xml b/core/sli/provider-base/src/test/resources/breakGraph.xml
new file mode 100644
index 000000000..e2b89e84f
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/breakGraph.xml
@@ -0,0 +1,26 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='JUNIT' version='1'>
+ <method rpc='BREAK' mode='sync'>
+ <block>
+ <set>
+ <parameter name='a' value='0' />
+ </set>
+ <for index='idx' start='0' end='999' >
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder">
+ <parameter name="logger" value="message-log" />
+ <parameter name="level" value="error" />
+ <parameter name="field1" value="`$idx`" />
+ </record>
+ <set>
+ <parameter name='a' value='`$a + 1`' />
+ </set>
+ <switch test="`$idx == 2`">
+ <outcome value='true'>
+ <break/>
+ </outcome>
+ </switch>
+ </for>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml b/core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml
new file mode 100644
index 000000000..8f40058f1
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml
@@ -0,0 +1,23 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si[0].field1' value='1' />
+ <parameter name='si[1].field2' value='2' />
+ <parameter name='si[2].field3' value='3' />
+ <parameter name='si_length' value='3' />
+ <parameter name='si[0].subarray[0]' value='a' />
+ <parameter name='si[0].subarray[1]' value='b' />
+ <parameter name='si[0].subarray[2]' value='c' />
+ <parameter name='si[0].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si.' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml b/core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml
new file mode 100644
index 000000000..a80b3e56c
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml
@@ -0,0 +1,27 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='tmp.si[0].field1' value='1' />
+ <parameter name='tmp.si[1].field2' value='2' />
+ <parameter name='tmp.si[2].field3' value='3' />
+ <parameter name='tmp.si_length' value='3' />
+ <parameter name='tmp.si[0].subarray[0]' value='a' />
+ <parameter name='tmp.si[0].subarray[1]' value='b' />
+ <parameter name='tmp.si[0].subarray[2]' value='c' />
+ <parameter name='tmp.si[0].subarray_length' value='3' />
+ <parameter name='tmp.si[1].subarray[0]' value='x' />
+ <parameter name='tmp.si[1].subarray[1]' value='y' />
+ <parameter name='tmp.si[1].subarray[2]' value='z' />
+ <parameter name='tmp.si[1].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='tmp.si[0].subarray.' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml b/core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml
new file mode 100644
index 000000000..56781a066
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml
@@ -0,0 +1,23 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si[0].field1' value='1' />
+ <parameter name='si[1].field2' value='2' />
+ <parameter name='si[2].field3' value='3' />
+ <parameter name='si_length' value='3' />
+ <parameter name='si[0].subarray[0]' value='a' />
+ <parameter name='si[0].subarray[1]' value='b' />
+ <parameter name='si[0].subarray[2]' value='c' />
+ <parameter name='si[0].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si[0].' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml b/core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml
new file mode 100644
index 000000000..22f14f37b
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml
@@ -0,0 +1,27 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='tmp.si[0].field1' value='1' />
+ <parameter name='tmp.si[1].field2' value='2' />
+ <parameter name='tmp.si[2].field3' value='3' />
+ <parameter name='tmp.si_length' value='3' />
+ <parameter name='tmp.si[0].subarray[0]' value='a' />
+ <parameter name='tmp.si[0].subarray[1]' value='b' />
+ <parameter name='tmp.si[0].subarray[2]' value='c' />
+ <parameter name='tmp.si[0].subarray_length' value='3' />
+ <parameter name='tmp.si[1].subarray[0]' value='x' />
+ <parameter name='tmp.si[1].subarray[1]' value='y' />
+ <parameter name='tmp.si[1].subarray[2]' value='z' />
+ <parameter name='tmp.si[1].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='tmp.si[0].subarray[1]' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/clearSubArrayValues.xml b/core/sli/provider-base/src/test/resources/clearSubArrayValues.xml
new file mode 100644
index 000000000..cb25f38af
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/clearSubArrayValues.xml
@@ -0,0 +1,24 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si[0].field1' value='1' />
+ <parameter name='si[1].field2' value='2' />
+ <parameter name='si[2].field3' value='3' />
+ <parameter name='si_length' value='3' />
+ <parameter name='si[0].subarray[0]' value='a' />
+ <parameter name='si[0].subarray[1]' value='b' />
+ <parameter name='si[0].subarray[2]' value='c' />
+ <parameter name='si[0].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si[0].subarray.' value='' />
+ <!-- <parameter name='si.subarray.' value='' /> -->
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/clearValues.xml b/core/sli/provider-base/src/test/resources/clearValues.xml
new file mode 100644
index 000000000..dc7f5c8a2
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/clearValues.xml
@@ -0,0 +1,22 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si.field1' value='1' />
+ <parameter name='si.field2' value='2' />
+ <parameter name='si.field3' value='3' />
+ <parameter name='si.subarray[0]' value='a' />
+ <parameter name='si.subarray[1]' value='b' />
+ <parameter name='si.subarray[2]' value='c' />
+ <parameter name='si.subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si.' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/copyValues.xml b/core/sli/provider-base/src/test/resources/copyValues.xml
new file mode 100644
index 000000000..f56f7140a
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/copyValues.xml
@@ -0,0 +1,16 @@
+<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si.field1' value='1' />
+ <parameter name='si.field2' value='2' />
+ <parameter name='si.field3' value='3' />
+ </set>
+ <set>
+ <parameter name='rootTwo.' value='si.' />
+ </set>
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/expression.tests b/core/sli/provider-base/src/test/resources/expression.tests
new file mode 100644
index 000000000..848a0e7a4
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/expression.tests
@@ -0,0 +1,24 @@
+# $uni-circuit-id = abc123
+# $uni-cir-units = 10
+# value = 1
+# $arg1 = 2
+# $network.name = vCE0001.in
+# $network.segment[0].provider-segmentation-id = 1212
+# $network.segment[1].provider-segmentation-id = 1213
+# $availability-zone = mtsnj-esx-az01
+length($uni-circuit-id) > 0 # true
+$uni-cir-units * 1000 * 100 / 100 # 10000
+$uni-cir-units / 1000 # 0
+$uni-cir-units - 100 # -90
+$uni-cir-units + 100 # 110
+(value * 3 - $arg1 > 0) and (length($uni-circuit-id) == 0) # true
+'pg-'+$network.name # pg-vCE0001.in
+$network.segment[0].provider-segmentation-id # 1212
+toUpperCase($network.name) # VCE0001.IN
+toLowerCase($network.name) # vce0001.in
+toUpperCase(substr($availability-zone, 0, 5)) # MTSNJ
+convertBase(1234, 10) # 1234
+convertBase(10, 16, 10) # 16
+convertBase(ZZ, 36, 10) # 1295
+convertBase(10, 10, 36) # a
+(0 - 1) * $arg1 # -1
diff --git a/core/sli/provider-base/src/test/resources/expressions.xml b/core/sli/provider-base/src/test/resources/expressions.xml
new file mode 100755
index 000000000..79118570c
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/expressions.xml
@@ -0,0 +1,55 @@
+<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='add' value='`1 + 1`' />
+ <parameter name='sub' value='`2 - 1`' />
+ <parameter name='div' value='`6 / 2`' />
+ <parameter name='multi' value='`2 * 2`' />
+ <parameter name='addDoubleQuotes' value="`1 + 1`" />
+ <parameter name='subDoubleQuotes' value="`2 - 1`" />
+ <parameter name='divDoubleQuotes' value="`6 / 2`" />
+ <parameter name='multiDoubleQuotes' value="`2 * 2`" />
+ </set>
+ <set>
+ <parameter name='varA' value='`$a + $b`' />
+ <parameter name='varB' value='`$a + &apos;literal&apos; `' />
+ <parameter name='varC' value='`&apos;literal&apos; + $b `' />
+ <parameter name='varD' value='`&apos;too&apos; + &apos;literal&apos;`' />
+ <parameter name='varADoubleQuotes' value="`$a + $b`" />
+ <parameter name='varBDoubleQuotes' value="`$a +'literal' `" />
+ <parameter name='varCDoubleQuotes' value="`'literal' + $b `" />
+ <parameter name='varDDoubleQuotes' value="`'too' + 'literal'`" />
+ </set>
+ <set>
+ <parameter name='testOne' value='`1 + 1`' />
+ <parameter name='testThree' value='"1" +"1"' />
+ <parameter name='testFour' value='`$portNumber + $slot + $shelf`' />
+ <parameter name='testOneDoubleQuotes' value="`1 + 1`" />
+ <parameter name='testThreeDoubleQuotes' value="'1' +'1'" />
+ <parameter name='testFourDoubleQuotes' value="`$portNumber + $slot + $shelf`" />
+ </set>
+ <switch test="`'PIZZA' == 'NOTPIZZA' or $a != $b`" />
+ <switch test="`'PIZZA' == 'PIZZA' and $a != $b`" />
+ <switch test="`'PIZZA' == 'NOTPIZZA' or $a &gt;= $b`" />
+ <switch test="`'PIZZA' == 'PIZZA' and $b &lt; $a`" />
+ <switch test="`'PIZZA' == 'PIZZA'`" />
+ <switch test="`$a == $b`" />
+ <switch test="`'PIZZA' == 'NOTPIZZA'`" />
+ <switch test="`'PIZZA' != 'PIZZA'`" />
+ <switch test="`'PIZZA' != 'NOTPIZZA'`" />
+ <switch test='`$a != $b`' />
+ <switch test='`1 &lt; 2`' />
+ <switch test='`2 &lt;= 2`' />
+ <switch test='`3 &gt; 2`' />
+ <switch test='`2 &gt;= 2`' />
+ <switch test='$literalStartingWithDollarSign' />
+ <switch test='`$dollarSignFollowedByVariableSurroundedinBackticks`' />
+ <switch test='`$a == $b`' />
+ <switch test="`$a == $b`" />
+ <switch test='$a == $b' />
+ <switch test="$a == $b" />
+ </block>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/core/sli/provider-base/src/test/resources/simplelogger.properties b/core/sli/provider-base/src/test/resources/simplelogger.properties
new file mode 100644
index 000000000..07ab67f70
--- /dev/null
+++ b/core/sli/provider-base/src/test/resources/simplelogger.properties
@@ -0,0 +1,22 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+org.slf4j.simpleLogger.defaultLogLevel=info
diff --git a/core/sli/provider/pom.xml b/core/sli/provider/pom.xml
new file mode 100755
index 000000000..3d5c389c4
--- /dev/null
+++ b/core/sli/provider/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name>
+ <description>SLI Provider is the OSGi bundle that exposes the service logic interpreter as a service.</description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-model</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-provider-base</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
+ <artifactId>rfc6991</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>bgp-concepts</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-core-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.derby</groupId>
+ <artifactId>derby</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <DynamicImport-Package>*</DynamicImport-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <!-- Jacoco / Sonar -->
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <version>${jacoco.version}</version>
+ <executions>
+ <execution>
+ <id>aggregate-report</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>report-aggregate</goal>
+ </goals>
+ <configuration>
+ <dataFileIncludes>
+ target/code-coverage/jacoco-ut.exec,
+ target/code-coverage/jacoco-it.exec,
+ ../provider-base/target/code-coverage/jacoco-ut.exec,
+ ../provider-base/target/code-coverage/jacoco-it.exec
+ </dataFileIncludes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java
new file mode 100755
index 000000000..d3ab6c33a
--- /dev/null
+++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java
@@ -0,0 +1,1274 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisherBuilder;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MdsalHelper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class);
+ private static Properties yangMappingProperties = new Properties();
+ private static final String IP_ADDRESS="IpAddress";
+ private static final String IPV4_ADDRESS="Ipv4Address";
+ private static final String IPV6_ADDRESS="Ipv6Address";
+
+ private static final String IP_PREFIX="IpPrefix";
+ private static final String SETTING_PROPERTY="Setting property ";
+ private static final String BUILDER="-builder";
+
+ @Deprecated
+ public static void setProperties(Properties input) {
+ setYangMappingProperties(input);
+ }
+
+ @Deprecated
+ public static void setYangMappingProperties(Properties properties) {
+ for (Object propNameObj : properties.keySet()) {
+ String propName = (String) propNameObj;
+ MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
+ }
+ }
+
+ @Deprecated
+ public static void loadProperties(String propertiesFile) {
+ File file = new File(propertiesFile);
+ Properties properties = new Properties();
+ if (file.isFile() && file.canRead()) {
+ try (InputStream input = new FileInputStream(file)) {
+ properties.load(input);
+ MdsalHelper.setYangMappingProperties(properties);
+ LOG.info("Loaded properties from " + propertiesFile);
+ } catch (Exception e) {
+ LOG.error("Failed to load properties " + propertiesFile + "\n", e);
+ }
+ } else {
+ LOG.error("Failed to load the properties file " + propertiesFile + "\n");
+ LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n");
+ }
+ }
+
+ public static Properties toProperties(Properties props, Object fromObj) {
+ return toProperties(props, fromObj, false);
+ }
+
+ public static Properties toProperties(Properties props, Object fromObj, Boolean useLegacyEnumerationMapping) {
+ Class fromClass = null;
+
+ if (fromObj != null) {
+ fromClass = fromObj.getClass();
+ }
+ return toProperties(props, "", fromObj, fromClass, useLegacyEnumerationMapping);
+ }
+
+ public static Properties toProperties(Properties props, String pfx, Object fromObj) {
+ return toProperties(props, pfx, fromObj, false);
+ }
+
+ public static Properties toProperties(Properties props, String pfx, Object fromObj, Boolean useLegacyEnumerationMapping) {
+ Class fromClass = null;
+
+ if (fromObj != null) {
+ fromClass = fromObj.getClass();
+ }
+
+ return toProperties(props, pfx, fromObj, fromClass, useLegacyEnumerationMapping);
+ }
+
+ public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) {
+ return toProperties(props, pfx, fromObj, fromClass, false);
+ }
+
+ public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass, Boolean useLegacyEnumerationMapping) {
+
+ if (fromObj == null) {
+ return props;
+ }
+ String simpleTypeName = fromObj.getClass().getTypeName();
+ simpleTypeName = simpleTypeName.substring(simpleTypeName.lastIndexOf(".") + 1);
+
+ if (classHasSpecialHandling(simpleTypeName)) {
+ try {
+
+ Method m = fromClass.getMethod(getStringValueMethod(simpleTypeName), null);
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object retValue = m.invoke(fromObj);
+ if (retValue != null) {
+ String propVal = null;
+ if (IP_ADDRESS.equals(simpleTypeName) || IP_PREFIX.equals(simpleTypeName)
+ || IPV4_ADDRESS.equals(simpleTypeName) || IPV6_ADDRESS.equals(simpleTypeName)) {
+ propVal = (String) retValue;
+ } else if ("Dscp".equals(simpleTypeName)) {
+ propVal = String.valueOf((short) retValue);
+ } else if ("PortNumber".equals(simpleTypeName)) {
+ propVal = String.valueOf((Integer) retValue);
+ }
+ LOG.debug(SETTING_PROPERTY + pfx + " to " + propVal);
+ props.setProperty(pfx, propVal);
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value returned by " + fromClass.getName()
+ + ".getValue() to Properties entry", e);
+ }
+ } else if (fromObj instanceof List) {
+ List fromList = (List) fromObj;
+
+ for (int i = 0; i < fromList.size(); i++) {
+ toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass, useLegacyEnumerationMapping);
+ }
+ props.setProperty(pfx + "_length", Integer.toString(fromList.size()));
+
+ } else if (isYangGenerated(fromClass)) {
+ // Class is yang generated.
+
+ String propNamePfx = null;
+
+ // If called from a list (so prefix ends in ']'), don't
+ // add class name again
+ if (pfx.endsWith("]")) {
+ propNamePfx = pfx;
+ } else {
+ if ((pfx != null) && (pfx.length() > 0)) {
+ propNamePfx = pfx;
+ } else {
+ propNamePfx = toLowerHyphen(fromClass.getSimpleName());
+ }
+
+ if (propNamePfx.endsWith(BUILDER)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
+ }
+
+ if (propNamePfx.endsWith("-impl")) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
+ }
+ }
+
+ // Iterate through getter methods to figure out values we need to
+ // save from
+
+ int numGetters = 0;
+ String lastGetterName = null;
+ String propVal = null;
+
+ for (Method m : fromClass.getMethods()) {
+ if (isGetter(m)) {
+
+ numGetters++;
+ lastGetterName = m.getName();
+
+ Class returnType = m.getReturnType();
+ String fieldName;
+ if (m.getName().startsWith("get")) {
+ fieldName = toLowerHyphen(m.getName().substring(3));
+ } else {
+
+ fieldName = toLowerHyphen(m.getName().substring(2));
+ }
+
+ fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(returnType)) {
+ // Is it an enum?
+ if (returnType.isEnum()) {
+ // Return type is a typedef. Save its value.
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ Object retValue = m.invoke(fromObj);
+
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ if (retValue != null) {
+ String propName = propNamePfx + "." + fieldName;
+ if (useLegacyEnumerationMapping) {
+ propVal = retValue.toString();
+ props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
+ } else {
+ Method method = retValue.getClass().getMethod("getName");
+ String yangValue = (String) method.invoke(retValue);
+ props.setProperty(propName, yangValue);
+ }
+
+ }
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert Yang-generated enum returned by "
+ + fromClass.getName() + "." + m.getName() + "() to Properties entry",
+ e);
+ }
+ } else {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object retValue = m.invoke(fromObj);
+
+ if (retValue instanceof byte[]) {
+ retValue = new String((byte[]) retValue, "UTF-8");
+ }
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ if (retValue != null) {
+ toProperties(props, propNamePfx + "." + fieldName, retValue, returnType, useLegacyEnumerationMapping);
+ }
+ } catch (Exception e) {
+
+ if (m.getName().equals("getKey")) {
+ LOG.trace("Caught " + e.getClass().getName()
+ + " exception trying to convert results from getKey() - ignoring");
+ } else {
+ LOG.error("Caught exception trying to convert Yang-generated class returned by"
+ + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+ }
+ }
+ }
+ } else if (returnType.equals(Class.class)) {
+
+ } else if (List.class.isAssignableFrom(returnType)) {
+
+ // This getter method returns a list.
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object retList = m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ // Figure out what type of elements are stored in
+ // this array.
+ Type paramType = m.getGenericReturnType();
+ Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
+ toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType, useLegacyEnumerationMapping);
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "."
+ + m.getName() + "() to Properties entry", e);
+ }
+
+ } else {
+
+ // Method returns something that is not a List and not
+ // yang-generated.
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object propValObj = m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (propValObj != null) {
+ if (propValObj instanceof byte[]) {
+ propVal = new String((byte[]) propValObj, "UTF-8");
+ } else {
+ propVal = propValObj.toString();
+ }
+ LOG.debug(SETTING_PROPERTY + propName + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ if (m.getName().equals("getKey")) {
+ LOG.trace("Caught " + e.getClass().getName()
+ + " exception trying to convert results from getKey() - ignoring");
+ } else {
+ LOG.error("Caught exception trying to convert value returned by" + fromClass.getName()
+ + "." + m.getName() + "() to Properties entry", e);
+ }
+ }
+ }
+
+ }
+ }
+
+ // End of method loop. If there was only one getter, named
+ // "getValue", then
+ // set value identified by "prefix" to that one value.
+ if ((numGetters == 1) && ("getValue".equals(lastGetterName))) {
+ props.setProperty(propNamePfx, propVal);
+ }
+ } else {
+ // Class is not yang generated and not a list
+ // It must be an element of a leaf list - set "prefix" to value
+ String fromVal = null;
+ if (fromObj instanceof byte[]) {
+ try {
+ fromVal = new String((byte[]) fromObj, "UTF-8");
+ } catch (Exception e) {
+ LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e);
+ fromVal = fromObj.toString();
+ }
+
+ } else {
+ fromVal = fromObj.toString();
+ }
+ LOG.debug(SETTING_PROPERTY + pfx + " to " + fromVal);
+ props.setProperty(pfx, fromVal);
+ }
+
+ return (props);
+ }
+
+ public static Object toBuilder(Properties props, Object toObj) {
+
+ return (toBuilder(props, "", toObj));
+ }
+
+ public static List toList(Properties props, String pfx, List toObj, Class elemType) {
+
+ int maxIdx = -1;
+ boolean foundValue = false;
+
+ if (props.containsKey(pfx + "_length")) {
+ try {
+ int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
+
+ if (listLength > 0) {
+ maxIdx = listLength - 1;
+ }
+ } catch (NumberFormatException e) {
+ LOG.info("Invalid input for length ", e);
+ }
+ }
+
+ String arrayKey = pfx + "[";
+ int arrayKeyLength = arrayKey.length();
+ if (maxIdx == -1) {
+ // Figure out array size
+ for (Object pNameObj : props.keySet()) {
+ String key = (String) pNameObj;
+
+ if (key.startsWith(arrayKey)) {
+ String idxStr = key.substring(arrayKeyLength);
+ int endloc = idxStr.indexOf("]");
+ if (endloc != -1) {
+ idxStr = idxStr.substring(0, endloc);
+ }
+ try {
+ int curIdx = Integer.parseInt(idxStr);
+ if (curIdx > maxIdx) {
+ maxIdx = curIdx;
+ }
+ } catch (Exception e) {
+ LOG.error("Illegal subscript in property {}", key, e);
+ }
+
+ }
+ }
+ }
+
+ for (int i = 0; i <= maxIdx; i++) {
+
+ String curBase = pfx + "[" + i + "]";
+
+ if (isYangGenerated(elemType)) {
+
+ if (isIpAddress(elemType)) {
+
+ String curValue = props.getProperty(curBase, "");
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ toObj.add(IpAddressBuilder.getDefaultInstance(curValue));
+ foundValue = true;
+ }
+ } else if (isIpv4Address(elemType)) {
+ String curValue = props.getProperty(curBase, "");
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ toObj.add(new Ipv4Address(curValue));
+ foundValue = true;
+ }
+
+ } else if (isIpv6Address(elemType)) {
+ String curValue = props.getProperty(curBase, "");
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ toObj.add(new Ipv6Address(curValue));
+ foundValue = true;
+ }
+ } else if (isIpPrefix(elemType)) {
+
+ String curValue = props.getProperty(curBase, "");
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ toObj.add(IpPrefixBuilder.getDefaultInstance(curValue));
+ foundValue = true;
+ }
+ } else if (isPortNumber(elemType)) {
+
+ String curValue = props.getProperty(curBase, "");
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ toObj.add(PortNumber.getDefaultInstance(curValue));
+ foundValue = true;
+ }
+ } else if (isDscp(elemType)) {
+
+ String curValue = props.getProperty(curBase, "");
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ toObj.add(Dscp.getDefaultInstance(curValue));
+ foundValue = true;
+ }
+ } else {
+ String builderName = elemType.getName() + "Builder";
+ try {
+ Class builderClass = Class.forName(builderName);
+ Object builderObj = builderClass.newInstance();
+ Method buildMethod = builderClass.getMethod("build");
+ builderObj = toBuilder(props, curBase, builderObj, true);
+ if (builderObj != null) {
+ Object builtObj = buildMethod.invoke(builderObj);
+ toObj.add(builtObj);
+ foundValue = true;
+ }
+
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Could not find builder class {}", builderName, e);
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to populate list from {}", pfx, e);
+ }
+ }
+ } else {
+ // Must be a leaf list
+ String curValue = props.getProperty(curBase, "");
+
+ toObj.add(curValue);
+
+ if ((curValue != null) && (curValue.length() > 0)) {
+ foundValue = true;
+ }
+ }
+
+ }
+
+ if (foundValue) {
+ return (toObj);
+ } else {
+ return (null);
+ }
+
+ }
+
+ public static Object toBuilder(Properties props, String pfx, Object toObj) {
+ return (toBuilder(props, pfx, toObj, false));
+ }
+
+ public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
+
+ Class toClass = toObj.getClass();
+ boolean foundValue = false;
+
+ Ipv4Address addr;
+
+ if (isYangGenerated(toClass)) {
+ // Class is yang generated.
+ String propNamePfx = null;
+ if (preservePfx) {
+ propNamePfx = pfx;
+ } else {
+
+ if ((pfx != null) && (pfx.length() > 0)) {
+ propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
+ } else {
+ propNamePfx = toLowerHyphen(toClass.getSimpleName());
+ }
+
+ if (propNamePfx.endsWith(BUILDER)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
+ }
+
+ if (propNamePfx.endsWith("-impl")) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
+ }
+ }
+
+ if (toObj instanceof Identifier) {
+ return (toObj);
+ }
+
+ // Iterate through getter methods to figure out values we need to
+ // set
+
+ for (Method m : toClass.getMethods()) {
+ if (isSetter(m)) {
+ Class paramTypes[] = m.getParameterTypes();
+ Class paramClass = paramTypes[0];
+
+ String fieldName = toLowerHyphen(m.getName().substring(3));
+ fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+
+ String propName = propNamePfx + "." + fieldName;
+
+ String paramValue = props.getProperty(propName);
+ if (paramValue == null) {
+
+ } else if ("".equals(paramValue)) {
+ LOG.trace(propName + " was set to the empty string, setting it to null");
+ paramValue = null;
+ } else {
+
+ }
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(paramClass)) {
+ // Is it an enum?
+ if (paramClass.isEnum()) {
+
+ // Param type is a typedef.
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ Object paramObj = null;
+
+ try {
+ paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue));
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert field " + propName + " to enum "
+ + paramClass.getName(), e);
+ }
+
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ m.invoke(toObj, paramObj);
+
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to create Yang-generated enum expected by"
+ + toClass.getName() + "." + m.getName() + "() from Properties entry", e);
+ }
+ }
+ } else {
+
+ String simpleName = paramClass.getSimpleName();
+
+ if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
+ || IP_ADDRESS.equals(simpleName)) {
+
+
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ try {
+ IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
+
+ if (IPV4_ADDRESS.equals(simpleName)) {
+ m.invoke(toObj, ipAddr.getIpv4Address());
+ } else if (IPV6_ADDRESS.equals(simpleName)) {
+ m.invoke(toObj, ipAddr.getIpv6Address());
+
+ } else {
+ m.invoke(toObj, ipAddr);
+ }
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
+ + "(" + paramValue + ")", e);
+
+ }
+ } else {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ m.invoke(toObj, paramValue);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to call " + toClass.getName() + "."
+ + m.getName() + "() with Properties entry", e);
+ }
+ }
+ } else if (IP_PREFIX.equals(simpleName)) {
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ try {
+ IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue);
+ m.invoke(toObj, ipPrefix);
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
+ + "(" + paramValue + ")", e);
+ }
+ }
+ } else if ("PortNumber".equals(simpleName)) {
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ try {
+ PortNumber portNumber = PortNumber.getDefaultInstance(paramValue);
+ m.invoke(toObj, portNumber);
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
+ + "(" + paramValue + ")", e);
+ }
+ }
+ } else if ("Dscp".equals(simpleName)) {
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ try {
+ Dscp dscp = Dscp.getDefaultInstance(paramValue);
+ m.invoke(toObj, dscp);
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
+ + "(" + paramValue + ")", e);
+ }
+ }
+ } else if ("RouteDistinguisher".equals(simpleName)) {
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ try {
+ RouteDistinguisher routeDistinguisher = RouteDistinguisherBuilder.getDefaultInstance(paramValue);
+ m.invoke(toObj, routeDistinguisher);
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName()
+ + "(" + paramValue + ")", e);
+ }
+ }
+ }
+ else {
+ // setter expects a yang-generated class. Need
+ // to
+ // create a builder to set it.
+
+ String builderName = paramClass.getName() + "Builder";
+ Class builderClass = null;
+ Object builderObj = null;
+ Object paramObj = null;
+
+ Object constObj = null;
+
+ try {
+ builderClass = Class.forName(builderName);
+ builderObj = builderClass.newInstance();
+ paramObj = toBuilder(props, propNamePfx, builderObj);
+ } catch (ClassNotFoundException e) {
+ LOG.trace("Builder class {} not found catching ClassNotFoundException and trying other methods",
+ builderName);
+ if (paramValue == null) {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ m.invoke(toObj, new Object[] { null });
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e1) {
+ LOG.error("Caught exception trying to cally" + toClass.getName() + "."
+ + m.getName() + "() with Properties entry", e1);
+ }
+ } else {
+ try {
+ // See if I can find a constructor I
+ // can
+ // use
+ Constructor[] constructors = paramClass.getConstructors();
+ // Is there a String constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c.getParameterTypes();
+ if ((cParms != null) && (cParms.length == 1)) {
+ if (String.class.isAssignableFrom(cParms[0])) {
+ constObj = c.newInstance(paramValue);
+ }
+ }
+ }
+
+ if (constObj == null) {
+ // Is there a Long constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c.getParameterTypes();
+ if ((cParms != null) && (cParms.length == 1)) {
+ if (Long.class.isAssignableFrom(cParms[0])) {
+ constObj = c.newInstance(Long.parseLong(paramValue));
+ }
+ }
+ }
+
+ }
+
+ if (constObj == null) {
+
+ // Last chance - see if
+ // parameter class has a static
+ // method
+ // getDefaultInstance(String)
+ try {
+ Method gm =
+ paramClass.getMethod("getDefaultInstance", String.class);
+
+ int gmodifier = gm.getModifiers();
+ if (Modifier.isStatic(gmodifier)) {
+ // Invoke static
+ // getDefaultInstance(String)
+ paramObj = gm.invoke(null, paramValue);
+ }
+
+ } catch (Exception gme) {
+ LOG.info("Unable to find static method getDefaultInstance for "
+ + "class {}", paramClass.getSimpleName(), gme);
+ }
+ }
+
+ } catch (Exception e1) {
+ LOG.warn(
+ "Could not find a suitable constructor for " + paramClass.getName(),
+ e1);
+ }
+
+ if (constObj == null) {
+ LOG.warn("Could not find builder class " + builderName
+ + " and could not find a String or Long constructor or static "
+ + "getDefaultInstance(String) - trying just to set passing paramValue");
+
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to create builder " + builderName, e);
+ }
+
+ if (paramObj != null && builderClass != null) {
+
+ try {
+ Method buildMethod = builderClass.getMethod("build");
+
+ Object builtObj = buildMethod.invoke(paramObj);
+
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ m.invoke(toObj, builtObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to set Yang-generated class expected by"
+ + toClass.getName() + "." + m.getName() + "() from Properties entry",
+ e);
+ }
+ } else {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ if (constObj != null) {
+ m.invoke(toObj, constObj);
+ } else {
+ m.invoke(toObj, paramValue);
+ }
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value returned by"
+ + toClass.getName() + "." + m.getName() + "() to Properties entry", e);
+ }
+ }
+ }
+ }
+ } else {
+
+ // Setter's argument is not a yang-generated class. See
+ // if it is a List.
+
+ if (List.class.isAssignableFrom(paramClass)) {
+ // Figure out what type of args are in List and pass
+ // that to toList().
+
+ Type paramType = m.getGenericParameterTypes()[0];
+ Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0];
+ Object paramObj = new LinkedList();
+ try {
+ paramObj = toList(props, propName, (List) paramObj, (Class) elementType);
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to create list expected as argument to {}.{}",
+ toClass.getName(), m.getName(), e);
+ }
+
+ if (paramObj != null) {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ m.invoke(toObj, paramObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert List returned by" + toClass.getName()
+ + "." + m.getName() + "() to Properties entry", e);
+ }
+ }
+ } else {
+
+ // Setter expects something that is not a List and
+ // not yang-generated. Just pass the parameter value
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+
+ Object constObj = null;
+
+ try {
+ // See if I can find a constructor I can use
+ Constructor[] constructors = paramClass.getConstructors();
+ // Is there a String constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c.getParameterTypes();
+ if ((cParms != null) && (cParms.length == 1)) {
+ if (String.class.isAssignableFrom(cParms[0])) {
+ constObj = c.newInstance(paramValue);
+ }
+ }
+ }
+
+ if (constObj == null) {
+ // Is there a Long constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c.getParameterTypes();
+ if ((cParms != null) && (cParms.length == 1)) {
+ if (Long.class.isAssignableFrom(cParms[0])) {
+ constObj = c.newInstance(Long.parseLong(paramValue));
+ }
+ }
+ }
+
+ }
+
+ if (constObj != null) {
+ try {
+ m.invoke(toObj, constObj);
+ foundValue = true;
+ } catch (Exception e2) {
+ LOG.error("Caught exception trying to call " + m.getName(), e2);
+ }
+ } else {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ m.invoke(toObj, paramValue);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value returned by"
+ + toClass.getName() + "." + m.getName() + "() to Properties entry",
+ e);
+ }
+ }
+ } catch (Exception e1) {
+ LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1);
+ }
+
+ }
+ }
+ }
+ } // End of section handling "setter" method
+ } // End of loop through Methods
+ } // End of section handling yang-generated class
+
+ if (foundValue) {
+ return (toObj);
+ } else {
+ return (null);
+ }
+ }
+
+ private static boolean classHasSpecialHandling(String simpleName) {
+ if (IP_ADDRESS.equals(simpleName) || IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
+ || IP_PREFIX.equals(simpleName) || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
+ return true;
+ }
+ return false;
+ }
+
+ private static String getStringValueMethod(String simpleName){
+ if (IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)) {
+ return("stringValue");
+ } else {
+ return("getValue");
+ }
+ }
+
+ public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
+ boolean foundValue = false;
+
+ if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
+ // Class is yang generated.
+ String propNamePfx = null;
+ if (pfx.endsWith("]")) {
+ propNamePfx = pfx;
+ } else {
+
+ if ((pfx != null) && (pfx.length() > 0)) {
+ propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName());
+ } else {
+ propNamePfx = toLowerHyphen(toClass.getSimpleName());
+ }
+
+ if (propNamePfx.endsWith(BUILDER)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length());
+ }
+
+ if (propNamePfx.endsWith("-impl")) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length());
+ }
+ }
+
+ // Iterate through getter methods to figure out values we need to
+ // set
+
+ for (Method m : toClass.getMethods()) {
+ if (isGetter(m)) {
+ Class returnClass = m.getReturnType();
+
+ String fieldName = toLowerHyphen(m.getName().substring(3));
+ if (fieldName != null) {
+ fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+ } else {
+ fieldName = "";
+ }
+ String propName = propNamePfx + "." + fieldName;
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(returnClass)) {
+ // Is it an enum?
+ if (returnClass.isEnum()) {
+ pstr.print("\n\n * " + propName);
+ } else {
+
+ String simpleName = returnClass.getSimpleName();
+
+ if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName)
+ || IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)
+ || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) {
+ pstr.print("\n\n * " + propName);
+ } else {
+ printPropertyList(pstr, propNamePfx, returnClass);
+ }
+
+ }
+ } else {
+
+ // Setter's argument is not a yang-generated class. See
+ // if it is a List.
+
+ if (List.class.isAssignableFrom(returnClass)) {
+ // Figure out what type of args are in List and pass
+ // that to toList().
+
+ Type returnType = m.getGenericReturnType();
+ Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0];
+ Class elementClass = (Class) elementType;
+ printPropertyList(pstr,
+ propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]",
+ elementClass);
+
+ } else if (!returnClass.equals(Class.class)) {
+
+ // Setter expects something that is not a List and
+ // not yang-generated. Just pass the parameter value
+ pstr.print("\n\n * " + propName);
+ }
+ }
+ } // End of section handling "setter" method
+ } // End of loop through Methods
+ } // End of section handling yang-generated class
+
+ }
+
+ public static boolean isYangGenerated(Class c) {
+ if (c != null) {
+ return (c.getName().startsWith("org.opendaylight.yang.gen."));
+ }
+ return false;
+ }
+
+ public static boolean isIpPrefix(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ if (!isIetfInet(c)) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return (IP_PREFIX.equals(simpleName));
+ }
+
+ public static boolean isIpv4Address(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ if (!isIetfInet(c)) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return (IPV4_ADDRESS.equals(simpleName));
+ }
+
+ public static boolean isIpv6Address(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ if (!isIetfInet(c)) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return (IPV6_ADDRESS.equals(simpleName));
+ }
+
+ public static boolean isIpAddress(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ if (!isIetfInet(c)) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return (IP_ADDRESS.equals(simpleName));
+ }
+
+ public static boolean isPortNumber(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ if (!isIetfInet(c)) {
+ return (false);
+ }
+
+ String simpleName = c.getSimpleName();
+ return ("PortNumber".equals(simpleName));
+ }
+
+ public static boolean isDscp(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ if (!isIetfInet(c)) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return ("Dscp".equals(simpleName));
+ }
+
+ public static boolean isIetfInet(Class c) {
+
+ Package p = c.getPackage();
+ if (p != null) {
+ String pkgName = p.getName();
+
+ if ((pkgName != null) && (pkgName.indexOf("yang.ietf.inet.types") > -1)) {
+ return (true);
+ }
+ }
+
+ return (false);
+ }
+
+ public static String toLowerHyphen(String inStr) {
+ if (inStr == null) {
+ return (null);
+ }
+
+ String str = inStr.substring(0, 1).toLowerCase();
+ if (inStr.length() > 1) {
+ str = str + inStr.substring(1);
+ }
+
+ String regex = "([a-z0-9A-Z])(?=[A-Z])";
+ String replacement = "$1-";
+
+ String retval = str.replaceAll(regex, replacement).toLowerCase();
+
+ return (retval);
+ }
+
+ // This is called when mapping the yang value back to a valid java enumeration
+ public static String toJavaEnum(String inStr) {
+ if (inStr == null) {
+ return (null);
+ } else if (inStr.length() == 0) {
+ return (inStr);
+ }
+
+ // This is needed for enums containing under scores
+ inStr = inStr.replaceAll("_", "");
+
+ // This will strip out all periods, which cannot be in a java enum
+ inStr = inStr.replaceAll("\\.", "");
+
+ // This is needed for enums containing spaces
+ inStr = inStr.replaceAll(" ", "");
+
+ String[] terms = inStr.split("-");
+ StringBuffer sbuff = new StringBuffer();
+
+ // appends an _ if the string starts with a digit to make it a valid java enum
+ if (Character.isDigit(inStr.charAt(0))) {
+ sbuff.append('_');
+ }
+ // If the string contains hyphens it will convert the string to upperCamelCase without hyphens
+ for (String term : terms) {
+ sbuff.append(term.substring(0, 1).toUpperCase());
+ if (term.length() > 1) {
+ sbuff.append(term.substring(1));
+ }
+ }
+ return (sbuff.toString());
+
+ }
+
+ public static boolean isGetter(Method m) {
+ if (m == null) {
+ return (false);
+ }
+
+ if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) {
+ if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) {
+ if (!"getClass".equals(m.getName())) {
+ return (true);
+ }
+ }
+
+ if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) {
+ return (true);
+ }
+
+ if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) {
+ return (true);
+ }
+ }
+
+ return (false);
+ }
+
+ public static boolean isSetter(Method m) {
+ if (m == null) {
+ return (false);
+ }
+
+ if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) {
+ if (m.getName().matches("^set[A-Z].*")) {
+ Class[] paramTypes = m.getParameterTypes();
+ if (paramTypes[0].isAssignableFrom(Identifier.class)
+ || Identifier.class.isAssignableFrom(paramTypes[0])) {
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ }
+
+ return (false);
+ }
+
+ @Deprecated
+ public static String getFullPropertiesPath(String propertiesFileName) {
+ String karafHome = System.getProperty("karaf.home","/opt/lsc/controller");
+ return karafHome + "/configuration/" + propertiesFileName;
+ }
+
+ // This is called when mapping a valid java enumeration back to the yang model value
+ @Deprecated
+ public static String mapEnumeratedValue(String propertyName, String propertyValue) {
+ LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue);
+ String mappingKey = "yang." + propertyName + "." + propertyValue;
+ if (yangMappingProperties.containsKey(mappingKey)) {
+ return (yangMappingProperties.getProperty(mappingKey));
+ } else {
+ LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value.");
+ return propertyValue;
+ }
+ }
+
+}
diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java
new file mode 100644
index 000000000..992ed64d4
--- /dev/null
+++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java
@@ -0,0 +1,1355 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import java.io.PrintStream;
+import java.io.FileDescriptor;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.io.*;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.base.Strings;
+
+
+public class PrintYangToProp {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PrintYangToProp.class);
+ public static final String PROPERTIES_FILE="";
+ private static Properties properties;
+ private static final String BUILDER="-builder";
+ private static final String IMPL="-impl";
+ private static final String TO_PROPERTIES_STRING="() to Properties entry";
+ private static final String CAUGHT_EXCEPTION_MSG="Caught exception trying to convert value returned by ";
+ public static Properties prop = new Properties();
+ public static ArrayList<String> propList = new ArrayList<>();
+
+
+ public static Properties toProperties(Properties props, Object fromObj) {
+ Class fromClass = null;
+
+ if (fromObj != null)
+ {
+ fromClass = fromObj.getClass();
+ }
+ return (toProperties(props, "", fromObj, fromClass));
+ }
+
+ public static Properties toProperties(Properties props, String pfx, Object fromObj)
+ {
+ Class fromClass = null;
+
+ if (fromObj != null)
+ {
+ fromClass = fromObj.getClass();
+ }
+
+ return(toProperties(props, pfx, fromObj, fromClass));
+ }
+
+ public static Properties toProperties(Properties props, String pfx,
+ Object fromObj, Class fromClass) {
+
+ if (fromObj == null) {
+ return (props);
+ }
+
+
+ String simpleName = fromClass.getSimpleName();
+
+ if (fromObj instanceof List) {
+
+
+ List fromList = (List) fromObj;
+
+ for (int i = 0; i < fromList.size(); i++) {
+ toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass);
+ }
+ props.setProperty(pfx + "_length", "" + fromList.size());
+
+ } else if (isYangGenerated(fromClass)) {
+
+ String propNamePfx = null;
+
+ // If called from a list (so prefix ends in ']'), don't
+ // add class name again
+ if (pfx.endsWith("]")) {
+ propNamePfx = pfx;
+ } else {
+ if ((pfx != null) && (pfx.length() > 0)) {
+ propNamePfx = pfx ;
+ } else {
+ propNamePfx = toLowerHyphen(fromClass.getSimpleName());
+ }
+
+ if (propNamePfx.endsWith(BUILDER)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length()
+ - BUILDER.length());
+ }
+
+ if (propNamePfx.endsWith(IMPL)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length()
+ - IMPL.length());
+ }
+ }
+
+ // Iterate through getter methods to figure out values we need to
+ // save from
+
+ for (Method m : fromClass.getMethods()) {
+
+ if (isGetter(m)) {
+
+ Class returnType = m.getReturnType();
+ String fieldName = toLowerHyphen(m.getName().substring(3));
+ if(m != null && m.getName().matches("^is[A-Z].*")){
+ fieldName = toLowerHyphen(m.getName().substring(2));
+ }
+
+ if(Strings.isNullOrEmpty(fieldName)) fieldName = fieldName.substring(0, 1).toLowerCase()+ fieldName.substring(1);
+
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(returnType)) {
+
+ // Is it an enum?
+ if (returnType.isEnum()) {
+ // Return type is a typedef. Save its value.
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ Object retValue = m.invoke(fromObj);
+
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ if (retValue != null) {
+ String propName = propNamePfx + "."
+ + fieldName;
+ String propVal = retValue.toString();
+ String yangProp = "yang." + fieldName + "." + propVal;
+ if ( properties.containsKey(yangProp)) {
+ propVal = properties.getProperty(yangProp);
+ }
+ props.setProperty(propName, propVal);
+ }
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert Yang-generated enum returned by "
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ } else if (isIpv4Address(returnType)) {
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (retValue != null) {
+ String propVal = retValue.getValue();
+
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error(
+ CAUGHT_EXCEPTION_MSG
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ } else if (isIpv6Address(returnType)) {
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (retValue != null) {
+ String propVal = retValue.getValue();
+
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error(
+ CAUGHT_EXCEPTION_MSG
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ } else if (isIpv4Prefix(returnType)) {
+
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Ipv4Prefix retValue = (Ipv4Prefix) m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (retValue != null) {
+ String propVal = retValue.getValue();
+
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error(
+ CAUGHT_EXCEPTION_MSG
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ } else if (isIpv6Prefix(returnType)) {
+ //System.out.println("isIpv6Prefix");
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Ipv6Prefix retValue = (Ipv6Prefix) m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (retValue != null) {
+ String propVal = retValue.getValue().toString();
+ //LOG.debug("Setting property " + propName
+ // + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error(
+ CAUGHT_EXCEPTION_MSG
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ } else {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object retValue = m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ if (retValue != null) {
+ toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
+ }
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert Yang-generated class returned by"
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ }
+ } else if (returnType.equals(Class.class)) {
+
+ //LOG.debug(m.getName()
+ // + " returns a Class object - not interested");
+
+ } else if (List.class.isAssignableFrom(returnType)) {
+
+ // This getter method returns a list.
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object retList = m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ // Figure out what type of elements are stored in this array.
+ Type paramType = m.getGenericReturnType();
+ Type elementType = ((ParameterizedType) paramType)
+ .getActualTypeArguments()[0];
+ toProperties(props, propNamePfx + "." + fieldName,
+ retList, (Class)elementType);
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert List returned by "
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+
+ } else {
+
+ // Method returns something that is not a List and not
+ // yang-generated.
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ Object propValObj = m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (propValObj != null) {
+ String propVal = propValObj.toString();
+ //LOG.debug("Setting property " + propName
+ // + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error(
+ CAUGHT_EXCEPTION_MSG
+ + fromClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING, e);
+ }
+ }
+
+ }
+ }
+
+ } else {
+ // Class is not yang generated and not a list
+ // Do nothing.
+
+ }
+
+ return (props);
+ }
+
+ public static Object toBuilder(Properties props, Object toObj) {
+
+ return (toBuilder(props, "", toObj));
+ }
+
+ public static List toList(Properties props, String pfx, List toObj,
+ Class elemType) {
+
+ int maxIdx = -1;
+ boolean foundValue = false;
+
+ //LOG.debug("Saving properties to List<" + elemType.getName()
+ // + "> from " + pfx);
+
+ // Figure out array size
+ for (Object pNameObj : props.keySet()) {
+ String key = (String) pNameObj;
+
+ if (key.startsWith(pfx + "[")) {
+ String idxStr = key.substring(pfx.length() + 1);
+ int endloc = idxStr.indexOf("]");
+ if (endloc != -1) {
+ idxStr = idxStr.substring(0, endloc);
+ }
+
+ try {
+ int curIdx = Integer.parseInt(idxStr);
+ if (curIdx > maxIdx) {
+ maxIdx = curIdx;
+ }
+ } catch (Exception e) {
+ LOG.error("Illegal subscript in property " + key);
+ }
+
+ }
+ }
+
+ //LOG.debug(pfx + " has max index of " + maxIdx);
+ for (int i = 0; i <= maxIdx; i++) {
+
+ String curBase = pfx + "[" + i + "]";
+
+ if (isYangGenerated(elemType)) {
+ String builderName = elemType.getName() + "Builder";
+ try {
+ Class builderClass = Class.forName(builderName);
+ Object builderObj = builderClass.newInstance();
+ Method buildMethod = builderClass.getMethod("build");
+ builderObj = toBuilder(props, curBase, builderObj, true);
+ if (builderObj != null) {
+ //LOG.debug("Calling " + builderObj.getClass().getName()
+ // + "." + buildMethod.getName() + "()");
+ Object builtObj = buildMethod.invoke(builderObj);
+ toObj.add(builtObj);
+ foundValue = true;
+ }
+
+ } catch (ClassNotFoundException e) {
+ LOG.warn("Could not find builder class " + builderName, e);
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to populate list from "
+ + pfx);
+ }
+ }
+
+ }
+
+ if (foundValue) {
+ return (toObj);
+ } else {
+ return (null);
+ }
+
+ }
+
+ public static Object toBuilder(Properties props, String pfx, Object toObj) {
+ return(toBuilder(props, pfx, toObj, false));
+ }
+
+ public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) {
+ Class toClass = toObj.getClass();
+ boolean foundValue = false;
+
+ //LOG.debug("Saving properties to " + toClass.getName() + " class from "
+ // + pfx);
+
+ Ipv4Address addr;
+
+ if (isYangGenerated(toClass)) {
+ // Class is yang generated.
+ //LOG.debug(toClass.getName() + " is a Yang-generated class");
+
+ String propNamePfx = null;
+ if (preservePfx) {
+ propNamePfx = pfx;
+ } else {
+
+ if ((pfx != null) && (pfx.length() > 0)) {
+ propNamePfx = pfx + "."
+ + toLowerHyphen(toClass.getSimpleName());
+ } else {
+ propNamePfx = toLowerHyphen(toClass.getSimpleName());
+ }
+
+ if (propNamePfx.endsWith(BUILDER)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length()
+ - BUILDER.length());
+ }
+
+ if (propNamePfx.endsWith(IMPL)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length()
+ - IMPL.length());
+ }
+ }
+
+ if (toObj instanceof Identifier) {
+ //LOG.debug(toClass.getName() + " is a Key - skipping");
+ return (toObj);
+ }
+
+ // Iterate through getter methods to figure out values we need to
+ // set
+
+ for (Method m : toClass.getMethods()) {
+ // LOG.debug("Is " + m.getName() + " method a setter?");
+ if (isSetter(m)) {
+ // LOG.debug(m.getName() + " is a setter");
+ Class paramTypes[] = m.getParameterTypes();
+ Class paramClass = paramTypes[0];
+
+ String fieldName = toLowerHyphen(m.getName().substring(3));
+ fieldName = fieldName.substring(0, 1).toLowerCase()
+ + fieldName.substring(1);
+
+ String propName = propNamePfx + "." + fieldName;
+
+ String paramValue = props.getProperty(propName);
+ if (paramValue == null) {
+ //LOG.debug(propName + " is unset");
+ } else {
+ //LOG.debug(propName + " = " + paramValue);
+ }
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(paramClass)) {
+ // Is it an enum?
+ if (paramClass.isEnum()) {
+
+ //LOG.debug(m.getName() + " expects an Enum");
+ // Param type is a typedef.
+ if (paramValue != null) {
+ Object paramObj = null;
+
+ try {
+ paramObj = Enum.valueOf(paramClass,
+ toUpperCamelCase(paramValue));
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert field "
+ + propName + " to enum "
+ + paramClass.getName(), e);
+ }
+
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ //LOG.debug("Calling "
+ // + toObj.getClass().getName() + "."
+ // + m.getName() + "(" + paramValue
+ // + ")");
+ m.invoke(toObj, paramObj);
+
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to create Yang-generated enum expected by"
+ + toClass.getName()
+ + "."
+ + m.getName()
+ + "() from Properties entry",
+ e);
+ }
+ }
+ } else {
+
+ String simpleName = paramClass.getSimpleName();
+ LOG.info("simpleName:" + simpleName);
+
+ if ("Ipv4Address".equals(simpleName)
+ || "Ipv6Address".equals(simpleName) || "Ipv4Prefix".equals(simpleName) || "Ipv6Prefix".equals(simpleName)) {
+
+ if (paramValue != null) {
+ if("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName)){
+ try {
+ IpAddress ipAddr = IpAddressBuilder
+ .getDefaultInstance(paramValue);
+
+
+ if ("Ipv4Address".equals(simpleName))
+ {
+ m.invoke(toObj, ipAddr.getIpv4Address());
+ }
+ else
+ {
+ m.invoke(toObj, ipAddr.getIpv6Address());
+
+ }
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception calling "
+ + toClass.getName() + "."
+ + m.getName() + "("
+ + paramValue + ")", e);
+
+ }
+ }else if("Ipv4Prefix".equals(simpleName)|| "Ipv6Prefix".equals(simpleName)){
+ try {
+ IpPrefix ipPrefix = IpPrefixBuilder
+ .getDefaultInstance(paramValue);
+
+
+ if ("Ipv4Prefix".equals(simpleName))
+ {
+ m.invoke(toObj, ipPrefix.getIpv4Prefix());
+ }
+ else
+ {
+ m.invoke(toObj, ipPrefix.getIpv6Prefix());
+
+ }
+ foundValue = true;
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception calling "
+ + toClass.getName() + "."
+ + m.getName() + "("
+ + paramValue + ")", e);
+
+ }
+ }
+ }
+
+ } else {
+ // setter expects a yang-generated class. Need
+ // to
+ // create a builder to set it.
+
+ String builderName = paramClass.getName()
+ + "Builder";
+ Class builderClass = null;
+ Object builderObj = null;
+ Object paramObj = null;
+
+ //LOG.debug(m.getName()
+ // + " expects a yang-generated class - looking for builder "
+ // + builderName);
+ try {
+ builderClass = Class.forName(builderName);
+ builderObj = builderClass.newInstance();
+ paramObj = toBuilder(props, propNamePfx,
+ builderObj);
+ } catch (ClassNotFoundException e) {
+ Object constObj = null;
+ try {
+ // See if I can find a constructor I can
+ // use
+ Constructor[] constructors = paramClass
+ .getConstructors();
+ // Is there a String constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c
+ .getParameterTypes();
+ if ((cParms != null)
+ && (cParms.length == 1)) {
+ if (String.class
+ .isAssignableFrom(cParms[0])) {
+ constObj = c
+ .newInstance(paramValue);
+ }
+ }
+ }
+
+ if (constObj == null) {
+ // Is there a Long constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c
+ .getParameterTypes();
+ if ((cParms != null)
+ && (cParms.length == 1)) {
+ if (Long.class
+ .isAssignableFrom(cParms[0])) {
+ constObj = c
+ .newInstance(Long
+ .parseLong(paramValue));
+ }
+ }
+ }
+
+ }
+
+ if (constObj != null) {
+ try {
+ m.invoke(toObj, constObj);
+ foundValue = true;
+ } catch (Exception e2) {
+ LOG.error(
+ "Caught exception trying to call "
+ + m.getName(),
+ e2);
+ }
+ }
+ } catch (Exception e1) {
+ LOG.warn(
+ "Could not find a suitable constructor for "
+ + paramClass.getName(),
+ e1);
+ }
+
+ if (paramObj == null) {
+ LOG.warn("Could not find builder class "
+ + builderName
+ + " and could not find a String or Long constructor - trying just to set passing paramValue");
+
+ }
+
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to create builder "
+ + builderName, e);
+ }
+
+ if (paramObj != null) {
+
+ try {
+
+ Method buildMethod = builderClass
+ .getMethod("build");
+ //LOG.debug("Calling "
+ // + paramObj.getClass().getName()
+ // + "." + buildMethod.getName()
+ // + "()");
+ Object builtObj = buildMethod
+ .invoke(paramObj);
+
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ //LOG.debug("Calling "
+ // + toObj.getClass().getName()
+ // + "." + m.getName() + "()");
+ m.invoke(toObj, builtObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to set Yang-generated class expected by"
+ + toClass.getName()
+ + "."
+ + m.getName()
+ + "() from Properties entry",
+ e);
+ }
+ } else {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ //LOG.debug("Calling "
+ // + toObj.getClass().getName()
+ // + "." + m.getName() + "("
+ // + paramValue + ")");
+ m.invoke(toObj, paramValue);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert value returned by"
+ + toClass.getName()
+ + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING,
+ e);
+ }
+ }
+ }
+ }
+ }else {
+
+ // Setter's argument is not a yang-generated class. See
+ // if it is a List.
+
+ if (List.class.isAssignableFrom(paramClass)) {
+
+ //LOG.debug("Parameter class " + paramClass.getName()
+ // + " is a List");
+
+ // Figure out what type of args are in List and pass
+ // that to toList().
+
+ Type paramType = m.getGenericParameterTypes()[0];
+ Type elementType = ((ParameterizedType) paramType)
+ .getActualTypeArguments()[0];
+ Object paramObj = new LinkedList();
+ try {
+ paramObj = toList(props, propName,
+ (List) paramObj, (Class) elementType);
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to create list expected as argument to "
+ + toClass.getName() + "." + m.getName());
+ }
+
+ if (paramObj != null) {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ //LOG.debug("Calling "
+ // + toObj.getClass().getName() + "."
+ // + m.getName() + "(" + paramValue
+ // + ")");
+ m.invoke(toObj, paramObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert List returned by"
+ + toClass.getName() + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING,
+ e);
+ }
+ }
+ } else {
+
+ // Setter expects something that is not a List and
+ // not yang-generated. Just pass the parameter value
+
+ //LOG.debug("Parameter class "
+ // + paramClass.getName()
+ // + " is not a yang-generated class or a List");
+
+ if (paramValue != null) {
+
+ Object constObj = null;
+
+ try {
+ // See if I can find a constructor I can use
+ Constructor[] constructors = paramClass
+ .getConstructors();
+ // Is there a String constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c.getParameterTypes();
+ if ((cParms != null)
+ && (cParms.length == 1)) {
+ if (String.class
+ .isAssignableFrom(cParms[0])) {
+ constObj = c
+ .newInstance(paramValue);
+ }
+ }
+ }
+
+ if (constObj == null) {
+ // Is there a Long constructor?
+ for (Constructor c : constructors) {
+ Class[] cParms = c
+ .getParameterTypes();
+ if ((cParms != null)
+ && (cParms.length == 1)) {
+ if (Long.class
+ .isAssignableFrom(cParms[0])) {
+ constObj = c
+ .newInstance(Long
+ .parseLong(paramValue));
+ }
+ }
+ }
+
+ }
+
+ if (constObj != null) {
+ try {
+ //LOG.debug("Calling "
+ // + toObj.getClass()
+ // .getName() + "."
+ // + m.getName() + "("
+ // + constObj + ")");
+ m.invoke(toObj, constObj);
+ foundValue = true;
+ } catch (Exception e2) {
+ LOG.error(
+ "Caught exception trying to call "
+ + m.getName(), e2);
+ }
+ } else {
+ try {
+ boolean isAccessible = m
+ .isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ //LOG.debug("Calling "
+ // + toObj.getClass()
+ // .getName() + "."
+ // + m.getName() + "("
+ // + paramValue + ")");
+ m.invoke(toObj, paramValue);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ foundValue = true;
+
+ } catch (Exception e) {
+ LOG.error(
+ "Caught exception trying to convert value returned by"
+ + toClass.getName()
+ + "."
+ + m.getName()
+ + TO_PROPERTIES_STRING,
+ e);
+ }
+ }
+ } catch (Exception e1) {
+ LOG.warn(
+ "Could not find a suitable constructor for "
+ + paramClass.getName(), e1);
+ }
+
+ /*
+ * try { boolean isAccessible =
+ * m.isAccessible(); if (!isAccessible) {
+ * m.setAccessible(true); } LOG.debug("Calling "
+ * + toObj.getClass().getName() + "." +
+ * m.getName() + "(" + paramValue + ")");
+ * m.invoke(toObj, paramValue); if
+ * (!isAccessible) {
+ * m.setAccessible(isAccessible); } foundValue =
+ * true;
+ *
+ * } catch (Exception e) { LOG.error(
+ * "Caught exception trying to convert value returned by"
+ * + toClass.getName() + "." + m.getName() +
+ * "() to Properties entry", e); }
+ */
+ }
+ }
+ }
+ } // End of section handling "setter" method
+ } // End of loop through Methods
+ } // End of section handling yang-generated class
+
+ if (foundValue) {
+ return (toObj);
+ } else {
+ return (null);
+ }
+ }
+
+ public static Properties getProperties(PrintStream pstr, String pfx,
+ Class toClass) {
+ boolean foundValue = false;
+
+ //LOG.debug("Analyzing " + toClass.getName() + " class : pfx " + pfx);
+
+ if (isYangGenerated(toClass)
+ && (!Identifier.class.isAssignableFrom(toClass))) {
+ // Class is yang generated.
+ //LOG.debug(toClass.getName() + " is a Yang-generated class");
+
+ if (toClass.getName().endsWith("Key")) {
+ if (Identifier.class.isAssignableFrom(toClass)) {
+ //LOG.debug(Identifier.class.getName()
+ // + " is assignable from " + toClass.getName());
+ } else {
+
+ //LOG.debug(Identifier.class.getName()
+ // + " is NOT assignable from " + toClass.getName());
+ }
+ }
+
+ String propNamePfx = null;
+ if (pfx.endsWith("]")) {
+ propNamePfx = pfx;
+ }else if(pfx.indexOf(".CLASS_FOUND") != -1){
+ pfx = pfx.replace(".CLASS_FOUND","");
+ propNamePfx = pfx + "."
+ + toLowerHyphen(toClass.getSimpleName());
+ } else {
+
+ if ((pfx != null) && (pfx.length() > 0)) {
+ propNamePfx = pfx + "."
+ + toLowerHyphen(toClass.getSimpleName());
+ } else {
+ propNamePfx = toLowerHyphen(toClass.getSimpleName());
+ }
+
+ if (propNamePfx.endsWith(BUILDER)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length()
+ - BUILDER.length());
+ }
+
+ if (propNamePfx.endsWith(IMPL)) {
+ propNamePfx = propNamePfx.substring(0, propNamePfx.length()
+ - IMPL.length());
+ }
+ }
+
+ // Iterate through getter methods to figure out values we need to
+ // set
+
+ for (Method m : toClass.getMethods()) {
+ //LOG.debug("Is " + m.getName() + " method a getter?");
+ if (isGetter(m)) {
+ // LOG.debug(m.getName() + " is a getter");
+ Class returnClass = m.getReturnType();
+
+ String fieldName = toLowerHyphen(m.getName().substring(3));
+ if(m != null && m.getName().matches("^is[A-Z].*")){
+ fieldName = toLowerHyphen(m.getName().substring(2));
+ }
+ fieldName = fieldName.substring(0, 1).toLowerCase()
+ + fieldName.substring(1);
+
+ String propName = propNamePfx + "." + fieldName;
+ //System.out.println("****" + propName);
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(returnClass)) {
+ // Is it an enum?
+ if (returnClass.isEnum()) {
+
+ //LOG.debug(m.getName() + " is an Enum");
+ //pstr.print("\n" + propName);
+ //pstr.print("\n" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\n");
+ pstr.print("\"" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+
+ } else {
+
+ String simpleName = returnClass.getSimpleName();
+ //System.out.println("simpleName:" + simpleName);
+
+ if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "Ipv4Prefix".equals(simpleName) || "Ipv6Prefix".equals(simpleName) || "IpPrefix".equals(simpleName)) {
+ //LOG.debug(m.getName()+" is an "+simpleName);
+ //pstr.print("\n" + propName);
+ //pstr.print("\n" + propName + ":" + simpleName + "\n");
+ pstr.print("\"" + propName + ":" + simpleName + "\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ } else {
+ boolean isString = false;
+ boolean isNumber = false;
+ boolean isBoolean = false;
+ boolean isIdentifier = false;
+ //System.out.println("simpleName:" + simpleName);
+ //System.out.println("propName:" + propName);
+ for(Method mthd : returnClass.getMethods()){
+ String methodName = mthd.getName();
+ //System.out.println("methodName:" + methodName);
+ if(methodName.equals("getValue")){
+ Class retType = mthd.getReturnType();
+ //System.out.println("retType:" + retType);
+ isString = String.class.isAssignableFrom(retType);
+ isNumber = Number.class.isAssignableFrom(retType);
+ isBoolean = Boolean.class.isAssignableFrom(retType);
+ isIdentifier = Identifier.class.isAssignableFrom(retType);
+ //System.out.println("isString:" + isString);
+ //System.out.println("isNumber:" + isNumber);
+ //System.out.println("isNumber:" + isNumber);
+ break;
+ }
+ }
+
+ if(isString){
+ pstr.print("\"" + propName + ":String\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }else if(isNumber){
+ pstr.print("\"" + propName + ":Number\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }else if(isBoolean){
+ pstr.print("\"" + propName + ":Boolean\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }else if(isIdentifier){
+ //System.out.println("isIdentifier");
+ //isIdentifer so skipping
+ continue;
+ }else{
+ /*
+ System.out.println("fieldName:" + fieldName);
+ System.out.println("simpleName:" + simpleName);
+ System.out.println("returnClass:" + returnClass);
+ System.out.println("pstr:" + pstr);
+ System.out.println("propNamePfx:" + propNamePfx);
+ */
+ getProperties(pstr, propNamePfx + ".CLASS_FOUND", returnClass);
+ }
+ }
+
+ }
+ } else {
+
+ // Setter's argument is not a yang-generated class. See
+ // if it is a List.
+
+ if (List.class.isAssignableFrom(returnClass)) {
+
+ //LOG.debug("Parameter class "
+ // + returnClass.getName() + " is a List");
+
+ // Figure out what type of args are in List and pass
+ // that to toList().
+
+ Type returnType = m.getGenericReturnType();
+ Type elementType = ((ParameterizedType) returnType)
+ .getActualTypeArguments()[0];
+ Class elementClass = (Class) elementType;
+ //LOG.debug("Calling printPropertyList on list type ("
+ //+ elementClass.getName()
+ // + "), pfx is ("
+ // + pfx
+ // + "), toClass is ("
+ // + toClass.getName() + ")");
+ //System.out.println("List propNamePfx:" + propNamePfx+ "." + toLowerHyphen(elementClass.getSimpleName()) + "[]");
+ if(String.class.isAssignableFrom(elementClass)){
+ pstr.print("\"" + propName + ":[String,String,...]\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }else if(Number.class.isAssignableFrom(elementClass)){
+ pstr.print("\"" + propName + ":[Number,Number,...]\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }else if(Boolean.class.isAssignableFrom(elementClass)){
+ pstr.print("\"" + propName + ":[Boolean,Boolean,...]\",");
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }else if(Identifier.class.isAssignableFrom(elementClass)){
+ continue;
+ }else{
+ getProperties(
+ pstr,
+ propNamePfx
+ + "."
+ + toLowerHyphen(elementClass
+ .getSimpleName()) + "[]",
+ elementClass);
+ }
+
+ } else if (!returnClass.equals(Class.class)) {
+
+ // Setter expects something that is not a List and
+ // not yang-generated. Just pass the parameter value
+
+ //LOG.debug("Parameter class "
+ // + returnClass.getName()
+ // + " is not a yang-generated class or a List");
+
+ //pstr.print("\n" + propName);
+ String className=returnClass.getName();
+ int nClassNameIndex = className.lastIndexOf('.');
+ String nClassName = className;
+ if(nClassNameIndex != -1){
+ nClassName=className.substring(nClassNameIndex+1);
+ }
+ boolean isString = String.class.isAssignableFrom(returnClass);
+ boolean isNumber = Number.class.isAssignableFrom(returnClass);
+ boolean isBoolean = Boolean.class.isAssignableFrom(returnClass);
+ //pstr.print("\n" + propName +":" + nClassName +"\n");
+ boolean isIdentifier = Identifier.class.isAssignableFrom(returnClass);
+ if(!isIdentifier && !nClassName.equals("[C")){
+ if(isNumber){
+ pstr.print("\"" + propName +":Number\",");
+ }else if(isBoolean){
+ pstr.print("\"" + propName +":Boolean\",");
+ }else{
+ if(nClassName.equals("[B")){
+ pstr.print("\"" + propName +":Binary\",");
+ }else{
+ pstr.print("\"" + propName +":" + nClassName +"\",");
+ }
+ }
+ prop.setProperty(propName,"");
+ propList.add(propName);
+ }
+
+ }
+ }
+ } // End of section handling "setter" method
+ } // End of loop through Methods
+ } // End of section handling yang-generated class
+
+ return prop;
+ }
+
+ public static boolean isYangGenerated(Class c) {
+ if (c == null) {
+ return (false);
+ } else {
+ //System.out.println(c.getName());
+ return (c.getName().startsWith("org.opendaylight.yang.gen."));
+ }
+ }
+
+ public static boolean isIpv4Address(Class c) {
+
+ if (c == null ) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return ("Ipv4Address".equals(simpleName)) ;
+ }
+
+ public static boolean isIpv6Address(Class c) {
+
+ if (c == null ) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return ("Ipv6Address".equals(simpleName)) ;
+ }
+ public static boolean isIpv4Prefix(Class c) {
+
+ if (c == null ) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ //System.out.println("simpleName:" + simpleName);
+ return ("Ipv4Prefix".equals(simpleName)) ;
+ }
+
+ public static boolean isIpv6Prefix(Class c) {
+
+ if (c == null ) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ //System.out.println("simpleName:" + simpleName);
+ return ("Ipv6Prefix".equals(simpleName)) ;
+ }
+
+ public static String toLowerHyphen(String inStr) {
+ if (inStr == null) {
+ return (null);
+ }
+
+ String str = inStr.substring(0, 1).toLowerCase();
+ if (inStr.length() > 1) {
+ str = str + inStr.substring(1);
+ }
+
+ String regex = "([a-z0-9A-Z])(?=[A-Z])";
+ String replacement = "$1-";
+
+ String retval = str.replaceAll(regex, replacement).toLowerCase();
+
+ //LOG.debug("Converting " + inStr + " => " + str + " => " + retval);
+ return (retval);
+ }
+
+ public static String toUpperCamelCase(String inStr) {
+ if (inStr == null) {
+ return (null);
+ }
+
+ String[] terms = inStr.split("-");
+ StringBuffer sbuff = new StringBuffer();
+ // Check if string begins with a digit
+ if (Character.isDigit(inStr.charAt(0))) {
+ sbuff.append('_');
+ }
+ for (String term : terms) {
+ sbuff.append(term.substring(0, 1).toUpperCase());
+ if (term.length() > 1) {
+ sbuff.append(term.substring(1));
+ }
+ }
+ return (sbuff.toString());
+
+ }
+
+ public static boolean isGetter(Method m) {
+ //System.out.println(m);
+ if (m == null) {
+ return (false);
+ }
+
+ if (Modifier.isPublic(m.getModifiers())
+ && (m.getParameterTypes().length == 0)) {
+ if ((m.getName().matches("^is[A-Z].*") || m.getName().matches("^get[A-Z].*"))
+ && m.getReturnType().equals(Boolean.class)) {
+ return (true);
+ }
+ if (m.getName().matches("^get[A-Z].*")
+ && !m.getReturnType().equals(void.class)) {
+ return (true);
+ }
+
+ }
+
+ return (false);
+ }
+
+ public static boolean isSetter(Method m) {
+ if (m == null) {
+ return (false);
+ }
+
+ if (Modifier.isPublic(m.getModifiers())
+ && (m.getParameterTypes().length == 1)) {
+ if (m.getName().matches("^set[A-Z].*")) {
+ Class[] paramTypes = m.getParameterTypes();
+ if (paramTypes[0].isAssignableFrom(Identifier.class)
+ || Identifier.class.isAssignableFrom(paramTypes[0])) {
+ return (false);
+ } else {
+ return (true);
+ }
+ }
+
+ }
+
+ return (false);
+ }
+
+ public static void main(String[] args){
+
+ try(PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out))){
+ PrintYangToProp printYangToProp = new PrintYangToProp();
+ String className = args[0];
+ //ClassLoader classLoader = PrintYangToProp.class.getClassLoader();
+ //Class aClass = classLoader.loadClass(className);
+ Class cl = Class.forName(className);
+ //printPropertyList(ps,"",cl);
+ //JsonObject jsonObj = Json.createObjectBuilder().build();
+ Properties p = getProperties(ps,"",cl);
+ //System.out.println(p);
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+
+}
diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java
new file mode 100644
index 000000000..08e957f1d
--- /dev/null
+++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java
@@ -0,0 +1,98 @@
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import java.util.HashMap;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicResolver;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicClassResolver implements SvcLogicResolver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicClassResolver.class);
+ private static HashMap<String, SvcLogicAdaptor> adaptorMap = new HashMap<>();
+
+ public void registerAdaptor(SvcLogicAdaptor adaptor) {
+ String name = adaptor.getClass().getName();
+ LOG.info("Registering adaptor " + name);
+ adaptorMap.put(name, adaptor);
+
+ }
+
+ public void unregisterAdaptor(String name) {
+ if (adaptorMap.containsKey(name)) {
+ LOG.info("Unregistering " + name);
+ adaptorMap.remove(name);
+ }
+ }
+
+ private SvcLogicAdaptor getAdaptorInstance(String name) {
+ if (adaptorMap.containsKey(name)) {
+ return adaptorMap.get(name);
+ } else {
+
+ SvcLogicAdaptor adaptor = (SvcLogicAdaptor) resolve(name);
+
+ if (adaptor != null) {
+ registerAdaptor(adaptor);
+ }
+
+ return adaptor;
+ }
+ }
+
+ private Object resolve(String className) {
+
+ Bundle bundle = FrameworkUtil.getBundle(SvcLogicClassResolver.class);
+
+ if (bundle == null) {
+ // Running outside OSGi container (e.g. jUnit). Use Reflection
+ // to resolve class
+ try {
+ return (Class.forName(className).newInstance());
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+
+ LOG.error("Could not resolve class " + className, e);
+ return null;
+ }
+
+ } else {
+ BundleContext bctx = bundle.getBundleContext();
+ ServiceReference sref = bctx.getServiceReference(className);
+ if (sref != null) {
+ return bctx.getService(sref);
+ } else {
+
+ LOG.warn("Could not find service reference object for class " + className);
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public SvcLogicResource getSvcLogicResource(String resourceName) {
+ return (SvcLogicResource) resolve(resourceName);
+ }
+
+ @Override
+ public SvcLogicRecorder getSvcLogicRecorder(String recorderName) {
+ return (SvcLogicRecorder) resolve(recorderName);
+ }
+
+ @Override
+ public SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) {
+ return (SvcLogicJavaPlugin) resolve(pluginName);
+ }
+
+ @Override
+ public SvcLogicAdaptor getSvcLogicAdaptor(String adaptorName) {
+ return getAdaptorInstance(adaptorName);
+ }
+
+}
diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java
new file mode 100644
index 000000000..aad7a5a6d
--- /dev/null
+++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java
@@ -0,0 +1,189 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * onap
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 ONAP
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.onap.ccsdk.sli.core.sli.ConfigurationException;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider;
+import org.onap.ccsdk.sli.core.utils.JREFileResolver;
+import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver;
+import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for determining the properties file to use and instantiating the
+ * <code>DBResourceManager</code> Service. The priority for properties file
+ * resolution is as follows:
+ *
+ * <ol>
+ * <li>A directory identified by the system environment variable
+ * <code>SDNC_CONFIG_DIR</code></li>
+ * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li>
+ * <li>A directory identified by the JRE argument
+ * <code>dblib.properties</code></li>
+ * <li>A <code>dblib.properties</code> file located in the karaf root
+ * directory</li>
+ * </ol>
+ */
+public class SvcLogicPropertiesProviderImpl implements SvcLogicPropertiesProvider {
+
+ private static final Logger log = LoggerFactory.getLogger(SvcLogicPropertiesProviderImpl.class);
+
+ /**
+ * The name of the properties file for database configuration
+ */
+ private static final String SVCLOGIC_PROP_FILE_NAME = "svclogic.properties";
+
+ /**
+ * A prioritized list of strategies for resolving dblib properties files.
+ */
+ private Vector<PropertiesFileResolver> sliPropertiesFileResolvers = new Vector<>();
+
+ /**
+ * The configuration properties for the db connection.
+ */
+ private Properties properties;
+
+ /**
+ * Set up the prioritized list of strategies for resolving dblib properties
+ * files.
+ */
+ public SvcLogicPropertiesProviderImpl() {
+ sliPropertiesFileResolvers
+ .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable"));
+ sliPropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory"));
+
+ sliPropertiesFileResolvers.add(
+ new JREFileResolver("Using property file (3) from JRE argument", SvcLogicPropertiesProviderImpl.class));
+ sliPropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this));
+
+ // determines properties file as according to the priority described in the
+ // class header comment
+ final File propertiesFile = determinePropertiesFile(this);
+ if (propertiesFile != null) {
+ try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) {
+ properties = new Properties();
+ properties.load(fileInputStream);
+ } catch (final IOException e) {
+ log.error("Failed to load properties for file: {}", propertiesFile.toString(),
+ new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(),
+ e));
+ }
+ } else {
+ // Try to read properties as resource
+
+ InputStream propStr = getClass().getResourceAsStream("/" + SVCLOGIC_PROP_FILE_NAME);
+ if (propStr != null) {
+ properties = new Properties();
+ try {
+ properties.load(propStr);
+ propStr.close();
+ } catch (IOException e) {
+ log.error("IO Exception",e);
+ properties = null;
+ }
+ }
+
+ }
+
+ if (properties == null) {
+ reportFailure("Missing configuration properties resource(3)", new ConfigurationException(
+ "Missing configuration properties resource(3): " + SVCLOGIC_PROP_FILE_NAME));
+ }
+ }
+
+ /**
+ * Extract svclogic config properties.
+ *
+ * @return the svclogic config properties
+ */
+ public Properties getProperties() {
+ return properties;
+ }
+
+ /**
+ * Reports the method chosen for properties resolution to the
+ * <code>Logger</code>.
+ *
+ * @param message
+ * Some user friendly message
+ * @param fileOptional
+ * The file location of the chosen properties file
+ * @return the file location of the chosen properties file
+ */
+ private static File reportSuccess(final String message, final Optional<File> fileOptional) {
+ if (fileOptional.isPresent()) {
+ final File file = fileOptional.get();
+ log.info("{} {}", message, file.getPath());
+ return file;
+ }
+ return null;
+ }
+
+ /**
+ * Reports fatal errors. This is the case in which no properties file could be
+ * found.
+ *
+ * @param message
+ * An appropriate fatal error message
+ * @param configurationException
+ * An exception describing what went wrong during resolution
+ */
+ private static void reportFailure(final String message, final ConfigurationException configurationException) {
+
+ log.error("{}", message, configurationException);
+ }
+
+ /**
+ * Determines the dblib properties file to use based on the following priority:
+ * <ol>
+ * <li>A directory identified by the system environment variable
+ * <code>SDNC_CONFIG_DIR</code></li>
+ * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li>
+ * <li>A directory identified by the JRE argument
+ * <code>dblib.properties</code></li>
+ * <li>A <code>dblib.properties</code> file located in the karaf root
+ * directory</li>
+ * </ol>
+ */
+ File determinePropertiesFile(final SvcLogicPropertiesProviderImpl resourceProvider) {
+
+ for (final PropertiesFileResolver sliPropertiesFileResolver : sliPropertiesFileResolvers) {
+ final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(SVCLOGIC_PROP_FILE_NAME);
+ if (fileOptional.isPresent()) {
+ return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional);
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java
new file mode 100644
index 000000000..a23594ee3
--- /dev/null
+++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider;
+
+import java.util.Properties;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+
+public interface SvcLogicService extends SvcLogicServiceBase {
+
+ String NAME = "org.onap.ccsdk.sli.core.sli.provider.SvcLogicService";
+
+ @Deprecated
+ Properties execute(String module, String rpc, String version, String mode, Properties parms) throws SvcLogicException;
+
+ /**
+ * Execute a directed graph
+ *
+ * @param module - module name
+ * @param rpc - rpc name
+ * @param version - version. If null, use active version
+ * @param mode - mode (sync/async)
+ * @param parms - parameters, used to set SvcLogicContext attributes
+ * @param domDataBroker - DOMDataBroker object
+ * @return final values of attributes from SvcLogicContext, as Properties
+ * @throws SvcLogicException
+ */
+ Properties execute(String module, String rpc, String version, String mode, Properties parms, DOMDataBroker domDataBroker) throws SvcLogicException;
+
+
+}
diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java
new file mode 100755
index 000000000..92c2aa49a
--- /dev/null
+++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import java.util.Properties;
+import org.onap.ccsdk.sli.core.dblib.DbLibService;
+import org.onap.ccsdk.sli.core.sli.ConfigurationException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicDblibStore;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStoreFactory;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicResolver;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceImplBase;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicServiceImpl extends SvcLogicServiceImplBase implements SvcLogicService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicServiceImpl.class);
+
+ public SvcLogicServiceImpl(SvcLogicPropertiesProvider resourceProvider, SvcLogicResolver resolver)
+ throws SvcLogicException {
+ super(null, resolver);
+ properties = resourceProvider.getProperties();
+ this.store = getStore();
+ }
+
+ public SvcLogicServiceImpl(SvcLogicPropertiesProvider resourceProvider, DbLibService dbSvc,
+ SvcLogicResolver resolver) throws SvcLogicException {
+ super(null, resolver);
+ properties = resourceProvider.getProperties();
+ this.store = new SvcLogicDblibStore(dbSvc);
+ }
+
+ @Override
+ @Deprecated
+ // DomDataBroker is not being used, this should be removed eventually
+ public Properties execute(String module, String rpc, String version, String mode, Properties props,
+ DOMDataBroker domDataBroker) throws SvcLogicException {
+ return (execute(module, rpc, version, mode, props));
+ }
+
+ @Override
+ public SvcLogicStore getStore() throws SvcLogicException {
+ // Create and initialize SvcLogicStore object - used to access
+ // saved service logic.
+ if (store != null) {
+ return store;
+ }
+
+ try {
+ store = SvcLogicStoreFactory.getSvcLogicStore(properties);
+ } catch (Exception e) {
+ throw new ConfigurationException("Could not get service logic store", e);
+
+ }
+
+ try {
+ store.init(properties);
+ } catch (SvcLogicException e) {
+ throw new ConfigurationException("Could not get service logic store", e);
+ }
+
+ return store;
+ }
+
+}
diff --git a/core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml b/core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml
new file mode 100644
index 000000000..fb3ab9a03
--- /dev/null
+++ b/core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <bean id="propProvider" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicPropertiesProviderImpl" />
+ <reference id="dblibService" interface="org.onap.ccsdk.sli.core.dblib.DbLibService" />
+ <bean id="svcLogicClassResolver" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicClassResolver" />
+
+ <bean id="svcLogicService" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicServiceImpl">
+ <argument ref="propProvider" />
+ <argument ref="dblibService" />
+ <argument ref="svcLogicClassResolver" />
+ </bean>
+
+ <service ref="svcLogicService">
+ <interfaces>
+ <value>org.onap.ccsdk.sli.core.sli.provider.SvcLogicService</value>
+ </interfaces>
+ </service>
+
+ <bean id="fileRecorder" class="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" />
+ <!-- Implementation name was chosen over interface name due to the fact that this Service
+ was previously registered using the implementation name rather than the interface name.
+ To ensure backwards compatibility with abstractions polling the Service Registry for the
+ fileRecorder, the implementation name was chosen here. -->
+ <service ref="fileRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" />
+
+ <bean id="slf4jRecorder" class="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" />
+ <!-- Implementation name was chosen over interface name due to the fact that this Service
+ was previously registered using the implementation name rather than the interface name.
+ To ensure backwards compatibility with abstractions polling the Service Registry for the
+ slf4jRecorder, the implementation name was chosen here. -->
+ <service ref="slf4jRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" />
+
+</blueprint>
diff --git a/core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml b/core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml
new file mode 100644
index 000000000..fb3ab9a03
--- /dev/null
+++ b/core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <bean id="propProvider" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicPropertiesProviderImpl" />
+ <reference id="dblibService" interface="org.onap.ccsdk.sli.core.dblib.DbLibService" />
+ <bean id="svcLogicClassResolver" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicClassResolver" />
+
+ <bean id="svcLogicService" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicServiceImpl">
+ <argument ref="propProvider" />
+ <argument ref="dblibService" />
+ <argument ref="svcLogicClassResolver" />
+ </bean>
+
+ <service ref="svcLogicService">
+ <interfaces>
+ <value>org.onap.ccsdk.sli.core.sli.provider.SvcLogicService</value>
+ </interfaces>
+ </service>
+
+ <bean id="fileRecorder" class="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" />
+ <!-- Implementation name was chosen over interface name due to the fact that this Service
+ was previously registered using the implementation name rather than the interface name.
+ To ensure backwards compatibility with abstractions polling the Service Registry for the
+ fileRecorder, the implementation name was chosen here. -->
+ <service ref="fileRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" />
+
+ <bean id="slf4jRecorder" class="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" />
+ <!-- Implementation name was chosen over interface name due to the fact that this Service
+ was previously registered using the implementation name rather than the interface name.
+ To ensure backwards compatibility with abstractions polling the Service Registry for the
+ slf4jRecorder, the implementation name was chosen here. -->
+ <service ref="slf4jRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" />
+
+</blueprint>
diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java
new file mode 100644
index 000000000..ad439cdb4
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java
@@ -0,0 +1,265 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Properties;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicParser;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStoreFactory;
+import org.onap.ccsdk.sli.core.sli.provider.base.AbstractSvcLogicNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.BlockNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.BreakNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.CallNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ConfigureNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.DeleteNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ExecuteNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ExistsNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ForNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.GetResourceNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.IsAvailableNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.NotifyNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.RecordNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ReleaseNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ReserveNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.ReturnNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.SaveNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.SetNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider;
+import org.onap.ccsdk.sli.core.sli.provider.base.SwitchNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.UpdateNodeExecutor;
+import org.onap.ccsdk.sli.core.sli.provider.base.WhileNodeExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ITCaseSvcLogicGraphExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicGraph.class);
+ private static final Map<String, AbstractSvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, AbstractSvcLogicNodeExecutor>() {
+ {
+ put("block", new BlockNodeExecutor());
+ put("break", new BreakNodeExecutor());
+ put("call", new CallNodeExecutor());
+ put("configure", new ConfigureNodeExecutor());
+ put("delete", new DeleteNodeExecutor());
+ put("execute", new ExecuteNodeExecutor());
+ put("exists", new ExistsNodeExecutor());
+ put("for", new ForNodeExecutor());
+ put("get-resource", new GetResourceNodeExecutor());
+ put("is-available", new IsAvailableNodeExecutor());
+ put("notify", new NotifyNodeExecutor());
+ put("record", new RecordNodeExecutor());
+ put("release", new ReleaseNodeExecutor());
+ put("reserve", new ReserveNodeExecutor());
+ put("return", new ReturnNodeExecutor());
+ put("save", new SaveNodeExecutor());
+ put("set", new SetNodeExecutor());
+ put("switch", new SwitchNodeExecutor());
+ put("update", new UpdateNodeExecutor());
+ put("while", new WhileNodeExecutor());
+
+ }
+ };
+
+ private static SvcLogicClassResolver svcLogicClassResolver;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+
+ LOG.info("before class");
+
+ InputStream propStr = ITCaseSvcLogicGraphExecutor.class.getResourceAsStream("/svclogic.properties");
+
+ Properties svcprops = new Properties();
+ svcprops.load(propStr);
+
+ SvcLogicStore store = SvcLogicStoreFactory.getSvcLogicStore(svcprops);
+
+ assertNotNull(store);
+
+ SvcLogicParser parser = new SvcLogicParser();
+
+ SvcLogicPropertiesProvider resourceProvider = new SvcLogicPropertiesProviderImpl();
+ svcLogicClassResolver = new SvcLogicClassResolver();
+ SvcLogicServiceImpl svc = new SvcLogicServiceImpl(resourceProvider, svcLogicClassResolver);
+
+ for (String nodeType : BUILTIN_NODES.keySet()) {
+ svc.registerExecutor(nodeType, BUILTIN_NODES.get(nodeType));
+ }
+
+
+
+
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ LOG.info("after class");
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ LOG.info("before");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ LOG.info("after");
+ }
+
+ @Test
+ public void testExecute() {
+
+ try {
+ InputStream testStr = getClass().getResourceAsStream("/executor.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+
+ InputStream propStr = getClass().getResourceAsStream("/svclogic.properties");
+
+ Properties svcprops = new Properties();
+ svcprops.load(propStr);
+
+
+
+
+ SvcLogicParser parser = new SvcLogicParser();
+
+ // Loop through executor tests
+ SvcLogicPropertiesProvider resourceProvider = new SvcLogicPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return svcprops;
+ }
+ };
+ SvcLogicServiceImpl svc = new SvcLogicServiceImpl(resourceProvider, svcLogicClassResolver);
+ SvcLogicStore store = svc.getStore();
+ assertNotNull(store);
+ for (String nodeType : BUILTIN_NODES.keySet()) {
+
+
+ svc.registerExecutor(nodeType, BUILTIN_NODES.get(nodeType));
+
+ }
+ String testCaseLine = null;
+ while ((testCaseLine = testsReader.readLine()) != null) {
+
+ String[] testCaseFields = testCaseLine.split(":");
+ String testCaseFile = testCaseFields[0];
+ String testCaseMethod = testCaseFields[1];
+ String testCaseParameters = null;
+
+ if (testCaseFields.length > 2) {
+ testCaseParameters = testCaseFields[2];
+ }
+
+ SvcLogicContext ctx = new SvcLogicContext();
+ if (testCaseParameters != null) {
+ String[] testCaseParameterSettings = testCaseParameters.split(",");
+
+ for (int i = 0; i < testCaseParameterSettings.length; i++) {
+ String[] nameValue = testCaseParameterSettings[i].split("=");
+ if (nameValue != null) {
+ String name = nameValue[0];
+ String value = "";
+ if (nameValue.length > 1) {
+ value = nameValue[1];
+ }
+
+ ctx.setAttribute(name, value);
+ }
+ }
+ }
+
+ testCaseFile = testCaseFile.trim();
+
+ if (testCaseFile.length() > 0) {
+ if (!testCaseFile.startsWith("/")) {
+ testCaseFile = "/" + testCaseFile;
+ }
+ URL testCaseUrl = getClass().getResource(testCaseFile);
+ if (testCaseUrl == null) {
+ fail("Could not resolve test case file " + testCaseFile);
+ }
+
+
+ LinkedList<SvcLogicGraph> graphs = parser.parse(testCaseUrl.getPath());
+
+ assertNotNull(graphs);
+
+ // Load grqphs into db to support call node
+ SvcLogicParser.load(testCaseUrl.getPath(), store);
+ SvcLogicParser.activate("neutron", "canCreateNetwork", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "switchTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "forRecordTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "whileNodeTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "resourceTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "configureTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "javaPluginTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "allNodesTester", "1.0.0", "sync", store);
+ SvcLogicParser.activate("neutron", "networkCreated", "1.0.0", "sync", store);
+
+ for (SvcLogicGraph graph : graphs) {
+ if (graph.getRpc().equals(testCaseMethod)) {
+ Properties props = ctx.toProperties();
+ LOG.info("SvcLogicContext before executing {}:", testCaseMethod);
+ for (Enumeration e1 = props.propertyNames(); e1.hasMoreElements(); ) {
+ String propName = (String) e1.nextElement();
+ LOG.info(propName + " = " + props.getProperty(propName));
+ }
+
+ svc.execute(graph, ctx);
+
+ props = ctx.toProperties();
+ LOG.info("SvcLogicContext after executing {}:", testCaseMethod);
+ for (Enumeration e2 = props.propertyNames(); e2.hasMoreElements(); ) {
+ String propName = (String) e2.nextElement();
+ LOG.info(propName + " = " + props.getProperty(propName));
+ }
+ }
+ }
+
+ }
+ }
+
+ } catch (Exception e) {
+ LOG.error("Caught exception executing directed graphs", e);
+ fail("Exception executing graphs");
+ }
+ }
+}
diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java
new file mode 100755
index 000000000..93d9931d0
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java
@@ -0,0 +1,763 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.Inet6Address;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInput.Mode;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameter;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameterBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Builtin.SampleBits;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Builtin.SampleEnumeration;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Builtin.SampleUnion;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Percentage;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.SampleContainer;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.SampleContainerBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.sample.container.LoginBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.sample.container.login.CustomerAddresses;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.sample.container.login.CustomerAddressesBuilder;
+import org.opendaylight.yang.gen.v1.test.TestObjectBuilder;
+import org.opendaylight.yang.gen.v1.test.WrapperObj;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.DomainName;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.HostBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZoneBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpVersion;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import junit.framework.TestCase;
+
+public class MdsalHelperTest extends TestCase {
+ private static final Logger LOG = LoggerFactory.getLogger(MdsalHelperTest.class);
+ public static final String pathToSdnPropertiesFile = "src/test/resources/l3sdn.properties";
+
+ public void testSdnProperties() {
+
+ MdsalHelperTesterUtil.loadProperties(pathToSdnPropertiesFile);
+ assertEquals("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "synccomplete"));
+ assertEquals("asynccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "asynccomplete"));
+ assertEquals("notifycomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "notifycomplete"));
+ assertEquals("service-configuration-operation",
+ MdsalHelperTesterUtil.mapEnumeratedValue("rpc-name", "service-configuration-operation"));
+ }
+
+ public void testNegativeSdnProperties() {
+ assertNotSame("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "Synccomplete"));
+ }
+
+ public void testToProperties() {
+
+ ExecuteGraphInputBuilder execBuilder = new ExecuteGraphInputBuilder();
+ SliParameterBuilder parmBuilder = new SliParameterBuilder();
+ List<SliParameter> params = new LinkedList<SliParameter>();
+
+ parmBuilder.setParameterName("boolean-parm");
+ parmBuilder.setBooleanValue(Boolean.TRUE);
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("int-parm");
+ parmBuilder.setBooleanValue(null);
+ parmBuilder.setIntValue(1);
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("str-parm");
+ parmBuilder.setIntValue(null);
+ parmBuilder.setStringValue("hello");
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("ipaddress4-parm");
+ parmBuilder.setStringValue(null);
+ parmBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("127.0.0.1"));
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("ipaddress6-parm");
+ parmBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("ef::1"));
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("ipprefix-parm");
+ parmBuilder.setIpaddressValue(null);
+ parmBuilder.setIpprefixValue(IpPrefixBuilder.getDefaultInstance("10.0.0.0/24"));
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("portnumber-parm");
+ parmBuilder.setIpprefixValue(null);
+ parmBuilder.setPortNumber(PortNumber.getDefaultInstance("8080"));
+ params.add(parmBuilder.build());
+
+ parmBuilder.setParameterName("dcsp-parm");
+ parmBuilder.setPortNumber(null);
+ parmBuilder.setDscp(Dscp.getDefaultInstance("57"));
+ params.add(parmBuilder.build());
+
+ execBuilder.setMode(Mode.Sync);
+ execBuilder.setModuleName("my-module");
+ execBuilder.setRpcName("do-it-now");
+ execBuilder.setSliParameter(params);
+
+ Properties props = new Properties();
+
+ MdsalHelperTesterUtil.toProperties(props, execBuilder);
+
+ LOG.info("Converted to properties");
+ for (Map.Entry<Object, Object> e : props.entrySet()) {
+ LOG.info(e.getKey().toString() + " = " + e.getValue().toString());
+
+ }
+
+ }
+
+ public void testToBuilder() {
+
+ Properties props = new Properties();
+
+ props.setProperty("execute-graph-input.mode", "Sync");
+ props.setProperty("execute-graph-input.module", "my-module");
+ props.setProperty("execute-graph-input.rpc", "do-it-now");
+ props.setProperty("execute-graph-input.sli-parameter[0].parameter-name", "bool-parm");
+ props.setProperty("execute-graph-input.sli-parameter[0].boolean-value", "true");
+ props.setProperty("execute-graph-input,sli-parameter[1].parameter-name", "int-param");
+ props.setProperty("execute-graph-input.sli-parameter[1].int-value", "1");
+ props.setProperty("execute-graph-input.sli-parameter[2].parameter-name", "str-param");
+ props.setProperty("execute-graph-input.sli-parameter[2].str-value", "hello");
+ props.setProperty("execute-graph-input.sli-parameter[3].parameter-name", "ipv4address-param");
+ props.setProperty("execute-graph-input.sli-parameter[3].ipaddress-value", "127.0.0.1");
+ props.setProperty("execute-graph-input.sli-parameter[4].parameter-name", "ipv6address-param");
+ props.setProperty("execute-graph-input.sli-parameter[4].ipaddress-value", "ef::1");
+ ExecuteGraphInputBuilder execBuilder = new ExecuteGraphInputBuilder();
+
+ MdsalHelperTesterUtil.toBuilder(props, execBuilder);
+
+ }
+
+ public void testToJavaEnum() throws Exception {
+ assertEquals("VENDOR6500MODEL", MdsalHelper.toJavaEnum("VENDOR_6500_MODEL"));
+ assertEquals("_2018HelloWorld", MdsalHelper.toJavaEnum("2018Hello World"));
+ assertEquals("SomethingElse", MdsalHelper.toJavaEnum("Something.Else"));
+ assertEquals("MyTestString", MdsalHelper.toJavaEnum("my-test-string"));
+ }
+
+ // During the default enumeration mapping no properties file is needed, the yang
+ // value is returned
+ // by the java object
+ public void testDefaultEnumerationMapping() throws Exception {
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, new WrapperObj());
+ assertEquals("4COS", props.getProperty("wrapper-obj.cos-model-type"));
+ }
+
+ // When no properties file exists the default java value will be returned if
+ // legacy enumeration
+ // mapping is enabled
+ public void testLegacyEnumerationMappingNoProperties() throws Exception {
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, new WrapperObj(), true);
+ assertEquals("_4COS", props.getProperty("wrapper-obj.cos-model-type"));
+ }
+
+ // When a properties file exists & legacy enumeration mapping is enabled the
+ // value from the
+ // properties file should be returned
+ public void testLegacyEnumerationMappingWithProperties() throws Exception {
+ MdsalHelper.loadProperties("src/test/resources/EnumerationMapping.properties");
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, new WrapperObj(), true);
+ assertEquals("HelloWorld", props.getProperty("wrapper-obj.cos-model-type"));
+ }
+
+ public void testSingleIpAddressToProperties() throws Exception {
+ Properties props = new Properties();
+ String ipAddress = "11.11.11.11";
+ MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(ipAddress));
+ assertEquals(ipAddress, props.getProperty(""));
+ ipAddress = "cafe::8888";
+ MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(ipAddress));
+ assertEquals(ipAddress, props.getProperty(""));
+ }
+
+ public void testSingleIpAddressToBuilder() throws Exception {
+ Properties props = new Properties();
+ String ipAddress = "11.11.11.11";
+ props.setProperty("test-object.single-ip", ipAddress);
+ TestObjectBuilder b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+
+ assertEquals(ipAddress, String.valueOf(b.getSingleIp().stringValue()));
+
+ ipAddress = "cafe::8888";
+ props.setProperty("test-object.single-ip", ipAddress);
+ b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(ipAddress, String.valueOf(b.getSingleIp().stringValue()));
+ }
+
+ public void testIpAddressListToProperties() throws Exception {
+ Properties props = new Properties();
+ String ipAddress = "11.11.11.11";
+ TestObjectBuilder b = new TestObjectBuilder();
+ List<IpAddress> ipAddressList = new ArrayList<IpAddress>();
+ ipAddressList.add(IpAddressBuilder.getDefaultInstance(ipAddress));
+ b.setFloatingIp(ipAddressList);
+ MdsalHelper.toProperties(props, b.build());
+ assertEquals(ipAddress, props.getProperty("test-object.floating-ip[0]"));
+ assertEquals("1", props.getProperty("test-object.floating-ip_length"));
+ }
+
+ public void testIpAddressListToBuilder() throws Exception {
+ Properties props = new Properties();
+ String ipaddress = "11.11.11.12";
+ props.setProperty("test-object.floating-ip_length", "1");
+ props.setProperty("test-object.floating-ip[0]", ipaddress);
+ TestObjectBuilder b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(ipaddress, String.valueOf(b.getFloatingIp().get(0).stringValue()));
+
+ props = new Properties();
+ ipaddress = "cafe::8888";
+ props.setProperty("test-object.floating-ip_length", "1");
+ props.setProperty("test-object.floating-ip[0]", ipaddress);
+ b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(ipaddress, String.valueOf(b.getFloatingIp().get(0).stringValue()));
+ }
+
+ public void testSingleIpv4AddressToProperties() throws Exception {
+ Properties props = new Properties();
+ String v4address = "11.11.11.11";
+ MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(v4address).getIpv4Address());
+ assertEquals(v4address, props.getProperty(""));
+ }
+
+ public void testSingleIpv4AddressToBuilder() throws Exception {
+ Properties props = new Properties();
+ String v4address = "11.11.11.11";
+ props.setProperty("test-object.single-ip-v4", v4address);
+ TestObjectBuilder b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(v4address, b.getSingleIpV4().getValue());
+ }
+
+ public void testIpv4AddressListToProperties() throws Exception {
+ Properties props = new Properties();
+ String v4address = "11.11.11.11";
+
+ TestObjectBuilder b = new TestObjectBuilder();
+ List<Ipv4Address> v4list = new ArrayList<Ipv4Address>();
+ v4list.add(IpAddressBuilder.getDefaultInstance(v4address).getIpv4Address());
+ b.setFloatingIpV4(v4list);
+ MdsalHelper.toProperties(props, b.build());
+ assertEquals(v4address, props.getProperty("test-object.floating-ip-v4[0]"));
+ assertEquals("1", props.getProperty("test-object.floating-ip-v4_length"));
+ }
+
+ public void testIpv4AddressListToBuilder() throws Exception {
+ Properties props = new Properties();
+ String v4address = "11.11.11.12";
+ props.setProperty("test-object.floating-ip-v4_length", "1");
+ props.setProperty("test-object.floating-ip-v4[0]", v4address);
+ TestObjectBuilder b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(v4address, b.getFloatingIpV4().get(0).getValue());
+ }
+
+ public void testSingleIpv6AddressToProperties() throws Exception {
+ Properties props = new Properties();
+ String v6address = "cafe::8888";
+ MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(v6address).getIpv6Address());
+ MdsalHelper.toBuilder(props, IpAddressBuilder.getDefaultInstance("cafe::8887"));
+ assertEquals(v6address, props.getProperty(""));
+ }
+
+ public void testSingleIpv6AddressToBuilder() throws Exception {
+ Properties props = new Properties();
+ String v6address = "cafe::8888";
+ props.setProperty("test-object.single-ip-v6", v6address);
+ TestObjectBuilder b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(v6address, b.getSingleIpV6().getValue());
+ }
+
+ public void testIpv6AddressListToProperties() throws Exception {
+ Properties props = new Properties();
+ String v6address = "cafe::8888";
+
+ TestObjectBuilder b = new TestObjectBuilder();
+ List<Ipv6Address> v6list = new ArrayList<Ipv6Address>();
+ v6list.add(IpAddressBuilder.getDefaultInstance(v6address).getIpv6Address());
+ b.setFloatingIpV6(v6list);
+ MdsalHelper.toProperties(props, b.build());
+ assertEquals(v6address, props.getProperty("test-object.floating-ip-v6[0]"));
+ assertEquals("1", props.getProperty("test-object.floating-ip-v6_length"));
+ }
+
+ public void testIpv6AddressListToBuilder() throws Exception {
+ Properties props = new Properties();
+ String v6address = "cafe::8888";
+ props.setProperty("test-object.floating-ip-v6_length", "1");
+ props.setProperty("test-object.floating-ip-v6[0]", v6address);
+ TestObjectBuilder b = new TestObjectBuilder();
+ MdsalHelper.toBuilder(props, b);
+ assertEquals(v6address, b.getFloatingIpV6().get(0).getValue());
+ }
+
+ public void testIpPrefix() throws Exception {
+ String ipPrefix = "10.0.0.0/24";
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, IpPrefixBuilder.getDefaultInstance(ipPrefix));
+ assertEquals(ipPrefix, props.getProperty(""));
+ }
+
+ public void testPortNumber() throws Exception {
+ Properties props = new Properties();
+ String portNumber = "5";
+ MdsalHelper.toProperties(props, PortNumber.getDefaultInstance(portNumber));
+ assertEquals(portNumber, props.getProperty(""));
+ }
+
+ public void testDscp() throws Exception {
+ Properties props = new Properties();
+ String dscp = "1";
+ MdsalHelper.toProperties(props, Dscp.getDefaultInstance(dscp));
+ assertEquals(dscp, props.getProperty(""));
+ }
+
+ public void testIetfInet() throws Exception {
+ Properties props = new Properties();
+ Inet6Address address =
+ IetfInetUtil.INSTANCE.inet6AddressFor(IpAddressBuilder.getDefaultInstance("cafe::8888").getIpv6Address());
+ MdsalHelper.toProperties(props, address);
+ assertEquals("/cafe:0:0:0:0:0:0:8888", props.getProperty(""));
+ }
+
+ public void testAsNumber() throws Exception {
+ String value = "1";
+ Properties props = new Properties();
+ AsNumber num = AsNumber.getDefaultInstance(value);
+ MdsalHelper.toProperties(props, num);
+ assertEquals(value, props.getProperty("as-number"));
+ assertEquals(value, props.getProperty("as-number.value"));
+
+ }
+
+ public void testGetFullPropertiesPath() {
+ String propertiesName = "l3ucpe.properties";
+ String path = MdsalHelper.getFullPropertiesPath(propertiesName);
+ // verify the default works
+ assertEquals("/opt/lsc/controller/configuration/l3ucpe.properties", path);
+ System.setProperty("karaf.home", "/opt/opendaylight/current");
+ path = MdsalHelper.getFullPropertiesPath(propertiesName);
+ // verify the system property is read
+ assertEquals("/opt/opendaylight/current/configuration/l3ucpe.properties", path);
+ }
+
+ public void testToPropertiesWithBinary() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Properties props = new Properties();
+ byte arr[] = new byte[] {1, 6, 3};
+ sampleBuilder.setSampleBinary(arr);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertNotNull(props.get("sample-container.sample-binary"));
+ }
+
+ public void testToPropertiesWithBits() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Boolean fanRunning = true;
+ Boolean hdLed = false;
+ Boolean powerLed = false;
+ SampleBits sampleBits = new SampleBits(fanRunning, hdLed, powerLed);
+ sampleBuilder.setSampleBits(sampleBits);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(fanRunning.toString(), props.get("sample-container.sample-bits.fan-running"));
+ assertEquals(hdLed.toString(), props.get("sample-container.sample-bits.hd-led"));
+ assertEquals(powerLed.toString(), props.get("sample-container.sample-bits.power-led"));
+ }
+
+ public void testToPropertiesWithBoolean() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Boolean myBoolean = true;
+ sampleBuilder.setSampleBoolean(myBoolean);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myBoolean.toString(), props.get("sample-container.sample-boolean"));
+ }
+
+ public void testToPropertiesWithDecimal64() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ BigDecimal myBigDecimal = new BigDecimal(".0000000000000000000000000000001");
+ sampleBuilder.setSampleDecimal64(myBigDecimal);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ // note toString() value is 1E-31
+ assertEquals(myBigDecimal.toString(), props.get("sample-container.sample-decimal64"));
+ }
+
+ public void testToPropertiesWithEmpty() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Empty isEmpty = Empty.getInstance();
+ sampleBuilder.setSampleEmpty(isEmpty);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(isEmpty.toString(), props.get("sample-container.sample-empty"));
+ }
+
+ public void testToPropertiesWithEnumeration() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Properties props = new Properties();
+ SampleEnumeration currentEnum = SampleEnumeration.ShelfSlotPort;
+ sampleBuilder.setSampleEnumeration(currentEnum);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals("shelf.slot.port", props.get("sample-container.sample-enumeration"));
+
+ currentEnum = SampleEnumeration.NotAvailable;
+ sampleBuilder.setSampleEnumeration(currentEnum);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals("not available", props.get("sample-container.sample-enumeration"));
+
+ currentEnum = SampleEnumeration.CURRENTLYAVAILABLE;
+ sampleBuilder.setSampleEnumeration(currentEnum);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals("CURRENTLY_AVAILABLE", props.get("sample-container.sample-enumeration"));
+
+ currentEnum = SampleEnumeration._200OK;
+ sampleBuilder.setSampleEnumeration(currentEnum);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals("200OK", props.get("sample-container.sample-enumeration"));
+
+ currentEnum = SampleEnumeration.HyphenSeparatedValue;
+ sampleBuilder.setSampleEnumeration(currentEnum);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals("hyphen-separated-value", props.get("sample-container.sample-enumeration"));
+ }
+
+ // TODO test sampleBuilder.setSampleIdentityref(value);
+
+ public void testToPropertiesWithInt8() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Byte myByte = new Byte("-128");
+ sampleBuilder.setSampleInt8(myByte);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myByte.toString(), props.get("sample-container.sample-int8"));
+ }
+
+ public void testToPropertiesWithInt16() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Short myShort = new Short("-32768");
+ sampleBuilder.setSampleInt16(myShort);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myShort.toString(), props.get("sample-container.sample-int16"));
+ }
+
+ public void testToPropertiesWithInt32() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Integer myInt = new Integer("-32768");
+ sampleBuilder.setSampleInt32(myInt);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myInt.toString(), props.get("sample-container.sample-int32"));
+ }
+
+ public void testToPropertiesWithInt64() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Long myLong = new Long("-9223372036854775808");
+ sampleBuilder.setSampleInt64(myLong);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myLong.toString(), props.get("sample-container.sample-int64"));
+ }
+
+ public void testToPropertiesWithLeafRef() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Boolean myBool = false;
+ sampleBuilder.setSampleLeafref(myBool);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myBool.toString(), props.get("sample-container.sample-leafref"));
+ }
+
+ public void testToPropertiesWithString() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ String myString = "Hello World!";
+ sampleBuilder.setSampleString(myString);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myString.toString(), props.get("sample-container.sample-string"));
+ }
+
+ public void testToPropertiesWithuInt8() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Short myShort = new Short("255");
+ sampleBuilder.setSampleUint8(myShort);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myShort.toString(), props.get("sample-container.sample-uint8"));
+ }
+
+ public void testToPropertiesWithuInt16() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Integer myInt = new Integer("65535");
+ sampleBuilder.setSampleUint16(myInt);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myInt.toString(), props.get("sample-container.sample-uint16"));
+ }
+
+ public void testToPropertiesWithuInt32() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Long myLong = new Long("4294967295");
+ sampleBuilder.setSampleUint32(myLong);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myLong.toString(), props.get("sample-container.sample-uint32"));
+ }
+
+ public void testToPropertiesWithuInt64() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ BigInteger myBigInt = new BigInteger("2432902008176640000");
+ sampleBuilder.setSampleUint64(myBigInt);
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myBigInt.toString(), props.get("sample-container.sample-uint64"));
+ }
+
+ public void testToPropertiesFromBuilderUnion() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Properties props = new Properties();
+
+ Integer myInt = new Integer("1");
+ SampleUnion test = new SampleUnion(myInt);
+ sampleBuilder.setSampleUnion(test);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(test.getInt32().toString(), props.get("sample-container.sample-union.int32"));
+
+ test = new SampleUnion(SampleUnion.Enumeration.Unbounded);
+ sampleBuilder.setSampleUnion(test);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals("unbounded", props.get("sample-container.sample-union.enumeration"));
+ }
+
+ public void testToPropertiesWithCustomType() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ Properties props = new Properties();
+
+ Short myShort = new Short("99");
+ Percentage myPercent = new Percentage(myShort);
+ sampleBuilder.setPercentCompleted(myPercent);
+ MdsalHelper.toProperties(props, sampleBuilder);
+ assertEquals(myShort.toString(), props.get("sample-container.percent-completed"));
+ assertEquals(myShort.toString(), props.get("sample-container.percent-completed.value"));
+ }
+
+ public void testToPropertiesWithLeaftList() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ List<String> nickNames = new ArrayList<String>();
+ sampleBuilder.setCustomerNicknames(nickNames);
+ String nameOne = "coffee";
+ String nameTwo = "java";
+ String nameThree = "mud";
+
+ nickNames.add(nameOne);
+ nickNames.add(nameTwo);
+ nickNames.add(nameThree);
+
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+
+ assertEquals(nameOne, props.get("sample-container.customer-nicknames[0]"));
+ assertEquals(nameTwo, props.get("sample-container.customer-nicknames[1]"));
+ assertEquals(nameThree, props.get("sample-container.customer-nicknames[2]"));
+ assertEquals(String.valueOf(nickNames.size()), props.get("sample-container.customer-nicknames_length"));
+ }
+
+ public void testToPropertiesWithComplexContainer() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ LoginBuilder lb = new LoginBuilder();
+ lb.setMessage("WELCOME!");
+ List<CustomerAddresses> addresses = new ArrayList<CustomerAddresses>();
+ CustomerAddressesBuilder cab = new CustomerAddressesBuilder();
+ cab.setAddressName("home");
+ cab.setState("NJ");
+ cab.setStreetAddress("yellowbrick road");
+
+ CustomerAddresses addressOne = cab.build();
+ addresses.add(addressOne);
+
+ cab.setAddressName("vacation house");
+ cab.setState("FL");
+ cab.setStreetAddress("ocean ave");
+
+ CustomerAddresses addressTwo = cab.build();
+ addresses.add(addressTwo);
+
+ lb.setCustomerAddresses(addresses);
+ sampleBuilder.setLogin(lb.build());
+
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+
+ assertEquals("WELCOME!", props.get("sample-container.login.message"));
+ assertEquals("NJ", props.get("sample-container.login.customer-addresses[0].state"));
+ assertEquals("home", props.get("sample-container.login.customer-addresses[0].address-name"));
+ assertEquals("yellowbrick road", props.get("sample-container.login.customer-addresses[0].street-address"));
+ assertEquals("FL", props.get("sample-container.login.customer-addresses[1].state"));
+ assertEquals("vacation house", props.get("sample-container.login.customer-addresses[1].address-name"));
+ assertEquals("ocean ave", props.get("sample-container.login.customer-addresses[1].street-address"));
+ assertEquals("2", props.get("sample-container.login.customer-addresses_length"));
+ }
+
+ public void testToPropertiesIetf() throws Exception {
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+ sampleBuilder.setIpVersion(IpVersion.Ipv4);
+ sampleBuilder.setDscp(Dscp.getDefaultInstance("1"));
+ sampleBuilder.setPortNumber(PortNumber.getDefaultInstance("2"));
+ sampleBuilder.setIpv6FlowLabel(Ipv6FlowLabel.getDefaultInstance("3"));
+ sampleBuilder.setAsNumber(AsNumber.getDefaultInstance("4"));
+ sampleBuilder.setIpv6Address(Ipv6Address.getDefaultInstance("fdda:5cc1:23:4::1f"));
+ sampleBuilder.setIpAddressNoZone(IpAddressNoZoneBuilder.getDefaultInstance("fdda:5cc1:23:4::1f"));
+ sampleBuilder.setIpv4Address(Ipv4Address.getDefaultInstance("192.168.1.2"));
+ sampleBuilder.setIpv4AddressNoZone(Ipv4AddressNoZone.getDefaultInstance("192.168.1.3"));
+ sampleBuilder.setIpv6AddressNoZone(Ipv6AddressNoZone.getDefaultInstance("fdda:5cc1:23:4::1f"));
+ sampleBuilder.setIpv4Prefix(Ipv4Prefix.getDefaultInstance("198.51.100.0/24"));
+ sampleBuilder.setIpv6Prefix(Ipv6Prefix.getDefaultInstance("2001:db8:aaaa:1111::100/64"));
+ sampleBuilder.setDomainName(DomainName.getDefaultInstance("onap.org"));
+ sampleBuilder.setHost(HostBuilder.getDefaultInstance("machine.onap.org"));
+ sampleBuilder.setUri(Uri.getDefaultInstance("http://wiki.onap.org:8080"));
+
+ Properties props = new Properties();
+ MdsalHelper.toProperties(props, sampleBuilder);
+
+ assertEquals("4", props.get("sample-container.as-number"));
+ assertEquals("4", props.get("sample-container.as-number.value"));
+ assertEquals("onap.org", props.get("sample-container.domain-name"));
+ assertEquals("onap.org", props.get("sample-container.domain-name.value"));
+ assertEquals("1", props.get("sample-container.dscp"));
+ assertEquals("machine.onap.org", props.get("sample-container.host.domain-name"));
+ assertEquals("machine.onap.org", props.get("sample-container.host.domain-name.value"));
+ assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ip-address-no-zone.ipv6-address-no-zone"));
+ assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ip-address-no-zone.ipv6-address-no-zone.value"));
+ assertEquals("ipv4", props.get("sample-container.ip-version"));
+ assertEquals("192.168.1.2", props.get("sample-container.ipv4-address"));
+ assertEquals("192.168.1.3", props.get("sample-container.ipv4-address-no-zone"));
+ assertEquals("192.168.1.3", props.get("sample-container.ipv4-address-no-zone.value"));
+ assertEquals("198.51.100.0/24", props.get("sample-container.ipv4-prefix"));
+ assertEquals("198.51.100.0/24", props.get("sample-container.ipv4-prefix.value"));
+ assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ipv6-address"));
+ assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ipv6-address-no-zone"));
+ assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ipv6-address-no-zone.value"));
+ assertEquals("3", props.get("sample-container.ipv6-flow-label"));
+ assertEquals("3", props.get("sample-container.ipv6-flow-label.value"));
+ assertEquals("2001:db8:aaaa:1111::100/64", props.get("sample-container.ipv6-prefix"));
+ assertEquals("2001:db8:aaaa:1111::100/64", props.get("sample-container.ipv6-prefix.value"));
+ assertEquals("2", props.get("sample-container.port-number"));
+ assertEquals("http://wiki.onap.org:8080", props.get("sample-container.uri"));
+ assertEquals("http://wiki.onap.org:8080", props.get("sample-container.uri.value"));
+ }
+
+ public void testIetfToBuilder() throws Exception {
+ Properties props = new Properties();
+ props.put("sample-container.as-number", "4");
+ props.put("sample-container.as-number.value", "4");
+ props.put("sample-container.domain-name", "onap.org");
+ props.put("sample-container.domain-name.value", "onap.org");
+ props.put("sample-container.dscp", "1");
+ props.put("sample-container.host.domain-name", "machine.onap.org");
+ props.put("sample-container.host.domain-name.value", "machine.onap.org");
+ props.put("sample-container.ip-address-no-zone.ipv6-address-no-zone", "fdda:5cc1:23:4::1f");
+ props.put("sample-container.ip-address-no-zone.ipv6-address-no-zone.value", "fdda:5cc1:23:4::1f");
+ props.put("sample-container.ip-version", "ipv4");
+ props.put("sample-container.ipv4-address", "192.168.1.2");
+ props.put("sample-container.ipv4-address-no-zone", "192.168.1.3");
+ props.put("sample-container.ipv4-address-no-zone.value", "192.168.1.3");
+ props.put("sample-container.ipv4-prefix", "198.51.100.0/24");
+ props.put("sample-container.ipv4-prefix.value", "198.51.100.0/24");
+ props.put("sample-container.ipv6-address", "fdda:5cc1:23:4::1f");
+ props.put("sample-container.ipv6-address-no-zone", "fdda:5cc1:23:4::1f");
+ props.put("sample-container.ipv6-address-no-zone.value", "fdda:5cc1:23:4::1f");
+ props.put("sample-container.ipv6-flow-label", "3");
+ props.put("sample-container.ipv6-flow-label.value", "3");
+ props.put("sample-container.ipv6-prefix", "2001:db8:aaaa:1111::100/64");
+ props.put("sample-container.ipv6-prefix.value", "2001:db8:aaaa:1111::100/64");
+ props.put("sample-container.port-number", "2");
+ props.put("sample-container.uri", "http://wiki.onap.org:8080");
+ props.put("sample-container.uri.value", "http://wiki.onap.org:8080");
+ SampleContainerBuilder sampleBuilder = new SampleContainerBuilder();
+
+ MdsalHelper.toBuilder(props, sampleBuilder);
+ SampleContainer result = sampleBuilder.build();
+ assertEquals(AsNumber.getDefaultInstance("4"), result.getAsNumber());
+ assertEquals(DomainName.getDefaultInstance("onap.org"), result.getDomainName());
+ assertEquals(Dscp.getDefaultInstance("1"), result.getDscp());
+ // assertEquals(HostBuilder.getDefaultInstance("machine.onap.org").getDomainName(),
+ // result.getHost().getDomainName());
+ assertEquals(Ipv6AddressNoZone.getDefaultInstance("fdda:5cc1:23:4::1f").getValue(),
+ result.getIpv6AddressNoZone().getValue());
+ assertEquals(IpVersion.Ipv4, result.getIpVersion());
+ assertEquals(Ipv4Address.getDefaultInstance("192.168.1.2"), result.getIpv4Address());
+ assertEquals(Ipv4AddressNoZone.getDefaultInstance("192.168.1.3"), result.getIpv4AddressNoZone());
+ assertEquals(Ipv4Prefix.getDefaultInstance("198.51.100.0/24"), result.getIpv4Prefix());
+ assertEquals(Ipv6Address.getDefaultInstance("fdda:5cc1:23:4::1f"), result.getIpv6Address());
+ assertEquals(IpAddressNoZoneBuilder.getDefaultInstance("fdda:5cc1:23:4::1f").getIpv6AddressNoZone().getValue(),
+ result.getIpv6AddressNoZone().getValue());
+ assertEquals(Ipv6FlowLabel.getDefaultInstance("3"), result.getIpv6FlowLabel());
+ assertEquals(Ipv6Prefix.getDefaultInstance("2001:db8:aaaa:1111::100/64"), result.getIpv6Prefix());
+ assertEquals(PortNumber.getDefaultInstance("2"), result.getPortNumber());
+ assertEquals(Uri.getDefaultInstance("http://wiki.onap.org:8080"), result.getUri());
+ }
+
+ public void testToLowerHyphen() throws Exception {
+ String camelCase = "HelloWorld";
+ String hypenCase = MdsalHelper.toLowerHyphen(camelCase);
+ assertEquals("hello-world", hypenCase);
+
+ camelCase = "L2SwitchInterfaces";
+ hypenCase = MdsalHelper.toLowerHyphen(camelCase);
+ assertEquals("l2-switch-interfaces", hypenCase);
+
+ camelCase = "ABC";
+ hypenCase = MdsalHelper.toLowerHyphen(camelCase);
+ assertEquals("a-b-c", hypenCase);
+ }
+
+}
diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java
new file mode 100644
index 000000000..2167b8101
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * 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.ccsdk.sli.core.sli.provider;
+
+import org.onap.ccsdk.sli.core.sli.provider.MdsalHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MdsalHelperTesterUtil extends MdsalHelper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MdsalHelperTesterUtil.class);
+
+ //Normally static init of classes goes here for some weird classloader thing
+ static {
+ String str = "Hello World!";
+ }
+
+}
diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java
new file mode 100644
index 000000000..50b7926a0
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java
@@ -0,0 +1,142 @@
+/*-
+ 2 * ============LICENSE_START=======================================================
+ 3 * ONAP CCSDK
+ 4 * ================================================================================
+ 5 * Copyright (C) 2019 AT&T Intellectual Property. All rights
+ 6 * reserved.
+ 7 * ================================================================================
+ 8 * Licensed under the Apache License, Version 2.0 (the "License");
+ 9 * you may not use this file except in compliance with the License.
+ 10 * You may obtain a copy of the License at
+ 11 *
+ 12 * http://www.apache.org/licenses/LICENSE-2.0
+ 13 *
+ 14 * Unless required by applicable law or agreed to in writing, software
+ 15 * distributed under the License is distributed on an "AS IS" BASIS,
+ 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ 17 * See the License for the specific language governing permissions and
+ 18 * limitations under the License.
+ 19 * ============LICENSE_END============================================
+ 20 * ===================================================================
+ 21 *
+ 22 */
+package org.onap.ccsdk.sli.core.sli.provider;
+
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.provider.PrintYangToProp;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInput.Mode;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.TestResultsBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameter;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameterBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.test.results.TestResult;
+import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.test.results.TestResultBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author dt5972
+ *
+ */
+public class PrintYangToPropTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PrintYangToPropTest.class);
+ @Test
+ public void test() {
+
+ Properties props = new Properties();
+
+ // Set up a builder with data
+ ExecuteGraphInputBuilder egBuilder = new ExecuteGraphInputBuilder();
+ egBuilder.setMode(Mode.Sync);
+ egBuilder.setModuleName("my-module");
+ egBuilder.setRpcName("my-rpc");
+
+ List<SliParameter> pList = new LinkedList<>();
+
+ SliParameterBuilder pBuilder = new SliParameterBuilder();
+ pBuilder.setParameterName("string-param");
+ pBuilder.setStringValue("hi");
+ pList.add(pBuilder.build());
+ pBuilder.setParameterName("int-param");
+ pBuilder.setIntValue(1);
+ pBuilder.setStringValue(null);
+ pList.add(pBuilder.build());
+ pBuilder.setParameterName("bool-param");
+ pBuilder.setIntValue(null);
+ pBuilder.setBooleanValue(true);
+ pList.add(pBuilder.build());
+ pBuilder.setParameterName("ipaddress-value1");
+ pBuilder.setBooleanValue(null);
+ pBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("127.0.0.1"));
+ pList.add(pBuilder.build());
+ pBuilder.setParameterName("ipaddress-value1");
+ pBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("::1"));
+ pList.add(pBuilder.build());
+ pBuilder.setParameterName("ipprefix-value1");
+ pBuilder.setIpaddressValue(null);
+ pBuilder.setIpprefixValue(IpPrefixBuilder.getDefaultInstance("192.168.0.0/16"));
+ pList.add(pBuilder.build());
+ pBuilder.setParameterName("ipprefix-value2");
+ pBuilder.setIpprefixValue(IpPrefixBuilder.getDefaultInstance("2001:db8:3c4d::/48"));
+ pList.add(pBuilder.build());
+
+
+
+ egBuilder.setSliParameter(pList);
+
+
+ // Generate properties
+ props = PrintYangToProp.toProperties(props, egBuilder);
+
+ Enumeration propNames = props.propertyNames();
+
+ while (propNames.hasMoreElements()) {
+ String propName = (String) propNames.nextElement();
+ LOG.info("Property {} = {}", propName, props.getProperty(propName));
+ }
+
+ // Generate builder from properties just generated
+ PrintYangToProp.toBuilder(props, pBuilder);
+
+
+ }
+
+ @Test
+ public void testWithList() {
+ TestResultsBuilder resultsBuilder = new TestResultsBuilder();
+ TestResultBuilder resultBuilder = new TestResultBuilder();
+
+ // Set builder with values
+ List<TestResult> resultList = new LinkedList<>();
+ resultBuilder.setTestIdentifier("test1");
+ List<String> results = new LinkedList<>();
+ results.add("pass");
+ resultBuilder.setResults(results);
+ resultList.add(resultBuilder.build());
+ resultsBuilder.setTestResult(resultList);
+
+ // Generate properties
+ Properties props = new Properties();
+ props = PrintYangToProp.toProperties(props, resultsBuilder);
+
+ Enumeration propNames = props.propertyNames();
+
+ while (propNames.hasMoreElements()) {
+ String propName = (String) propNames.nextElement();
+ LOG.info("Property {} = {}", propName, props.getProperty(propName));
+ }
+
+ // Generate builder from properties just generated
+ PrintYangToProp.toBuilder(props, resultsBuilder);
+
+ }
+
+}
diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java
new file mode 100644
index 000000000..2aaaf8aa3
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java
@@ -0,0 +1,51 @@
+package org.opendaylight.yang.gen.v1.test;
+
+public enum CosModelType {
+ _4COS(0, "4COS"),
+
+ _6COS(1, "6COS")
+ ;
+
+ private static final java.util.Map<java.lang.Integer, CosModelType> VALUE_MAP;
+
+ static {
+ final com.google.common.collect.ImmutableMap.Builder<java.lang.Integer, CosModelType> b = com.google.common.collect.ImmutableMap.builder();
+ for (CosModelType enumItem : CosModelType.values()) {
+ b.put(enumItem.value, enumItem);
+ }
+
+ VALUE_MAP = b.build();
+ }
+
+ private final java.lang.String name;
+ private final int value;
+
+ private CosModelType(int value, java.lang.String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of the enumeration item as it is specified in the input yang.
+ *
+ * @return the name of the enumeration item as it is specified in the input yang
+ */
+ public java.lang.String getName() {
+ return name;
+ }
+
+ /**
+ * @return integer value
+ */
+ public int getIntValue() {
+ return value;
+ }
+
+ /**
+ * @param valueArg integer value
+ * @return corresponding CosModelType item
+ */
+ public static CosModelType forValue(int valueArg) {
+ return VALUE_MAP.get(valueArg);
+ }
+} \ No newline at end of file
diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java
new file mode 100755
index 000000000..eacfc9f63
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java
@@ -0,0 +1,17 @@
+package org.opendaylight.yang.gen.v1.test;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+
+public interface TestObject {
+ List<IpAddress> getFloatingIp();
+ List<Ipv4Address> getFloatingIpV4();
+ List<Ipv6Address> getFloatingIpV6();
+ Ipv4Address getSingleIpV4();
+ Ipv6Address getSingleIpV6();
+ IpAddress getSingleIp();
+
+}
diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java
new file mode 100755
index 000000000..8301a0f05
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java
@@ -0,0 +1,134 @@
+package org.opendaylight.yang.gen.v1.test;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yangtools.concepts.Builder;
+
+public class TestObjectBuilder implements Builder<TestObject> {
+ private List<IpAddress> _floatingIp;
+ private List<Ipv4Address> _floatingIpV4;
+ private List<Ipv6Address> _floatingIpV6;
+ private IpAddress _singleIp;
+ private Ipv4Address _singleIpV4;
+ private Ipv6Address _singleIpV6;
+
+ public List<IpAddress> getFloatingIp() {
+ return _floatingIp;
+ }
+
+ public List<Ipv4Address> getFloatingIpV4() {
+ return _floatingIpV4;
+ }
+
+ public List<Ipv6Address> getFloatingIpV6() {
+ return _floatingIpV6;
+ }
+
+ public Ipv4Address getSingleIpV4() {
+ return _singleIpV4;
+ }
+
+ public Ipv6Address getSingleIpV6() {
+ return _singleIpV6;
+ }
+
+ public IpAddress getSingleIp() {
+ return _singleIp;
+ }
+
+ public TestObjectBuilder setFloatingIp(final List<IpAddress> value) {
+ this._floatingIp = value;
+ return this;
+ }
+
+ public TestObjectBuilder setFloatingIpV4(final List<Ipv4Address> value) {
+ this._floatingIpV4 = value;
+ return this;
+ }
+
+ public TestObjectBuilder setFloatingIpV6(final List<Ipv6Address> value) {
+ this._floatingIpV6 = value;
+ return this;
+ }
+
+ public TestObjectBuilder setSingleIp(final IpAddress value) {
+ this._singleIp = value;
+ return this;
+ }
+
+ public TestObjectBuilder setSingleIpV4(final Ipv4Address value) {
+ this._singleIpV4 = value;
+ return this;
+ }
+
+ public TestObjectBuilder setSingleIpV6(final Ipv6Address value) {
+ this._singleIpV6 = value;
+ return this;
+ }
+
+ public TestObjectBuilder() {
+
+ }
+
+ public TestObject build() {
+ return new TestObjectImpl(this);
+ }
+
+ @Override
+ public String toString() {
+ return "TestObjectBuilder [_floatingIp=" + _floatingIp + ", _floatingIpV4=" + _floatingIpV4 + ", _floatingIpV6="
+ + _floatingIpV6 + ", _singleIp=" + _singleIp + ", _singleIpV4=" + _singleIpV4 + ", _singleIpV6="
+ + _singleIpV6 + "]";
+ }
+
+ private static final class TestObjectImpl implements TestObject {
+ private List<IpAddress> _floatingIp;
+ private List<Ipv4Address> _floatingIpV4;
+ private List<Ipv6Address> _floatingIpV6;
+ private IpAddress _singleIp;
+ private Ipv4Address _singleIpV4;
+ private Ipv6Address _singleIpV6;
+
+ @Override
+ public List<IpAddress> getFloatingIp() {
+ return _floatingIp;
+ }
+
+ @Override
+ public List<Ipv4Address> getFloatingIpV4() {
+ return _floatingIpV4;
+ }
+
+ @Override
+ public List<Ipv6Address> getFloatingIpV6() {
+ return _floatingIpV6;
+ }
+
+ @Override
+ public Ipv4Address getSingleIpV4() {
+ return _singleIpV4;
+ }
+
+ @Override
+ public Ipv6Address getSingleIpV6() {
+ return _singleIpV6;
+ }
+
+ @Override
+ public IpAddress getSingleIp() {
+ return _singleIp;
+ }
+
+ private TestObjectImpl(TestObjectBuilder base) {
+ this._floatingIp = base.getFloatingIp();
+ this._floatingIpV4 = base.getFloatingIpV4();
+ this._floatingIpV6 = base.getFloatingIpV6();
+ this._singleIp = base.getSingleIp();
+ this._singleIpV4 = base.getSingleIpV4();
+ this._singleIpV6 = base.getSingleIpV6();
+ }
+ }
+}
diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java
new file mode 100644
index 000000000..bae0bdb1c
--- /dev/null
+++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java
@@ -0,0 +1,10 @@
+package org.opendaylight.yang.gen.v1.test;
+
+public class WrapperObj {
+
+ CosModelType cosModel = CosModelType._4COS;
+
+ public CosModelType getCosModelType() {
+ return cosModel;
+ }
+}
diff --git a/core/sli/provider/src/test/resources/EnumerationMapping.properties b/core/sli/provider/src/test/resources/EnumerationMapping.properties
new file mode 100644
index 000000000..d0fb29710
--- /dev/null
+++ b/core/sli/provider/src/test/resources/EnumerationMapping.properties
@@ -0,0 +1 @@
+yang.cos-model-type._4COS=HelloWorld \ No newline at end of file
diff --git a/core/sli/provider/src/test/resources/executor.tests b/core/sli/provider/src/test/resources/executor.tests
new file mode 100755
index 000000000..5468c8d60
--- /dev/null
+++ b/core/sli/provider/src/test/resources/executor.tests
@@ -0,0 +1,8 @@
+l3sdn_logic_v10.xml:switchTester:test-value=""
+l3sdn_logic_v10.xml:switchTester:test-value="hi"
+l3sdn_logic_v10.xml:forRecordTester
+l3sdn_logic_v10.xml:whileNodeTester
+l3sdn_logic_v10.xml:resourceTester
+l3sdn_logic_v10.xml:configureTester
+l3sdn_logic_v10.xml:javaPluginTester
+l3sdn_logic_v10.xml:allNodesTester \ No newline at end of file
diff --git a/core/sli/provider/src/test/resources/l3sdn.properties b/core/sli/provider/src/test/resources/l3sdn.properties
new file mode 100644
index 000000000..6f40ebca0
--- /dev/null
+++ b/core/sli/provider/src/test/resources/l3sdn.properties
@@ -0,0 +1,66 @@
+# yang conversion properties
+# used to convert Enum back to the original yang value
+yang.request-status.Synccomplete=synccomplete
+yang.request-status.Asynccomplete=asynccomplete
+yang.request-status.Notifycomplete=notifycomplete
+yang.rpc-name.ServiceConfigurationOperation=service-configuration-operation
+yang.rpc-name.SvcTopologyOperation=svc-topology-operation
+yang.rpc-name.ServiceConfigurationNotification=service-configuration-notification
+yang.rpc-action.Reserve=reserve
+yang.rpc-action.Activate=activate
+yang.rpc-action.Assign=assign
+yang.rpc-action.Turnup=turnup
+yang.rpc-action.Delete=delete
+yang.rpc-action.Changereserve=changereserve
+yang.rpc-action.Changeactivate=changeactivate
+yang.rpc-action.Changedelete=changedelete
+yang.rpc-action.Changeassign=changeassign
+yang.svc-vnf-type.Vce=vce
+yang.vnf-type.Vce=vce
+yang.vnf-status.PendingCreate=pending-create
+yang.vnf-status.Created=created
+yang.vnf-status.Active=active
+yang.vnf-status.PendingDelete=pending-delete
+yang.connection-type.Customer=customer
+yang.connection-type.Internet=internet
+yang.net-status.PendingCreate=pending-create
+yang.net-status.Created=created
+yang.net-status.Active=active
+yang.net-status.PendingDelete=pending-delete
+yang.svc-action.Reserve=reserve
+yang.svc-action.Activate=activate
+yang.svc-action.Assign=assign
+yang.svc-action.Turnup=turnup
+yang.svc-action.Delete=delete
+yang.svc-action.Changereserve=changereserve
+yang.svc-action.Changeactivate=changeactivate
+yang.svc-action.Changedelete=changedelete
+yang.svc-action.Changeassign=changeassign
+yang.service-type.SDNETHERNETINTERNET=SDN-ETHERNET-INTERNET
+yang.internet-evc-speed-value._2=2
+yang.internet-evc-speed-value._4=4
+yang.internet-evc-speed-value._5=5
+yang.internet-evc-speed-value._8=8
+yang.internet-evc-speed-value._10=10
+yang.internet-evc-speed-value._20=20
+yang.internet-evc-speed-value._50=50
+yang.internet-evc-speed-value._100=100
+yang.internet-evc-speed-value._150=150
+yang.internet-evc-speed-value._250=250
+yang.internet-evc-speed-value._400=400
+yang.internet-evc-speed-value._500=500
+yang.internet-evc-speed-value._600=600
+yang.internet-evc-speed-value._1000=1000
+yang.ip-version.Ds=ds
+yang.ip-version.V6=v6
+yang.routing-protocol.None=none
+yang.routing-protocol.Bgp=bgp
+yang.routing-protocol.Ospf=ospf
+yang.routing-protocol.Igrp=igrp
+yang.routing-protocol.Eigrp=eigrp
+yang.routing-protocol.Rip=rip
+yang.routing-protocol.IsIs=is-is
+yang.vr-designation.Primary=primary
+yang.feature-type.FIREWALLLITE=FIREWALL-LITE
+yang.equipment-role.VPLSPE=VPLS-PE
+yang.interface-role.CUSTOMERUPLINK=CUSTOMER-UPLINK
diff --git a/core/sli/provider/src/test/resources/l3sdn_logic_v10.xml b/core/sli/provider/src/test/resources/l3sdn_logic_v10.xml
new file mode 100644
index 000000000..64397236b
--- /dev/null
+++ b/core/sli/provider/src/test/resources/l3sdn_logic_v10.xml
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ============LICENSE_START=======================================================
+ ONAP : CCSDK ================================================================================
+ 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========================================================= -->
+
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd"
+ module="neutron" version="1.0.0">
+
+ <method rpc="canCreateNetwork" mode="sync">
+ <return status="success">
+ <parameter name="error-code" value="200" />
+ </return>
+ </method>
+
+ <method rpc="switchTester" mode="sync">
+
+ <switch test="`$test-value`">
+ <outcome value="">
+ <return status="success">
+ <parameter name="visited-outcome" value="empty string" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="success">
+ <parameter name="visited-outcome" value="Other" />
+ </return>
+ </outcome>
+ </switch>
+
+
+ </method>
+
+ <method rpc="forRecordTester" mode="sync">
+ <for index="i" start="0" end="1">
+ <record plugin="org.onap.ccsdk.sli.core.sli.provider.DummyRecorder">
+ <parameter name="level" value="INFO"/>
+ <parameter name="field1" value="`forRecordTester message $i`"/>
+ </record>
+ </for>
+ </method>
+
+ <method rpc="whileNodeTester" mode="sync">
+ <block>
+ <set>
+ <parameter name="counter" value="0" />
+
+ </set>
+ <while test="`$counter &lt; 10`">
+ <set>
+ <parameter name="counter" value="`$counter + 1`" />
+ </set>
+
+ <switch test="`$counter > 6`">
+ <outcome value="true">
+ <break />
+ </outcome>
+ </switch>
+ </while>
+ </block>
+
+ </method>
+
+ <method rpc="resourceTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='resource-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' />
+ </set>
+
+ <save plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'">
+ <parameter name="sample-key" value="resourceTester.status"/>
+ <parameter name="sample-value" value="FAILED"/>
+ </save>
+
+ <update plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'">
+ <parameter name="sample-key" value="resourceTester.status"/>
+ <parameter name="sample-value" value="PASSED"/>
+ </update>
+
+ <get-resource plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'" pfx="sample"/>
+
+ <exists plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <is-available plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <release plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+
+ <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+ <notify plugin="`$resource-plugin`" resource="sample" action="RESERVE"/>
+
+ <delete plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/>
+
+
+
+ </block>
+ </method>
+
+ <method rpc="configureTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='configure-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' />
+ </set>
+ <configure adaptor="`$configure-plugin`" key="dummy" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="FAILURE" activate="true">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="dummy" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="FAILURE" activate="false">
+ <parameter name="field1" value="1"/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="dummy" activate="true">
+ <parameter name="" value=""/>
+ </configure>
+ <configure adaptor="`$configure-plugin`" key="dummy" activate="false">
+ <parameter name="" value=""/>
+ </configure>
+ </block>
+ </method>
+
+
+ <method rpc="javaPluginTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='java-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' />
+ </set>
+ <execute plugin="`$java-plugin`" method="dummy"/>
+ </block>
+ </method>
+
+ <method rpc="allNodesTester" mode="sync">
+ <block>
+ <set>
+ <parameter name='resource-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' />
+ <parameter name='configure-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' />
+ <parameter name='java-plugin'
+ value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' />
+
+ </set>
+
+ <call rpc="switchTester" mode="sync" />
+
+ <call rpc="forRecordTester" mode="sync"/>
+
+ <call rpc="resourceTester" mode="sync"/>
+
+ <call rpc="configureTester" mode="sync"/>
+
+ <call rpc="javaPluginTester" mode="sync"/>
+
+ <call rpc="whileNodeTester" mode="sync"/>
+
+ </block>
+ </method>
+
+ <method rpc="networkCreated" mode="sync">
+ <switch
+ test="length($network.segment[0].provider-physical-network) >= 5 and substr($network.segment[0].provider-physical-network,0,5) == 'dvspg'">
+ <outcome value="true">
+ <block>
+ <set>
+ <parameter name="$vlanlist"
+ value="$network.segment[0].provider-segmentation-id" />
+ </set>
+ <for index="i" start="1" end="$network.num-segments">
+ <set>
+ <parameter name="$vlanlist"
+ value="eval($vlanlist+','+$network.segment[i].provider-segmentation-id)" />
+ </set>
+ </for>
+
+ </block>
+ </outcome>
+ <outcome value="Other">
+ <return status="success">
+ <parameter name="error-code" value="200" />
+ </return>
+ </outcome>
+ </switch>
+ </method>
+
+</service-logic>
diff --git a/core/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang b/core/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang
new file mode 100755
index 000000000..4af080608
--- /dev/null
+++ b/core/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang
@@ -0,0 +1,68 @@
+module ietf-l3vpn-svc-part {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-l3vpn-svc-part";
+
+ prefix l3vpn-svc;
+
+ organization
+ "IETF L3SM Working Group";
+
+ contact
+ "WG List: &lt;mailto:l3sm@ietf.org&gt;
+
+ Editor:
+
+ ";
+
+ description
+ "The YANG module defines a generic service configuration
+ model for Layer 3 VPN common across all of the vendor
+ implementations.";
+
+ revision 2017-09-21 {
+ description
+ "Part of draft-ietf-l3sm-l3vpn-service-yang-11";
+ reference
+ "draft-ietf-l3sm-l3vpn-service-yang-11";
+ }
+
+ /* Typedefs */
+
+ typedef svc-id {
+ type string;
+ description
+ "Defining a type of service component
+ identificators.";
+ }
+
+ /* Main blocks */
+
+ container l3vpn-svc {
+ container vpn-services {
+ list vpn-svc {
+ key vpn-id;
+
+ uses vpn-svc-cfg; /*Not used*/
+
+ description "
+ List of VPN services.";
+ }
+ description
+ "top level container
+ for the VPN services.";
+ }
+ }
+
+ grouping vpn-svc-cfg {
+ leaf vpn-id {
+ type svc-id;
+ description
+ "VPN identifier. Local administration meaning.";
+ }
+ leaf customer-name {
+ type string;
+ description
+ "Name of the customer.";
+ }
+ }
+}
diff --git a/core/sli/provider/src/test/resources/simplelogger.properties b/core/sli/provider/src/test/resources/simplelogger.properties
new file mode 100644
index 000000000..07ab67f70
--- /dev/null
+++ b/core/sli/provider/src/test/resources/simplelogger.properties
@@ -0,0 +1,22 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+org.slf4j.simpleLogger.defaultLogLevel=info
diff --git a/core/sli/provider/src/test/resources/svclogic.properties b/core/sli/provider/src/test/resources/svclogic.properties
new file mode 100644
index 000000000..426960f76
--- /dev/null
+++ b/core/sli/provider/src/test/resources/svclogic.properties
@@ -0,0 +1,27 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# 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=========================================================
+###
+
+org.onap.ccsdk.sli.dbtype = jdbc
+org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:sdnctl;create=true
+org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
+org.onap.ccsdk.sli.jdbc.database = sdnctl
+org.onap.ccsdk.sli.jdbc.user = test
+org.onap.ccsdk.sli.jdbc.password = test