aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore44
-rw-r--r--LICENSE.txt22
-rw-r--r--README.md7
-rwxr-xr-xdblib/.gitignore34
-rwxr-xr-xdblib/README.md6
-rwxr-xr-xdblib/features/pom.xml138
-rwxr-xr-xdblib/features/src/main/resources/features.xml18
-rwxr-xr-xdblib/installer/pom.xml143
-rwxr-xr-xdblib/installer/src/assembly/assemble_installer_zip.xml39
-rwxr-xr-xdblib/installer/src/assembly/assemble_mvnrepo_zip.xml29
-rw-r--r--dblib/installer/src/main/resources/scripts/install-feature.sh19
-rwxr-xr-xdblib/pom.xml114
-rwxr-xr-xdblib/provider/pom.xml82
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java616
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java45
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java47
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java130
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibConnection.java390
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java39
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java862
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java27
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java33
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java33
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java46
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java45
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/NoAvailableConnectionsException.java36
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java82
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java104
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java56
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java31
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java39
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java104
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java100
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java37
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java249
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java186
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java217
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java217
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java237
-rw-r--r--dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java37
-rwxr-xr-xdblib/provider/src/main/resources/dblib.properties13
-rw-r--r--example-settings.xml163
-rwxr-xr-xfilters/.gitignore34
-rwxr-xr-xfilters/.sonar/checkstyle.xml1
-rwxr-xr-xfilters/.sonar/pmd.xml67
-rwxr-xr-xfilters/README14
-rwxr-xr-xfilters/features/pom.xml101
-rw-r--r--filters/features/src/main/resources/features.xml32
-rwxr-xr-xfilters/installer/pom.xml138
-rw-r--r--filters/installer/src/assembly/assemble_installer_zip.xml61
-rw-r--r--filters/installer/src/assembly/assemble_mvnrepo_zip.xml49
-rw-r--r--filters/installer/src/main/resources/scripts/install-feature.sh40
-rw-r--r--filters/pom.xml81
-rwxr-xr-xfilters/provider/pom.xml94
-rw-r--r--filters/provider/src/main/java/org/openecomp/sdnc/filters/Activator.java63
-rw-r--r--filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java222
-rw-r--r--filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java297
-rw-r--r--filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java289
-rw-r--r--jenkins-settings.xml168
-rwxr-xr-xpom.xml183
-rwxr-xr-xsli/.gitignore38
-rwxr-xr-xsli/common/pom.xml150
-rwxr-xr-xsli/common/src/main/antlr4/org/openecomp/sdnc/sli/ExprGrammar.g466
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java46
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/ConfigurationException.java45
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/DuplicateValueException.java45
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java302
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/MetricLogger.java301
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAdaptor.java42
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAtom.java174
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicBinaryExpression.java149
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicContext.java248
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicDblibStore.java533
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicException.java46
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java316
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprParserErrorListener.java44
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpression.java51
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java99
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicFunctionCall.java80
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicGraph.java184
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJavaPlugin.java34
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJdbcStore.java895
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicNode.java456
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParser.java598
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParserException.java43
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicRecorder.java30
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicResource.java53
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStore.java37
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStoreFactory.java96
-rw-r--r--sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicVariableTerm.java77
-rw-r--r--sli/common/src/main/resources/crAseNetwork.sql82
-rwxr-xr-xsli/common/src/main/resources/svclogic.xsd334
-rwxr-xr-xsli/common/src/main/yang/ase-network.yang179
-rwxr-xr-xsli/common/src/main/yang/ase-type.yang561
-rwxr-xr-xsli/common/src/main/yang/ase.yang558
-rw-r--r--sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicContextTest.java69
-rw-r--r--sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicExpressionParserTest.java69
-rw-r--r--sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicParserTest.java163
-rw-r--r--sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml70
-rw-r--r--sli/common/src/test/resources/EvcPortSvcLogic_v100.xml263
-rw-r--r--sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml89
-rw-r--r--sli/common/src/test/resources/bad_neutron_logic_v11.xml61
-rwxr-xr-xsli/common/src/test/resources/expression.tests19
-rw-r--r--sli/common/src/test/resources/mergetest.xml54
-rw-r--r--sli/common/src/test/resources/neutron_logic_v10.xml56
-rw-r--r--sli/common/src/test/resources/nonsense.xml24
-rwxr-xr-xsli/common/src/test/resources/parser-bad.tests3
-rwxr-xr-xsli/common/src/test/resources/parser-good.tests2
-rw-r--r--sli/common/src/test/resources/simplelogger.properties24
-rw-r--r--sli/common/src/test/resources/svclogic.properties26
-rw-r--r--sli/common/src/test/resources/svclogic.sh32
-rwxr-xr-xsli/common/src/test/resources/svclogic.xsd323
-rwxr-xr-xsli/features/pom.xml137
-rw-r--r--sli/features/src/main/resources/features.xml39
-rwxr-xr-xsli/installer/pom.xml149
-rw-r--r--sli/installer/src/assembly/assemble_installer_zip.xml59
-rw-r--r--sli/installer/src/assembly/assemble_mvnrepo_zip.xml49
-rw-r--r--sli/installer/src/main/resources/scripts/install-feature.sh40
-rwxr-xr-xsli/pom.xml65
-rwxr-xr-xsli/provider/pom.xml96
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BlockNodeExecutor.java75
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java42
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java165
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ConfigureNodeExecutor.java248
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java101
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java161
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java105
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java109
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java134
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java103
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java1186
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java102
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java119
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java100
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java114
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReturnNodeExecutor.java78
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java142
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java189
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java225
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicAdaptorFactory.java86
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java605
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicNodeExecutor.java110
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicService.java76
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java273
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java63
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java136
-rw-r--r--sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/WhileNodeExecutor.java75
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java56
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java57
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java78
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java43
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java37
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java106
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolverTest.java123
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicGraphExecutorTest.java212
-rw-r--r--sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java38
-rwxr-xr-xsli/provider/src/test/resources/executor.tests2
-rwxr-xr-xsli/provider/src/test/resources/expression.tests24
-rw-r--r--sli/provider/src/test/resources/l3sdn_logic_v10.xml74
-rw-r--r--sli/provider/src/test/resources/simplelogger.properties22
-rw-r--r--sli/provider/src/test/resources/svclogic.properties26
-rwxr-xr-xsli/recording/pom.xml77
-rw-r--r--sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/FileRecorder.java117
-rw-r--r--sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/RecordingActivator.java75
-rw-r--r--sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/Slf4jRecorder.java130
-rw-r--r--sli/recording/src/main/resources/svclogic.properties26
-rwxr-xr-xsliPluginUtils/.gitignore34
-rwxr-xr-xsliPluginUtils/.sonar/checkstyle.xml1
-rwxr-xr-xsliPluginUtils/.sonar/pmd.xml67
-rwxr-xr-xsliPluginUtils/features/pom.xml127
-rw-r--r--sliPluginUtils/features/src/main/resources/features.xml39
-rwxr-xr-xsliPluginUtils/installer/pom.xml138
-rw-r--r--sliPluginUtils/installer/src/assembly/assemble_installer_zip.xml59
-rw-r--r--sliPluginUtils/installer/src/assembly/assemble_mvnrepo_zip.xml49
-rw-r--r--sliPluginUtils/installer/src/main/resources/scripts/install-feature.sh40
-rwxr-xr-xsliPluginUtils/pom.xml41
-rwxr-xr-xsliPluginUtils/provider/pom.xml85
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java111
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java754
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java95
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java396
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java210
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextObject.java28
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/YesNo.java51
-rw-r--r--sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/package-info.java28
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java116
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java109
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java250
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortList.java96
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java97
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java244
-rw-r--r--sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextListTest.java307
-rwxr-xr-xsliapi/.gitignore34
-rwxr-xr-xsliapi/README.txt35
-rwxr-xr-xsliapi/features/pom.xml134
-rw-r--r--sliapi/features/src/main/resources/features.xml39
-rwxr-xr-xsliapi/installer/pom.xml137
-rw-r--r--sliapi/installer/src/assembly/assemble_installer_zip.xml59
-rw-r--r--sliapi/installer/src/assembly/assemble_mvnrepo_zip.xml55
-rw-r--r--sliapi/installer/src/main/resources/scripts/install-feature.sh40
-rwxr-xr-xsliapi/model/pom.xml79
-rwxr-xr-xsliapi/model/src/main/yang/sliapi.yang111
-rwxr-xr-xsliapi/pom.xml61
-rwxr-xr-xsliapi/provider/pom.xml144
-rw-r--r--sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java59
-rw-r--r--sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java34
-rw-r--r--sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java40
-rw-r--r--sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java557
-rw-r--r--sliapi/provider/src/main/resources/initial/sliapi-provider.xml72
-rwxr-xr-xsliapi/provider/src/main/yang/sliapi-provider-impl.yang61
-rw-r--r--src/site/apt/nodes.apt953
-rw-r--r--src/site/site.xml31
-rw-r--r--version.properties15
213 files changed, 28390 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100755
index 00000000..f9801b8c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,44 @@
+#####standard .git ignore entries#####
+
+## IDE Specific Files ##
+org.eclipse.core.resources.prefs
+.classpath
+.project
+.settings
+.idea
+.externalToolBuilders
+.checkstyle
+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
+
+# BlackDuck generated file
+sdnc-core_bdio.jsonld
+blackDuckHubProjectName.txt
+blackDuckHubProjectVersionName.txt
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 00000000..3ea5081a
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,22 @@
+/*
+ * ============LICENSE_START==========================================
+ * ===================================================================
+ * Copyright © 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============================================
+ *
+ * ECOMP and OpenECOMP are trademarks
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..50134aea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+This source repository contains the code for the core SDN Controller components.
+To compile this code:
+
+1. Make sure your local Maven settings file ($HOME/.m2/settings.xml) contains references to the OpenECOMP repositories and OpenDaylight repositories. See example-settings.xml for an example.
+
+2. To compile, run "mvn clean install".
+
diff --git a/dblib/.gitignore b/dblib/.gitignore
new file mode 100755
index 00000000..b73caf31
--- /dev/null
+++ b/dblib/.gitignore
@@ -0,0 +1,34 @@
+#####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
+
+## Folders which contain auto generated source code ##
+yang-gen-config
+yang-gen-sal
diff --git a/dblib/README.md b/dblib/README.md
new file mode 100755
index 00000000..98e8f0c6
--- /dev/null
+++ b/dblib/README.md
@@ -0,0 +1,6 @@
+DBLIB Utility
+---------------------
+
+DBLIB utility is designed as a high availability connection manager.
+It is configured to use multiple databases, and based on the configured rules
+always provide the connection to te active database.
diff --git a/dblib/features/pom.xml b/dblib/features/pom.xml
new file mode 100755
index 00000000..6c174b1c
--- /dev/null
+++ b/dblib/features/pom.xml
@@ -0,0 +1,138 @@
+<?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>
+ <artifactId>dblib</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>dblib-features</artifactId>
+ <name>DBLIB Adaptor - Features</name>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${odl.mdsal.features.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-jdbc</artifactId>
+ <version>${tomcat-jdbc.version}</version>
+ </dependency>
+
+ <!-- dependency for opendaylight-karaf-empty for use by testing -->
+ <dependency>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>opendaylight-karaf-empty</artifactId>
+ <version>${odl.karaf.empty.distro.version}</version>
+ <type>zip</type>
+ </dependency>
+
+ <dependency>
+ <!-- Required for launching the feature tests -->
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-test</artifactId>
+ <version>${odl.commons.opendaylight.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${odl.yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- launches the feature test, which validates that your karaf feature
+ can be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent bundles
+ defined correctly.
+ <plugin>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.odlparent</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/dblib/features/src/main/resources/features.xml b/dblib/features/src/main/resources/features.xml
new file mode 100755
index 00000000..0c3e8fe3
--- /dev/null
+++ b/dblib/features/src/main/resources/features.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<features name="sdnc-dblib-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository>
+
+
+ <feature name='sdnc-dblib' description="sdnc-dblib" version='${project.version}'>
+ <!-- Most applications will have a dependency on the ODL MD-SAL Broker -->
+ <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+ <bundle>wrap:mvn:org.apache.tomcat/tomcat-jdbc/${tomcat-jdbc.version}/$DynamicImport-Package=com.mysql.*&amp;overwrite=merge</bundle>
+ <bundle>mvn:org.openecomp.sdnc.core/dblib-provider/${project.version}</bundle>
+ <bundle>mvn:mysql/mysql-connector-java/${mysql.connector.version}</bundle>
+ </feature>
+
+</features>
diff --git a/dblib/installer/pom.xml b/dblib/installer/pom.xml
new file mode 100755
index 00000000..9da6a459
--- /dev/null
+++ b/dblib/installer/pom.xml
@@ -0,0 +1,143 @@
+<?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>
+ <artifactId>dblib</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>dblib-installer</artifactId>
+ <name>DBLIB Adaptor - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>sdnc-dblib</application.name>
+ <features.boot>sdnc-dblib</features.boot>
+ <features.repositories>mvn:org.openecomp.sdnc.core/dblib-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-jdbc</artifactId>
+ <version>${tomcat-jdbc.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>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</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.openecomp.sdnc,org.apache.tomcat</includeGroupIds>
+ <excludeArtifactIds>sli-common,sli-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/dblib/installer/src/assembly/assemble_installer_zip.xml b/dblib/installer/src/assembly/assemble_installer_zip.xml
new file mode 100755
index 00000000..a6a22a9b
--- /dev/null
+++ b/dblib/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,39 @@
+<!-- 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/dblib/installer/src/assembly/assemble_mvnrepo_zip.xml b/dblib/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100755
index 00000000..d96c9f40
--- /dev/null
+++ b/dblib/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,29 @@
+<!-- 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/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/dblib/installer/src/main/resources/scripts/install-feature.sh b/dblib/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 00000000..16b5be8c
--- /dev/null
+++ b/dblib/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+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} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/dblib/pom.xml b/dblib/pom.xml
new file mode 100755
index 00000000..78af665a
--- /dev/null
+++ b/dblib/pom.xml
@@ -0,0 +1,114 @@
+<?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/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib</artifactId>
+
+
+ <name>DBLIB Adaptor</name>
+ <description>The DBLIB adaptor allows service logic to access persistent data in a local sql database</description>
+
+ <version>0.0.1-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+
+ <groupId>org.codehaus.mojo</groupId>
+
+ <artifactId>license-maven-plugin</artifactId>
+
+ <version>1.9</version>
+
+ <configuration>
+
+ <licenseName>apache_v2</licenseName>
+
+ <inceptionYear>2016</inceptionYear>
+
+ <organizationName>AT&amp;T</organizationName>
+
+ <projectName>openecomp</projectName>
+
+ <roots>
+
+ <root>src/main/java</root>
+
+ </roots>
+
+ <excludes>
+
+ <exclude>*.png</exclude>
+
+ </excludes>
+
+ </configuration>
+
+ </plugin>
+ </plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven.compile.plugin.version}</version>
+ <configuration>
+ <source>${java.version.source}</source>
+ <target>${java.version.target}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10</version>
+
+ <executions>
+ <execution>
+ <id>aggregate</id>
+ <goals>
+ <goal>aggregate</goal>
+ </goals>
+ <phase>site</phase>
+
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.1</version>
+ <executions>
+ <execution>
+ <id>bundle-sources</id>
+ <phase>package</phase>
+ <goals>
+ <!-- produce source artifact for main project sources -->
+ <goal>jar-no-fork</goal>
+
+ <!-- produce source artifact for project test sources -->
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </pluginManagement>
+ </build>
+ <organization>
+ <name>AT&amp;T</name>
+ </organization>
+ <modules>
+ <module>provider</module>
+ <module>features</module>
+ <module>installer</module>
+ </modules>
+</project>
diff --git a/dblib/provider/pom.xml b/dblib/provider/pom.xml
new file mode 100755
index 00000000..b5acc7e1
--- /dev/null
+++ b/dblib/provider/pom.xml
@@ -0,0 +1,82 @@
+<?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.openecomp.sdnc.core</groupId>
+ <artifactId>dblib</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>dblib-provider</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+ <name>DBLIB Adaptor - Provider</name>
+ <url>http://maven.apache.org</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${mysql.connector.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-jdbc</artifactId>
+ <version>${tomcat-jdbc.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.openecomp.sdnc.sli.resource.dblib</Bundle-SymbolicName>
+ <Bundle-Activator>org.openecomp.sdnc.sli.resource.dblib.DBLIBResourceActivator</Bundle-Activator>
+ <Export-Package>org.openecomp.sdnc.sli.resource.dblib;version=${project.version}</Export-Package>
+ <!--
+ <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.mysql.jdbc.*,javax.sql.*,org.apache.tomcat.*</Import-Package>
+ -->
+ <Import-Package>*</Import-Package>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+
+ </plugin>
+
+
+ </plugins>
+ </build>
+</project>
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java
new file mode 100644
index 00000000..58a0aeb1
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java
@@ -0,0 +1,616 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Observer;
+
+import javax.sql.DataSource;
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetProvider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.tomcat.jdbc.pool.PoolExhaustedException;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitorObserver;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor.TestObject;
+import com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException;
+
+
+/**
+ * @version $Revision: 1.13 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+
+public abstract class CachedDataSource implements DataSource, SQLExecutionMonitorObserver
+{
+ private static Logger LOGGER = LoggerFactory.getLogger(CachedDataSource.class);
+
+ protected static final String AS_CONF_ERROR = "AS_CONF_ERROR: ";
+
+ protected long CONN_REQ_TIMEOUT = 30L;
+ protected long DATA_REQ_TIMEOUT = 100L;
+
+ private final SQLExecutionMonitor monitor;
+ protected DataSource ds = null;
+ protected String connectionName = null;
+ protected boolean initialized = false;
+
+ private long interval = 1000;
+ private long initialDelay = 5000;
+ private long expectedCompletionTime = 50L;
+ private boolean canTakeOffLine = true;
+ private long unprocessedFailoverThreshold = 3L;
+
+ private long nextErrorReportTime = 0L;
+
+ private String globalHostName = null;
+
+
+ public CachedDataSource(BaseDBConfiguration jdbcElem) throws DBConfigException
+ {
+ configure(jdbcElem);
+ monitor = new SQLExecutionMonitor(this);
+ }
+
+ protected abstract void configure(BaseDBConfiguration jdbcElem) throws DBConfigException;
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getConnection()
+ */
+ public Connection getConnection() throws SQLException
+ {
+ return ds.getConnection();
+ }
+
+ public CachedRowSet getData(String statement, ArrayList<Object> arguments) throws SQLException, Throwable
+ {
+ TestObject testObject = null;
+ testObject = monitor.registerRequest();
+
+ Connection connection = null;
+ try {
+ connection = this.getConnection();
+ if(connection == null ) {
+ throw new SQLException("Connection invalid");
+ }
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Obtained connection <" + connectionName + ">: "+connection.toString());
+ return executePreparedStatement(connection, statement, arguments, true);
+ } finally {
+ try {
+ if(connection != null && !connection.isClosed()) {
+ connection.close();
+ }
+ } catch(Throwable exc) {
+ // the exception not monitored
+ } finally {
+ connection = null;
+ }
+
+ monitor.deregisterReguest(testObject);
+ }
+ }
+
+ public boolean writeData(String statement, ArrayList<Object> arguments) throws SQLException, Throwable
+ {
+ TestObject testObject = null;
+ testObject = monitor.registerRequest();
+
+ Connection connection = null;
+ try {
+ connection = this.getConnection();
+ if(connection == null ) {
+ throw new SQLException("Connection invalid");
+ }
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Obtained connection <" + connectionName + ">: "+connection.toString());
+ return executeUpdatePreparedStatement(connection, statement, arguments, true);
+ } finally {
+ try {
+ if(connection != null && !connection.isClosed()) {
+ connection.close();
+ }
+ } catch(Throwable exc) {
+ // the exception not monitored
+ } finally {
+ connection = null;
+ }
+
+ monitor.deregisterReguest(testObject);
+ }
+ }
+
+ CachedRowSet executePreparedStatement(Connection conn, String statement, ArrayList<Object> arguments, boolean close) throws SQLException, Throwable
+ {
+ long time = System.currentTimeMillis();
+
+ CachedRowSet data = null;
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL Statement: "+ statement);
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.debug("Argunments: "+ Arrays.toString(arguments.toArray()));
+ }
+ }
+
+ ResultSet rs = null;
+ try {
+ data = RowSetProvider.newFactory().createCachedRowSet();
+ PreparedStatement ps = conn.prepareStatement(statement);
+ if(arguments != null)
+ {
+ for(int i = 0, max = arguments.size(); i < max; i++){
+ ps.setObject(i+1, arguments.get(i));
+ }
+ }
+ rs = ps.executeQuery();
+ data.populate(rs);
+ // Point the rowset Cursor to the start
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL SUCCESS. rows returned: " + data.size()+ ", time(ms): "+ (System.currentTimeMillis() - time)); }
+ } catch(SQLException exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ try { conn.rollback(); } catch(Throwable thr){}
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc;
+ } catch(Throwable exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc; // new SQLException(exc);
+ } finally {
+
+ try {
+ if(rs != null){
+ rs.close();
+ rs = null;
+ }
+ } catch(Exception exc){
+
+ }
+ try {
+ if(conn != null && close){
+ conn.close();
+ conn = null;
+ }
+ } catch(Exception exc){
+
+ }
+ }
+
+ return data;
+ }
+
+ boolean executeUpdatePreparedStatement(Connection conn, String statement, ArrayList<Object> arguments, boolean close) throws SQLException, Throwable {
+ long time = System.currentTimeMillis();
+
+ CachedRowSet data = null;
+
+ int rs = -1;
+ try {
+ data = RowSetProvider.newFactory().createCachedRowSet();
+ PreparedStatement ps = conn.prepareStatement(statement);
+ if(arguments != null)
+ {
+ for(int i = 0, max = arguments.size(); i < max; i++){
+ if(arguments.get(i) instanceof Blob) {
+ ps.setBlob(i+1, (Blob)arguments.get(i));
+ } else if(arguments.get(i) instanceof Timestamp) {
+ ps.setTimestamp(i+1, (Timestamp)arguments.get(i));
+ } else if(arguments.get(i) instanceof Integer) {
+ ps.setInt(i+1, (Integer)arguments.get(i));
+ } else if(arguments.get(i) instanceof Long) {
+ ps.setLong(i+1, (Long)arguments.get(i));
+ } else if(arguments.get(i) instanceof Date) {
+ ps.setDate(i+1, (Date)arguments.get(i));
+ } else {
+ ps.setObject(i+1, arguments.get(i));
+ }
+ }
+ }
+ rs = ps.executeUpdate();
+ // Point the rowset Cursor to the start
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL SUCCESS. rows returned: " + data.size()+ ", time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ } catch(SQLException exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ try { conn.rollback(); } catch(Throwable thr){}
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc;
+ } catch(Throwable exc){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL FAILURE. time(ms): "+ (System.currentTimeMillis() - time));
+ }
+ if(arguments != null && !arguments.isEmpty()) {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with arguments: "+arguments.toString(), exc);
+ } else {
+ LOGGER.error("<"+connectionName+"> Failed to execute: "+ statement + " with no arguments. ", exc);
+ }
+ throw exc; // new SQLException(exc);
+ } finally {
+ try {
+ if(conn != null && close){
+ conn.close();
+ conn = null;
+ }
+ } catch(Exception exc){
+
+ }
+ }
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getConnection(java.lang.String, java.lang.String)
+ */
+ public Connection getConnection(String username, String password)
+ throws SQLException
+ {
+ return ds.getConnection(username, password);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getLogWriter()
+ */
+ public PrintWriter getLogWriter() throws SQLException
+ {
+ return ds.getLogWriter();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#getLoginTimeout()
+ */
+ public int getLoginTimeout() throws SQLException
+ {
+ return ds.getLoginTimeout();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#setLogWriter(java.io.PrintWriter)
+ */
+ public void setLogWriter(PrintWriter out) throws SQLException
+ {
+ ds.setLogWriter(out);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.sql.DataSource#setLoginTimeout(int)
+ */
+ public void setLoginTimeout(int seconds) throws SQLException
+ {
+ ds.setLoginTimeout(seconds);
+ }
+
+
+ public final String getDbConnectionName(){
+ return connectionName;
+ }
+
+ protected final void setDbConnectionName(String name) {
+ this.connectionName = name;
+ }
+
+ public void cleanUp(){
+ if(ds != null && ds instanceof Closeable) {
+ try {
+ ((Closeable)ds).close();
+ } catch (IOException e) {
+ LOGGER.warn(e.getMessage());
+ }
+ }
+ ds = null;
+ monitor.deleteObservers();
+ monitor.cleanup();
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ protected boolean testConnection(){
+ return testConnection(false);
+ }
+
+ protected boolean testConnection(boolean error_level){
+ Connection conn = null;
+ ResultSet rs = null;
+ Statement stmt = null;
+ try
+ {
+ Boolean readOnly = null;
+ String hostname = null;
+ conn = this.getConnection();
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery("SELECT @@global.read_only, @@global.hostname"); //("SELECT 1 FROM DUAL"); //"select BANNER from SYS.V_$VERSION"
+ while(rs.next())
+ {
+ readOnly = rs.getBoolean(1);
+ hostname = rs.getString(2);
+
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("SQL DataSource <"+getDbConnectionName() + "> connected to " + hostname + ", read-only is " + readOnly + ", tested successfully ");
+ }
+ }
+
+ } catch (Throwable exc) {
+ if(error_level) {
+ LOGGER.error("SQL DataSource <" + this.getDbConnectionName() + "> test failed. Cause : " + exc.getMessage());
+ } else {
+ LOGGER.info("SQL DataSource <" + this.getDbConnectionName() + "> test failed. Cause : " + exc.getMessage());
+ }
+ return false;
+ } finally {
+ if(rs != null) {
+ try {
+ rs.close();
+ rs = null;
+ } catch (SQLException e) {
+ }
+ }
+ if(stmt != null) {
+ try {
+ stmt.close();
+ stmt = null;
+ } catch (SQLException e) {
+ }
+ }
+ if(conn !=null){
+ try {
+ conn.close();
+ conn = null;
+ } catch (SQLException e) {
+ }
+ }
+ }
+ return true;
+ }
+
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return false;
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ return null;
+ }
+
+ @SuppressWarnings("deprecation")
+ public void setConnectionCachingEnabled(boolean state)
+ {
+// if(ds != null && ds instanceof OracleDataSource)
+// try {
+// ((OracleDataSource)ds).setConnectionCachingEnabled(true);
+// } catch (SQLException exc) {
+// LOGGER.warn("", exc);
+// }
+ }
+
+ public void addObserver(Observer observer) {
+ monitor.addObserver(observer);
+ }
+
+ public void deleteObserver(Observer observer) {
+ monitor.deleteObserver(observer);
+ }
+
+ public long getInterval() {
+ return interval;
+ }
+
+ public long getInitialDelay() {
+ return initialDelay;
+ }
+
+ public void setInterval(long value) {
+ interval = value;
+ }
+
+ public void setInitialDelay(long value) {
+ initialDelay = value;
+ }
+
+ public long getExpectedCompletionTime() {
+ return expectedCompletionTime;
+ }
+
+ public void setExpectedCompletionTime(long value) {
+ expectedCompletionTime = value;
+ }
+
+ public long getUnprocessedFailoverThreshold() {
+ return unprocessedFailoverThreshold;
+ }
+
+ public void setUnprocessedFailoverThreshold(long value) {
+ this.unprocessedFailoverThreshold = value;
+ }
+
+ public boolean canTakeOffLine() {
+ return canTakeOffLine;
+ }
+
+ public void blockImmediateOffLine() {
+ canTakeOffLine = false;
+ final Thread offLineTimer = new Thread()
+ {
+ public void run(){
+ try {
+ Thread.sleep(30000L);
+ }catch(Throwable exc){
+
+ }finally{
+ canTakeOffLine = true;
+ }
+ }
+ };
+ offLineTimer.setDaemon(true);
+ offLineTimer.start();
+ }
+
+ /**
+ * @return the monitor
+ */
+ final SQLExecutionMonitor getMonitor() {
+ return monitor;
+ }
+
+ protected boolean isSlave() throws PoolExhaustedException, MySQLNonTransientConnectionException {
+ CachedRowSet rs = null;
+ boolean isSlave = true;
+ String hostname = "UNDETERMINED";
+ try {
+ boolean localSlave = true;
+ rs = this.getData("SELECT @@global.read_only, @@global.hostname", new ArrayList<Object>());
+ while(rs.next()) {
+ localSlave = rs.getBoolean(1);
+ hostname = rs.getString(2);
+ }
+ isSlave = localSlave;
+ } catch(PoolExhaustedException | MySQLNonTransientConnectionException peexc){
+ throw peexc;
+ } catch (SQLException e) {
+ LOGGER.error("", e);
+ isSlave = true;
+ } catch (Throwable e) {
+ LOGGER.error("", e);
+ isSlave = true;
+ }
+ if(isSlave){
+ LOGGER.debug("SQL SLAVE : "+connectionName + " on server " + hostname);
+ } else {
+ LOGGER.debug("SQL MASTER : "+connectionName + " on server " + hostname);
+ }
+ return isSlave;
+ }
+
+ public boolean isFabric() {
+ return false;
+ }
+
+ protected boolean lockTable(Connection conn, String tableName) {
+ boolean retValue = false;
+ Statement lock = null;
+ try {
+ if(tableName != null) {
+ if(LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Executing 'LOCK TABLES " + tableName + " WRITE' on connection " + conn.toString());
+ if("SVC_LOGIC".equals(tableName)) {
+ Exception e = new Exception();
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ LOGGER.debug(sw.toString());
+ }
+ }
+ lock = conn.createStatement();
+ lock.execute("LOCK TABLES " + tableName + " WRITE");
+ retValue = true;
+ }
+ } catch(Exception exc){
+ LOGGER.error("", exc);
+ retValue = false;
+ } finally {
+ try {
+ lock.close();
+ } catch(Exception exc) {
+
+ }
+ }
+ return retValue;
+ }
+
+ protected boolean unlockTable(Connection conn) {
+ boolean retValue = false;
+ Statement lock = null;
+ try {
+ if(LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Executing 'UNLOCK TABLES' on connection " + conn.toString());
+ }
+ lock = conn.createStatement();
+ retValue = lock.execute("UNLOCK TABLES");
+ } catch(Exception exc){
+ LOGGER.error("", exc);
+ retValue = false;
+ } finally {
+ try {
+ lock.close();
+ } catch(Exception exc) {
+
+ }
+ }
+ return retValue;
+ }
+
+ public void getPoolInfo(boolean allocation) {
+
+ }
+
+ public long getNextErrorReportTime() {
+ return nextErrorReportTime;
+ }
+
+ public void setNextErrorReportTime(long nextTime) {
+ this.nextErrorReportTime = nextTime;
+ }
+
+ public void setGlobalHostName(String hostname) {
+ this.globalHostName = hostname;
+ }
+
+ public String getGlobalHostName() {
+ return globalHostName;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
new file mode 100644
index 00000000..3e51ed94
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.JdbcDBCachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.MySQLCachedDataSource;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class CachedDataSourceFactory {
+
+ public static CachedDataSource createDataSource(BaseDBConfiguration config) {
+ if(config instanceof JDBCConfiguration)
+ return JdbcDBCachedDataSource.createInstance(config);
+
+ return (CachedDataSource)null;
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java
new file mode 100644
index 00000000..b324e6a2
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class DBConfigException extends RuntimeException
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4752405152537680257L;
+
+ public DBConfigException(Exception e)
+ {
+ super(e.toString());
+ }
+
+ public DBConfigException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java
new file mode 100644
index 00000000..150a9a82
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java
@@ -0,0 +1,130 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Properties;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DBLIBResourceActivator implements BundleActivator {
+
+ private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+ private static final String DBLIB_PROP_PATH = "/dblib.properties";
+
+ private ServiceRegistration registration = null;
+
+ private static final Logger LOG = LoggerFactory.getLogger(DBLIBResourceActivator.class);
+
+ @Override
+ public void start(BundleContext ctx) throws Exception {
+ LOG.info("entering DBLIBResourceActivator.start");
+
+ DbLibService jdbcDataSource = null;
+ // Read properties
+ Properties props = new Properties();
+
+ File file = null;
+ URL propURL = null;
+ String propDir = System.getenv(SDNC_CONFIG_DIR);
+ if ((propDir == null) || (propDir.length() == 0)) {
+ propDir = "/opt/sdnc/data/properties";
+ }
+ file = new File(propDir + DBLIB_PROP_PATH);
+ if(file.exists()) {
+ propURL = file.toURI().toURL();
+ LOG.info("Using property file (1): " + file.toString());
+ } else {
+ propURL = ctx.getBundle().getResource("dblib.properties");
+ URL tmp = null;
+ if (propURL == null) {
+ file = new File(DBLIB_PROP_PATH);
+ tmp = this.getClass().getResource(DBLIB_PROP_PATH);
+// if(!file.exists()) {
+ if(tmp == null) {
+ throw new DblibConfigurationException("Missing configuration properties resource(3) : " + DBLIB_PROP_PATH);
+ } else {
+ propURL = tmp; //file.toURI().toURL();
+ LOG.info("Using property file (4): " + file.toString());
+ }
+ } else {
+ LOG.info("Using property file (2): " + propURL.toString());
+ }
+ }
+
+
+ try {
+ props.load(propURL.openStream());
+ } catch (Exception e) {
+ throw new DblibConfigurationException("Could not load properties at URL " + propURL.toString(), e);
+
+ }
+
+
+
+ try {
+ jdbcDataSource = DBResourceManager.create(props);
+ } catch (Exception exc) {
+ throw new DblibConfigurationException("Could not get initialize database", exc);
+ }
+
+ String regName = jdbcDataSource.getClass().getName();
+
+ LOG.info("Registering DBResourceManager service "+regName);
+ registration = ctx.registerService(new String[] { regName, DbLibService.class.getName(), "javax.sql.DataSource" }, jdbcDataSource, null);
+ }
+
+ @Override
+ public void stop(BundleContext ctx) throws Exception {
+ LOG.info("entering DBLIBResourceActivator.stop");
+ if (registration != null)
+ {
+ try {
+ ServiceReference sref = ctx.getServiceReference(DbLibService.class.getName());
+
+ if (sref == null) {
+ LOG.warn("Could not find service reference for DBLIB service (" + DbLibService.class.getName() + ")");
+ } else {
+ DBResourceManager dblibSvc = (DBResourceManager) ctx.getService(sref);
+ if (dblibSvc == null) {
+ LOG.warn("Could not find service reference for DBLIB service (" + DbLibService.class.getName() + ")");
+ } else {
+ dblibSvc.cleanUp();
+ }
+ }
+ } catch(Throwable exc) {
+ LOG.warn("Cleanup", exc);
+ }
+
+ registration.unregister();
+ registration = null;
+ LOG.debug("Deregistering DBResourceManager service");
+ }
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibConnection.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibConnection.java
new file mode 100644
index 00000000..5c1f5104
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibConnection.java
@@ -0,0 +1,390 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+import javax.sql.rowset.CachedRowSet;
+
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.apache.tomcat.jdbc.pool.ProxyConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DBLibConnection implements Connection {
+
+ private static Logger LOGGER = LoggerFactory.getLogger(DBLibConnection.class);
+
+ private final Connection connection;
+ private final CachedDataSource dataSource;
+ private boolean locked = false;
+ private String tableName = null;
+
+ public DBLibConnection(Connection con, CachedDataSource dataSource){
+ this.connection = con;
+ this.dataSource = dataSource;
+ locked = false;
+ dataSource.getPoolInfo(true);
+ }
+
+ public boolean lockTable(String tablename) {
+ this.tableName = tablename;
+ return locked = dataSource.lockTable(connection, tableName);
+ }
+
+ public void resetInactivityTimer() {
+ Class<org.apache.tomcat.jdbc.pool.PooledConnection> iface = PooledConnection.class;
+ try {
+ PooledConnection pc = connection.unwrap(iface);
+ pc.setTimestamp(System.currentTimeMillis());
+ } catch (SQLException e) {
+ LOGGER.warn("Failed resetting timeout timer", e);
+ }
+ }
+
+ public boolean unlock() {
+ dataSource.unlockTable(connection);
+ return locked = false;
+ }
+
+ public boolean writeData(String statement, ArrayList<String> arguments) throws SQLException, Throwable
+ {
+ ArrayList<Object> newList=new ArrayList<Object>();
+ if(arguments != null && !arguments.isEmpty()) {
+ newList.addAll(arguments);
+ }
+ resetInactivityTimer();
+ return dataSource.executeUpdatePreparedStatement(connection, statement, newList, false);
+ }
+
+ public CachedRowSet getData(String statement, ArrayList<String> arguments) throws SQLException, Throwable
+ {
+ ArrayList<Object> newList=new ArrayList<Object>();
+ if(arguments != null && !arguments.isEmpty()) {
+ newList.addAll(arguments);
+ }
+ resetInactivityTimer();
+ return dataSource.executePreparedStatement(connection, statement, newList, false);
+ }
+
+ @Override
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ @Override
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+
+ @Override
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ return connection.prepareStatement(sql);
+ }
+
+ @Override
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ return connection.prepareCall(sql);
+ }
+
+ @Override
+ public String nativeSQL(String sql) throws SQLException {
+ return connection.nativeSQL(sql);
+ }
+
+ @Override
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ @Override
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ @Override
+ public void commit() throws SQLException {
+ connection.commit();
+ }
+
+ @Override
+ public void rollback() throws SQLException {
+ connection.rollback();
+ }
+
+ @Override
+ public void close() throws SQLException {
+ if(this.locked) {
+ try {
+ this.unlock();
+ } catch(Throwable th) {
+ LOGGER.error("Failed unlocking",th);
+ }
+ }
+ if(connection != null && !connection.isClosed()) {
+ connection.close();
+ }
+ dataSource.getPoolInfo(false);
+ }
+
+ @Override
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ @Override
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ @Override
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ @Override
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ @Override
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ @Override
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ @Override
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ @Override
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
+ throws SQLException {
+ return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public Map<String, Class<?>> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ @Override
+ public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ @Override
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ @Override
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ @Override
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ @Override
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ @Override
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback(savepoint);
+ }
+
+ @Override
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ @Override
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException {
+ return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
+ int resultSetHoldability) throws SQLException {
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ return connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
+ return connection.prepareStatement(sql, columnIndexes);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
+ return connection.prepareStatement(sql, columnNames);
+ }
+
+ @Override
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ @Override
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ @Override
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ @Override
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ @Override
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ @Override
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ @Override
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ @Override
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ @Override
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ @Override
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ @Override
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java
new file mode 100644
index 00000000..cc80741d
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+
+/**
+ * An exception time for handling DBLIB specific error handling.
+ */
+public class DBLibException extends SQLException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5345059355083984696L;
+
+ public DBLibException(String message){
+ super(message);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
new file mode 100644
index 00000000..5cf2953b
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java
@@ -0,0 +1,862 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLDataException;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.sql.SQLSyntaxErrorException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Observable;
+import java.util.PriorityQueue;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.sql.DataSource;
+import javax.sql.rowset.CachedRowSet;
+
+import org.apache.tomcat.jdbc.pool.PoolExhaustedException;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractDBResourceManagerFactory;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
+import org.openecomp.sdnc.sli.resource.dblib.factory.DBConfigFactory;
+import org.openecomp.sdnc.sli.resource.dblib.pm.PollingWorker;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitor;
+import com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @version $Revision: 1.15 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class DBResourceManager implements DataSource, DataAccessor, DBResourceObserver, DbLibService {
+ private static Logger LOGGER = LoggerFactory.getLogger(DBResourceManager.class);
+
+ transient boolean terminating = false;
+ transient protected long retryInterval = 10000L;
+ transient boolean recoveryMode = true;
+
+ protected final AtomicBoolean dsSelector = new AtomicBoolean();
+
+// Queue<CachedDataSource> dsQueue = new ConcurrentLinkedQueue<CachedDataSource>();
+ Queue<CachedDataSource> dsQueue = new PriorityQueue<CachedDataSource>(4, new Comparator<CachedDataSource>(){
+
+ @Override
+ public int compare(CachedDataSource left, CachedDataSource right) {
+ try {
+ if(!left.isSlave())
+ return -1;
+ if(!right.isSlave())
+ return 1;
+
+ } catch (Throwable e) {
+ LOGGER.warn("", e);
+ }
+ return 0;
+ }
+
+ });
+ protected final Set<CachedDataSource> broken = Collections.synchronizedSet(new HashSet<CachedDataSource>());
+ protected final Object monitor = new Object();
+ protected final Properties configProps;
+ protected final Thread worker;
+
+ protected final long terminationTimeOut;
+ protected final boolean monitorDbResponse;
+ protected final long monitoringInterval;
+ protected final long monitoringInitialDelay;
+ protected final long expectedCompletionTime;
+ protected final long unprocessedFailoverThreshold;
+
+ public DBResourceManager(Properties props){
+ this.configProps = props;
+
+ // get retry interval value
+ retryInterval = getLongFromProperties(props, "org.openecomp.dblib.connection.retry", 10000L);
+
+ // get recovery mode flag
+ recoveryMode = getBooleanFromProperties(props, "org.openecomp.dblib.connection.recovery", true);
+ if(!recoveryMode)
+ {
+ recoveryMode = false;
+ LOGGER.info("Recovery Mode disabled");
+ }
+ // get time out value for thread cleanup
+ terminationTimeOut = getLongFromProperties(props, "org.openecomp.dblib.termination.timeout", 300000L);
+ // get properties for monitoring
+ monitorDbResponse = getBooleanFromProperties(props, "org.openecomp.dblib.connection.monitor", false);
+ monitoringInterval = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.interval", 1000L);
+ monitoringInitialDelay = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.startdelay", 5000L);
+ expectedCompletionTime = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.expectedcompletiontime", 5000L);
+ unprocessedFailoverThreshold = getLongFromProperties(props, "org.openecomp.dblib.connection.monitor.unprocessedfailoverthreshold", 3L);
+
+ // initialize performance monitor
+ PollingWorker.createInistance(props);
+
+ // initialize recovery thread
+ worker = new RecoveryMgr();
+ worker.setName("DBResourcemanagerWatchThread");
+ worker.setDaemon(true);
+ worker.start();
+ }
+
+ private void config(Properties ctx) throws Exception {
+
+ DbConfigPool dbConfig = DBConfigFactory.createConfig(this.configProps);
+
+ try {
+ AbstractResourceManagerFactory factory = AbstractDBResourceManagerFactory.getFactory(dbConfig.getType());
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info("Default DB config is : " + dbConfig.getType());
+ LOGGER.info("Using factory : " + factory.getClass().getName());
+ }
+ CachedDataSource[] cachedDS = factory.initDBResourceManager(dbConfig, this);
+ if(cachedDS == null || cachedDS.length == 0) {
+ LOGGER.error("Initialization of CachedDataSources failed. No instance was created.");
+ throw new Exception("Failed to initialize DB Library. No data source was created.");
+ }
+
+ for(int i=0; i<cachedDS.length; i++){
+ if(cachedDS[i] != null && cachedDS[i].isInitialized()){
+ setDataSource(cachedDS[i]);
+ cachedDS[i].setInterval(monitoringInterval);
+ cachedDS[i].setInitialDelay(monitoringInitialDelay);
+ cachedDS[i].setExpectedCompletionTime(expectedCompletionTime);
+ cachedDS[i].setUnprocessedFailoverThreshold(unprocessedFailoverThreshold);
+ cachedDS[i].addObserver(this);
+ }
+ }
+
+ } catch(Exception exc){
+ throw exc;
+ }
+ }
+
+ private long getLongFromProperties(Properties props, String property, long defaultValue)
+ {
+ String value = null;
+ long tmpLongValue = defaultValue;
+ try {
+ value = (String)props.getProperty(property);
+ if(value != null)
+ tmpLongValue = Long.parseLong(value);
+
+ } catch(NumberFormatException exc) {
+ if(LOGGER.isWarnEnabled()){
+ LOGGER.warn("'"+property+"'=" + value+" is invalid. It should be a numeric value");
+ }
+ } catch(Exception exc) {
+ }
+ return tmpLongValue;
+
+ }
+
+ private boolean getBooleanFromProperties(Properties props, String property, boolean defaultValue)
+ {
+ boolean tmpValue = defaultValue;
+ String value = null;
+
+ try {
+ value = (String)props.getProperty(property);
+ if(value != null)
+ tmpValue = Boolean.parseBoolean(value);
+
+ } catch(NumberFormatException exc) {
+ if(LOGGER.isWarnEnabled()){
+ LOGGER.warn("'"+property+"'=" + value+" is invalid. It should be a boolean value");
+ }
+ } catch(Exception exc) {
+ }
+ return tmpValue;
+
+ }
+
+
+ public void update(Observable observable, Object data) {
+ // if observable is active and there is a standby available, switch
+ if(observable instanceof SQLExecutionMonitor)
+ {
+ SQLExecutionMonitor monitor = (SQLExecutionMonitor)observable;
+ if(monitor.getParent() instanceof CachedDataSource)
+ {
+ CachedDataSource dataSource = (CachedDataSource)monitor.getParent();
+ if(dataSource == dsQueue.peek())
+ {
+ if(recoveryMode && dsQueue.size() > 1){
+ handleGetConnectionException(dataSource, new Exception(data.toString()));
+ }
+ }
+ }
+ }
+ }
+
+ public void testForceRecovery()
+ {
+ CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
+ handleGetConnectionException(active, new Exception("test"));
+ }
+
+ class RecoveryMgr extends Thread {
+
+ public void run() {
+ while(!terminating)
+ {
+ try {
+ Thread.sleep(retryInterval);
+ } catch (InterruptedException e1) { }
+ CachedDataSource brokenSource = null;
+ try {
+ if (!broken.isEmpty()) {
+ CachedDataSource[] sourceArray = broken.toArray(new CachedDataSource[0]);
+ for (int i = 0; i < sourceArray.length; i++)
+ {
+ brokenSource = sourceArray[i];
+ if (brokenSource instanceof TerminatingCachedDataSource)
+ break;
+ if (resetConnectionPool(brokenSource)) {
+ broken.remove(brokenSource);
+ brokenSource.blockImmediateOffLine();
+ dsQueue.add(brokenSource);
+ LOGGER.info("DataSource <"
+ + brokenSource.getDbConnectionName()
+ + "> recovered.");
+ }
+ brokenSource = null;
+ }
+ }
+ } catch (Exception exc) {
+ LOGGER.warn(exc.getMessage());
+ if(brokenSource != null){
+ try {
+ if(!broken.contains(brokenSource))
+ broken.add(brokenSource);
+ brokenSource = null;
+ } catch (Exception e1) { }
+ }
+ }
+ }
+ LOGGER.info("DBResourceManager.RecoveryMgr <"+this.toString() +"> terminated." );
+ }
+
+ private boolean resetConnectionPool(CachedDataSource dataSource){
+ try {
+ return dataSource.testConnection();
+ } catch (Exception exc) {
+ LOGGER.info("DataSource <" + dataSource.getDbConnectionName() + "> resetCache failed with error: "+ exc.getMessage());
+ return false;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#getData(java.lang.String, java.util.ArrayList, java.lang.String)
+ */
+ @Override
+ public CachedRowSet getData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException {
+ ArrayList<Object> newList=new ArrayList<Object>();
+ if(arguments != null && !arguments.isEmpty()) {
+ newList.addAll(arguments);
+ }
+ if(recoveryMode)
+ return requestDataWithRecovery(statement, newList, preferredDS);
+ else
+ return requestDataNoRecovery(statement, newList, preferredDS);
+ }
+
+ private CachedRowSet requestDataWithRecovery(String statement, ArrayList<Object> arguments, String preferredDS) throws SQLException {
+ Throwable lastException = null;
+ CachedDataSource active = null;
+
+ // test if there are any connection pools available
+ LinkedList<CachedDataSource> sources = new LinkedList<CachedDataSource>(this.dsQueue);
+ if(sources.isEmpty()){
+ LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
+ throw new DBLibException("No active DB connection pools are available in RequestDataWithRecovery call.");
+ }
+ if(preferredDS != null && !sources.peek().getDbConnectionName().equals(preferredDS)) {
+ Collections.reverse(sources);
+ }
+
+
+ // loop through available data sources to retrieve data.
+ while(!sources.isEmpty())
+ {
+ active = sources.peek();
+
+ long time = System.currentTimeMillis();
+ try {
+ if(!active.isFabric()) {
+ CachedDataSource master = findMaster();
+ if(master != null) {
+ active = master;
+ master = null;
+ }
+ }
+ sources.remove(active);
+ return active.getData(statement, arguments);
+ } catch(SQLDataException exc){
+ throw exc;
+ } catch(SQLSyntaxErrorException exc){
+ throw exc;
+ } catch(SQLIntegrityConstraintViolationException exc){
+ throw exc;
+ } catch(Throwable exc){
+ lastException = exc;
+ String message = exc.getMessage();
+ if(message == null) {
+ if(exc.getCause() != null) {
+ message = exc.getCause().getMessage();
+ }
+ if(message == null)
+ message = exc.getClass().getName();
+ }
+ LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ handleGetConnectionException(active, exc);
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ time = (System.currentTimeMillis() - time);
+ LOGGER.debug("getData processing time : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ }
+ }
+ }
+ if(lastException instanceof SQLException){
+ throw (SQLException)lastException;
+ }
+ // repackage the exception
+ // you are here because either you run out of available data sources
+ // or the last exception was not of SQLException type.
+ // repackage the exception
+ if(lastException == null) {
+ throw new DBLibException("The operation timed out while waiting to acquire a new connection." );
+ } else {
+ SQLException exception = new DBLibException(lastException.getMessage());
+ exception.setStackTrace(lastException.getStackTrace());
+ if(lastException.getCause() instanceof SQLException) {
+ throw (SQLException)lastException.getCause();
+ }
+ throw exception;
+ }
+ }
+
+ private CachedRowSet requestDataNoRecovery(String statement, ArrayList<Object> arguments, String preferredDS) throws SQLException {
+ if(dsQueue.isEmpty()){
+ LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
+ throw new DBLibException("No active DB connection pools are available in RequestDataNoRecovery call.");
+ }
+ CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
+ long time = System.currentTimeMillis();
+ try {
+ if(!active.isFabric()) {
+ CachedDataSource master = findMaster();
+ if(master != null)
+ active = master;
+ }
+ return active.getData(statement, arguments);
+// } catch(SQLDataException exc){
+// throw exc;
+ } catch(Throwable exc){
+ String message = exc.getMessage();
+ if(message == null)
+ message = exc.getClass().getName();
+ LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ if(exc instanceof SQLException)
+ throw (SQLException)exc;
+ else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ time = (System.currentTimeMillis() - time);
+ LOGGER.debug(">> getData : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#writeData(java.lang.String, java.util.ArrayList, java.lang.String)
+ */
+ @Override
+ public boolean writeData(String statement, ArrayList<String> arguments, String preferredDS) throws SQLException
+ {
+ ArrayList<Object> newList=new ArrayList<Object>();
+ if(arguments != null && !arguments.isEmpty()) {
+ newList.addAll(arguments);
+ }
+
+ return writeDataNoRecovery(statement, newList, preferredDS);
+ }
+
+ CachedDataSource findMaster() throws PoolExhaustedException, MySQLNonTransientConnectionException {
+ CachedDataSource master = null;
+ CachedDataSource[] dss = this.dsQueue.toArray(new CachedDataSource[0]);
+ for(int i=0; i<dss.length; i++) {
+ if(!dss[i].isSlave()) {
+ master = dss[i];
+ if(i != 0) {
+ dsQueue.remove(master);
+ dsQueue.add(master);
+ }
+ return master;
+ }
+ }
+ if(master == null) {
+ LOGGER.warn("MASTER not found.");
+ }
+ return master;
+ }
+
+
+ private boolean writeDataNoRecovery(String statement, ArrayList<Object> arguments, String preferredDS) throws SQLException {
+ if(dsQueue.isEmpty()){
+ LOGGER.error("Generated alarm: DBResourceManager.getData - No active DB connection pools are available.");
+ throw new DBLibException("No active DB connection pools are available in RequestDataNoRecovery call.");
+ }
+
+ boolean initialRequest = true;
+ boolean retryAllowed = true;
+ CachedDataSource active = (CachedDataSource) this.dsQueue.peek();
+ long time = System.currentTimeMillis();
+ while(initialRequest) {
+ initialRequest = false;
+ try {
+ if(!active.isFabric()) {
+ CachedDataSource master = findMaster();
+ if(master != null) {
+ active = master;
+ }
+ }
+
+ return active.writeData(statement, arguments);
+ } catch(Throwable exc){
+ String message = exc.getMessage();
+ if(message == null)
+ message = exc.getClass().getName();
+ LOGGER.error("Generated alarm: "+active.getDbConnectionName()+" - "+message);
+ if(exc instanceof SQLException) {
+ SQLException sqlExc = SQLException.class.cast(exc);
+ // handle read-only exception
+ if(sqlExc.getErrorCode() == 1290 && "HY000".equals(sqlExc.getSQLState())) {
+ LOGGER.warn("retrying due to: " + sqlExc.getMessage());
+ dsQueue.remove(active);
+ dsQueue.add(active);
+ if(retryAllowed){
+ retryAllowed = false;
+ initialRequest = true;
+ continue;
+ }
+ }
+ throw (SQLException)exc;
+ } else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ time = (System.currentTimeMillis() - time);
+ LOGGER.debug("writeData processing time : "+ active.getDbConnectionName()+" "+time+" miliseconds.");
+ }
+ }
+ }
+ return true;
+ }
+
+ private void setDataSource(CachedDataSource dataSource) {
+ if(dataSource.testConnection(true)){
+ this.dsQueue.add(dataSource);
+ } else {
+ this.broken.add(dataSource);
+ }
+ }
+
+ public Connection getConnection() throws SQLException {
+ Throwable lastException = null;
+ CachedDataSource active = null;
+
+ if(dsQueue.isEmpty()){
+ throw new DBLibException("No active DB connection pools are available in GetConnection call.");
+ }
+
+ try {
+ active = dsQueue.peek();
+ CachedDataSource tmpActive = findMaster();
+ if(tmpActive != null) {
+ active = tmpActive;
+ }
+ return new DBLibConnection(active.getConnection(), active);
+ } catch(javax.sql.rowset.spi.SyncFactoryException exc){
+ LOGGER.debug("Free memory (bytes): " + Runtime.getRuntime().freeMemory());
+ LOGGER.warn("CLASSPATH issue. Allowing retry", exc);
+ lastException = exc;
+ } catch(PoolExhaustedException exc) {
+ throw new NoAvailableConnectionsException(exc);
+ } catch(MySQLNonTransientConnectionException exc){
+ throw new NoAvailableConnectionsException(exc);
+ } catch(Exception exc){
+ lastException = exc;
+ if(recoveryMode){
+ handleGetConnectionException(active, exc);
+ } else {
+ if(exc instanceof MySQLNonTransientConnectionException) {
+ throw new NoAvailableConnectionsException(exc);
+ } if(exc instanceof SQLException) {
+ throw (SQLException)exc;
+ } else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ }
+ } catch (Throwable trwb) {
+ DBLibException excptn = new DBLibException(trwb.getMessage());
+ excptn.setStackTrace(trwb.getStackTrace());
+ throw excptn;
+ } finally {
+ if(LOGGER.isDebugEnabled()){
+ displayState();
+ }
+ }
+
+ if(lastException instanceof SQLException){
+ throw (SQLException)lastException;
+ }
+ // repackage the exception
+ if(lastException == null) {
+ throw new DBLibException("The operation timed out while waiting to acquire a new connection." );
+ } else {
+ SQLException exception = new DBLibException(lastException.getMessage());
+ exception.setStackTrace(lastException.getStackTrace());
+ if(lastException.getCause() instanceof SQLException) {
+// exception.setNextException((SQLException)lastException.getCause());
+ throw (SQLException)lastException.getCause();
+ }
+ throw exception;
+ }
+ }
+
+ public Connection getConnection(String username, String password)
+ throws SQLException {
+ CachedDataSource active = null;
+
+ if(dsQueue.isEmpty()){
+ throw new DBLibException("No active DB connection pools are available in GetConnection call.");
+ }
+
+
+ try {
+ active = dsQueue.peek();
+ CachedDataSource tmpActive = findMaster();
+ if(tmpActive != null) {
+ active = tmpActive;
+ }
+ return active.getConnection(username, password);
+ } catch(Throwable exc){
+ if(recoveryMode){
+ handleGetConnectionException(active, exc);
+ } else {
+ if(exc instanceof SQLException)
+ throw (SQLException)exc;
+ else {
+ DBLibException excptn = new DBLibException(exc.getMessage());
+ excptn.setStackTrace(exc.getStackTrace());
+ throw excptn;
+ }
+ }
+
+ }
+
+ throw new DBLibException("No connections available in DBResourceManager in GetConnection call.");
+ }
+
+ private void handleGetConnectionException(CachedDataSource source, Throwable exc) {
+ try {
+ if(!source.canTakeOffLine())
+ {
+ LOGGER.error("Could not switch due to blocking");
+ return;
+ }
+
+ boolean removed = dsQueue.remove(source);
+ if(!broken.contains(source))
+ {
+ if(broken.add(source))
+ {
+ LOGGER.warn("DB Recovery: DataSource <" + source.getDbConnectionName() + "> put in the recovery mode. Reason : " + exc.getMessage());
+ } else {
+ LOGGER.warn("Error putting DataSource <" +source.getDbConnectionName()+ "> in recovery mode.");
+ }
+ } else {
+ LOGGER.info("DB Recovery: DataSource <" + source.getDbConnectionName() + "> already in recovery queue");
+ }
+ if(removed)
+ {
+ if(!dsQueue.isEmpty())
+ {
+ LOGGER.warn("DB DataSource <" + dsQueue.peek().getDbConnectionName() + "> became active");
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("", e);
+ }
+ }
+
+ public void cleanUp() {
+ for(Iterator<CachedDataSource> it=dsQueue.iterator();it.hasNext();){
+ CachedDataSource cds = (CachedDataSource)it.next();
+ it.remove();
+ cds.cleanUp();
+ }
+
+ try {
+ this.terminating = true;
+ if(broken != null)
+ {
+ try {
+ broken.add( new TerminatingCachedDataSource(null));
+ } catch(Exception exc){
+ LOGGER.error("Waiting for Worker to stop", exc);
+ }
+ }
+ worker.join(terminationTimeOut);
+ LOGGER.info("DBResourceManager.RecoveryMgr <"+worker.toString() +"> termination was successful: " + worker.getState());
+ } catch(Exception exc){
+ LOGGER.error("Waiting for Worker thread to terminate ", exc);
+ }
+ }
+
+ public static DBResourceManager create(Properties props) throws Exception {
+ DBResourceManager dbmanager = new DBResourceManager(props);
+ dbmanager.config(props);
+ return dbmanager;
+ }
+
+ public PrintWriter getLogWriter() throws SQLException {
+ return ((CachedDataSource)this.dsQueue.peek()).getLogWriter();
+ }
+
+ public int getLoginTimeout() throws SQLException {
+ return ((CachedDataSource)this.dsQueue.peek()).getLoginTimeout();
+ }
+
+ public void setLogWriter(PrintWriter out) throws SQLException {
+ ((CachedDataSource)this.dsQueue.peek()).setLogWriter(out);
+ }
+
+ public void setLoginTimeout(int seconds) throws SQLException {
+ ((CachedDataSource)this.dsQueue.peek()).setLoginTimeout(seconds);
+ }
+
+ public void displayState(){
+ if(LOGGER.isDebugEnabled()){
+ LOGGER.debug("POOLS : Active = "+dsQueue.size() + ";\t Broken = "+broken.size());
+ CachedDataSource current = (CachedDataSource)dsQueue.peek();
+ if(current != null) {
+ LOGGER.debug("POOL : Active name = \'"+current.getDbConnectionName()+ "\'");
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.sdnc.sli.resource.dblib.DbLibService#isActive()
+ */
+ @Override
+ public boolean isActive() {
+ return this.dsQueue.size()>0;
+ }
+
+ public String getActiveStatus(){
+ return "Connected: " + dsQueue.size()+"\tIn-recovery: "+broken.size();
+ }
+
+ public String getDBStatus(boolean htmlFormat) {
+ StringBuilder buffer = new StringBuilder();
+
+ ArrayList<CachedDataSource> list = new ArrayList<CachedDataSource>();
+ list.addAll(dsQueue);
+ list.addAll(broken);
+ if (htmlFormat)
+ {
+ buffer.append("<tr class=\"headerRow\"><th id=\"header1\">")
+ .append("Name:").append("</th>");
+ for (int i = 0; i < list.size(); i++) {
+ buffer.append("<th id=\"header").append(2 + i).append("\">");
+ buffer.append(((CachedDataSource) list.get(i)).getDbConnectionName()).append("</th>");
+ }
+ buffer.append("</tr>");
+
+ buffer.append("<tr><td>State:</td>");
+ for (int i = 0; i < list.size(); i++) {
+ if (broken.contains(list.get(i))) {
+ buffer.append("<td>in recovery</td>");
+ }
+ if (dsQueue.contains(list.get(i))) {
+ if (dsQueue.peek() == list.get(i))
+ buffer.append("<td>active</td>");
+ else
+ buffer.append("<td>standby</td>");
+ }
+ }
+ buffer.append("</tr>");
+
+ } else {
+ for (int i = 0; i < list.size(); i++) {
+ buffer.append("Name: ").append(((CachedDataSource) list.get(i)).getDbConnectionName());
+ buffer.append("\tState: ");
+ if (broken.contains(list.get(i))) {
+ buffer.append("in recovery");
+ } else
+ if (dsQueue.contains(list.get(i))) {
+ if (dsQueue.peek() == list.get(i))
+ buffer.append("active");
+ else
+ buffer.append("standby");
+ }
+
+ buffer.append("\n");
+
+ }
+ }
+ return buffer.toString();
+ }
+
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return false;
+ }
+
+ public <T> T unwrap(Class<T> iface) throws SQLException {
+ return null;
+ }
+
+ /**
+ * @return the monitorDbResponse
+ */
+ public final boolean isMonitorDbResponse() {
+ return recoveryMode && monitorDbResponse;
+ }
+
+ public void test(){
+ CachedDataSource obj = dsQueue.peek();
+ Exception ption = new Exception();
+ try {
+ for(int i=0; i<5; i++)
+ {
+ handleGetConnectionException(obj, ption);
+ }
+ } catch(Throwable exc){
+ LOGGER.warn("", exc);
+ }
+ }
+
+ public String getPreferredDSName(){
+ if(isActive()){
+ return getPreferredDataSourceName(dsSelector);
+ }
+ return "";
+ }
+
+ public String getPreferredDataSourceName(AtomicBoolean flipper) {
+
+ LinkedList<CachedDataSource> snapshot = new LinkedList<CachedDataSource>(dsQueue);
+ if(snapshot.size() > 1){
+ CachedDataSource first = snapshot.getFirst();
+ CachedDataSource last = snapshot.getLast();
+
+ int delta = first.getMonitor().getPorcessedConnectionsCount() - last.getMonitor().getPorcessedConnectionsCount();
+ if(delta < 0) {
+ flipper.set(false);
+ } else if(delta > 0) {
+ flipper.set(true);
+ } else {
+ // check the last value and return !last
+ flipper.getAndSet(!flipper.get());
+ }
+
+ if (flipper.get())
+ Collections.reverse(snapshot);
+ }
+ return snapshot.peek().getDbConnectionName();
+ }
+
+ public java.util.logging.Logger getParentLogger()
+ throws SQLFeatureNotSupportedException {
+ return null;
+ }
+
+ public String getMasterName() {
+ if(isActive()){
+ return getMasterDataSourceName(dsSelector);
+ }
+ return "";
+ }
+
+
+ private String getMasterDataSourceName(AtomicBoolean flipper) {
+
+ LinkedList<CachedDataSource> snapshot = new LinkedList<CachedDataSource>(dsQueue);
+ if(snapshot.size() > 1){
+ CachedDataSource first = snapshot.getFirst();
+ CachedDataSource last = snapshot.getLast();
+
+ int delta = first.getMonitor().getPorcessedConnectionsCount() - last.getMonitor().getPorcessedConnectionsCount();
+ if(delta < 0) {
+ flipper.set(false);
+ } else if(delta > 0) {
+ flipper.set(true);
+ } else {
+ // check the last value and return !last
+ flipper.getAndSet(!flipper.get());
+ }
+
+ if (flipper.get())
+ Collections.reverse(snapshot);
+ }
+ return snapshot.peek().getDbConnectionName();
+ }
+
+ class RemindTask extends TimerTask {
+ public void run() {
+ CachedDataSource ds = dsQueue.peek();
+ if(ds != null)
+ ds.getPoolInfo(false);
+ }
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java
new file mode 100644
index 00000000..e06779f3
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.util.Observer;
+
+public interface DBResourceObserver extends Observer {
+ public boolean isMonitorDbResponse();
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java
new file mode 100644
index 00000000..cd054a51
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import javax.sql.rowset.CachedRowSet;
+
+public interface DataAccessor {
+
+ public abstract CachedRowSet getData(String statement, ArrayList<String> arguments, String preferredDS)
+ throws SQLException;
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java
new file mode 100644
index 00000000..37d62513
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.util.Comparator;
+
+public interface DataSourceComparator extends Comparator <CachedDataSource>{
+
+ public abstract CachedDataSource getLastUsed();
+
+ public abstract void setLastUsed(CachedDataSource lastUsed);
+
+ public abstract int compare(CachedDataSource ds1, CachedDataSource ds2);
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java
new file mode 100644
index 00000000..25edd1f0
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+import javax.sql.rowset.CachedRowSet;
+
+public interface DbLibService {
+
+ /* (non-Javadoc)
+ * @see DataAccessor#getData(java.lang.String, java.util.ArrayList)
+ */
+ public abstract CachedRowSet getData(String statement,
+ ArrayList<String> arguments, String preferredDS)
+ throws SQLException;
+
+ /* (non-Javadoc)
+ * @see DataAccessor#writeData(java.lang.String, java.util.ArrayList)
+ */
+ public abstract boolean writeData(String statement,
+ ArrayList<String> arguments, String preferredDS)
+ throws SQLException;
+
+ public abstract boolean isActive();
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java
new file mode 100644
index 00000000..17700a5e
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+
+public class DblibConfigurationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public DblibConfigurationException()
+ {
+ super();
+ }
+
+ public DblibConfigurationException(String msg)
+ {
+ super(msg);
+ }
+
+ public DblibConfigurationException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/NoAvailableConnectionsException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/NoAvailableConnectionsException.java
new file mode 100644
index 00000000..16895b4d
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/NoAvailableConnectionsException.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLException;
+
+public class NoAvailableConnectionsException extends SQLException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6259205931674413018L;
+
+ public NoAvailableConnectionsException(Exception exc) {
+ super(exc);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java
new file mode 100644
index 00000000..234bbed0
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib;
+
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.pm.SQLExecutionMonitorObserver;
+
+
+public class TerminatingCachedDataSource extends CachedDataSource implements SQLExecutionMonitorObserver {
+
+ public TerminatingCachedDataSource(BaseDBConfiguration jdbcElem) throws DBConfigException {
+ super(jdbcElem);
+ }
+
+ protected void configure(BaseDBConfiguration jdbcElem) throws DBConfigException {
+ // no action
+ }
+
+ public long getInterval() {
+ return 1000;
+ }
+
+ public long getInitialDelay() {
+ return 1000;
+ }
+
+ public long getExpectedCompletionTime() {
+ return 50;
+ }
+
+ public void setExpectedCompletionTime(long value) {
+
+ }
+
+ public void setInterval(long value) {
+
+ }
+
+ public void setInitialDelay(long value) {
+
+ }
+
+ public long getUnprocessedFailoverThreshold() {
+ return 3;
+ }
+
+ public void setUnprocessedFailoverThreshold(long value) {
+
+ }
+
+ public int compareTo(CachedDataSource ods)
+ {
+ return 0;
+ }
+
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java
new file mode 100644
index 00000000..976b1cf2
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.Properties;
+
+public abstract class BaseDBConfiguration {
+ public static final String DATABASE_TYPE = "org.openecomp.sdnc.sli.dbtype";
+ public static final String DATABASE_URL = "org.openecomp.sdnc.sli.jdbc.url";
+ public static final String DATABASE_NAME = "org.openecomp.sdnc.sli.jdbc.database";
+ public static final String CONNECTION_NAME = "org.openecomp.sdnc.sli.jdbc.connection.name";
+ public static final String DATABASE_USER = "org.openecomp.sdnc.sli.jdbc.user";
+ public static final String DATABASE_PSSWD = "org.openecomp.sdnc.sli.jdbc.password";
+ public static final String CONNECTION_TIMEOUT="org.openecomp.sdnc.sli.jdbc.connection.timeout";
+ public static final String REQUEST_TIMEOUT = "org.openecomp.sdnc.sli.jdbc.request.timeout";
+ public static final String MIN_LIMIT = "org.openecomp.sdnc.sli.jdbc.limit.min";
+ public static final String MAX_LIMIT = "org.openecomp.sdnc.sli.jdbc.limit.max";
+ public static final String INIT_LIMIT = "org.openecomp.sdnc.sli.jdbc.limit.init";
+ public static final String DATABASE_HOSTS = "org.openecomp.sdnc.sli.jdbc.hosts";
+
+
+ protected final Properties props;
+
+ public BaseDBConfiguration(Properties properties) {
+ this.props = properties;
+ }
+
+ public int getConnTimeout() {
+ try {
+ String value = props.getProperty(CONNECTION_TIMEOUT);
+ return Integer.parseInt(value);
+ } catch(Exception exc) {
+ return -1;
+ }
+ }
+
+ public int getRequestTimeout() {
+ try {
+ String value = props.getProperty(REQUEST_TIMEOUT);
+ if(value == null)
+ return -1;
+ return Integer.parseInt(value);
+ } catch(Exception exc) {
+ return -1;
+ }
+ }
+
+ public String getDbConnectionName() {
+ return props.getProperty(CONNECTION_NAME);
+ }
+
+ public String getDatabaseName() {
+ return props.getProperty(DATABASE_NAME);
+ }
+
+ public String getDbUserId() {
+ return props.getProperty(DATABASE_USER);
+ }
+
+ public String getDbPasswd() {
+ return props.getProperty(DATABASE_PSSWD);
+ }
+
+ public int getDbMinLimit() {
+ String value = props.getProperty(MIN_LIMIT);
+ return Integer.parseInt(value);
+ }
+
+ public int getDbMaxLimit() {
+ String value = props.getProperty(MAX_LIMIT);
+ return Integer.parseInt(value);
+ }
+
+ public int getDbInitialLimit() {
+ String value = props.getProperty(INIT_LIMIT);
+ return Integer.parseInt(value);
+ }
+
+ public String getDbUrl() {
+ return props.getProperty(DATABASE_URL);
+ }
+
+ public String getServerGroup() {
+ return null;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
new file mode 100644
index 00000000..117f9321
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.ArrayList;
+import java.util.Properties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DbConfigPool {
+ private static Logger LOGGER = LoggerFactory.getLogger(DbConfigPool.class);
+
+ private final String type;
+
+ private ArrayList<BaseDBConfiguration> configurations = new ArrayList<BaseDBConfiguration>();
+
+ public DbConfigPool(Properties properties) {
+ LOGGER.debug("Initializing DbConfigType");
+ type = properties.getProperty(BaseDBConfiguration.DATABASE_TYPE, "JDBC").toUpperCase();
+ }
+
+ public int getTimeout() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public JDBCConfiguration[] getJDBCbSourceArray() {
+ return configurations.toArray(new JDBCConfiguration[configurations.size()]);
+ }
+
+ public void addConfiguration(BaseDBConfiguration config) {
+ configurations.add(config);
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java
new file mode 100644
index 00000000..cb6ea3e5
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.config;
+
+import java.util.Properties;
+
+public class JDBCConfiguration extends BaseDBConfiguration {
+
+ public JDBCConfiguration(Properties xmlElem) {
+ super(xmlElem);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
new file mode 100644
index 00000000..f4291a7d
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.JdbcDbResourceManagerFactory;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class AbstractDBResourceManagerFactory {
+
+ public static AbstractResourceManagerFactory getFactory(String type) throws FactoryNotDefinedException {
+
+ // JDBC
+ return JdbcDbResourceManagerFactory.createIntstance();
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
new file mode 100644
index 00000000..0f58a3f0
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+
+import java.sql.SQLException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSourceFactory;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Revision: 1.6 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public abstract class AbstractResourceManagerFactory {
+ private static Logger LOGGER = LoggerFactory.getLogger(AbstractResourceManagerFactory.class);
+
+ public abstract CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) throws Exception;
+ public abstract CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager dbResourceManager, String sourceName) throws SQLException ;
+
+
+ public static AbstractResourceManagerFactory createIntstance() throws FactoryNotDefinedException {
+ throw new FactoryNotDefinedException("Factory method 'createIntstance' needs to be overriden in DBResourceManagerFactory");
+ }
+
+ public class DBInitTask implements Callable<CachedDataSource>
+ {
+ private BaseDBConfiguration config = null;
+ private Set<DBInitTask> activeTasks;
+
+ public DBInitTask(JDBCConfiguration jdbcconfig, Set<DBInitTask> tasks) {
+ this.config = jdbcconfig;
+ this.activeTasks = tasks;
+ }
+
+ public CachedDataSource call() throws Exception {
+ CachedDataSource ds = null;
+ try {
+ ds = CachedDataSourceFactory.createDataSource(config);
+ return ds;
+ } finally {
+ synchronized(activeTasks) {
+ activeTasks.remove(this);
+ if (activeTasks.isEmpty()) {
+ final Runnable closure = new Runnable() {
+
+ public void run() {
+ try {
+ Thread.sleep(300);
+ } catch (Exception e) {
+ }
+ synchronized(activeTasks) {
+ activeTasks.notifyAll();
+ }
+ }
+ };
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Completed CachedDataSource.Call and notifyAll from " + ds.getDbConnectionName());
+ }
+ Thread worker = new Thread(closure);
+ worker.setDaemon(true);
+ worker.start();
+ } else {
+ if (LOGGER.isDebugEnabled()) {
+ if (ds != null) {
+ LOGGER.debug("Completed CachedDataSource.Call from " + ds.getDbConnectionName());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
new file mode 100644
index 00000000..8aadcae6
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.slf4j.LoggerFactory;
+
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki 01/17/08 Initial version
+ */
+public class DBConfigFactory {
+
+ public static DbConfigPool createConfig(Properties resource) {
+ return getConfigparams(resource);
+ }
+
+ static DbConfigPool getConfigparams(Properties properties){
+ DbConfigPool xmlConfig = new DbConfigPool(properties);
+ ArrayList<Properties> propertySets = new ArrayList<Properties>();
+
+ if("JDBC".equalsIgnoreCase(xmlConfig.getType())) {
+ String hosts = properties.getProperty(BaseDBConfiguration.DATABASE_HOSTS);
+ if(hosts == null || hosts.isEmpty()) {
+ propertySets.add(properties);
+ } else {
+ String[] newhost = hosts.split(",");
+ for(int i=0; i< newhost.length; i++) {
+ Properties localset = new Properties();
+ localset.putAll(properties);
+ String url = localset.getProperty(BaseDBConfiguration.DATABASE_URL);
+ if(url.contains("DBHOST"))
+ url = url.replace("DBHOST", newhost[i]);
+ if(url.contains("dbhost"))
+ url = url.replace("dbhost", newhost[i]);
+ localset.setProperty(BaseDBConfiguration.DATABASE_URL, url);
+ localset.setProperty(BaseDBConfiguration.CONNECTION_NAME, newhost[i]);
+ propertySets.add(localset);
+ }
+ }
+ } else {
+ propertySets.add(properties);
+ }
+ try {
+ Iterator<Properties> it = propertySets.iterator();
+ while(it.hasNext()) {
+ BaseDBConfiguration config = parse(it.next());
+ xmlConfig.addConfiguration(config);
+ }
+
+ } catch (Exception e) {
+ LoggerFactory.getLogger(DBConfigFactory.class).warn("",e);
+ }
+
+ return xmlConfig;
+ }
+
+ public static BaseDBConfiguration parse(Properties props) throws Exception {
+
+ String type = props.getProperty(BaseDBConfiguration.DATABASE_TYPE);
+
+ BaseDBConfiguration config = null;
+
+ if("JDBC".equalsIgnoreCase(type)) {
+ config = new JDBCConfiguration(props);
+ }
+
+ return config;
+
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java
new file mode 100644
index 00000000..e38cd351
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.factory;
+
+
+/**
+ * @version 1.3
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki 01/16/08 Initial version
+ */
+public class FactoryNotDefinedException extends Exception {
+
+ public FactoryNotDefinedException(String message) {
+ super(message);
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java
new file mode 100644
index 00000000..90c76f63
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDBCachedDataSource.java
@@ -0,0 +1,249 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLFeatureNotSupportedException;
+
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.apache.tomcat.jdbc.pool.PoolProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import com.mysql.jdbc.Driver;
+
+
+/**
+ * @version $Revision: 1.7 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+
+public class JdbcDBCachedDataSource extends CachedDataSource
+{
+ private String dbUserId;
+ private String dbPasswd;
+ private String dbUrl;
+
+ private int minLimit;
+ private int maxLimit;
+ private int initialLimit;
+
+ private static final String AS_CONF_ERROR = "AS_CONF_ERROR: ";
+
+ private static Logger LOGGER = LoggerFactory.getLogger(JdbcDBCachedDataSource.class);
+
+ /**
+ * @param jdbcElem
+ */
+ public JdbcDBCachedDataSource(BaseDBConfiguration jdbcElem)
+ {
+ super(jdbcElem);
+ }
+
+ @Override
+ protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException
+ {
+ BaseDBConfiguration jdbcConfig = (BaseDBConfiguration)xmlElem;
+ if(jdbcConfig.getConnTimeout() > 0){
+ this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
+ }
+ if(jdbcConfig.getRequestTimeout() > 0){
+ this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
+ }
+
+ // set connection pool name
+ String dbConnectionName = jdbcConfig.getDbConnectionName();
+ super.setDbConnectionName(dbConnectionName);
+ // Configure the JDBC connection
+ dbUserId = jdbcConfig.getDbUserId();
+ if (dbUserId == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbUserId attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ dbPasswd = jdbcConfig.getDbPasswd();
+ if (dbPasswd == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbPasswd attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ /*
+ dbDriver = jdbcConfig.getDbDriver();
+ if (dbDriver == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbDriver attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new ScpTblUpdateError(errorMsg);
+ }
+ */
+
+ minLimit = jdbcConfig.getDbMinLimit();
+// if (minLimit == null)
+// {
+// String errorMsg = "Invalid XML contents: JDBC Connection missing minLimit attribute";
+// LOGGER.error(AS_CONF_ERROR + errorMsg);
+// throw new DBConfigException(errorMsg);
+// }
+ maxLimit = jdbcConfig.getDbMaxLimit();
+// if (maxLimit == null)
+// {
+// String errorMsg = "Invalid XML contents: JDBC Connection missing maxLimit attribute";
+// LOGGER.error(AS_CONF_ERROR + errorMsg);
+// throw new DBConfigException(errorMsg);
+// }
+ initialLimit = jdbcConfig.getDbInitialLimit();
+// if (initialLimit == null)
+// {
+// String errorMsg = "Invalid XML contents: JDBC Connection missing initialLimit attribute";
+// LOGGER.error(AS_CONF_ERROR + errorMsg);
+// throw new DBConfigException(errorMsg);
+// }
+
+ dbUrl = jdbcConfig.getDbUrl();
+ if(dbUrl == null){
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbUrl attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ try {
+ Driver dr = new com.mysql.jdbc.Driver();
+ Class clazz = Class.forName("com.mysql.jdbc.Driver") ;
+
+ PoolProperties p = new PoolProperties();
+ p.setDriverClassName("com.mysql.jdbc.Driver");
+ p.setUrl(dbUrl);
+ p.setUsername(dbUserId);
+ p.setPassword(dbPasswd);
+ p.setJmxEnabled(true);
+ p.setTestWhileIdle(false);
+ p.setTestOnBorrow(true);
+ p.setValidationQuery("SELECT 1");
+ p.setTestOnReturn(false);
+ p.setValidationInterval(30000);
+ p.setTimeBetweenEvictionRunsMillis(30000);
+ p.setInitialSize(initialLimit);
+ p.setMaxActive(maxLimit);
+ p.setMaxIdle(maxLimit);
+ p.setMaxWait(10000);
+ p.setRemoveAbandonedTimeout(60);
+ p.setMinEvictableIdleTimeMillis(30000);
+ p.setMinIdle(minLimit);
+ p.setLogAbandoned(true);
+ p.setRemoveAbandoned(true);
+ p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
+
+ DataSource dataSource = new DataSource(p);
+
+ synchronized(this)
+ {
+ this.ds = dataSource;
+ Connection con = null;
+ PreparedStatement st = null;
+ ResultSet rs = null;
+
+ try {
+ con = dataSource.getConnection();
+ st = con.prepareStatement("Select 1 FROM DUAL");
+ rs = st.executeQuery();
+ } catch(Exception exc) {
+ LOGGER.error(exc.getMessage());
+ } finally {
+ if(rs != null) rs.close();
+ if(st != null) st.close();
+ if(con != null) con.close();
+ }
+
+ initialized = true;
+ LOGGER.info("MySQLDataSource <"+dbConnectionName+"> configured successfully. Using URL: "+dbUrl);
+ }
+
+// } catch (SQLException exc) {
+// initialized = false;
+// StringBuffer sb = new StringBuffer();
+// sb.append("Failed to initialize MySQLDataSource<");
+// sb.append(dbConnectionName).append(">. Reason: ");
+// sb.append(exc.getMessage());
+// LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+//// throw new DBConfigException(e.getMessage());
+ } catch (Exception exc) {
+ initialized = false;
+ StringBuffer sb = new StringBuffer();
+ sb.append("Failed to initialize MySQLCachedDataSource <");
+ sb.append(dbConnectionName).append(">. Reason: ");
+ sb.append(exc.getMessage());
+ LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+// throw new DBConfigException(e.getMessage());
+ }
+ }
+
+ public final String getDbUrl()
+ {
+ return dbUrl;
+ }
+
+ public final String getDbUserId()
+ {
+ return dbUserId;
+ }
+
+ public final String getDbPasswd()
+ {
+ return dbPasswd;
+ }
+
+ public static JdbcDBCachedDataSource createInstance(BaseDBConfiguration config) /*throws Exception*/ {
+ return new JdbcDBCachedDataSource(config);
+ }
+
+ public String toString(){
+ return getDbConnectionName();
+ }
+
+ public java.util.logging.Logger getParentLogger()
+ throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void cleanUp(){
+ DataSource dataSource = (DataSource)ds;
+ dataSource.getPool().purge();
+ int active = dataSource.getActive();
+ int size = dataSource.getSize();
+ dataSource.close(true);
+ super.cleanUp();
+ }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java
new file mode 100644
index 00000000..84399dfd
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java
@@ -0,0 +1,186 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.jdbc;
+
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSourceFactory;
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
+import org.openecomp.sdnc.sli.resource.dblib.DataSourceComparator;
+import org.openecomp.sdnc.sli.resource.dblib.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.factory.AbstractResourceManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Revision: 1.6 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class JdbcDbResourceManagerFactory extends AbstractResourceManagerFactory {
+ private static Logger LOGGER = LoggerFactory.getLogger(JdbcDbResourceManagerFactory.class );
+ private JdbcDbResourceManagerFactory(){
+
+ }
+
+ class MyFutureTask extends FutureTask<CachedDataSource>
+ {
+
+ public MyFutureTask(Callable<CachedDataSource> result) {
+ super(result);
+ }
+
+ }
+
+ public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager, String sourceName) throws SQLException
+ {
+ // here create the data sources objects
+ JDBCConfiguration[] list = dbConfig.getJDBCbSourceArray();
+ CachedDataSource[] cachedDS = new CachedDataSource[1];
+
+ for(int i=0, max=list.length; i<max; i++){
+ if(!sourceName.equals(list[i].getDbConnectionName()))
+ continue;
+
+ JDBCConfiguration config = list[i];
+ CachedDataSource dataSource = CachedDataSourceFactory.createDataSource(config);
+ cachedDS[0] = dataSource;
+ }
+ return cachedDS;
+ }
+
+ public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) /* throws Exception */ {
+
+ ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
+ // here create the data sources objects
+ JDBCConfiguration[] list = dbConfig.getJDBCbSourceArray();
+
+ MyFutureTask[] futures = new MyFutureTask[list.length];
+ final Set<DBInitTask> tasks = new HashSet<DBInitTask>();
+ if(LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Creating " + list.length + " datasources.");
+ }
+
+ for(int i=0, max=list.length; i<max; i++){
+ JDBCConfiguration config = list[i];
+
+ DBInitTask task = new DBInitTask(config, tasks);
+ tasks.add(task);
+ futures[i] = new MyFutureTask(task);
+ }
+
+ try {
+ synchronized(tasks){
+ for(int i=0, max=list.length; i<max; i++){
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("Starting executor tasks.");
+ threadExecutor.execute(futures[i]);
+ }
+ // the timeout param is set is seconds.
+ long timeout = ((dbConfig.getTimeout() <= 0) ? 60L : dbConfig.getTimeout());
+ LOGGER.debug("Timeout set to " +timeout+" seconds");
+ timeout *= 1000;
+ // the timeout param is set is seconds, hence it needs to be multiplied by 1000.
+ tasks.wait(timeout);
+ if(LOGGER.isDebugEnabled())
+ LOGGER.debug("initDBResourceManager wait completed.");
+ }
+ } catch(Exception exc) {
+ LOGGER.error("Failed to initialize JndiCachedDataSource. Reason: ", exc);
+ }
+
+ if(threadExecutor != null){
+ try {
+ threadExecutor.shutdown();
+ } catch(Exception exc){}
+ }
+
+ CachedDataSource[] cachedDS = new CachedDataSource[futures.length];
+
+ boolean initialized = false;
+ for(int i=0; i<futures.length; i++){
+ Object obj = null;
+ if(futures[i].isDone()){
+ try {
+ obj = futures[i].get();
+ if(obj instanceof CachedDataSource){
+ cachedDS[i] = (CachedDataSource)obj;
+ initialized |= cachedDS[i].isInitialized();
+ if(cachedDS[i].isInitialized())
+ LOGGER.info("DataSource "+list[i].getDbConnectionName()+" initialized successfully");
+ else
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed");
+ } else {
+ if(obj == null) {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is null");
+ } else {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is " + obj.getClass().getName());
+ }
+ }
+ } catch (InterruptedException exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ } catch (ExecutionException exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ } catch (Exception exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ }
+ } else {
+ try {
+ obj = futures[i].get();
+ if(obj instanceof CachedDataSource){
+ LOGGER.warn("DataSource "+((CachedDataSource)obj).getDbConnectionName()+" failed");
+ } else {
+ if(obj == null) {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is null");
+ } else {
+ LOGGER.warn("DataSource " + i + " initialization failed. Returned object is " + obj.getClass().getName());
+ }
+ }
+ } catch (Exception exc) {
+ LOGGER.error("DataSource "+list[i].getDbConnectionName()+" initialization failed", exc);
+ }
+ }
+ }
+
+ if(!initialized){
+ new Error("Failed to initialize DB Library.");
+ }
+ return cachedDS;
+ }
+
+ public static AbstractResourceManagerFactory createIntstance() {
+ return new JdbcDbResourceManagerFactory();
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java
new file mode 100644
index 00000000..a5482d08
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java
@@ -0,0 +1,217 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.jdbc;
+
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+
+import org.openecomp.sdnc.sli.resource.dblib.CachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.DBConfigException;
+import org.openecomp.sdnc.sli.resource.dblib.config.BaseDBConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.config.JDBCConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
+
+
+
+
+/**
+ * @version $Revision: 1.7 $
+ * Change Log
+ * Author Date Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+
+public class MySQLCachedDataSource extends CachedDataSource
+{
+ private String dbUserId;
+ private String dbPasswd;
+ private String dbUrl;
+
+ private String minLimit;
+ private String maxLimit;
+ private String initialLimit;
+
+ private static final String AS_CONF_ERROR = "AS_CONF_ERROR: ";
+
+ private static Logger LOGGER = LoggerFactory.getLogger(MySQLCachedDataSource.class);
+
+ /**
+ * @param jdbcElem
+ */
+ public MySQLCachedDataSource(BaseDBConfiguration jdbcElem)
+ {
+ super(jdbcElem);
+ }
+
+ @Override
+ protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException
+ {
+ BaseDBConfiguration jdbcConfig = (BaseDBConfiguration)xmlElem;
+ if(jdbcConfig.getConnTimeout() > 0){
+ this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
+ }
+ if(jdbcConfig.getRequestTimeout() > 0){
+ this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
+ }
+
+ // set connection pool name
+ String dbConnectionName = jdbcConfig.getDbConnectionName();
+ super.setDbConnectionName(dbConnectionName);
+ // Configure the JDBC connection
+ dbUserId = jdbcConfig.getDbUserId();
+ if (dbUserId == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbUserId attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ dbPasswd = jdbcConfig.getDbPasswd();
+ if (dbPasswd == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbPasswd attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ /*
+ dbDriver = jdbcConfig.getDbDriver();
+ if (dbDriver == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbDriver attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new ScpTblUpdateError(errorMsg);
+ }
+ */
+
+ minLimit = Integer.toString(jdbcConfig.getDbMinLimit());
+ if (minLimit == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBC Connection missing minLimit attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ maxLimit = Integer.toString(jdbcConfig.getDbMaxLimit());
+ if (maxLimit == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBC Connection missing maxLimit attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+ initialLimit = Integer.toString(jdbcConfig.getDbInitialLimit());
+ if (initialLimit == null)
+ {
+ String errorMsg = "Invalid XML contents: JDBC Connection missing initialLimit attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ dbUrl = jdbcConfig.getDbUrl();
+ if(dbUrl == null){
+ String errorMsg = "Invalid XML contents: JDBCConnection missing dbUrl attribute";
+ LOGGER.error(AS_CONF_ERROR + errorMsg);
+ throw new DBConfigException(errorMsg);
+ }
+
+ try {
+
+ MysqlDataSource dataSource = new MysqlDataSource();
+ dataSource.setUser(dbUserId);
+ dataSource.setPassword(dbPasswd);
+ dataSource.setURL(dbUrl);
+// dataSource.setInitialSize(5);
+// dataSource.setMaxTotal(60);
+// dataSource.setMaxActive(100);
+// dataSource.setMaxWait(10000);
+// dataSource.setMaxIdle(10);
+
+ Properties connAttr = new Properties();
+
+ connAttr.setProperty("MinLimit", minLimit);
+ connAttr.setProperty("MaxLimit", maxLimit);
+ connAttr.setProperty("InitialLimit", initialLimit);
+ connAttr.setProperty("TRANSACTION_ISOLATION","SERIALIZABLE");
+ connAttr.setProperty("CONNECTION_TAG", dbConnectionName.toUpperCase()+"_CONNECTION");
+ connAttr.setProperty("InactivityTimeout", "900");
+ connAttr.setProperty("AbandonedConnectionTimeout", "600");
+ connAttr.setProperty("PropertyCheckInterval", "60");
+ connAttr.setProperty("ValidateConnection", "true");
+
+
+ synchronized(this)
+ {
+ this.ds = dataSource;
+
+ initialized = true;
+ LOGGER.info("MySQLDataSource <"+dbConnectionName+"> configured successfully. Using URL: "+dbUrl);
+ }
+
+// } catch (SQLException exc) {
+// initialized = false;
+// StringBuffer sb = new StringBuffer();
+// sb.append("Failed to initialize MySQLDataSource<");
+// sb.append(dbConnectionName).append(">. Reason: ");
+// sb.append(exc.getMessage());
+// LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+//// throw new DBConfigException(e.getMessage());
+ } catch (Exception exc) {
+ initialized = false;
+ StringBuffer sb = new StringBuffer();
+ sb.append("Failed to initialize MySQLCachedDataSource <");
+ sb.append(dbConnectionName).append(">. Reason: ");
+ sb.append(exc.getMessage());
+ LOGGER.error("AS_CONF_ERROR: " + sb.toString());
+// throw new DBConfigException(e.getMessage());
+ }
+ }
+
+ public final String getDbUrl()
+ {
+ return dbUrl;
+ }
+
+ public final String getDbUserId()
+ {
+ return dbUserId;
+ }
+
+ public final String getDbPasswd()
+ {
+ return dbPasswd;
+ }
+
+ public static MySQLCachedDataSource createInstance(BaseDBConfiguration config) /*throws Exception*/ {
+ return new MySQLCachedDataSource(config);
+ }
+
+ public String toString(){
+ return getDbConnectionName();
+ }
+
+ public java.util.logging.Logger getParentLogger()
+ throws SQLFeatureNotSupportedException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java
new file mode 100644
index 00000000..de87fa7e
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java
@@ -0,0 +1,217 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.pm;
+
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class PollingWorker implements Runnable {
+
+ private Logger LOGGER = LoggerFactory.getLogger(PollingWorker.class);
+
+ private static PollingWorker self = null;
+
+ private LinkedBlockingQueue tasks = new LinkedBlockingQueue(100);
+ private long interval = 1000L;
+ private Thread worker = null;
+ private AtomicLong[] counters = null;
+ private int[] bucketUnit = null;
+ private static boolean enabled = false;
+ private Timer timer = null;
+
+ public static void post(long starttime){
+ PollingWorker temp = self;
+ if(temp != null && enabled) {
+ temp.register(new TestSample(starttime));
+ }
+ }
+
+ public static void createInistance(Properties props){
+ self = new PollingWorker(props);
+ }
+
+ private PollingWorker(Properties ctxprops){
+ if(ctxprops==null || ctxprops.getProperty("org.openecomp.sdnc.dblib.pm") == null){
+ enabled = false;
+ } else {
+ if("true".equalsIgnoreCase((String)ctxprops.getProperty("org.openecomp.sdnc.dblib.pm"))){
+ enabled = true;
+ } else {
+ enabled = false;
+ }
+ }
+
+ interval = Long.parseLong(( ctxprops == null || ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.interval") == null) ? "60" : (String)ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.interval"));
+ // '0' bucket is to count exceptions
+ String sampling[] = ((ctxprops == null || ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.sampling")==null) ? "0,2,5,10,20,50,100" : (String)ctxprops.getProperty("org.openecomp.sdnc.dblib.pm.sampling")).split(",");
+
+ if(enabled){
+ bucketUnit = new int[sampling.length];
+ for(int i=0, max = bucketUnit.length; i<max; i++){
+ bucketUnit[i] = Integer.parseInt(sampling[i].trim());
+ }
+ counters = new AtomicLong[bucketUnit.length+1];
+ for(int i=0, max = counters.length; i<max; i++){
+ counters[i] = new AtomicLong();
+ }
+ worker = new Thread(this);
+ worker.setDaemon(true);
+ worker.start();
+ timer = new Timer(true);
+ timer.schedule(new MyTimerTask(), interval*1000L, interval*1000L);
+ }
+ }
+
+ private void register(TestSample object){
+ try {
+ tasks.add(object);
+ } catch(Throwable exc) {
+ // if cannot add an object to the queue, do nothing
+ }
+ }
+
+ private void deRegister(TestSample object){
+ tasks.remove(object);
+ }
+
+ public void run() {
+ for(;;){
+ Set data = new TreeSet();
+ tasks.drainTo(data);
+ for(Iterator it = data.iterator(); it.hasNext(); ){
+ Object next = it.next();
+ if(next instanceof TestSample){
+ consume((TestSample)next);
+ } else {
+ System.out.println(next.getClass().getName());
+ }
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ public void clearReqister(){
+ AtomicLong[] tmp = new AtomicLong[counters.length];
+ for(int i=0, max = tmp.length; i<max; i++){
+ tmp[i] = new AtomicLong();
+ }
+ AtomicLong[] tmp2 = counters;
+ synchronized(tmp2){
+ counters = tmp;
+ }
+ StringBuffer sb = new StringBuffer("CPM: ");
+ for(int i=0, max = tmp2.length; i < max; i++){
+ if(i==0 && bucketUnit[0]==0){
+ sb.append("[Exc]=");
+ } else {
+ sb.append("[");
+ if(i==bucketUnit.length){
+ sb.append("Other]=");
+ } else {
+ sb.append(bucketUnit[i]).append(" ms]=");
+ }
+ }
+ sb.append(tmp2[i].get()).append("\t");
+ }
+ LOGGER.info(sb.toString());
+ }
+
+ class MyTimerTask extends TimerTask{
+
+ public void run() {
+
+ clearReqister();
+ }
+
+ }
+
+ private void consume(TestSample probe) {
+ AtomicLong[] tmp = counters;
+ synchronized(tmp){
+ counters[getBucket(probe.getDuration())].incrementAndGet();
+ }
+ }
+
+ /*
+ * This method is used to find the offset of the bucket in
+ * counters. 'counters' array is 1 size longer than bucketUnit,
+ * hence by default it returns 'bucketUnit.length'
+ */
+ private int getBucket(long difftime){
+ for(int i=0; i<bucketUnit.length; i++){
+ if(difftime < bucketUnit[i]){
+ return i;
+ }
+ }
+ return bucketUnit.length;
+ }
+
+ private static boolean isEnabled() {
+ return enabled;
+ }
+ /**
+ * @author Rich Tabedzki
+ * A helper class to pass measured parameter to the counter.
+ */
+ static class TestSample implements Comparable{
+ private long starttime;
+ private long endtime;
+
+ public TestSample(long starttime) {
+ this.endtime = System.currentTimeMillis();
+ this.starttime = starttime;
+ }
+
+ public long getDuration(){
+ return endtime - starttime;
+ }
+
+ public int compareTo(Object o) {
+ if(o instanceof TestSample){
+ TestSample x = (TestSample)o;
+ if(starttime < x.starttime)
+ return 1;
+ if(endtime < x.endtime)
+ return 1;
+ if(starttime > x.starttime)
+ return -1;
+ if(endtime > x.endtime)
+ return -1;
+ return 0;
+ }
+ return 1;
+ }
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java
new file mode 100644
index 00000000..c58c9db7
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java
@@ -0,0 +1,237 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.pm;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.SortedSet;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.openecomp.sdnc.sli.resource.dblib.DBResourceObserver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SQLExecutionMonitor extends Observable
+{
+ private static Logger LOGGER = LoggerFactory.getLogger(SQLExecutionMonitor.class);
+
+ final static long MILISECOND = 1000000L;
+ final static long SECOND = 1000L*MILISECOND;
+
+ private final Timer timer;
+ // collection
+ private final SortedSet<TestObject> innerSet;
+ private SQLExecutionMonitorObserver parent = null;
+ private final AtomicLong completionCounter;
+ private boolean activeState = false;
+ private final long interval;
+ private final long initialDelay;
+ private final long EXPECTED_TIME_TO_COMPLETE;
+ private final long UNPROCESSED_FAILOVER_THRESHOLD;
+
+ private final class MonitoringTask extends TimerTask
+ {
+
+ public void run()
+ {
+ try {
+ TestObject testObj = new TestObject();
+ testObj.setStartTime(testObj.getStartTime() - EXPECTED_TIME_TO_COMPLETE);
+
+ // take a snapshot of the current task list
+ TestObject[] array = innerSet.toArray(new TestObject[0]);
+ SortedSet<TestObject> copyCurrent = new TreeSet<TestObject>(Arrays.asList(array));
+ // get the list of the tasks that are older than the specified
+ // interval.
+ SortedSet<TestObject> unprocessed = copyCurrent.headSet(testObj);
+
+ long succesfulCount = completionCounter.get();
+ int unprocessedCount = unprocessed.size();
+
+ if (!unprocessed.isEmpty() && unprocessedCount > UNPROCESSED_FAILOVER_THRESHOLD && succesfulCount == 0)
+ {
+ // switch the Connection Pool to passive
+ setChanged();
+ notifyObservers("Open JDBC requests=" + unprocessedCount+" in "+SQLExecutionMonitor.this.parent.getDbConnectionName());
+ }
+ } catch (Exception exc) {
+ LOGGER.error("", exc);
+ } finally {
+ completionCounter.set(0L);
+ }
+ }
+ }
+
+ public static class TestObject implements Comparable<TestObject>, Serializable
+ {
+
+ private static final long serialVersionUID = 1L;
+ private long starttime;
+ private long randId;
+
+ public TestObject()
+ {
+ starttime = System.nanoTime();
+ }
+
+ public long getStartTime()
+ {
+ return starttime;
+ }
+
+ public void setStartTime(long newTime)
+ {
+ starttime = newTime;
+ }
+
+ public int compareTo(TestObject o)
+ {
+ if( this == o)
+ return 0;
+ if(this.starttime > o.getStartTime())
+ return 1;
+ if(this.starttime < o.getStartTime())
+ return -1;
+
+ if(this.hashCode() > o.hashCode())
+ return 1;
+ if(this.hashCode() < o.hashCode())
+ return -1;
+
+ return 0;
+ }
+
+ public String toString()
+ {
+ return Long.toString(starttime)+"#"+ this.hashCode();
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ return (obj instanceof TestObject
+ && starttime == ((TestObject) obj).getStartTime()
+ && hashCode() == ((TestObject) obj).hashCode());
+ }
+ }
+
+ public SQLExecutionMonitor(SQLExecutionMonitorObserver parent)
+ {
+ this.parent = parent;
+ completionCounter = new AtomicLong(0L);
+ interval = parent.getInterval();
+ initialDelay = parent.getInitialDelay();
+ this.UNPROCESSED_FAILOVER_THRESHOLD = parent.getUnprocessedFailoverThreshold();
+ this.EXPECTED_TIME_TO_COMPLETE = parent.getExpectedCompletionTime()*MILISECOND;
+
+ innerSet = Collections.synchronizedSortedSet(new TreeSet<TestObject>());
+ timer = new Timer();
+ }
+
+ public void cleanup()
+ {
+ timer.cancel();
+ }
+
+ // registerRequest
+ public TestObject registerRequest()
+ {
+ if(activeState)
+ {
+ TestObject test = new TestObject();
+ if(innerSet.add(test))
+ return test;
+ }
+ return null;
+ }
+
+ // deregisterSuccessfulReguest
+ public boolean deregisterReguest(TestObject test)
+ {
+ if(test == null)
+ return false;
+ // remove from the collection
+ if(innerSet.remove(test) && activeState)
+ {
+ completionCounter.incrementAndGet();
+ return true;
+ }
+ return false;
+ }
+
+ public void terminate() {
+ timer.cancel();
+ }
+
+ /**
+ * @return the parent
+ */
+ public final Object getParent() {
+ return parent;
+ }
+
+ public void addObserver(Observer observer)
+ {
+ if(observer instanceof DBResourceObserver)
+ {
+ DBResourceObserver dbObserver = (DBResourceObserver)observer;
+ if(dbObserver.isMonitorDbResponse())
+ {
+ if(countObservers() == 0)
+ {
+ TimerTask remindTask = new MonitoringTask();
+ timer.schedule(remindTask, initialDelay, interval);
+ activeState = true;
+ }
+ }
+ }
+ super.addObserver(observer);
+ }
+
+ public void deleteObserver(Observer observer)
+ {
+ super.deleteObserver(observer);
+ if(observer instanceof DBResourceObserver)
+ {
+ DBResourceObserver dbObserver = (DBResourceObserver)observer;
+ if(dbObserver.isMonitorDbResponse())
+ {
+ if(countObservers() == 0)
+ {
+ timer.cancel();
+ activeState = false;
+ }
+ }
+ }
+ }
+
+ public final int getPorcessedConnectionsCount() {
+ return innerSet.size();
+ }
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java
new file mode 100644
index 00000000..1f329750
--- /dev/null
+++ b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openecomp
+ * ================================================================================
+ * Copyright (C) 2016 - 2017 AT&T
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.openecomp.sdnc.sli.resource.dblib.pm;
+
+public interface SQLExecutionMonitorObserver {
+ public String getDbConnectionName();
+
+ public long getInterval();
+ public void setInterval(long value);
+
+ public long getInitialDelay();
+ public void setInitialDelay(long value);
+
+ public long getExpectedCompletionTime();
+ public void setExpectedCompletionTime(long value);
+
+ public long getUnprocessedFailoverThreshold();
+ public void setUnprocessedFailoverThreshold(long value);
+}
diff --git a/dblib/provider/src/main/resources/dblib.properties b/dblib/provider/src/main/resources/dblib.properties
new file mode 100755
index 00000000..ac295c78
--- /dev/null
+++ b/dblib/provider/src/main/resources/dblib.properties
@@ -0,0 +1,13 @@
+org.openecomp.sdnc.sli.dbtype=jdbc
+org.openecomp.sdnc.sli.jdbc.hosts=sdnctldb01,sdnctldb02
+org.openecomp.sdnc.sli.jdbc.url=jdbc:mysql://DBHOST:3306/sdnctl
+org.openecomp.sdnc.sli.jdbc.database=sdnctl
+org.openecomp.sdnc.sli.jdbc.user={user for sdnctl}
+org.openecomp.sdnc.sli.jdbc.password={password for sdnctl}
+org.openecomp.sdnc.sli.jdbc.connection.name=sdnctldb01
+
+org.openecomp.sdnc.sli.jdbc.connection.timeout=50
+org.openecomp.sdnc.sli.jdbc.request.timeout=100
+org.openecomp.sdnc.sli.jdbc.limit.init=10
+org.openecomp.sdnc.sli.jdbc.limit.min=10
+org.openecomp.sdnc.sli.jdbc.limit.max=20
diff --git a/example-settings.xml b/example-settings.xml
new file mode 100644
index 00000000..bfd6b9f4
--- /dev/null
+++ b/example-settings.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=2 tabstop=2: -->
+<!--
+ Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+ <profiles>
+ <profile>
+ <id>openecomp-release</id>
+ <repositories>
+ <repository>
+ <id>openecomp-release</id>
+ <name>openecomp-release</name>
+ <url>https://nexus.onap.org/content/repositories/releases/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>openecomp-release</id>
+ <name>openecomp-release</name>
+ <url>https://nexus.onap.org/content/repositories/releases/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+
+ <profile>
+ <id>openecomp-snapshots</id>
+ <repositories>
+ <repository>
+ <id>openecomp-snapshot</id>
+ <name>openecomp-snapshot</name>
+ <url>https://nexus.onap.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>openecomp-snapshot</id>
+ <name>openecomp-snapshot</name>
+ <url>https://nexus.onap.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ <profile>
+ <id>opendaylight-release</id>
+ <repositories>
+ <repository>
+ <id>opendaylight-mirror</id>
+ <name>opendaylight-mirror</name>
+ <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>opendaylight-mirror</id>
+ <name>opendaylight-mirror</name>
+ <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+
+ <profile>
+ <id>opendaylight-snapshots</id>
+ <repositories>
+ <repository>
+ <id>opendaylight-snapshot</id>
+ <name>opendaylight-snapshot</name>
+ <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>opendaylight-snapshot</id>
+ <name>opendaylight-snapshot</name>
+ <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ </profiles>
+
+ <activeProfiles>
+ <activeProfile>openecomp-release</activeProfile>
+ <activeProfile>openecomp-snapshots</activeProfile>
+ <activeProfile>opendaylight-release</activeProfile>
+ <activeProfile>opendaylight-snapshots</activeProfile>
+ </activeProfiles>
+
+ <servers>
+ <server>
+ <id>nexus</id>
+ <username>USERNAME</username>
+ <password>PASSWORD</password>
+ </server>
+ <server>
+ <id>openecomp-release</id>
+ <username>USERNAME</username>
+ <password>PASSWORD</password>
+ </server>
+ <server>
+ <id>openecomp-snapshot</id>
+ <username>USERNAME</username>
+ <password>PASSWORD</password>
+ </server>
+ </servers>
+</settings>
diff --git a/filters/.gitignore b/filters/.gitignore
new file mode 100755
index 00000000..b73caf31
--- /dev/null
+++ b/filters/.gitignore
@@ -0,0 +1,34 @@
+#####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
+
+## Folders which contain auto generated source code ##
+yang-gen-config
+yang-gen-sal
diff --git a/filters/.sonar/checkstyle.xml b/filters/.sonar/checkstyle.xml
new file mode 100755
index 00000000..3fa23153
--- /dev/null
+++ b/filters/.sonar/checkstyle.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"><!-- Generated by Sonar --><module name="Checker"><module name="SuppressionCommentFilter"/><module name="TreeWalker"><module name="FileContentsHolder"/> <module name="ClassFanOutComplexity"><property name="severity" value="warning"/></module><module name="NestedForDepth"><property name="severity" value="warning"/><property name="max" value="1"/></module><module name="ClassDataAbstractionCoupling"><property name="severity" value="warning"/></module></module></module> \ No newline at end of file
diff --git a/filters/.sonar/pmd.xml b/filters/.sonar/pmd.xml
new file mode 100755
index 00000000..80343b3b
--- /dev/null
+++ b/filters/.sonar/pmd.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleset>
+ <rule ref="rulesets/java/naming.xml/BooleanGetMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/j2ee.xml/StaticEJBFieldShouldBeFinal">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/codesize.xml/TooManyMethods">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/DoubleCheckedLocking">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/ExcessiveImports">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode">
+ <priority>2</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/ShortMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/BooleanInstantiation">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/codesize.xml/TooManyFields">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/LooseCoupling">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/design.xml/NonThreadSafeSingleton">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/j2ee.xml/DoNotUseThreads">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly">
+ <priority>5</priority>
+ </rule>
+ <rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray">
+ <priority>2</priority>
+ </rule>
+ <rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException">
+ <priority>3</priority>
+ </rule>
+</ruleset>
+
diff --git a/filters/README b/filters/README
new file mode 100755
index 00000000..9d69d638
--- /dev/null
+++ b/filters/README
@@ -0,0 +1,14 @@
+
+/restconf filters are enabled by specifying filter chain in
+ /opt/opendaylight/current/etc/org.opendaylight.aaa.filterchain.cfg
+and enabling bundle class loading
+ >bundle:dynamic-import org.openecomp.sdnc.filters-provider
+
+loggers:
+ org.openecomp.sdnc.filters.audit
+ org.openecomp.sdnc.filters.metric
+ org.openecomp.sdnc.filters.request.response
+
+
+
+
diff --git a/filters/features/pom.xml b/filters/features/pom.xml
new file mode 100755
index 00000000..1e3875de
--- /dev/null
+++ b/filters/features/pom.xml
@@ -0,0 +1,101 @@
+<?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>
+ <artifactId>filters</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>filters-features</artifactId>
+ <name>Filters - Features</name>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>filters-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+<!--
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${odl.mdsal.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+
+ <scope>runtime</scope>
+ </dependency>
+-->
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- launches the feature test, which validates that your karaf feature
+ can be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent bundles
+ defined correctly.
+ <plugin>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.odlparent</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/filters/features/src/main/resources/features.xml b/filters/features/src/main/resources/features.xml
new file mode 100644
index 00000000..1c58e649
--- /dev/null
+++ b/filters/features/src/main/resources/features.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+ -->
+
+
+<features name="sdnc-filters-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <feature name='sdnc-filters' description="servlet filters" version='${project.version}'>
+ <bundle>mvn:org.openecomp.sdnc.core/filters-provider/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/filters/installer/pom.xml b/filters/installer/pom.xml
new file mode 100755
index 00000000..579c0e9a
--- /dev/null
+++ b/filters/installer/pom.xml
@@ -0,0 +1,138 @@
+<?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.openecomp.sdnc.core</groupId>
+ <artifactId>filters</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>filters-installer</artifactId>
+ <name>Filters - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>sdnc-filters</application.name>
+ <features.boot>sdnc-filters</features.boot>
+ <features.repositories>mvn:org.openecomp.sdnc.core/filters-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>filters-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>filters-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>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</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.openecomp.sdnc</includeGroupIds>
+ <excludeArtifactIds>sli-common,sli-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/filters/installer/src/assembly/assemble_installer_zip.xml b/filters/installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 00000000..3a5c5f65
--- /dev/null
+++ b/filters/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,61 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/filters/installer/src/assembly/assemble_mvnrepo_zip.xml b/filters/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 00000000..a9fca4d0
--- /dev/null
+++ b/filters/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,49 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/filters/installer/src/main/resources/scripts/install-feature.sh b/filters/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 00000000..93236c5b
--- /dev/null
+++ b/filters/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+###
+# ============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=========================================================
+###
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+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} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/filters/pom.xml b/filters/pom.xml
new file mode 100644
index 00000000..b075be98
--- /dev/null
+++ b/filters/pom.xml
@@ -0,0 +1,81 @@
+<?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/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>filters</artifactId>
+
+
+ <name>Filters</name>
+ <description>Servlet filter to implement ECOMP logging spec</description>
+
+ <version>0.0.1-SNAPSHOT</version>
+
+
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven.compile.plugin.version}</version>
+ <configuration>
+ <source>${java.version.source}</source>
+ <target>${java.version.target}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10</version>
+
+ <executions>
+ <execution>
+ <id>aggregate</id>
+ <goals>
+ <goal>aggregate</goal>
+ </goals>
+ <phase>site</phase>
+
+ </execution>
+
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.1</version>
+ <executions>
+ <execution>
+ <id>bundle-sources</id>
+ <phase>package</phase>
+ <goals>
+ <!-- produce source artifact for main project sources -->
+ <goal>jar-no-fork</goal>
+
+ <!-- produce source artifact for project test sources -->
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </pluginManagement>
+ </build>
+ <organization>
+ <name>OpenECOMP</name>
+ </organization>
+ <modules>
+ <module>provider</module>
+ <module>features</module>
+ <module>installer</module>
+ </modules>
+</project>
diff --git a/filters/provider/pom.xml b/filters/provider/pom.xml
new file mode 100755
index 00000000..a7b6daec
--- /dev/null
+++ b/filters/provider/pom.xml
@@ -0,0 +1,94 @@
+<?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.openecomp.sdnc.core</groupId>
+ <artifactId>filters</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>filters-provider</artifactId>
+ <packaging>bundle</packaging>
+ <name>Filters - Provider</name>
+ <url>http://maven.apache.org</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>${commons.codec.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+<!--
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${mysql.connector.version}</version>
+ </dependency>
+-->
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.openecomp.sdnc.filters</Bundle-SymbolicName>
+ <Bundle-Activator>org.openecomp.sdnc.filters.Activator</Bundle-Activator>
+ <Export-Package>org.openecomp.sdnc.filters</Export-Package>
+ <DynamicImport-Package>org.openecomp.sdnc.filters</DynamicImport-Package>
+ <Import-Package>javax.servlet.*,java.io.*,org.osgi.framework.*,org.slf4j.*,org.apache.commons.codec.binary.*</Import-Package>
+ <!--
+ <Import-Package>org.openecomp.sdnc.filters.filters.*,javax.servlet.*,java.io.*,org.osgi.framework.*,org.slf4j.*</Import-Package>
+ <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency>
+ <Import-Package>*</Import-Package>
+ -->
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+
+ </plugin>
+
+
+ </plugins>
+ </build>
+</project>
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/Activator.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/Activator.java
new file mode 100644
index 00000000..d21b3099
--- /dev/null
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/Activator.java
@@ -0,0 +1,63 @@
+/*-
+ * ============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.openecomp.sdnc.filters;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class Activator implements BundleActivator {
+
+ private ServiceRegistration registration = null;
+
+ private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
+
+ @Override
+ public void start(BundleContext ctx) throws Exception {
+
+
+
+ Object impl = new String();
+ String regName = impl.getClass().getName();
+
+ if (registration == null)
+ {
+ LOG.debug("Registering Filters service "+regName);
+ registration = ctx.registerService(regName, impl, null);
+ }
+
+ }
+
+ @Override
+ public void stop(BundleContext ctx) throws Exception {
+
+ if (registration != null)
+ {
+ registration.unregister();
+ registration = null;
+ }
+ }
+
+}
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java
new file mode 100644
index 00000000..809cfb28
--- /dev/null
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java
@@ -0,0 +1,222 @@
+/*-
+ * ============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.openecomp.sdnc.filters;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.codec.binary.Base64;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+
+/**
+ * Logs IN request according ECOMP Logging Guidelines at https://tspace.web.att.com/viewer/app/lcfiles/ae5f7751-39da-4c6b-8a83-5836c8c815e1/content
+ */
+public class LogFilter implements Filter {
+
+ //X-ECOMP is shared between audit and metric
+ public static final String BEGIN_TIMESTAMP = "AUDIT-BeginTimestamp";
+ public static final String END_TIMESTAMP = "AUDIT-EndTimestamp";
+ public static final String REQUEST_ID = "X-ECOMP-RequestID";
+ public static final String SERVICE_INSTANCE = "X-ECOMP-ServiceInstanceID";
+ public static final String THREAD_ID ="X-ECOMP-ThreadId"; //optional
+ public static final String PHYSICAL_SERVER_NAME="X-ECOMP-PhysicalServerName"; //optional
+ public static final String SERVICE_NAME="X-ECOMP-ServiceName";
+ public static final String PARTNER_NAME="X-ECOMP-PartnerName";
+ public static final String STATUS_CODE="AUDIT-StatusCode";
+ public static final String RESP_CODE="AUDIT-ResponseCode";
+ public static final String RESP_DESC="AUDIT-ResponseDescription";
+ public static final String INSTANCE_UUID="AUDIT-InstanceUUID";
+ public static final String CATEGORY="AUDIT-INFO";
+ public static final String SEVERITY ="AUDIT-Severity"; //optional
+ public static final String SERVER_IP="AUDIT-ServerIP"; //by chef node['ip']
+ public static final String ELAPSED_TIME="AUDIT-ElapsedTime";
+ public static final String SERVER_HOST="AUDIT-Server";//by chef node['fqdn']
+ public static final String CLIENT_IP="AUDIT-ClientIPaddress";
+ public static final String CLASS="AUDIT-Classname"; //optional
+ public static final String UNUSED="AUDIT-Unused"; //empty
+ public static final String PROCESS_KEY="AUDIT-ProcessKey"; //optional
+ public static final String CUST_1="AUDIT-CustomField1";//optional
+ public static final String CUST_2="AUDIT-CustomField2"; //optional
+ public static final String CUST_3="AUDIT-CustomField3"; //optional
+ public static final String CUST_4="AUDIT-CustomField4"; //optional
+ public static final String DETAIL_MESSAGE="AUDIT-DetailMessage";//optional
+
+
+ private static final Logger log = LoggerFactory.getLogger(LogFilter.class);
+ private static final Logger AUDIT = LoggerFactory.getLogger("org.openecomp.sdnc.filters.audit");
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response,
+ final FilterChain filterChain) throws IOException, ServletException {
+
+ long startTime = System.currentTimeMillis();
+ try {
+
+ if ( request != null && request instanceof HttpServletRequest ) {
+ pre((HttpServletRequest)request);
+ }
+ filterChain.doFilter(request, response);
+
+
+ } finally {
+
+ if (request != null && request instanceof HttpServletRequest ) {
+ post((HttpServletRequest)request,(HttpServletResponse)response,startTime);
+ }
+ MDC.clear();
+ }
+
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+
+
+ private void pre(HttpServletRequest request) {
+
+ UUID uuid = UUID.randomUUID();
+ // check if uuid is in header X-ECOMP-RequestID
+
+ String ecompUUID = request.getHeader(REQUEST_ID);
+
+ if (ecompUUID != null && ecompUUID.length() > 0) {
+ try {
+ uuid = UUID.fromString(ecompUUID);
+ log.info("UUID is ECOMP UUID " + uuid.toString());
+ } catch (Exception ex){
+ log.warn("Failed to convert ECOMP UUID to java.util.UUID format:" + ecompUUID,ex);
+ }
+ }
+ MDC.put(REQUEST_ID, uuid.toString());
+
+ String userName="unknown";
+
+ /* below returning org.opendaylight.aaa.shiro.realm.TokenAuthRealm$ODLPrincipal@745dfcfe
+ if ( request.getUserPrincipal() != null) {
+ userName = request.getUserPrincipal().getName();
+ }
+ */
+ // going directly after Authorization header
+ if (request.getHeader("Authorization") != null) {
+ String authzHeader = request.getHeader("Authorization");
+ String usernameAndPassword = new String(Base64.decodeBase64(authzHeader.substring(6).getBytes()));
+
+ int userNameIndex = usernameAndPassword.indexOf(":");
+ String username = usernameAndPassword.substring(0, userNameIndex);
+ userName = username;
+
+ }
+
+
+ MDC.put(PARTNER_NAME, userName);
+ //just to initilaze for metric logger (outbound calls)
+ MDC.put("X-ECOMP-TargetEntity","");
+ MDC.put("X-ECOMP-TargetServiceName","");
+
+ MDC.put(SERVICE_NAME,request.getRequestURL().toString());
+ MDC.put(SERVICE_INSTANCE,"");
+
+ }
+
+
+ private void post(HttpServletRequest request,HttpServletResponse response,long startTime) {
+
+ //AUDIT.info("{}|{}|{}{}",request.getRemoteHost(),request.getMethod(),request.getRequestURL().toString(),request.getQueryString());
+ //AUDIT.info(request.getRemoteHost() + D + request.getMethod() + D + request.getRequestURL().toString() + D + request.getQueryString());
+ //METRIC.info(request.getMethod() + D + response.getStatus() + D + request.getRequestURL().toString() + D + (System.currentTimeMillis() - startTime) + " ms");
+ MDC.put(BEGIN_TIMESTAMP,asIso8601(startTime));
+ MDC.put(END_TIMESTAMP,asIso8601(System.currentTimeMillis()));
+ //MDC.put(REQUEST_ID,"already done above");
+ MDC.put(SERVICE_NAME,request.getRequestURL().toString());
+ int idx = request.getPathInfo().toString().lastIndexOf(":");
+ String instance = "";
+ if ( idx != -1 ) {
+ instance = request.getPathInfo().substring(idx+1);
+ }
+ MDC.put(SERVICE_INSTANCE,instance);
+ MDC.put(THREAD_ID,"");
+ MDC.put(PHYSICAL_SERVER_NAME,"");
+ //MDC.put(PARTNER_NAME,"already done above");
+ if ( response.getStatus() >= 400 ) {
+ MDC.put(STATUS_CODE,"ERROR");
+ } else {
+ MDC.put(STATUS_CODE,"COMPLETE");
+ }
+
+ MDC.put(RESP_CODE,"" + response.getStatus());
+ MDC.put(RESP_DESC,"");
+ MDC.put(INSTANCE_UUID,"");
+ MDC.put(CATEGORY,"");
+ MDC.put(SEVERITY,"");
+ //MDC.put(SERVER_IP,""); //by chef
+ MDC.put(ELAPSED_TIME,"" + (System.currentTimeMillis() - startTime));
+ //MDC.put(SERVER_HOST,""); //by chef
+ MDC.put(CLIENT_IP,request.getRemoteHost());
+ MDC.put(CLASS,"");
+ MDC.put(UNUSED,"");
+ MDC.put(PROCESS_KEY,"");
+ MDC.put(CUST_1,"");
+ MDC.put(CUST_2,"");
+ MDC.put(CUST_3,"");
+ MDC.put(CUST_4,"");
+ MDC.put(DETAIL_MESSAGE,request.getMethod());
+
+ AUDIT.info("");
+ }
+
+ private 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);
+ }
+
+ private String asIso8601(long tsInMillis) {
+ return asIso8601(new Date(tsInMillis));
+ }
+
+
+}
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java
new file mode 100644
index 00000000..183301be
--- /dev/null
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseDbLoggingFilter.java
@@ -0,0 +1,297 @@
+/*-
+ * ============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.openecomp.sdnc.filters;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.zip.GZIPInputStream;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.openecomp.sdnc.sli.MessageWriter;
+
+public class RequestResponseDbLoggingFilter implements Filter {
+
+ private static Logger log = LoggerFactory.getLogger(RequestResponseDbLoggingFilter.class);
+
+ public static final String REQUEST_ID = "X-ECOMP-RequestID";
+
+ private static class ByteArrayServletStream extends ServletOutputStream {
+
+ ByteArrayOutputStream baos;
+
+ ByteArrayServletStream(ByteArrayOutputStream baos) {
+ this.baos = baos;
+ }
+
+ @Override
+ public void write(int param) throws IOException {
+ baos.write(param);
+ }
+ }
+
+ private static class ByteArrayPrintWriter {
+
+ private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ private PrintWriter pw = new PrintWriter(baos);
+
+ private ServletOutputStream sos = new ByteArrayServletStream(baos);
+
+ public PrintWriter getWriter() {
+ return pw;
+ }
+
+ public ServletOutputStream getStream() {
+ return sos;
+ }
+
+ byte[] toByteArray() {
+ return baos.toByteArray();
+ }
+ }
+
+ private class BufferedServletInputStream extends ServletInputStream {
+
+ ByteArrayInputStream bais;
+
+ public BufferedServletInputStream(ByteArrayInputStream bais) {
+ this.bais = bais;
+ }
+
+ @Override
+ public int available() {
+ return bais.available();
+ }
+
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public int read(byte[] buf, int off, int len) {
+ return bais.read(buf, off, len);
+ }
+
+ }
+
+ private class BufferedRequestWrapper extends HttpServletRequestWrapper {
+
+ ByteArrayInputStream bais;
+
+ ByteArrayOutputStream baos;
+
+ BufferedServletInputStream bsis;
+
+ byte[] buffer;
+
+ public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
+ super(req);
+
+ InputStream is = req.getInputStream();
+ baos = new ByteArrayOutputStream();
+ byte buf[] = new byte[1024];
+ int letti;
+ while ((letti = is.read(buf)) > 0) {
+ baos.write(buf, 0, letti);
+ }
+ buffer = baos.toByteArray();
+
+ }
+
+ @Override
+ public ServletInputStream getInputStream() {
+ try {
+ bais = new ByteArrayInputStream(buffer);
+ bsis = new BufferedServletInputStream(bais);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ return bsis;
+ }
+
+ public byte[] getBuffer() {
+ return buffer;
+ }
+
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
+ throws IOException, ServletException {
+
+ if (request == null || !(request instanceof HttpServletRequest)) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+ long t1 = System.currentTimeMillis();
+
+ final HttpServletRequest httpRequest = (HttpServletRequest) request;
+ BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
+
+ String requestId = httpRequest.getHeader(REQUEST_ID);
+ if (requestId == null || requestId.trim().length() == 0) {
+ log.warn("Could not write request in DB: " + REQUEST_ID + " is missing in the HTTP headers.");
+ return;
+ }
+
+ String requestHost = request.getRemoteHost();
+ if (requestHost == null)
+ requestHost = request.getRemoteAddr();
+
+ String requestStr = new String(bufferedRequest.getBuffer());
+
+ MessageWriter.saveIncomingRequest(requestId, null, requestHost, requestStr);
+
+ long t2 = System.currentTimeMillis();
+
+ log.info("Request saved in DB for request-id: " + requestId + ". TIme: " + (t2 - t1));
+
+ final HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+ final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
+ HttpServletResponse wrappedResp = new HttpServletResponseWrapper(httpResponse) {
+
+ @Override
+ public PrintWriter getWriter() {
+ return pw.getWriter();
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() {
+ return pw.getStream();
+ }
+ };
+
+ try {
+
+ filterChain.doFilter(bufferedRequest, wrappedResp);
+
+ } finally {
+
+ if (request != null && request instanceof HttpServletRequest) {
+
+ t1 = System.currentTimeMillis();
+
+ byte[] bytes = pw.toByteArray();
+ response.getOutputStream().write(bytes);
+ response.getOutputStream().flush();
+
+ String responseStr = null;
+ if ("gzip".equals(httpResponse.getHeader("Content-Encoding"))) {
+ responseStr = decompressGZIPByteArray(bytes);
+ } else {
+ responseStr = new String(bytes);
+ }
+
+ MessageWriter.saveIncomingResponse(requestId, httpResponse.getStatus(), responseStr);
+
+ t2 = System.currentTimeMillis();
+
+ log.info("Response saved in DB for request-id: " + requestId + ". TIme: " + (t2 - t1));
+ }
+ }
+
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ private String decompressGZIPByteArray(byte[] bytes) {
+
+ BufferedReader in = null;
+ InputStreamReader inR = null;
+ ByteArrayInputStream byteS = null;
+ GZIPInputStream gzS = null;
+ StringBuilder str = new StringBuilder();
+ try {
+ byteS = new ByteArrayInputStream(bytes);
+ gzS = new GZIPInputStream(byteS);
+ inR = new InputStreamReader(gzS);
+ in = new BufferedReader(inR);
+
+ if (in != null) {
+
+ String content;
+
+ while ((content = in.readLine()) != null) {
+ str.append(content);
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("Failed get read GZIPInputStream", e);
+ } finally {
+
+ if (byteS != null)
+ try {
+ byteS.close();
+ } catch (IOException e1) {
+ log.error("Failed to close ByteStream", e1);
+ }
+ if (gzS != null)
+ try {
+ gzS.close();
+ } catch (IOException e2) {
+ log.error("Failed to close GZStream", e2);
+ }
+ if (inR != null)
+ try {
+ inR.close();
+ } catch (IOException e3) {
+ log.error("Failed to close InputReader", e3);
+ }
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ log.error("Failed to close BufferedReader", e);
+ }
+ }
+ return str.toString();
+ }
+}
diff --git a/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java
new file mode 100644
index 00000000..b15932f0
--- /dev/null
+++ b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java
@@ -0,0 +1,289 @@
+/*-
+ * ============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.openecomp.sdnc.filters;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.zip.GZIPInputStream;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+public class RequestResponseLoggingFilter implements Filter {
+
+ private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("org.openecomp.sdnc.filters.request.response");
+
+ private static class ByteArrayServletStream extends ServletOutputStream {
+
+ ByteArrayOutputStream baos;
+
+ ByteArrayServletStream(ByteArrayOutputStream baos) {
+ this.baos = baos;
+ }
+
+ @Override
+ public void write(int param) throws IOException {
+ baos.write(param);
+ }
+ }
+
+ private static class ByteArrayPrintWriter {
+
+ private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ private PrintWriter pw = new PrintWriter(baos);
+
+ private ServletOutputStream sos = new ByteArrayServletStream(baos);
+
+ public PrintWriter getWriter() {
+ return pw;
+ }
+
+ public ServletOutputStream getStream() {
+ return sos;
+ }
+
+ byte[] toByteArray() {
+ return baos.toByteArray();
+ }
+ }
+
+ private class BufferedServletInputStream extends ServletInputStream {
+
+ ByteArrayInputStream bais;
+
+ public BufferedServletInputStream(ByteArrayInputStream bais) {
+ this.bais = bais;
+ }
+
+ @Override
+ public int available() {
+ return bais.available();
+ }
+
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public int read(byte[] buf, int off, int len) {
+ return bais.read(buf, off, len);
+ }
+
+ }
+
+ private class BufferedRequestWrapper extends HttpServletRequestWrapper {
+
+ ByteArrayInputStream bais;
+
+ ByteArrayOutputStream baos;
+
+ BufferedServletInputStream bsis;
+
+ byte[] buffer;
+
+ public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
+ super(req);
+
+ InputStream is = req.getInputStream();
+ baos = new ByteArrayOutputStream();
+ byte buf[] = new byte[1024];
+ int letti;
+ while ((letti = is.read(buf)) > 0) {
+ baos.write(buf, 0, letti);
+ }
+ buffer = baos.toByteArray();
+
+ }
+
+ @Override
+ public ServletInputStream getInputStream() {
+ try {
+ bais = new ByteArrayInputStream(buffer);
+ bsis = new BufferedServletInputStream(bais);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ return bsis;
+ }
+
+ public byte[] getBuffer() {
+ return buffer;
+ }
+
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+
+ final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
+ BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(httpRequest);
+
+ StringBuilder requestHeaders = new StringBuilder("REQUEST|");
+ requestHeaders.append(httpRequest.getMethod());
+ requestHeaders.append(":");
+ requestHeaders.append(httpRequest.getRequestURL().toString());
+ requestHeaders.append("|");
+ String header;
+ for (Enumeration<String> e = httpRequest.getHeaderNames(); e.hasMoreElements();) {
+ header = e.nextElement();
+ requestHeaders.append(header);
+ requestHeaders.append(":");
+ requestHeaders.append(httpRequest.getHeader(header));
+ requestHeaders.append(";");
+
+ }
+ log.info(requestHeaders.toString());
+
+ log.info("REQUEST BODY|" + new String(bufferedRequest.getBuffer()));
+
+ final HttpServletResponse response = (HttpServletResponse) servletResponse;
+
+ final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
+ HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
+ @Override
+ public PrintWriter getWriter() {
+ return pw.getWriter();
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() {
+ return pw.getStream();
+ }
+
+ };
+
+ try {
+
+ filterChain.doFilter(bufferedRequest, wrappedResp);
+
+ }catch (Exception e){
+ log.error("Chain Exception",e);
+ throw e;
+ } finally {
+ byte[] bytes = pw.toByteArray();
+ response.getOutputStream().write(bytes);
+ response.getOutputStream().flush();
+
+ StringBuilder responseHeaders = new StringBuilder("RESPONSE HEADERS|");
+
+ for (String headerName : response.getHeaderNames()) {
+ responseHeaders.append(headerName);
+ responseHeaders.append(":");
+ responseHeaders.append(response.getHeader(headerName));
+ responseHeaders.append(";");
+
+ }
+ log.info(responseHeaders.toString());
+
+ if ("gzip".equals(response.getHeader("Content-Encoding"))) {
+
+ log.info("UNGZIPED RESPONSE BODY|" + decompressGZIPByteArray(bytes));
+
+ } else {
+
+ log.info("RESPONSE BODY|" + new String(bytes));
+ }
+ }
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ private String decompressGZIPByteArray(byte[] bytes) {
+
+ BufferedReader in = null;
+ InputStreamReader inR = null;
+ ByteArrayInputStream byteS = null;
+ GZIPInputStream gzS = null;
+ StringBuilder str = new StringBuilder();
+ try {
+ byteS = new ByteArrayInputStream(bytes);
+ gzS = new GZIPInputStream(byteS);
+ inR = new InputStreamReader(gzS);
+ in = new BufferedReader(inR);
+
+ if (in != null) {
+
+ String content;
+
+ while ((content = in.readLine()) != null) {
+ str.append(content);
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("Failed get read GZIPInputStream", e);
+ } finally {
+
+ if (byteS != null)
+ try {
+ byteS.close();
+ } catch (IOException e1) {
+ log.error("Failed to close ByteStream", e1);
+ }
+ if (gzS != null)
+ try {
+ gzS.close();
+ } catch (IOException e2) {
+ log.error("Failed to close GZStream", e2);
+ }
+ if (inR != null)
+ try {
+ inR.close();
+ } catch (IOException e3) {
+ log.error("Failed to close InputReader", e3);
+ }
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ log.error("Failed to close BufferedReader", e);
+ }
+ }
+ return str.toString();
+ }
+}
diff --git a/jenkins-settings.xml b/jenkins-settings.xml
new file mode 100644
index 00000000..344994f8
--- /dev/null
+++ b/jenkins-settings.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=2 tabstop=2: -->
+<!--
+ Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+ <profiles>
+ <profile>
+ <id>openecomp-release</id>
+ <repositories>
+ <repository>
+ <id>openecomp-release</id>
+ <name>openecomp-release</name>
+ <url>https://ecomp-nexus:8443/repository/maven-releases/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>openecomp-release</id>
+ <name>openecomp-release</name>
+ <url>https://ecomp-nexus:8443/repository/maven-releases/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+
+ <profile>
+ <id>openecomp-snapshots</id>
+ <repositories>
+ <repository>
+ <id>openecomp-snapshot</id>
+ <name>openecomp-snapshot</name>
+ <url>https://ecomp-nexus:8443/repository/maven-snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>openecomp-snapshot</id>
+ <name>openecomp-snapshot</name>
+ <url>https://ecomp-nexus:8443/repository/maven-snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ <profile>
+ <id>opendaylight-release</id>
+ <repositories>
+ <repository>
+ <id>opendaylight-mirror</id>
+ <name>opendaylight-mirror</name>
+ <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>opendaylight-mirror</id>
+ <name>opendaylight-mirror</name>
+ <url>https://nexus.opendaylight.org/content/repositories/public/</url>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+
+ <profile>
+ <id>opendaylight-snapshots</id>
+ <repositories>
+ <repository>
+ <id>opendaylight-snapshot</id>
+ <name>opendaylight-snapshot</name>
+ <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>opendaylight-snapshot</id>
+ <name>opendaylight-snapshot</name>
+ <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ </profiles>
+
+ <activeProfiles>
+ <activeProfile>openecomp-release</activeProfile>
+ <activeProfile>openecomp-snapshots</activeProfile>
+ <activeProfile>opendaylight-release</activeProfile>
+ <activeProfile>opendaylight-snapshots</activeProfile>
+ </activeProfiles>
+
+ <servers>
+ <server>
+ <id>nexus</id>
+ <username>${ecomp.nexus.user}</username>
+ <password>${ecomp.nexus.password}</password>
+ </server>
+ <server>
+ <id>openecomp-release</id>
+ <username>${ecomp.nexus.user}</username>
+ <password>${ecomp.nexus.password}</password>
+ </server>
+ <server>
+ <id>openecomp-snapshot</id>
+ <username>${ecomp.nexus.user}</username>
+ <password>${ecomp.nexus.password}</password>
+ </server>
+ <server>
+ <id>sdnc-javadoc</id>
+ <username>${ecomp.nexus.user}</username>
+ <password>${ecomp.nexus.password}</password>
+ </server>
+ </servers>
+</settings>
diff --git a/pom.xml b/pom.xml
new file mode 100755
index 00000000..bb0df7e7
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,183 @@
+<?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/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+
+ <name>SDN-C Core Components</name>
+ <url>https://wiki.onap.org</url>
+ <description>The SDN-C core components contains the SLI, dblib and root pom</description>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>odlparent-boron-sr3</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <issueManagement>
+ <system>JIRA</system>
+ <url>http://jira.onap.org/</url>
+ </issueManagement>
+
+
+ <scm>
+ <connection>scm:git:ssh://git@${onap.git.host}/sdnc-code.git</connection>
+ <developerConnection>scm:git:ssh://${onap.git.host}:${onap.git.port}/${onap.git.project}/sdnc-core.git</developerConnection>
+ <url>${onap.git.protocol}://${onap.git.host}/projects/${onap.git.project}/repos/sdnc-core/browse</url>
+ <tag>sdnc-core-1.1.0</tag>
+ </scm>
+
+ <ciManagement>
+ <system>Jenkins</system>
+ <url>https://jenkins.onap.org/</url>
+ </ciManagement>
+
+
+ <distributionManagement>
+ <site>
+ <id>ecomp-site</id>
+ <url>dav:https://${onap.nexus.host}/content/sites/site/org/onap/sdnc/core/${project.artifactId}/${project.version}</url>
+ </site>
+ </distributionManagement>
+
+
+ <profiles>
+ <profile>
+ <id>blackduck</id>
+ <activation>
+ <property>
+ <name>blackduck-scan</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.blackducksoftware.integration</groupId>
+ <artifactId>hub-maven-plugin</artifactId>
+ <version>1.4.0</version>
+ <inherited>false</inherited>
+ <configuration>
+ <hubProjectName>${project.name}</hubProjectName>
+ <outputDirectory>${project.basedir}</outputDirectory>
+ </configuration>
+ <executions>
+ <execution>
+ <id>create-bdio-file</id>
+ <phase>package</phase>
+ <goals>
+ <goal>createHubOutput</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+
+
+ </build>
+
+ </profile>
+
+ </profiles>
+
+ <build>
+ <plugins>
+ <!-- license plugin -->
+
+ <plugin>
+
+ <groupId>org.codehaus.mojo</groupId>
+
+ <artifactId>license-maven-plugin</artifactId>
+
+ <version>1.10</version>
+
+ <configuration>
+
+ <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+
+ <processStartTag>============LICENSE_START=======================================================</processStartTag>
+
+ <processEndTag>============LICENSE_END=========================================================</processEndTag>
+
+ <sectionDelimiter>================================================================================</sectionDelimiter>
+
+ <licenseName>apache_v2</licenseName>
+
+ <inceptionYear>2017</inceptionYear>
+
+ <organizationName>AT&amp;T Intellectual Property. All rights
+ reserved.</organizationName>
+
+ <projectName>openECOMP : SDN-C</projectName>
+
+ <canUpdateCopyright>true</canUpdateCopyright>
+
+ <canUpdateDescription>true</canUpdateDescription>
+
+ <canUpdateLicense>true</canUpdateLicense>
+
+ <emptyLineAfterHeader>true</emptyLineAfterHeader>
+
+ </configuration>
+
+ <executions>
+
+ <execution>
+
+ <id>first</id>
+
+ <goals>
+
+ <goal>update-file-header</goal>
+
+ </goals>
+
+ <phase>process-sources</phase>
+
+ </execution>
+
+ </executions>
+
+ </plugin>
+
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.17</version>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.sonatype.plugins</groupId>
+ <artifactId>nexus-staging-maven-plugin</artifactId>
+ <version>1.6.7</version>
+ <extensions>true</extensions>
+ <configuration>
+ <nexusUrl>https://${onap.nexus.host}</nexusUrl>
+ <stagingProfileId>${onap.nexus.staging.profile-id}</stagingProfileId>
+ <serverId>${onap.nexus.staging.server-id}</serverId>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+ <modules>
+ <module>dblib</module>
+ <module>sli</module>
+ <module>filters</module>
+ <module>sliPluginUtils</module>
+ <module>sliapi</module>
+ </modules>
+ <organization>
+ <name>OpenECOMP</name>
+ </organization>
+ <version>0.0.1-SNAPSHOT</version>
+
+
+</project>
diff --git a/sli/.gitignore b/sli/.gitignore
new file mode 100755
index 00000000..3632ac67
--- /dev/null
+++ b/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/sli/common/pom.xml b/sli/common/pom.xml
new file mode 100755
index 00000000..ce98b947
--- /dev/null
+++ b/sli/common/pom.xml
@@ -0,0 +1,150 @@
+<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>
+ <artifactId>sli</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sli-common</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>SLI - Common Classes</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>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4</artifactId>
+ <version>${antlr.version}</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.7.5</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${commons.lang3.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>yang-binding</artifactId>
+ <version>${odl.mdsal.yang.binding.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-common</artifactId>
+ <version>${odl.yangtools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ <version>${odl.ietf-inet-types.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types</artifactId>
+ <version>${odl.ietf-yang-types.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-core-api</artifactId>
+ <version>${odl.mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>${odl.yangtools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${mysql.connector.version}</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</artifactId>
+ <version>${sdnctl.dblib.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <includes>**/*.xsd</includes>
+ <archive>
+ <manifest>
+ <mainClass>org.openecomp.sdnc.sli.SvcLogicParser</mainClass>
+ <packageName>org.openecomp.sdnc.sli</packageName>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>org.openecomp.sdnc.sli;version=${project.version}</Export-Package>
+ <Import-Package>*</Import-Package>
+ <Embed-Dependency>*;scope=compile;artifactId=commons-lang|commons-lang3</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-maven-plugin</artifactId>
+ <version>${antlr.version}</version>
+ <executions>
+ <execution>
+ <configuration>
+ <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/sli/common/src/main/antlr4/org/openecomp/sdnc/sli/ExprGrammar.g4 b/sli/common/src/main/antlr4/org/openecomp/sdnc/sli/ExprGrammar.g4
new file mode 100755
index 00000000..51f40169
--- /dev/null
+++ b/sli/common/src/main/antlr4/org/openecomp/sdnc/sli/ExprGrammar.g4
@@ -0,0 +1,66 @@
+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/sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java
new file mode 100644
index 00000000..3e355baa
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/BreakNodeException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/ConfigurationException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/ConfigurationException.java
new file mode 100644
index 00000000..fa1308f0
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/ConfigurationException.java
@@ -0,0 +1,45 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/DuplicateValueException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/DuplicateValueException.java
new file mode 100644
index 00000000..beb22b0b
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/DuplicateValueException.java
@@ -0,0 +1,45 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java
new file mode 100644
index 00000000..5e5b621b
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/MessageWriter.java
@@ -0,0 +1,302 @@
+/*-
+ * ============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.openecomp.sdnc.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.openecomp.sdnc.sli.resource.dblib.DbLibService;
+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 MessageWriter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MessageWriter.class);
+
+ private static final String DBLIB_SERVICE = "org.openecomp.sdnc.sli.resource.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.openecomp.sdnc.sli.MessageWriter.writeIncomingRequests";
+ private static final String OUTGOING_PROPERTY_NAME = "org.openecomp.sdnc.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);
+
+ if (dbLibService != null)
+ return;
+
+ BundleContext bctx = FrameworkUtil.getBundle(MessageWriter.class).getBundleContext();
+
+ ServiceReference sref = bctx.getServiceReference(DBLIB_SERVICE);
+
+ if (sref == null) {
+ LOG.warn("Could not find service reference for DBLIB service (" + DBLIB_SERVICE + ")");
+ } else {
+ dbLibService = (DbLibService) bctx.getService(sref);
+ if (dbLibService == null) {
+ LOG.warn("Could not find service reference for DBLIB service (" + DBLIB_SERVICE + ")");
+ }
+ }
+ }
+
+ 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/sli/common/src/main/java/org/openecomp/sdnc/sli/MetricLogger.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/MetricLogger.java
new file mode 100644
index 00000000..14b1f008
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/MetricLogger.java
@@ -0,0 +1,301 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.net.InetAddress;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+/**
+ * @author dt5972
+ *
+ */
+public class MetricLogger {
+
+ private static final Logger KARAF = LoggerFactory.getLogger(MetricLogger.class);
+ private static final Logger METRIC = LoggerFactory.getLogger("org.openecomp.sdnc.filters.metric");
+
+ public static final String BEGIN_TIMESTAMP = "X-ECOMP-BeginTimestamp";
+ public static final String END_TIMESTAMP = "X-ECOMP-EndTimestamp";
+ public static final String REQUEST_ID = "X-ECOMP-RequestID";
+ public static final String SERVICE_INSTANCE_ID = "X-ECOMP-ServiceInstanceID";
+ public static final String SERVICE_NAME = "X-ECOMP-ServiceName";
+ public static final String PARTNER_NAME = "X-ECOMP-PartnerName";
+ public static final String TARGET_ENTITY = "X-ECOMP-TargetEntity";
+ public static final String TARGET_SERVICE_NAME = "X-ECOMP-TargetServiceName";
+ public static final String STATUS_CODE = "X-ECOMP-StatusCode";
+ public static final String RESPONSE_CODE = "X-ECOMP-ResponseCode";
+ public static final String RESPONSE_DESCRIPTION = "X-ECOMP-ResponseDescription";
+ public static final String INSTANCE_UUID = "X-ECOMP-InstanceUUID";
+ public static final String CATEGORY_LOG_LEVEL = "X-ECOMP-CategoryLogLevel";
+ public static final String SEVERITY = "X-ECOMP-Severity";
+ public static final String SERVER_IP_ADDRESS = "X-ECOMP-ServerIpAddress";
+ public static final String ELAPSED_TIME = "X-ECOMP-ElapsedTime";
+ public static final String SERVER = "X-ECOMP-Server";
+ public static final String CLIENT_IP = "X-ECOMP-ClientIp";
+ public static final String CLASS_NAME = "X-ECOMP-ClassName";
+ public static final String TARGET_VIRTUAL_ENTITY = "X-ECOMP-TargetVirtualEntity";
+
+ private long beginTimestamp;
+ private String lastMsg = null;
+
+ public MetricLogger() {
+ beginTimestamp = System.currentTimeMillis();
+
+ try {
+ InetAddress localhost = InetAddress.getLocalHost();
+ setServerIpAddress(localhost.getHostAddress());
+ setServer(localhost.getCanonicalHostName());
+ } catch (Exception e) {
+ KARAF.error("Could not get localhost", e);
+ }
+
+ }
+
+
+ public String getBeginTimestamp() {
+ return MDC.get(BEGIN_TIMESTAMP);
+ }
+
+ private void setBeginTimestamp(long beginTimestamp) {
+ this.beginTimestamp = beginTimestamp;
+ MDC.put(BEGIN_TIMESTAMP, MetricLogger.asIso8601(beginTimestamp));
+ }
+
+ public String getEndTimestamp() {
+ return MDC.get(END_TIMESTAMP);
+ }
+
+ private void setEndTimestamp(long endTimestamp) {
+ // Set MDC with formatted time stamp
+ MDC.put(END_TIMESTAMP, MetricLogger.asIso8601(endTimestamp));
+
+ // Set elapsed time
+ setElapsedTime(endTimestamp - beginTimestamp);
+
+ }
+
+ public String getRequestID() {
+ return MDC.get(REQUEST_ID);
+ }
+
+
+ public String getServiceInstanceID() {
+ return MDC.get(SERVICE_INSTANCE_ID);
+ }
+
+ private void setServiceInstanceID(String svcInstanceId) {
+ MDC.put(SERVICE_INSTANCE_ID, svcInstanceId);
+ }
+
+ public String getServiceName() {
+ return MDC.get(SERVICE_NAME);
+ }
+
+ private void setServiceName(String svcName) {
+ MDC.put(SERVICE_NAME, svcName);
+ }
+
+ public String getPartnerName() {
+ return MDC.get(PARTNER_NAME);
+ }
+
+ private void setPartnerName(String partnerName) {
+ MDC.put(PARTNER_NAME, partnerName);
+ }
+
+ public String getTargetEntity() {
+ return MDC.get(TARGET_ENTITY);
+ }
+
+ private void setTargetEntity(String targetEntity) {
+ MDC.put(TARGET_ENTITY, targetEntity);
+ }
+
+ public String getTargetServiceName() {
+ return MDC.get(TARGET_SERVICE_NAME);
+ }
+
+ private void setTargetServiceName(String targetServiceName) {
+ MDC.put(TARGET_SERVICE_NAME, targetServiceName);
+ }
+
+ public String getStatusCode() {
+ return MDC.get(STATUS_CODE);
+ }
+
+ private void setStatusCode(String statusCode) {
+ MDC.put(STATUS_CODE, statusCode);
+ }
+
+ public String getResponseCode() {
+ return MDC.get(RESPONSE_CODE);
+ }
+
+ private void setResponseCode(String responseCode) {
+ MDC.put(RESPONSE_CODE, responseCode);
+ }
+
+ public String getResponseDescription() {
+ return MDC.get(RESPONSE_DESCRIPTION);
+ }
+
+ private void setResponseDescription(String responseDesc) {
+ MDC.put(RESPONSE_DESCRIPTION, responseDesc);
+ }
+
+ public String getInstanceUUID() {
+ return MDC.get(INSTANCE_UUID);
+ }
+
+ private void setInstanceUUID(String instanceUUID) {
+ MDC.put(INSTANCE_UUID, instanceUUID);
+ }
+
+ public String getCategoryLogLevel() {
+ return MDC.get(CATEGORY_LOG_LEVEL);
+ }
+
+ private void setCategoryLogLevel(String categoryLogLevel) {
+ MDC.put(CATEGORY_LOG_LEVEL, categoryLogLevel);
+ }
+
+ public String getSeverity() {
+ return MDC.get(SEVERITY);
+ }
+
+ private void setSeverity(String severity) {
+ MDC.put(SEVERITY, severity);
+ }
+
+ public String getServerIpAddress() {
+ return MDC.get(SERVER_IP_ADDRESS);
+ }
+
+ private void setServerIpAddress(String serverIpAddress) {
+ MDC.put(SERVER_IP_ADDRESS, serverIpAddress);
+ }
+
+ public String getElapsedTime() {
+ return MDC.get(ELAPSED_TIME);
+ }
+
+ private void setElapsedTime(long elapsedTime) {
+ MDC.put(ELAPSED_TIME, ""+elapsedTime);
+ }
+
+ public String getServer() {
+ return MDC.get(SERVER);
+ }
+
+ private void setServer(String server) {
+ MDC.put(SERVER, server);
+ }
+
+ public String getClientIp() {
+ return MDC.get(CLIENT_IP);
+ }
+
+ private void setClientIp(String clientIp) {
+ MDC.put(CLIENT_IP, clientIp);
+ }
+
+ public String getClassName() {
+ return MDC.get(CLASS_NAME);
+ }
+
+ private void setClassName(String className) {
+ MDC.put(CLASS_NAME, className);
+ }
+
+ public String getTargetVirtualEntity() {
+ return MDC.get(TARGET_VIRTUAL_ENTITY);
+ }
+
+ private void setTargetVirtualEntity(String targetVirtualEntity) {
+ MDC.put(TARGET_VIRTUAL_ENTITY, targetVirtualEntity);
+ }
+
+ 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);
+ }
+
+ public static String asIso8601(long tsInMillis) {
+ return MetricLogger.asIso8601(new Date(tsInMillis));
+ }
+
+ public void logRequest(String svcInstanceId, String svcName, String partnerName, String targetEntity, String targetServiceName, String targetVirtualEntity, String msg) {
+
+ setBeginTimestamp(System.currentTimeMillis());
+
+ if (svcInstanceId != null) {
+ setServiceInstanceID(svcInstanceId);
+ }
+
+ if (svcName != null) {
+ setServiceName(svcName);
+ }
+
+ if (partnerName != null) {
+ setPartnerName(partnerName);
+ }
+
+ if (targetEntity != null) {
+ setTargetEntity(targetEntity);
+ }
+
+ if (targetServiceName != null) {
+ setTargetServiceName(targetServiceName);
+ }
+
+ if (targetVirtualEntity != null) {
+ setTargetVirtualEntity(targetVirtualEntity);
+ }
+
+ this.lastMsg = msg;
+
+
+ }
+
+ public void logResponse(String statusCode, String responseCode, String responseDescription) {
+ setEndTimestamp(System.currentTimeMillis());
+
+ setStatusCode(statusCode);
+ setResponseCode(responseCode);
+ setResponseDescription(responseDescription);
+
+ METRIC.info(lastMsg);
+
+ }
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAdaptor.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAdaptor.java
new file mode 100644
index 00000000..b4d62ab4
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAdaptor.java
@@ -0,0 +1,42 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAtom.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAtom.java
new file mode 100644
index 00000000..9ac64893
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAtom.java
@@ -0,0 +1,174 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicBinaryExpression.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicBinaryExpression.java
new file mode 100644
index 00000000..1d780d7e
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicBinaryExpression.java
@@ -0,0 +1,149 @@
+/*-
+ * ============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.openecomp.sdnc.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<OperatorType>();
+ }
+
+ 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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicContext.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicContext.java
new file mode 100644
index 00000000..79082af2
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicContext.java
@@ -0,0 +1,248 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+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 HashMap<String, String> attributes;
+
+ private DOMDataBroker domDataBroker;
+
+ private String status = "success";
+
+ public SvcLogicContext()
+ {
+ this.attributes = new HashMap<String,String> ();
+
+ }
+
+ public SvcLogicContext(Properties props)
+ {
+ this.attributes = new HashMap<String, String> ();
+
+ if (props.containsKey("SvcLogic.status"))
+ {
+ this.status = props.getProperty("SvcLogic.status");
+ }
+
+ for (Object nameObj : props.keySet())
+ {
+ String propName = (String) nameObj;
+ attributes.put(propName, props.getProperty(propName));
+ }
+ }
+
+
+
+ public DOMDataBroker getDomDataBroker() {
+ return domDataBroker;
+ }
+
+ public void setDomDataBroker(DOMDataBroker domDataBroker) {
+ this.domDataBroker = domDataBroker;
+ }
+
+ 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 String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public Properties toProperties()
+ {
+ Properties props = new Properties();
+
+ if (status != null)
+ {
+ props.setProperty("SvcLogic.status", status);
+ }
+
+ for (String attrName : attributes.keySet())
+ {
+ String attrVal = attributes.get(attrName);
+ if (attrVal == null) {
+ LOG.warn("attribute " + attrName
+ + "null - setting to empty string");
+ props.setProperty(attrName, "");
+ } else {
+ props.setProperty(attrName, attributes.get(attrName));
+ }
+ }
+
+ 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).intValue();
+ }
+
+ nodeMap.put(curTagName, new Integer(myIdx+1));
+ this.setAttribute(prefix+"_length", ""+(myIdx+1));
+ }
+
+ NodeList children = element.getChildNodes();
+
+ int numChildren = children.getLength();
+
+ Map<String, Integer> childMap = new HashMap<String, Integer>();
+ Map<String, Integer> idxChildMap = new HashMap<String, Integer>();
+
+ 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 String resolve(String ctxVarName) {
+
+ if (ctxVarName.indexOf('[') == -1) {
+ // Ctx variable contains no arrays
+ return (this.getAttribute(ctxVarName));
+ }
+
+ // Resolve any array references
+ StringBuffer sbuff = new StringBuffer();
+ 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 " + ctxVarName
+ + " seems to be missing a ']'");
+ return (this.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 (this.getAttribute(sbuff.toString()));
+ }
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicDblibStore.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicDblibStore.java
new file mode 100644
index 00000000..d494eaab
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicDblibStore.java
@@ -0,0 +1,533 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+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.openecomp.sdnc.sli.resource.dblib.DBResourceManager;
+import org.openecomp.sdnc.sli.resource.dblib.DbLibService;
+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 SvcLogicDblibStore implements SvcLogicStore {
+
+ private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicDblibStore.class);
+
+ private static final String DBLIB_SERVICE =
+ // "org.openecomp.sdnc.sli.resource.dblib.DBLibService";
+ "org.openecomp.sdnc.sli.resource.dblib.DBResourceManager";
+
+ Properties props = null;
+
+ public void init(Properties props) throws ConfigurationException {
+
+ DbLibService dbSvc = getDbLibService();
+ 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);
+ }
+ }
+
+ public boolean hasGraph(String module, String rpc, String version,
+ String mode) throws SvcLogicException {
+
+ DbLibService dbSvc = getDbLibService();
+
+ 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'";
+
+ PreparedStatement hasGraphStmt = null;
+
+ ArrayList<String> args = new ArrayList<String>();
+ 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) {
+ }
+ }
+
+ }
+
+ return (retval);
+
+ }
+
+ public SvcLogicGraph fetch(String module, String rpc, String version,
+ String mode) throws SvcLogicException {
+
+ DbLibService dbSvc = getDbLibService();
+
+ 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 = ((DBResourceManager) dbSvc).getConnection();
+ PreparedStatement fetchGraphStmt;
+
+ ArrayList<String> args = new ArrayList<String>();
+ args.add(module);
+ args.add(rpc);
+ args.add(mode);
+
+ 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 (SQLException e) {
+ throw new ConfigurationException("SQL query failed", e);
+ } catch (Exception e) {
+ throw new ConfigurationException("Graph processing failed", e);
+ } finally {
+ if (results != null) {
+ try {
+ results.close();
+ } catch (SQLException x) {
+ }
+ }
+ try {
+ if (dbConn != null && !dbConn.isClosed()) {
+ dbConn.close();
+ }
+ } catch (Throwable exc) {
+ // the exception not monitored
+ } finally {
+ dbConn = null;
+ }
+
+ }
+
+ return (retval);
+
+ }
+
+ public void store(SvcLogicGraph graph) throws SvcLogicException {
+
+ DbLibService dbSvc = getDbLibService();
+
+ String storeGraphSql = "INSERT INTO SVC_LOGIC (module, rpc, version, mode, active, graph)"
+ + " VALUES(?, ?, ?, ?, ?, ?)";
+
+ if (graph == null) {
+ throw new SvcLogicException("graph cannot be null");
+ }
+
+ byte[] graphBytes = null;
+
+ ByteArrayOutputStream byteStr = null;
+ ObjectOutputStream goutStr = null;
+
+ try {
+ byteStr = new ByteArrayOutputStream();
+ goutStr = new ObjectOutputStream(byteStr);
+ goutStr.writeObject(graph);
+
+ graphBytes = byteStr.toByteArray();
+
+ } catch (Exception e) {
+ throw new SvcLogicException("could not serialize graph", e);
+ } finally {
+
+ if (goutStr != null) {
+ try {
+ goutStr.close();
+ } catch (IOException e) {
+
+ }
+ }
+
+ if (byteStr != null) {
+ try {
+ byteStr.close();
+ } catch (IOException 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;
+
+ try {
+ dbConn = ((DBResourceManager) dbSvc).getConnection();
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ PreparedStatement 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.executeUpdate();
+ dbConn.commit();
+
+ dbConn.setAutoCommit(oldAutoCommit);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not write object to database", e);
+ } finally {
+ try {
+ if (dbConn != null && !dbConn.isClosed()) {
+ dbConn.close();
+ }
+ } catch (Throwable exc) {
+ // the exception not monitored
+ } finally {
+ dbConn = null;
+ }
+
+ }
+ }
+
+ public void delete(String module, String rpc, String version, String mode)
+ throws SvcLogicException {
+
+ DbLibService dbSvc = getDbLibService();
+
+ String deleteGraphSql = "DELETE FROM SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?";
+
+ ArrayList<String> args = new ArrayList<String>();
+
+ 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 {
+ DbLibService dbSvc = getDbLibService();
+
+ 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<String>();
+
+ 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 registerNodeType(String nodeType) throws SvcLogicException {
+
+ String registerNodeSql = "INSERT INTO NODE_TYPES (nodetype) VALUES(?)";
+
+ if (isValidNodeType(nodeType)) {
+ return;
+ }
+
+ DbLibService dbSvc = getDbLibService();
+ ArrayList<String> args = new ArrayList<String>();
+
+ args.add(nodeType);
+
+ try {
+ dbSvc.writeData(registerNodeSql, args, null);
+ } catch (Exception e) {
+ throw new SvcLogicException("Could not add node type to database",
+ e);
+ }
+
+ }
+
+ @Override
+ public void unregisterNodeType(String nodeType) throws SvcLogicException {
+
+ if (!isValidNodeType(nodeType)) {
+ return;
+ }
+
+ String unregisterNodeSql = "DELETE FROM NODE_TYPES WHERE nodetype = ?";
+
+ DbLibService dbSvc = getDbLibService();
+ ArrayList<String> args = new ArrayList<String>();
+
+ args.add(nodeType);
+
+ try {
+ dbSvc.writeData(unregisterNodeSql, args, null);
+ } catch (Exception e) {
+ throw new SvcLogicException(
+ "Could not delete node type from database", e);
+ }
+
+ }
+
+ @Override
+ public boolean isValidNodeType(String nodeType) throws SvcLogicException {
+
+ String validateNodeSql = "SELECT count(*) FROM NODE_TYPES WHERE nodetype = ?";
+
+ DbLibService dbSvc = getDbLibService();
+
+ ArrayList<String> args = new ArrayList<String>();
+
+ args.add(nodeType);
+
+ boolean isValid = false;
+
+ CachedRowSet results = null;
+ try {
+ results = dbSvc.getData(validateNodeSql, args, null);
+ if (results != null) {
+ if (results.next()) {
+ int cnt = results.getInt(1);
+
+ if (cnt > 0) {
+ isValid = true;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new SvcLogicException(
+ "Cannot select node type from database", e);
+ } finally {
+ if (results != null) {
+ try {
+ results.close();
+ } catch (SQLException x) {
+ }
+ }
+
+ }
+
+ return (isValid);
+ }
+
+ private DbLibService getDbLibService() {
+
+ // Get DbLibService interface object.
+ DbLibService dblibSvc = null;
+ ServiceReference sref = null;
+ BundleContext bctx = null;
+
+ Bundle bundle = FrameworkUtil.getBundle(SvcLogicDblibStore.class);
+
+ if (bundle != null) {
+ bctx = bundle.getBundleContext();
+
+ if (bctx != null) {
+ sref = bctx.getServiceReference(DBLIB_SERVICE);
+ }
+
+ if (sref == null) {
+ LOG.warn("Could not find service reference for DBLIB service ("
+ + DBLIB_SERVICE + ")");
+ } else {
+ dblibSvc = (DbLibService) bctx.getService(sref);
+ if (dblibSvc == null) {
+
+ LOG.warn("Could not find service reference for DBLIB service ("
+ + DBLIB_SERVICE + ")");
+ }
+ }
+ }
+
+ // initialize a stand-alone instance of dblib resource
+ else {
+ // Try to create a DbLibService object from dblib properties
+ if(JavaSingleton.getInstance() == null){
+ Properties dblibProps = new Properties();
+
+ String propDir = System.getenv(SDNC_CONFIG_DIR);
+ if (propDir == null) {
+
+ propDir = "/opt/sdnc/data/properties";
+ }
+ String propPath = propDir + "/dblib.properties";
+
+ File propFile = new File(propPath);
+
+ if (!propFile.exists()) {
+
+ LOG.warn(
+ "Missing configuration properties file : "
+ + propFile);
+ return(null);
+ }
+
+ try {
+
+ dblibProps.load(new FileInputStream(propFile));
+ } catch (Exception e) {
+ LOG.warn(
+ "Could not load properties file " + propPath, e);
+ return(null);
+
+ }
+
+ try {
+ dblibSvc = DBResourceManager.create(dblibProps);
+ JavaSingleton.setInstance(dblibSvc);
+ } catch (Exception e) {
+ LOG.warn("Caught exception trying to create DBResourceManager", e);
+ }
+ } else {
+ dblibSvc = JavaSingleton.getInstance();
+ }
+ }
+ return (dblibSvc);
+ }
+
+
+ static class JavaSingleton {
+ /* Private constructor */
+ private JavaSingleton() {
+ /* the body of the constructor here */
+ }
+
+ /* instance of the singleton declaration */
+ private static volatile DbLibService INSTANCE ;
+
+ /* Access point to the unique instance of the singleton */
+ public static DbLibService getInstance() {
+ return INSTANCE;
+ }
+
+ public static void setInstance(DbLibService dbresource) {
+ INSTANCE = dbresource;
+ }
+ }
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicException.java
new file mode 100644
index 00000000..c087b8ad
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicException.java
@@ -0,0 +1,46 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java
new file mode 100644
index 00000000..4fef12fb
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java
@@ -0,0 +1,316 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.openecomp.sdnc.sli.ExprGrammarParser.AddExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.AtomContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.CompareExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.ConstantContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.ExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.FuncExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.MultExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.ParenExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.RelExprContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.VariableContext;
+import org.openecomp.sdnc.sli.ExprGrammarParser.VariableLeadContext;
+import org.openecomp.sdnc.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<SvcLogicExpression>();
+ }
+
+ public SvcLogicExpression getParsedExpr()
+ {
+ return(curExpr);
+ }
+
+ private void pushOperand(SvcLogicExpression operand)
+ {
+ if (curExpr == null)
+ {
+ curExpr = operand;
+ }
+ else
+ {
+ curExpr.addOperand(operand);
+ }
+ }
+
+ private void pushExpr(SvcLogicExpression expr)
+ {
+ LOG.trace("Pushing expression ["+expr.getClass().getName()+"]");
+ if (curExpr != null)
+ {
+ exprStack.push(curExpr);
+ }
+ curExpr = expr;
+ }
+
+ private void popExpr()
+ {
+ if (exprStack.isEmpty())
+ {
+ LOG.trace("Popping last expression");
+ topExpr = curExpr;
+ }
+ else
+ {
+ SvcLogicExpression lastExpr = curExpr;
+ curExpr = exprStack.pop();
+ curExpr.addOperand(lastExpr);
+ LOG.trace("New curExpr is ["+curExpr.getClass().getName()+"]");
+ }
+
+ }
+
+ @Override
+ public void enterAtom(AtomContext ctx) {
+
+ String atomText = ctx.getText();
+
+ LOG.trace("enterAtom: text = "+atomText);
+
+
+ SvcLogicAtom newAtom = new SvcLogicAtom(atomText);
+
+ pushExpr(newAtom);
+ }
+
+
+ @Override
+ public void enterMultExpr(MultExprContext ctx) {
+ LOG.trace("enterMultExpr: text = "+ctx.getText());
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+ List<TerminalNode> opList = ctx.MULTOP();
+
+ for (TerminalNode nd : opList)
+ {
+ LOG.trace("enterMultExpr: operator - "+nd.getText());
+ curBinExpr.addOperator(nd.getText());
+ }
+
+ }
+
+ @Override
+ public void exitMultExpr(MultExprContext ctx) {
+
+ LOG.trace("exitMultExpr: text = "+ctx.getText());
+
+ popExpr();
+
+ }
+
+ @Override
+ public void exitAtom(AtomContext ctx) {
+ LOG.trace("exitAtom: text = "+ctx.getText());
+ popExpr();
+ }
+
+ @Override
+ public void enterAddExpr(AddExprContext ctx) {
+ LOG.trace("enterAddExpr: text = "+ctx.getText());
+ List<TerminalNode> opList = ctx.ADDOP();
+
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+
+ for (TerminalNode nd : opList)
+ {
+ LOG.trace("enterAddExpr: operator - "+nd.getText());
+ curBinExpr.addOperator(nd.getText());
+ }
+
+ }
+
+ @Override
+ public void exitAddExpr(AddExprContext ctx) {
+ LOG.trace("exitAddExpr: text = "+ctx.getText());
+
+ 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) {
+ LOG.trace("exitFuncExpr: text = "+ctx.getText());
+
+ 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) {
+ LOG.trace("enterRelExpr: text = "+ctx.getText());
+
+ List<TerminalNode> opList = ctx.RELOP();
+
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+
+ for (TerminalNode nd : opList)
+ {
+ LOG.trace("enterRelExpr: operator - "+nd.getText());
+ curBinExpr.addOperator(nd.getText());
+ }
+
+ }
+
+ @Override
+ public void exitRelExpr(RelExprContext ctx) {
+ LOG.trace("exitRelExpr: text = "+ctx.getText());
+
+ popExpr();
+ }
+
+ @Override
+ public void enterCompareExpr(CompareExprContext ctx) {
+ LOG.trace("enterCompareExpr: text = "+ctx.getText());
+
+ TerminalNode nd = ctx.COMPAREOP();
+
+ SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+ pushExpr(curBinExpr);
+
+ LOG.trace("enterCompareExpr: operator - "+nd.getText());
+ curBinExpr.addOperator(nd.getText());
+
+ }
+
+ @Override
+ public void exitCompareExpr(CompareExprContext ctx) {
+ LOG.trace("exitCompareExpr : text = "+ctx.getText());
+
+ popExpr();
+ }
+
+
+
+ @Override
+ public void enterConstant(ConstantContext ctx) {
+ LOG.trace("enterConstant: text = "+ctx.getText());
+ }
+
+ @Override
+ public void exitConstant(ConstantContext ctx) {
+ LOG.trace("exitConstant: text = "+ctx.getText());
+ }
+
+
+ @Override
+ public void enterVariable(VariableContext ctx) {
+ LOG.trace("enterVariable: text = "+ctx.getText());
+
+
+ }
+
+ @Override
+ public void exitVariable(VariableContext ctx) {
+ LOG.debug("exitVariable: text ="+ctx.getText());
+
+ }
+
+
+ @Override
+ public void enterVariableLead(VariableLeadContext ctx) {
+
+ LOG.debug("enterVariableLead: text ="+ctx.getText());
+
+
+ }
+
+ @Override
+ public void exitVariableLead(VariableLeadContext ctx) {
+
+ LOG.trace("exitVariableLead: text ="+ctx.getText());
+ }
+
+ @Override
+ public void enterVariableTerm(VariableTermContext ctx) {
+ LOG.trace("enterVariableTerm: text ="+ctx.getText());
+
+ 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) {
+ LOG.trace("exitVariableTerm: text="+ctx.getText());
+ popExpr();
+ }
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprParserErrorListener.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprParserErrorListener.java
new file mode 100644
index 00000000..4c7dd22b
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprParserErrorListener.java
@@ -0,0 +1,44 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpression.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpression.java
new file mode 100644
index 00000000..a6af8201
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpression.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.openecomp.sdnc.sli;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+
+public abstract class SvcLogicExpression implements Serializable {
+
+ private List<SvcLogicExpression> operands = new LinkedList<SvcLogicExpression>();
+
+
+ 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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java
new file mode 100644
index 00000000..cce8e044
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java
@@ -0,0 +1,99 @@
+/*-
+ * ============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.openecomp.sdnc.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.openecomp.sdnc.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
+ {
+ LOG.trace("parse("+exprStr+")");
+ 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());
+ }
+
+ public static void main(String argv[]) {
+
+
+ System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "debug");
+
+ StringBuffer sbuff = new StringBuffer();
+
+ for (int i = 0 ; i < argv.length ; i++)
+ {
+ if (sbuff.length() > 0)
+ {
+ sbuff.append(" ");
+ }
+ sbuff.append(argv[i]);
+ }
+
+ try {
+ SvcLogicExpressionFactory.parse(sbuff.toString());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicFunctionCall.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicFunctionCall.java
new file mode 100644
index 00000000..a98cf6b2
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicFunctionCall.java
@@ -0,0 +1,80 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicGraph.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicGraph.java
new file mode 100644
index 00000000..d3d6d950
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicGraph.java
@@ -0,0 +1,184 @@
+/*-
+ * ============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.openecomp.sdnc.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 Map<String, Serializable> attributes;
+ private Map<String, SvcLogicNode> namedNodes;
+ private SvcLogicNode rootNode;
+
+ public SvcLogicGraph()
+ {
+ attributes = new HashMap<String, Serializable>();
+ namedNodes = new HashMap<String, SvcLogicNode>();
+ rootNode = null;
+ }
+
+
+ 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 + "]";
+ }
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJavaPlugin.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJavaPlugin.java
new file mode 100644
index 00000000..ac14cacc
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJavaPlugin.java
@@ -0,0 +1,34 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.util.Map;
+
+public interface SvcLogicJavaPlugin {
+
+ /**
+ * 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)
+ */
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJdbcStore.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJdbcStore.java
new file mode 100644
index 00000000..b9e7f80e
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJdbcStore.java
@@ -0,0 +1,895 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+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 PreparedStatement registerNodeStmt = null;
+ private PreparedStatement unregisterNodeStmt = null;
+ private PreparedStatement validateNodeStmt = null;
+
+ private void getConnection() throws ConfigurationException
+ {
+
+ Properties jdbcProps = new Properties();
+
+ jdbcProps.setProperty("user", dbUser);
+ jdbcProps.setProperty("password", dbPasswd);
+
+ try {
+ Driver dvr = new com.mysql.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 = null;
+
+
+ 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.
+ try
+ {
+
+
+ ResultSet tables = dbm.getTables(null, null, "SVC_LOGIC", null);
+ if (tables.next()) {
+ // Table 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,"
+ + "CONSTRAINT P_SVC_LOGIC PRIMARY KEY(module, rpc, version, mode))";
+
+ Statement stmt = null;
+ ConfigurationException myExc = null;
+ try
+ {
+ stmt = dbConn.createStatement();
+ stmt.executeUpdate(crTableCmd);
+ }
+ catch (SQLException e1)
+ {
+ myExc = new ConfigurationException("cannot create SVC_LOGIC table", e1);
+ }
+ finally
+ {
+ if (stmt != null)
+ {
+ stmt.close();
+ }
+ }
+
+ if (myExc != null)
+ {
+ throw myExc;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not create SVC_LOGIC table", e);
+ }
+
+ // See if NODE_TYPES table exists and, if not, create it
+
+ try
+ {
+
+
+ ResultSet tables = dbm.getTables(null, null, "NODE_TYPES", null);
+ if (tables.next()) {
+ // Table exists
+ }
+ else {
+
+ String crTableCmd = "CREATE TABLE "+dbName+".NODE_TYPES ("
+ + "nodetype varchar(80) NOT NULL,"
+ + "CONSTRAINT P_NODE_TYPES PRIMARY KEY(nodetype))";
+
+ Statement stmt = null;
+ ConfigurationException myExc = null;
+ try
+ {
+ stmt = dbConn.createStatement();
+ stmt.executeUpdate(crTableCmd);
+ }
+ catch (SQLException e1)
+ {
+ myExc = new ConfigurationException("cannot create SVC_LOGIC table", e1);
+ }
+ finally
+ {
+ if (stmt != null)
+ {
+ stmt.close();
+ }
+ }
+
+ if (myExc != null)
+ {
+ throw myExc;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not create SVC_LOGIC table", e);
+ }
+ }
+
+ private void prepStatements() throws ConfigurationException
+ {
+
+ // Prepare statements
+ String hasVersionGraphSql = "SELECT count(*) FROM "+dbName+".SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+
+ try
+ {
+ hasVersionGraphStmt = dbConn.prepareStatement(hasVersionGraphSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+hasVersionGraphSql, e);
+
+ }
+
+ String hasActiveGraphSql = "SELECT count(*) FROM "+dbName+".SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
+
+ try
+ {
+ hasActiveGraphStmt = dbConn.prepareStatement(hasActiveGraphSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+hasVersionGraphSql, e);
+
+ }
+
+ String fetchVersionGraphSql = "SELECT graph FROM "+dbName+".SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
+
+ try
+ {
+ fetchVersionGraphStmt = dbConn.prepareStatement(fetchVersionGraphSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+fetchVersionGraphSql, e);
+
+ }
+
+ String fetchActiveGraphSql = "SELECT graph FROM "+dbName+".SVC_LOGIC"
+ + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
+
+ try
+ {
+ fetchActiveGraphStmt = dbConn.prepareStatement(fetchActiveGraphSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+fetchVersionGraphSql, e);
+
+ }
+
+ String storeGraphSql = "INSERT INTO "+dbName+".SVC_LOGIC (module, rpc, version, mode, active, graph)"
+ + " VALUES(?, ?, ?, ?, ?, ?)";
+
+ try
+ {
+ storeGraphStmt = dbConn.prepareStatement(storeGraphSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+storeGraphSql, e);
+ }
+
+ String deleteGraphSql = "DELETE FROM "+dbName+".SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?";
+
+ try
+ {
+ deleteGraphStmt = dbConn.prepareStatement(deleteGraphSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+deleteGraphSql, e);
+ }
+
+ String deactivateSql = "UPDATE "+dbName+".SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?";
+
+ try
+ {
+ deactivateStmt = dbConn.prepareStatement(deactivateSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+deactivateSql, e);
+ }
+
+ String activateSql = "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("could not prepare statement "+activateSql, e);
+ }
+
+ String registerNodeSql = "INSERT INTO "+dbName+".NODE_TYPES (nodetype) VALUES(?)";
+ try
+ {
+ registerNodeStmt = dbConn.prepareStatement(registerNodeSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+registerNodeSql, e);
+ }
+
+ String unregisterNodeSql = "DELETE FROM "+dbName+".NODE_TYPES WHERE nodetype = ?";
+ try
+ {
+ unregisterNodeStmt = dbConn.prepareStatement(unregisterNodeSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+unregisterNodeSql, e);
+ }
+
+ String validateNodeSql = "SELECT count(*) FROM "+dbName+".NODE_TYPES WHERE nodetype = ?";
+ try
+ {
+ validateNodeStmt = dbConn.prepareStatement(validateNodeSql);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("could not prepare statement "+validateNodeSql, 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();
+ }
+
+
+ public void init(Properties props) throws ConfigurationException {
+
+
+ dbUrl = props.getProperty("org.openecomp.sdnc.sli.jdbc.url");
+ if ((dbUrl == null) || (dbUrl.length() == 0))
+ {
+ throw new ConfigurationException("property org.openecomp.sdnc.sli.jdbc.url unset");
+ }
+
+ dbName = props.getProperty("org.openecomp.sdnc.sli.jdbc.database");
+ if ((dbName == null) || (dbName.length() == 0))
+ {
+ throw new ConfigurationException("property org.openecomp.sdnc.sli.jdbc.database unset");
+ }
+
+ dbUser = props.getProperty("org.openecomp.sdnc.sli.jdbc.user");
+ if ((dbUser == null) || (dbUser.length() == 0))
+ {
+ throw new ConfigurationException("property org.openecomp.sdnc.sli.jdbc.user unset");
+ }
+
+
+ dbPasswd = props.getProperty("org.openecomp.sdnc.sli.jdbc.password");
+ if ((dbPasswd == null) || (dbPasswd.length() == 0))
+ {
+ throw new ConfigurationException("property org.openecomp.sdnc.sli.jdbc.password unset");
+ }
+
+ dbDriver = props.getProperty("org.openecomp.sdnc.sli.jdbc.driver");
+
+
+ initDbResources();
+
+ }
+
+ private boolean isDbConnValid()
+ {
+
+ boolean isValid = false;
+
+ try
+ {
+ if (dbConn != null)
+ {
+ isValid = dbConn.isValid(1);
+ }
+ }
+ catch (SQLException e)
+ {}
+
+ return(isValid);
+ }
+public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException {
+
+
+
+
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+
+
+ boolean retval = false;
+ ResultSet results = null;
+
+ PreparedStatement hasGraphStmt = null;
+ 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)
+ {}
+ }
+
+ }
+
+
+ return(retval);
+
+
+ }
+
+ public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException {
+
+
+
+
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+
+
+ SvcLogicGraph retval = null;
+ ResultSet results = null;
+
+ PreparedStatement fetchGraphStmt = null;
+ 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());
+
+ }
+
+ }
+ else
+ {
+ return(null);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("SQL query failed", e);
+ }
+ finally
+ {
+ if (results != null)
+ {
+ try
+ {
+ results.close();
+ }
+ catch (SQLException x)
+ {}
+ }
+
+ }
+
+
+ return(retval);
+
+
+ }
+
+ public void store(SvcLogicGraph graph) throws SvcLogicException {
+
+
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+ if (graph == null)
+ {
+ throw new SvcLogicException("graph cannot be null");
+ }
+
+ byte[] graphBytes = null;
+
+ ByteArrayOutputStream byteStr = null;
+ ObjectOutputStream goutStr = null;
+
+ try
+ {
+ byteStr = new ByteArrayOutputStream();
+ goutStr = new ObjectOutputStream(byteStr);
+ goutStr.writeObject(graph);
+
+ graphBytes = byteStr.toByteArray();
+
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("could not serialize graph", e);
+ }
+ finally
+ {
+
+ if (goutStr != null)
+ {
+ try {
+ goutStr.close();
+ } catch (IOException e) {
+
+ }
+ }
+
+ if (byteStr != null)
+ {
+ try {
+ byteStr.close();
+ } catch (IOException 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.executeUpdate();
+ dbConn.commit();
+
+ dbConn.setAutoCommit(oldAutoCommit);
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Could not write object to database", e);
+ }
+ }
+
+ public void delete(String module, String rpc, String version, String mode) throws SvcLogicException
+ {
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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 registerNodeType(String nodeType) throws SvcLogicException {
+
+ if (isValidNodeType(nodeType))
+ {
+ return;
+ }
+
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+ try
+ {
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ registerNodeStmt.setString(1, nodeType);
+ registerNodeStmt.executeUpdate();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Could not add node type to database", e);
+ }
+
+ }
+
+ @Override
+ public void unregisterNodeType(String nodeType) throws SvcLogicException {
+
+ if (!isValidNodeType(nodeType))
+ {
+ return;
+ }
+
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+ try
+ {
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ unregisterNodeStmt.setString(1, nodeType);
+ unregisterNodeStmt.executeUpdate();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Could not delete node type from database", e);
+ }
+
+ }
+
+ @Override
+ public boolean isValidNodeType(String nodeType) throws SvcLogicException {
+
+ boolean isValid = false;
+
+ if (!isDbConnValid())
+ {
+
+ // Try reinitializing
+ initDbResources();
+
+ if (!isDbConnValid())
+ {
+ throw new ConfigurationException("no jdbc connection");
+ }
+ }
+
+ ResultSet results = null;
+ try
+ {
+ validateNodeStmt.setString(1, nodeType);
+
+ boolean oldAutoCommit = dbConn.getAutoCommit();
+ dbConn.setAutoCommit(false);
+ results = validateNodeStmt.executeQuery();
+ dbConn.commit();
+ dbConn.setAutoCommit(oldAutoCommit);
+
+ if (results != null)
+ {
+ if (results.next())
+ {
+ int cnt = results.getInt(1);
+
+ if (cnt > 0)
+ {
+ isValid = true;
+ }
+ }
+ }
+
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Cannot select node type from database", e);
+ }
+ finally
+ {
+ if (results != null)
+ {
+ try
+ {
+ results.close();
+ }
+ catch (SQLException x)
+ {}
+ }
+
+ }
+
+ return(isValid);
+ }
+
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicNode.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicNode.java
new file mode 100644
index 00000000..6828e9ad
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicNode.java
@@ -0,0 +1,456 @@
+/*-
+ * ============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.openecomp.sdnc.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.TreeMap;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.Locator;
+
+
+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<String, SvcLogicExpression> ();
+ parameters = new HashMap<String, SvcLogicExpression> ();
+ 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<String, SvcLogicExpression> ();
+ parameters = new HashMap<String, SvcLogicExpression> ();
+ 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<String, SvcLogicNode>();
+ }
+
+ 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 null;
+ }
+
+ return(outcomes.entrySet());
+
+ }
+
+ public Set<Map.Entry<String, SvcLogicExpression>> getParameterSet()
+ {
+ if (parameters == null)
+ {
+ return null;
+ }
+
+ 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<String, SvcLogicNode>(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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParser.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParser.java
new file mode 100644
index 00000000..398c28de
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParser.java
@@ -0,0 +1,598 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.LinkedList;
+
+import javax.xml.XMLConstants;
+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.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * @author dt5972
+ *
+ */
+public class SvcLogicParser {
+
+ SvcLogicStore store = null;
+ 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.openecomp.sdnc.sli.parser.validate";
+ private static final String SVCLOGIC_XSD = "/svclogic.xsd";
+
+ 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;
+ private SvcLogicStore svcLogicStore = null;
+
+ public SvcLogicHandler(LinkedList<SvcLogicGraph> graphs, SvcLogicStore store) {
+ this.graphs = graphs;
+ this.curNode = null;
+ this.nodeStack = new LinkedList<>();
+ this.outcomeStack = new LinkedList<>();
+ this.curNodeId = 1;
+ this.outcomeValue = null;
+ this.svcLogicStore = store;
+
+ }
+
+ @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 = null;
+
+ try {
+ if (!svcLogicStore.isValidNodeType(qName)) {
+ throw new SAXNotRecognizedException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Unknown tag " + qName);
+ }
+ } catch (Exception e) {
+ throw new SAXNotRecognizedException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + "Cannot validate node type " + qName);
+ }
+
+ 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 = null;
+ 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("" + (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 SvcLogicParser(SvcLogicStore store) {
+ this.store = store;
+ }
+
+ public SvcLogicParser(String propFile) {
+
+ try {
+ this.store = SvcLogicStoreFactory.getSvcLogicStore(propFile);
+ } catch (Exception e) {
+ LOGGER.error(SVC_LOGIC_STORE_ERROR, e);
+
+ }
+
+ }
+
+ public SvcLogicParser(InputStream propStr) {
+
+ try {
+ this.store = SvcLogicStoreFactory.getSvcLogicStore(propStr);
+ } catch (Exception e) {
+ LOGGER.error(SVC_LOGIC_STORE_ERROR, e);
+
+ }
+
+ }
+
+ public LinkedList<SvcLogicGraph> parse(String fileName) throws SvcLogicException {
+ LinkedList<SvcLogicGraph> graphs = null;
+
+ URL xsdUrl = null;
+ Schema schema = null;
+ String validateSchema = System.getProperty(SLI_VALIDATING_PARSER, "true");
+
+ if (validateSchema != null || validateSchema.equalsIgnoreCase("true")) {
+ xsdUrl = getClass().getResource(SVCLOGIC_XSD);
+
+ }
+
+ if (xsdUrl != null) {
+ try {
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ schema = schemaFactory.newSchema(xsdUrl);
+ } catch (Exception e) {
+ LOGGER.warn("Could not validate using schema " + xsdUrl.getPath(), e);
+ }
+ } else {
+ LOGGER.warn("Could not find resource " + SVCLOGIC_XSD);
+ }
+
+ try {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+
+ if (schema != null) {
+ factory.setNamespaceAware(true);
+ factory.setSchema(schema);
+ }
+ SAXParser saxParser = factory.newSAXParser();
+
+ if (saxParser.isValidating()) {
+ LOGGER.info("Validating against schema " + xsdUrl.getPath());
+ }
+ graphs = new LinkedList<>();
+
+ saxParser.parse(fileName, new SvcLogicHandler(graphs, store));
+
+ } catch (Exception e) {
+ String msg = e.getMessage();
+ if (msg != null) {
+ LOGGER.error(msg);
+ throw new SvcLogicException("Compiler error: " + fileName + " @ " + msg);
+ } else {
+ LOGGER.info("Caught exception parsing " + fileName, e);
+ 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(e.getMessage(), 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])) {
+
+ switch (argv.length) {
+ case 6:
+ SvcLogicStore store = SvcLogicParser.getStore(argv[5]);
+ SvcLogicParser.getSource(argv[1], argv[2], argv[3], argv[4], store);
+ break;
+ default:
+ 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(e.getMessage(), e);
+ }
+ } else {
+ SvcLogicParser.usage();
+ }
+ }
+
+ System.exit(0);
+ }
+
+ private 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 {
+ File xmlFile = new File(xmlfile);
+ if (!xmlFile.canRead()) {
+ throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");
+ }
+
+ SvcLogicParser parser = new SvcLogicParser(store);
+ 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 (SvcLogicGraph graph : graphs) {
+
+ String module = graph.getModule();
+ String rpc = graph.getRpc();
+ String version = graph.getVersion();
+ String mode = graph.getMode();
+ try {
+ LOGGER.info("Saving SvcLogicGraph to database (module:" + module + ",rpc:" + rpc + ",version:" + version + ",mode:" + mode + ")");
+ store.store(graph);
+ } catch (Exception e) {
+ throw new SvcLogicException(e.getMessage(), e);
+ }
+
+ }
+
+ }
+
+ public static void validate(String xmlfile, SvcLogicStore store) throws SvcLogicException {
+ File xmlFile = new File(xmlfile);
+ if (!xmlFile.canRead()) {
+ throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")");
+ }
+
+ SvcLogicParser parser = new SvcLogicParser(store);
+ LinkedList<SvcLogicGraph> graphs = null;
+ 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);
+ }
+
+ }
+
+ private 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.exit(1);
+ }
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParserException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParserException.java
new file mode 100644
index 00000000..ac9c515e
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParserException.java
@@ -0,0 +1,43 @@
+/*-
+ * ============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.openecomp.sdnc.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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicRecorder.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicRecorder.java
new file mode 100644
index 00000000..8a23adf1
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicRecorder.java
@@ -0,0 +1,30 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.util.Map;
+
+public interface SvcLogicRecorder {
+
+ void record(Map<String, String> parmMap) throws SvcLogicException;
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicResource.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicResource.java
new file mode 100644
index 00000000..5fc00f87
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicResource.java
@@ -0,0 +1,53 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.sql.SQLException;
+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/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStore.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStore.java
new file mode 100644
index 00000000..6959c86a
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStore.java
@@ -0,0 +1,37 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.util.Properties;
+
+public interface SvcLogicStore {
+
+ public void init(Properties props) throws SvcLogicException;
+ public void registerNodeType(String nodeType) throws SvcLogicException;
+ public void unregisterNodeType(String nodeType) throws SvcLogicException;
+ public boolean isValidNodeType(String nodeType) 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;
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStoreFactory.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStoreFactory.java
new file mode 100644
index 00000000..8b6618be
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStoreFactory.java
@@ -0,0 +1,96 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Properties;
+
+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 {
+ 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.openecomp.sdnc.sli.dbtype");
+ if ((storeType == null) || (storeType.length() == 0)) {
+ throw new ConfigurationException(
+ "property org.openecomp.sdnc.sli.dbtype unset");
+
+ }
+
+ SvcLogicStore retval = null;
+ LOG.debug(String.format("Using org.openecomp.sdnc.sli.dbtype=%s", storeType));
+
+ if ("jdbc".equalsIgnoreCase(storeType)) {
+ retval = new SvcLogicJdbcStore();
+
+ } else if ("dblib".equalsIgnoreCase(storeType)) {
+ retval = new SvcLogicDblibStore();
+ } else {
+ throw new ConfigurationException("unsupported dbtype (" + storeType
+ + ")");
+
+ }
+
+
+ retval.init(props);
+ return (retval);
+ }
+
+}
diff --git a/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicVariableTerm.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicVariableTerm.java
new file mode 100644
index 00000000..9ddc3c0b
--- /dev/null
+++ b/sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicVariableTerm.java
@@ -0,0 +1,77 @@
+/*-
+ * ============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.openecomp.sdnc.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);
+ }
+ }
+
+
+ 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/sli/common/src/main/resources/crAseNetwork.sql b/sli/common/src/main/resources/crAseNetwork.sql
new file mode 100644
index 00000000..41231176
--- /dev/null
+++ b/sli/common/src/main/resources/crAseNetwork.sql
@@ -0,0 +1,82 @@
+---
+-- ============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=========================================================
+---
+
+CREATE TABLE sdnctl.ASE (
+ ase_network_id INT NOT NULL,
+ topology VARCHAR(25),
+ CONSTRAINT P_ASE PRIMARY KEY(ase_network_id));
+
+CREATE TABLE sdnctl.ASE_PORT (
+ esm_name VARCHAR(25),
+ resource_emt_clli VARCHAR(25) NOT NULL,
+ resource_emt_ip_addr VARCHAR(25) NOT NULL,
+ port_action VARCHAR(25),
+ profile VARCHAR(25) ,
+ port VARCHAR(15) NOT NULL,
+ state VARCHAR(25),
+ resource_mode VARCHAR(25),
+ speed INT,
+ resource_lldp VARCHAR(1),
+ resource_mtu VARCHAR(5),
+ resource_autoneg VARCHAR(10),
+ resource_twamp VARCHAR(10),
+ resource_description VARCHAR(80),
+ uni_circuit_id VARCHAR(45),
+ CONSTRAINT P_ASE_PORT PRIMARY KEY(resource_emt_clli, port));
+
+CREATE TABLE sdnctl.ASE_EVC (
+ esm_name VARCHAR(25),
+ emt_ip_addr VARCHAR(25) NOT NULL,
+ evc_action VARCHAR(25),
+ service_id VARCHAR(25),
+ serv_type VARCHAR(25),
+ evc_choice VARCHAR(25),
+ uni_port VARCHAR(25) NOT NULL,
+ lag_port VARCHAR(25),
+ mac_onoff VARCHAR(25),
+ ppcos VARCHAR(25),
+ cir VARCHAR(25),
+ cbs VARCHAR(25),
+ ebs VARCHAR(25),
+ sgos VARCHAR(25),
+ pe VARCHAR(25),
+ unit VARCHAR(25),
+ qinq VARCHAR(25),
+ interface VARCHAR(25),
+ evc_description VARCHAR(80),
+ bandwidth VARCHAR(10),
+ svlan VARCHAR(5),
+ cvlan VARCHAR(5),
+ routing_instance VARCHAR(25),
+ rd VARCHAR(25),
+ rt VARCHAR(25),
+ evc_limit VARCHAR(25),
+ label_block_size VARCHAR(25),
+ site VARCHAR(25),
+ int_mac_limit VARCHAR(5),
+ sgos_grade VARCHAR(25),
+ bum_rate VARCHAR(25),
+ uni_circuit_id VARCHAR(45),
+ leg INT,
+ CONSTRAINT P_ASE_EVC PRIMARY KEY(emt_ip_addr, uni_port,leg));
+
+
+
diff --git a/sli/common/src/main/resources/svclogic.xsd b/sli/common/src/main/resources/svclogic.xsd
new file mode 100755
index 00000000..f74bd5dc
--- /dev/null
+++ b/sli/common/src/main/resources/svclogic.xsd
@@ -0,0 +1,334 @@
+<?xml version = "1.0" encoding = "UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.openecomp.org/sdnc/svclogic" xmlns="http://www.openecomp.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:choice>
+ </xsd:group>
+
+ <xsd:element name="service-logic">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="method" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="while">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="node" minOccurs="0" maxOccurs="unbounded" />
+ </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/sli/common/src/main/yang/ase-network.yang b/sli/common/src/main/yang/ase-network.yang
new file mode 100755
index 00000000..ae654ae0
--- /dev/null
+++ b/sli/common/src/main/yang/ase-network.yang
@@ -0,0 +1,179 @@
+module ase {
+ namespace "att:ase";
+ prefix ase;
+ revision "2014-06-03" {
+ description "Example ASE Network Module";
+ }
+
+ container ase {
+ config true;
+ leaf ase-network-id{
+ type uint32;
+ }
+ leaf topology {
+ type string ; // check enum
+ }
+ }
+
+ container ase-port {
+ config true;
+ // is this really a list of cpe ports one for each uni-ckt
+ leaf esm-name {
+ type string;
+ }
+
+ leaf resource-emt-clli {
+ type string;
+ }
+
+ leaf resource-emt-ip-addr{
+ type string;
+ }
+ leaf port-action {
+ type string;
+ }
+ leaf profile {
+ type string;
+ }
+ leaf port {
+ type string;
+ }
+ leaf state {
+ type string;
+ }
+ leaf resource-mode {
+ type string;
+ }
+ leaf speed {
+ type string;
+ }
+ leaf resource-lldp {
+ type string;
+ }
+ leaf resource-mtu {
+ type string;
+ }
+ leaf resource-autoneg{
+ type string;
+ }
+ leaf resource-twamp {
+ type string;
+ }
+ leaf resource-description {
+ type string;
+ }
+ leaf uni-circuit-id {
+ type string;
+ }
+ } // ase-port container
+
+ container ase-evc {
+// Port contains a list of EVC
+// EVCs are either point to point or multipoint (topology)
+// EVCs are connected ? what ID is used to connected them ? (network-id) ?
+ config true;
+ leaf esm-name {
+ type string;
+ }
+ leaf emt-ip-addr {
+ type string;
+ }
+ leaf evc-action {
+ type string;
+ }
+ leaf service-id {
+ type string;
+ }
+
+ leaf serv-type {
+ type string;
+ }
+ leaf evc-choice {
+ type string;
+ }
+ leaf uni-port {
+ type string;
+ }
+ leaf lag-port {
+ type string;
+ }
+ leaf mac-onoff {
+ type string;
+ }
+
+ leaf ppcos {
+ type string;
+ }
+ leaf cir {
+ type string;
+ }
+ leaf cbs {
+ type string;
+ }
+ leaf ebs {
+ type string;
+ }
+ leaf sgos {
+ type string;
+ }
+// ipag Device Data
+ leaf pe {
+ type string;
+ }
+ leaf unit {
+ type string;
+ }
+ leaf qinq {
+ type string;
+ }
+ leaf interface {
+ type string;
+ }
+ leaf evc-description {
+ type string;
+ }
+ leaf bandwidth {
+ type string;
+ }
+ leaf svlan {
+ type string;
+ description "Service VLAN is either outer tag or only tag depending on QinQ";
+ }
+ leaf cvlan {
+ type string;
+ description "Customer VLAN is null if not QinQ";
+ }
+ leaf routing-instance {
+ type string;
+ }
+ leaf rd {
+ type string;
+ }
+ leaf rt {
+ type string;
+ }
+ leaf limit {
+ type string;
+ }
+ leaf label-block-size {
+ type string;
+ }
+ leaf site {
+ type string;
+ }
+ leaf int-mac-limit {
+ type string;
+ }
+ leaf sgos-grade {
+ type string;
+ }
+ leaf bum-rate {
+ type string;
+ }
+ leaf uni-circuit-id {
+ type string;
+ }
+ } // ase-evc container
+
+} // module ase-network
+
diff --git a/sli/common/src/main/yang/ase-type.yang b/sli/common/src/main/yang/ase-type.yang
new file mode 100755
index 00000000..2de186e6
--- /dev/null
+++ b/sli/common/src/main/yang/ase-type.yang
@@ -0,0 +1,561 @@
+module ase-type {
+
+ namespace "att:ase:type";
+ prefix ase-type;
+
+ organization "AT&T ASE";
+
+ revision 2014-06-09 {
+ description
+ "Initial version";
+ }
+
+ /////////////////////////////////////////////////////
+ // ASE Service Model Typedefs & Groupings
+ /////////////////////////////////////////////////////
+
+ typedef query-type {
+ type enumeration {
+ enum getDevicePortDetails{
+ value 0;
+ }
+ enum GetServiceDetailsRequest{
+ value 1;
+ }
+ }
+ }
+
+ typedef uni-action-type {
+ type enumeration {
+ enum PortPreReserveRequest{
+ value 0;
+ }
+ enum PortReleaseRequest{
+ value 1;
+ }
+ enum PortDeProvRequest{
+ value 2;
+ }
+ enum ChangePortProvRequest{
+ value 3;
+ }
+ enum PortActivateRequest{
+ value 4;
+ }
+ enum ChangePortActivateRequest{
+ value 5;
+ }
+ enum DisconnectPortRequest{
+ value 6;
+ }
+ enum getDevicePortDetails{
+ value 7;
+ }
+ }
+ }
+
+ typedef evc-action-type {
+ type enumeration {
+ enum ConnectionProvRequest{
+ value 0;
+ }
+ enum ChangeConnectionProvRequest{
+ value 1;
+ }
+ enum ConnectionDeProvrequest{
+ value 2;
+ }
+ enum ConnectionActivateRequest{
+ value 3;
+ }
+ enum ChangeConnectionActivateRequest{
+ value 4;
+ }
+ enum DisconnectConnectionRequest{
+ value 5;
+ }
+ enum GetServiceDetailsRequest{
+ value 6;
+ }
+ }
+ }
+
+ typedef evc-gos-type {
+ type enumeration {
+ enum "REAL-TIME"{
+ value 0;
+ }
+ enum "INTERACTIVE"{
+ value 1;
+ }
+ enum "BUSINESS-CRITICAL-HIGH"{
+ value 2;
+ }
+ enum "BUSINESS-CRITICAL-MEDIUM"{
+ value 3;
+ }
+ enum "NON-CRITICAL-HIGH"{
+ value 4;
+ }
+ enum "NON-CRITICAL-LOW"{
+ value 5;
+ }
+ }
+ }
+
+ typedef cir-rate-type {
+ type enumeration {
+ enum "Mbps"{
+ value 0;
+ }
+ enum "Gbps"{
+ value 1;
+ }
+ }
+ }
+
+ typedef ase-yes-no-type {
+ type enumeration {
+ enum "Y"{
+ value 0;
+ }
+ enum "N"{
+ value 1;
+ }
+ }
+ }
+
+ typedef provisioning-indicator {
+ type enumeration {
+ enum "Y"{
+ value 0;
+ }
+ enum "N"{
+ value 1;
+ }
+ }
+ }
+
+ typedef media-type {
+ type enumeration {
+ enum "SFP-1GE-SX"{
+ value 0;
+ }
+ enum "SFP-1GE-LX"{
+ value 1;
+ }
+ enum "SFP-1GE"{
+ value 2;
+ }
+ enum "Ethernet-10_100_1000M"{
+ value 3;
+ }
+ }
+ }
+
+ typedef media-speed-type {
+ type enumeration {
+ enum "100"{
+ value 0;
+ }
+ enum "1000"{
+ value 1;
+ }
+ enum "10000"{
+ value 2;
+ }
+ }
+ }
+
+ typedef cos-category-type {
+ type enumeration {
+ enum "GOS"{
+ value 0;
+ }
+ enum "PPCOS"{
+ value 1;
+ }
+ }
+ }
+
+ typedef uni-gos-type {
+ type enumeration {
+ enum "INTERACTIVE"{
+ value 0;
+ }
+ enum "BUSINESS-CRITICAL-HIGH"{
+ value 1;
+ }
+ enum "BUSINESS-CRITICAL-MEDIUM"{
+ value 2;
+ }
+ enum "NON-CRITICAL-HIGH"{
+ value 3;
+ }
+ }
+ }
+
+ typedef uni-cir-value-type {
+ type enumeration {
+ enum "2"{
+ value 0;
+ }
+ enum "4"{
+ value 1;
+ }
+ enum "5"{
+ value 2;
+ }
+ enum "8"{
+ value 3;
+ }
+ enum "10"{
+ value 4;
+ }
+ enum "20"{
+ value 5;
+ }
+ enum "30"{
+ value 6;
+ }
+ enum "40"{
+ value 7;
+ }
+ enum "50"{
+ value 8;
+ }
+ enum "60"{
+ value 9;
+ }
+ enum "70"{
+ value 10;
+ }
+ enum "80"{
+ value 11;
+ }
+ enum "90"{
+ value 12;
+ }
+ enum "100"{
+ value 13;
+ }
+ enum "125"{
+ value 14;
+ }
+ enum "150"{
+ value 15;
+ }
+ enum "175"{
+ value 16;
+ }
+ enum "200"{
+ value 17;
+ }
+ enum "225"{
+ value 18;
+ }
+ enum "250"{
+ value 19;
+ }
+ }
+ }
+
+ typedef uni-mac-limit-type {
+ description "MAC address limit for UNI port";
+ type enumeration {
+ enum "Y"{
+ value 0;
+ }
+ enum "N"{
+ value 1;
+ }
+ }
+ }
+
+ typedef port-tagging-type {
+ type enumeration {
+ enum "port-based"{
+ value 0;
+ }
+ enum "vlan-based"{
+ value 1;
+ }
+ }
+ }
+
+ typedef port-status {
+ type enumeration {
+ enum "Available"{
+ value 0;
+ }
+ enum "Reserved"{
+ value 1;
+ }
+ enum "Active" {
+ value 2;
+ }
+ }
+ }
+
+ grouping uni-common-request-hdr {
+ leaf request-id {
+ type string;
+ mandatory true;
+ }
+ leaf source {
+ description "The source system requesting action or info";
+ type string;
+ mandatory true;
+ }
+ leaf request-action {
+ description "action indicator for this service instance";
+ type uni-action-type;
+ }
+ leaf undo-indicator {
+ type provisioning-indicator;
+ }
+ leaf notification-url {
+ description "When this field exists, NCS will return an "
+ + "acknowledgement that the request is legal "
+ + "Once the activate is finished (or fails) NCS"
+ + "will utilize the URL to indicate the status";
+ type string;
+ }
+ }
+
+ grouping uni-common-return-hdr {
+ leaf request-action {
+ description "action indicator for this service instance";
+ type uni-action-type;
+ }
+ leaf request-id {
+ description "Identifier for the request from NGO";
+ type string;
+
+ }
+ }
+
+ grouping uni-common-error-format {
+ leaf error-code {
+ description "Error code";
+ type int32;
+ }
+ leaf error-message {
+ description "Error text describing the API error occurance";
+ type string;
+ }
+ }
+
+ grouping query-common-hdr {
+ leaf request-id {
+ description "Identifier for the request from NGO";
+ type string;
+ }
+ leaf request-type {
+ description "action indicator for this service instance";
+ type query-type;
+ }
+ }
+
+ grouping query-error-format {
+ leaf error-code {
+ description "Error code";
+ type int32;
+ }
+ leaf error-message {
+ description "Error text describing the API error occurance";
+ type string;
+ }
+ }
+
+ grouping evc-common-request-hdr {
+ leaf request-id {
+ description "Identifier for the request from NGO";
+ type string;
+ }
+ leaf source {
+ description "The source system requesting action or info";
+ type string;
+ mandatory true;
+ }
+ leaf uni-order-number {
+ type string;
+ }
+ leaf request-action {
+ description "action indicator for this service instance";
+ type evc-action-type;
+ mandatory true;
+ }
+ leaf undo-indicator {
+ type provisioning-indicator;
+ }
+ leaf notification-url {
+ description "When this field exists, NCS will return an "
+ + "acknowledgement that the request is legal "
+ + "Once the activate is finished (or fails) NCS"
+ + "will utilize the URL to indicate the status";
+ type string;
+ }
+ leaf evc-name {
+ type string;
+ mandatory true;
+ }
+ }
+
+ grouping evc-common-error-format {
+ leaf error-code {
+ description "Error code";
+ type int32;
+ }
+ leaf error-message {
+ description "Error text describing the API error occurance";
+ type string;
+ }
+ }
+
+ /////////////////////////////////////////
+ // UNI-PORTS table contains all circuits
+ /////////////////////////////////////////
+ container uni-ports {
+ description
+ "UNI port container";
+ list uni-port {
+ key "uni-circuit-id";
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ leaf subscriber-name {
+ type string;
+ mandatory true;
+ }
+ leaf uni-order-number {
+ type string;
+ mandatory true;
+ }
+ leaf edge-device-clli {
+ description "Edge device (e.g. EMT) on which port "
+ + " reservation is needed";
+ type string;
+ mandatory true;
+ }
+ leaf uni-location-city {
+ type string;
+ mandatory true;
+ }
+ leaf uni-location-state {
+ type string;
+ mandatory true;
+ }
+ leaf media-type {
+ type media-type;
+ mandatory true;
+ }
+ leaf media-speed {
+ type media-speed-type;
+ mandatory true;
+ }
+ leaf uni-cir-value {
+ description "Integer value for the CIR";
+ type uni-cir-value-type;
+ mandatory true;
+ }
+ leaf uni-cir-units {
+ description "Units for the CIR";
+ type cir-rate-type;
+ mandatory true;
+ }
+ leaf cos-category {
+ description "CoS Type";
+ type cos-category-type;
+ mandatory true;
+ }
+ leaf gos-profile {
+ description "GoS tpye";
+ type uni-gos-type;
+ mandatory true;
+ }
+ leaf aditional-mac-allowed {
+ type uni-mac-limit-type;
+ }
+ leaf port-tagging {
+ type port-tagging-type;
+ mandatory true;
+ }
+ leaf port-status {
+ type port-status;
+ }
+ leaf name-value-pair {
+ type string;
+ }
+ }
+ }
+
+ ///////////////////////////////////////////
+ // EVCS table contains all evc associations
+ ///////////////////////////////////////////
+ container evcs {
+ list evc {
+ key "evc-name";
+ leaf evc-name {
+ type string;
+ mandatory true;
+ }
+ leaf topology {
+ type enumeration {
+ enum "MultiPoint"{
+ value 0;
+ }
+ enum "PointToPoint"{
+ value 1;
+ }
+ }
+ }
+ list evc-leg {
+ key evc-access-name;
+ leaf evc-access-name {
+ type string;
+ }
+ leaf subscriber-name {
+ type string;
+ }
+ leaf cvlan {
+ type uint16 {
+ range "2..4090";
+ }
+ }
+ leaf connection-cir-value {
+ type uni-cir-value-type;
+ }
+ leaf connection-cir-units-string {
+ type cir-rate-type;
+ }
+ leaf connection-gos-profile {
+ type evc-gos-type;
+ }
+ leaf connection-additional-mac-allowed {
+ type uni-mac-limit-type;
+ }
+ leaf connection-emc-indicator {
+ type enumeration {
+ enum "Y"{
+ value 0;
+ }
+ enum "N"{
+ value 1;
+ }
+ }
+ }
+ leaf connection-emc-speed-value {
+ type uni-cir-value-type;
+ }
+ leaf connection-emc-speed-units-string {
+ type cir-rate-type;
+ }
+ }
+ leaf name-value-pair {
+ type string;
+ }
+ }
+ }
+}
diff --git a/sli/common/src/main/yang/ase.yang b/sli/common/src/main/yang/ase.yang
new file mode 100755
index 00000000..0b36a561
--- /dev/null
+++ b/sli/common/src/main/yang/ase.yang
@@ -0,0 +1,558 @@
+module ase {
+
+ namespace "att:ase";
+ prefix ase;
+
+ import ase-type {prefix ase-type; revision-date "2014-06-09";}
+
+ organization "AT&T ASE";
+
+ description
+ "This submodule contains a collection of YANG definitions for
+ defining the ASE service model(s) for UNI and EVC";
+
+ revision 2014-03-27 {
+ description
+ "Additional detail for UNI and EVC API";
+ }
+ revision 2014-03-18 {
+ description
+ "Initial version";
+ }
+
+
+ /////////////////////////////////////////////////////
+ // ASE Query Actions
+ /////////////////////////////////////////////////////
+
+ ////
+ // Port Reserve Request
+ ////
+ rpc ase-port-reserve {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ leaf edge-device-clli {
+ description "Edge device (e.g. EMT) on which port "
+ + " reservation is needed";
+ type string;
+ mandatory true;
+ }
+ leaf uni-cir-value {
+ description "Integer value for the CIR";
+ type ase-type:uni-cir-value-type;
+ mandatory true;
+ }
+ leaf uni-cir-units {
+ description "Units for the CIR";
+ type ase-type:cir-rate-type;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ }
+ leaf uni-port-id {
+ description "Allocated UNI port id";
+ type string;
+ }
+
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Release Port Request
+ ////
+ rpc ase-release-port-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:uni-common-return-hdr;
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Port Provisioning Request
+ ////
+ rpc ase-port-prov-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ leaf subscriber-name {
+ type string;
+ mandatory true;
+ }
+ leaf uni-order-number {
+ type string;
+ mandatory true;
+ }
+ leaf edge-device-clli {
+ description "Edge device (e.g. EMT) on which port "
+ + " reservation is needed";
+ type string;
+ mandatory true;
+ }
+ leaf uni-location-city {
+ type string;
+ mandatory true;
+ }
+ leaf uni-location-state {
+ type string;
+ mandatory true;
+ }
+ leaf media-type {
+ type ase-type:media-type;
+ mandatory true;
+ }
+ leaf media-speed {
+ type ase-type:media-speed-type;
+ mandatory true;
+ }
+ leaf uni-cir-value {
+ description "Integer value for the CIR";
+ type ase-type:uni-cir-value-type;
+ mandatory true;
+ }
+ leaf uni-cir-units {
+ description "Units for the CIR";
+ type ase-type:cir-rate-type;
+ mandatory true;
+ }
+ leaf cos-category {
+ description "CoS Type";
+ type ase-type:cos-category-type;
+ mandatory true;
+ }
+ leaf gos-profile {
+ description "GoS tpye";
+ type ase-type:uni-gos-type;
+ mandatory true;
+ }
+ leaf aditional-mac-allowed {
+ type ase-type:uni-mac-limit-type;
+ }
+ leaf port-tagging {
+ type ase-type:port-tagging-type;
+ mandatory true;
+ }
+ leaf name-value-pair {
+ type string;
+ }
+ }
+ output {
+ uses ase-type:uni-common-return-hdr;
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Deprovisioning Port Request
+ ////
+ rpc ase-deprov-port-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Change Port Provisioning Request
+ ////
+ rpc ase-change-port-prov-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ leaf subscriber-name {
+ type string;
+ }
+ leaf media-speed {
+ type ase-type:media-speed-type;
+ }
+ leaf uni-cir-value {
+ description "Integer value for the CIR";
+ type ase-type:uni-cir-value-type;
+ }
+ leaf uni-cir-units {
+ description "Units for the CIR";
+ type ase-type:cir-rate-type;
+ }
+ leaf cos-catagory {
+ type ase-type:cos-category-type;
+ }
+ leaf gos-profile {
+ type ase-type:uni-gos-type;
+ }
+ leaf additional-mac-allowed {
+ type ase-type:uni-mac-limit-type;
+ }
+ leaf port-tagging {
+ type ase-type:port-tagging-type;
+ mandatory true;
+ }
+ leaf name-value-pair {
+ type string;
+ }
+ }
+ output {
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Port Activate Request
+ ////
+ rpc ase-port-activate-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Port Change Activation Request
+ ////
+ rpc ase-change-port-activation-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ ////
+ // Port Disconnect Request
+ ////
+ rpc ase-port-disconnect-request {
+ input {
+ uses ase-type:uni-common-request-hdr;
+
+ leaf uni-circuit-id {
+ type string;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:uni-common-error-format;
+ }
+ }
+
+ /////////////////////////////////////////////////////
+ // EVC API
+ /////////////////////////////////////////////////////
+
+ ////
+ // EVC Provision Request
+ ////
+ rpc ase-evc-activation {
+ input {
+ uses ase-type:evc-common-request-hdr;
+ leaf topology {
+ type enumeration {
+ enum "MultiPoint"{
+ value 0;
+ }
+ enum "PointToPoint"{
+ value 1;
+ }
+ }
+ }
+ list evc-leg {
+ key evc-access-name;
+ leaf evc-access-name {
+ type string;
+ }
+ leaf subscriber-name {
+ type string;
+ }
+ leaf cvlan {
+ type uint16 {
+ range "2..4090";
+ }
+ }
+ leaf connection-cir-value {
+ type ase-type:uni-cir-value-type;
+ }
+ leaf connection-cir-units-string {
+ type ase-type:cir-rate-type;
+ }
+ leaf connection-gos-profile {
+ type ase-type:evc-gos-type;
+ }
+ leaf connection-additional-mac-allowed {
+ type ase-type:uni-mac-limit-type;
+ }
+ leaf connection-emc-indicator {
+ type enumeration {
+ enum "Y"{
+ value 0;
+ }
+ enum "N"{
+ value 1;
+ }
+ }
+ }
+ leaf connection-emc-speed-value {
+ type ase-type:uni-cir-value-type;
+ }
+ leaf connection-emc-speed-units-string {
+ type ase-type:cir-rate-type;
+ }
+ }
+ leaf name-value-pair {
+ type string;
+ }
+ }
+ output {
+ uses ase-type:evc-common-error-format;
+ }
+ }
+
+ ////
+ // EVC Change Activation Request
+ ////
+ rpc ase-evc-change-activation {
+ input {
+ uses ase-type:evc-common-request-hdr;
+ leaf topology {
+ type enumeration {
+ enum "MultiPoint"{
+ value 0;
+ }
+ enum "PointToPoint"{
+ value 1;
+ }
+ }
+ }
+ list evc-leg {
+ key evc-access-name;
+ leaf evc-access-name {
+ type string;
+ }
+ leaf connection-cir-value {
+ type ase-type:uni-cir-value-type;
+ }
+ leaf connection-cir-units-string {
+ type ase-type:cir-rate-type;
+ }
+ leaf connection-gos-profile {
+ type ase-type:evc-gos-type;
+ }
+ leaf connection-additional-mac-allowed {
+ type ase-type:uni-mac-limit-type;
+ }
+
+ }
+ leaf name-value-pair {
+ type string;
+ }
+
+ }
+ output {
+ uses ase-type:evc-common-error-format;
+ }
+ }
+
+ ////
+ // EVC Disconnet Connection Request
+ ////
+ rpc ase-evc-disconnect-request {
+ input {
+ uses ase-type:evc-common-request-hdr;
+ leaf topology {
+ type enumeration {
+ enum "MultiPoint"{
+ value 0;
+ }
+ enum "PointToPoint"{
+ value 1;
+ }
+ }
+ }
+ list evc-leg {
+ key evc-access-name;
+ leaf evc-access-name {
+ type string;
+ }
+ }
+ leaf name-value-pair {
+ type string;
+ }
+
+ }
+ output {
+ uses ase-type:evc-common-error-format;
+ }
+ }
+
+ /////////////////////////////////////////////////////
+ // ASE Query Actions
+ /////////////////////////////////////////////////////
+
+ rpc find-available-ports {
+ description "Return a count of available ports";
+ input {
+ uses ase-type:query-common-hdr;
+ leaf edge-device-clli {
+ type string;
+ mandatory true;
+ }
+
+ leaf port-role {
+ type enumeration {
+ enum "NETWORK"{
+ value 0;
+ }
+ enum "ACCESS"{
+ value 1;
+ }
+ enum "SDN-ACCESS"{
+ value 2;
+ }
+ }
+ mandatory true;
+ }
+ leaf port-assigned {
+ type string;
+ }
+ }
+ output {
+ uses ase-type:query-common-hdr;
+ container statuss {
+ leaf edge-device-clli {
+ type string;
+ }
+ container max-cir {
+ leaf cir-value {
+ type uint16;
+ }
+ leaf cir-type {
+ type ase-type:cir-rate-type;
+ }
+ }
+ leaf if-count {
+ type uint16;
+ }
+ }
+ uses ase-type:query-error-format;
+ }
+ }
+
+ rpc find-evcs-in-uni {
+ description "Return EVC instances for a specified UNI";
+ input {
+ uses ase-type:query-common-hdr;
+
+ leaf uni-circuit-id {
+ type string; //leafref
+ }
+ leaf edge-device-clli {
+ description "Edge device (e.g. EMT) on which port "
+ + " reservation is needed";
+ type string;
+ }
+ }
+ output {
+ uses ase-type:query-common-hdr;
+
+ leaf uni-leg-name {
+ description "NGO-proivded named";
+ type string;
+ }
+ uses ase-type:query-error-format;
+ }
+ }
+
+ rpc find-service-details {
+ description "Return EVC instances for a specified UNI";
+ input {
+ uses ase-type:query-common-hdr;
+ leaf uni-circuit-id {
+ type string; //leafref
+ }
+ leaf source {
+ type string;
+ mandatory true;
+ }
+ leaf service-name {
+ type string;
+ mandatory true;
+ }
+ leaf service-type {
+ type string;
+ mandatory true;
+ }
+ }
+ output {
+ uses ase-type:query-common-hdr;
+
+ leaf service-name {
+ type string;
+ mandatory true;
+ }
+ leaf service-type {
+ type string;
+ mandatory true;
+ }
+ leaf service-state {
+ type enumeration {
+ enum "Active"{
+ value 0;
+ }
+ enum "NotActive"{
+ value 1;
+ }
+ }
+ }
+ leaf has-pending-change {
+ type ase-type:ase-yes-no-type;
+ }
+ leaf allowed-connection-count {
+ type int16;
+ }
+ uses ase-type:query-error-format;
+ }
+ }
+} //module
diff --git a/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicContextTest.java b/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicContextTest.java
new file mode 100644
index 00000000..6e6656e8
--- /dev/null
+++ b/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicContextTest.java
@@ -0,0 +1,69 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class SvcLogicContextTest extends TestCase {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicContext.class);
+
+ 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");
+ }
+
+ }
+
+}
diff --git a/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicExpressionParserTest.java b/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicExpressionParserTest.java
new file mode 100644
index 00000000..d6503b60
--- /dev/null
+++ b/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicExpressionParserTest.java
@@ -0,0 +1,69 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.openecomp.sdnc.sli.SvcLogicExprListener;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicExpressionFactory;
+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/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicParserTest.java b/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicParserTest.java
new file mode 100644
index 00000000..e8ff2fee
--- /dev/null
+++ b/sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicParserTest.java
@@ -0,0 +1,163 @@
+/*-
+ * ============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.openecomp.sdnc.sli;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.LinkedList;
+
+import org.openecomp.sdnc.sli.SvcLogicParser;
+import org.openecomp.sdnc.sli.SvcLogicParserException;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.openecomp.sdnc.sli.SvcLogicStoreFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * @author dt5972
+ *
+ */
+public class SvcLogicParserTest extends TestCase {
+
+ /**
+ * Test method for {@link org.openecomp.sdnc.sli.SvcLogicParser#parse(java.lang.String)}.
+ */
+
+
+ public void testParse() {
+
+
+ try
+ {
+
+ URL propUrl = getClass().getResource("/svclogic.properties");
+
+ InputStream propStr = getClass().getResourceAsStream("/svclogic.properties");
+
+ SvcLogicStore store = SvcLogicStoreFactory.getSvcLogicStore(propStr);
+
+ assertNotNull(store);
+
+ store.registerNodeType("switch");
+ store.registerNodeType("block");
+ store.registerNodeType("get-resource");
+ store.registerNodeType("reserve");
+ store.registerNodeType("is-available");
+ store.registerNodeType("exists");
+ store.registerNodeType("configure");
+ store.registerNodeType("return");
+ store.registerNodeType("record");
+ store.registerNodeType("allocate");
+ store.registerNodeType("release");
+ store.registerNodeType("for");
+ store.registerNodeType("set");
+
+
+ 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.validate(testCaseUrl.getPath(), store);
+ } catch (Exception e) {
+ fail("Validation failure ["+e.getMessage()+"]");
+
+ }
+
+
+
+
+
+ }
+ }
+
+ testStr = getClass().getResourceAsStream("/parser-bad.tests");
+ testsReader = new BufferedReader(new InputStreamReader(testStr));
+ 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);
+ }
+
+ boolean valid = true;
+ try {
+ SvcLogicParser.load(testCaseUrl.getPath(), store);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ valid = false;
+ }
+
+ if (valid) {
+ fail("Expected compiler error on "+testCaseFile+", but got success");
+ }
+
+
+ }
+ }
+ }
+ catch (SvcLogicParserException e)
+ {
+ fail("Parser error : "+e.getMessage());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ fail("Caught exception processing test cases");
+ }
+
+
+ }
+
+
+
+}
diff --git a/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml b/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml
new file mode 100644
index 00000000..097078a8
--- /dev/null
+++ b/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.openecomp.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.openecomp.org/sdnc/svclogic ./svclogic.xsd"
+ module="ase" version="1.0.0">
+
+
+ <method rpc="ase-evc-activation" mode="sync">
+ <configure adaptor="org.openecomp.sdnc.sli.adaptor.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.openecomp.sdnc.sli.adaptor.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/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml b/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml
new file mode 100644
index 00000000..08084420
--- /dev/null
+++ b/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.openecomp.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.openecomp.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.openecomp.sdnc.sli.resource.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.openecomp.sdnc.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.openecomp.sdnc.sli.resource.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.openecomp.sdnc.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.openecomp.sdnc.sli.resource.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id" pfx="asePort">
+
+ <outcome value="success">
+ <configure adaptor="org.openecomp.sdnc.sli.adaptor.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.openecomp.sdnc.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.openecomp.sdnc.sli.resource.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.openecomp.sdnc.sli.resource.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.openecomp.sdnc.sli.resource.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id">
+ <outcome value="success">
+ <block>
+ <record plugin="org.openecomp.sdnc.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/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml b/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml
new file mode 100644
index 00000000..5a835b7b
--- /dev/null
+++ b/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.openecomp.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.openecomp.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.openecomp.sdnc.sli.resource.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.openecomp.sdnc.sli.resource.sample.SampleResource"
+ resource="ase-port" key="uni-circuit-id == $uni-circuit-id">
+ <outcome value="success">
+ <configure adaptor="org.openecomp.sdnc.sli.adaptor.emt.EmtAdaptor"
+ key="$uni-circuit-id" activate="false">
+
+ <outcome value="success">
+ <block>
+ <record plugin="org.openecomp.sdnc.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/sli/common/src/test/resources/bad_neutron_logic_v11.xml b/sli/common/src/test/resources/bad_neutron_logic_v11.xml
new file mode 100644
index 00000000..4e1e8d9b
--- /dev/null
+++ b/sli/common/src/test/resources/bad_neutron_logic_v11.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.openecomp.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.openecomp.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/sli/common/src/test/resources/expression.tests b/sli/common/src/test/resources/expression.tests
new file mode 100755
index 00000000..c352e9b0
--- /dev/null
+++ b/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/sli/common/src/test/resources/mergetest.xml b/sli/common/src/test/resources/mergetest.xml
new file mode 100644
index 00000000..12e083c7
--- /dev/null
+++ b/sli/common/src/test/resources/mergetest.xml
@@ -0,0 +1,54 @@
+<!--
+ ============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=========================================================
+ -->
+
+<multicast-parameters xmlns="org.openecomp.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/sli/common/src/test/resources/neutron_logic_v10.xml b/sli/common/src/test/resources/neutron_logic_v10.xml
new file mode 100644
index 00000000..9cd33127
--- /dev/null
+++ b/sli/common/src/test/resources/neutron_logic_v10.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.openecomp.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.openecomp.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/sli/common/src/test/resources/nonsense.xml b/sli/common/src/test/resources/nonsense.xml
new file mode 100644
index 00000000..61220825
--- /dev/null
+++ b/sli/common/src/test/resources/nonsense.xml
@@ -0,0 +1,24 @@
+<!--
+ ============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=========================================================
+ -->
+
+<non>
+<sense>Hello world</sense>
+</non>
diff --git a/sli/common/src/test/resources/parser-bad.tests b/sli/common/src/test/resources/parser-bad.tests
new file mode 100755
index 00000000..82913afc
--- /dev/null
+++ b/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/sli/common/src/test/resources/parser-good.tests b/sli/common/src/test/resources/parser-good.tests
new file mode 100755
index 00000000..06543126
--- /dev/null
+++ b/sli/common/src/test/resources/parser-good.tests
@@ -0,0 +1,2 @@
+ReleasePortSvcLogic_v101.xml
+neutron_logic_v10.xml
diff --git a/sli/common/src/test/resources/simplelogger.properties b/sli/common/src/test/resources/simplelogger.properties
new file mode 100644
index 00000000..6f70984c
--- /dev/null
+++ b/sli/common/src/test/resources/simplelogger.properties
@@ -0,0 +1,24 @@
+###
+# ============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=========================================================
+###
+
+org.slf4j.simpleLogger.defaultLogLevel=info
+org.slf4j.simplelogger.log.org.openecomp.sdnc.sli.SvcLogicContext=debug
+org.slf4j.simplelogger.log.SvcLogicContext=debug
diff --git a/sli/common/src/test/resources/svclogic.properties b/sli/common/src/test/resources/svclogic.properties
new file mode 100644
index 00000000..fa33146e
--- /dev/null
+++ b/sli/common/src/test/resources/svclogic.properties
@@ -0,0 +1,26 @@
+###
+# ============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=========================================================
+###
+
+org.openecomp.sdnc.sli.dbtype = jdbc
+org.openecomp.sdnc.sli.jdbc.url = jdbc:mysql://localhost:3306/sdnctl
+org.openecomp.sdnc.sli.jdbc.database = sdnctl
+org.openecomp.sdnc.sli.jdbc.user = sdnctl
+org.openecomp.sdnc.sli.jdbc.password = gamma
diff --git a/sli/common/src/test/resources/svclogic.sh b/sli/common/src/test/resources/svclogic.sh
new file mode 100644
index 00000000..09f0637d
--- /dev/null
+++ b/sli/common/src/test/resources/svclogic.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+###
+# ============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=========================================================
+###
+
+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.openecomp.sdnc.sli.SvcLogicParser $*
diff --git a/sli/common/src/test/resources/svclogic.xsd b/sli/common/src/test/resources/svclogic.xsd
new file mode 100755
index 00000000..07430891
--- /dev/null
+++ b/sli/common/src/test/resources/svclogic.xsd
@@ -0,0 +1,323 @@
+<?xml version = "1.0" encoding = "UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.openecomp.org/sdnc/svclogic" xmlns="http://www.openecomp.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:choice>
+ </xsd:group>
+
+ <xsd:element name="service-logic">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="method" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ <xsd:element ref="outcome" minOccurs="0" maxOccurs="unbounded" />
+ </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="unbounded" />
+ </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:schema>
diff --git a/sli/features/pom.xml b/sli/features/pom.xml
new file mode 100755
index 00000000..2556a579
--- /dev/null
+++ b/sli/features/pom.xml
@@ -0,0 +1,137 @@
+<?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>
+ <artifactId>sli</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sli-features</artifactId>
+ <name>SLI - Features</name>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-recording</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${odl.mdsal.features.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+
+ <scope>runtime</scope>
+ </dependency>
+
+
+ <!-- dependency for opendaylight-karaf-empty for use by testing
+ <dependency>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>opendaylight-karaf-empty</artifactId>
+ <version>${odl.karaf.empty.version}</version>
+ <type>zip</type>
+ </dependency>
+ -->
+
+
+ <dependency>
+ <!-- Required for launching the feature tests -->
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-test</artifactId>
+ <version>${odl.commons.opendaylight.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${odl.yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Comment out feature test, since it fails in Jenkins due to env issues
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.odlparent</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ -->
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sli/features/src/main/resources/features.xml b/sli/features/src/main/resources/features.xml
new file mode 100644
index 00000000..e1ce255a
--- /dev/null
+++ b/sli/features/src/main/resources/features.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+ -->
+
+
+<features name="sdnc-sli-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository>
+
+
+ <feature name='sdnc-sli' description="sdnc-sli" version='${project.version}'>
+
+ <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+ <bundle>mvn:org.openecomp.sdnc.core/sli-common/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.sdnc.core/sli-provider/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.sdnc.core/sli-recording/${project.version}</bundle>
+ <feature>sdnc-dblib</feature>
+ <bundle>mvn:mysql/mysql-connector-java/${mysql.connector.version}</bundle>
+ </feature>
+
+</features>
diff --git a/sli/installer/pom.xml b/sli/installer/pom.xml
new file mode 100755
index 00000000..d43769e2
--- /dev/null
+++ b/sli/installer/pom.xml
@@ -0,0 +1,149 @@
+<?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>
+ <artifactId>sli</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sli-installer</artifactId>
+ <name>SLI - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>sdnc-sli</application.name>
+ <features.boot>sdnc-sli</features.boot>
+ <features.repositories>mvn:org.openecomp.sdnc.core/sli-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-recording</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>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</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.openecomp.sdnc</includeGroupIds>
+ <excludeArtifactIds>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/sli/installer/src/assembly/assemble_installer_zip.xml b/sli/installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 00000000..85e2e1e8
--- /dev/null
+++ b/sli/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,59 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/sli/installer/src/assembly/assemble_mvnrepo_zip.xml b/sli/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 00000000..38e6d47b
--- /dev/null
+++ b/sli/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,49 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/sli/installer/src/main/resources/scripts/install-feature.sh b/sli/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 00000000..93236c5b
--- /dev/null
+++ b/sli/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+###
+# ============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=========================================================
+###
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+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} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/sli/pom.xml b/sli/pom.xml
new file mode 100755
index 00000000..53a8b629
--- /dev/null
+++ b/sli/pom.xml
@@ -0,0 +1,65 @@
+<?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/maven-v4_0_0.xsd">
+
+
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>pom</packaging>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli</artifactId>
+
+ <dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-features</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-recording</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+
+ <name>Service Logic Interpreter</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>
+
+ <modules>
+ <module>common</module>
+ <module>provider</module>
+ <module>recording</module>
+ <module>features</module>
+ <module>installer</module>
+ </modules>
+ <organization>
+ <name>openECOMP</name>
+ </organization>
+ <version>0.0.1-SNAPSHOT</version>
+
+
+</project>
diff --git a/sli/provider/pom.xml b/sli/provider/pom.xml
new file mode 100755
index 00000000..f73d0071
--- /dev/null
+++ b/sli/provider/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<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.openecomp.sdnc.core</groupId>
+ <artifactId>sli</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sli-provider</artifactId>
+ <packaging>bundle</packaging>
+ <name>SLI - Provider</name>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>${commons.lang.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+
+ <!--
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4</artifactId>
+ <version>${antlr.version}</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ -->
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.openecomp.sdnc.sli.provider.SvcLogicActivator</Bundle-Activator>
+ <Export-Package>org.openecomp.sdnc.sli.provider;version=${project.version}</Export-Package>
+
+ <DynamicImport-Package>*</DynamicImport-Package>
+ <!--
+ <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.vim25.*,org.apache.xerces.*,com.mysql.jdbc.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*</Import-Package>
+ -->
+
+ <Import-Package>org.openecomp.sdnc.sli;version="${project.version}",*</Import-Package>
+ <!--
+ <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|jcl-over-slf4j|xml-apis|mysql-connector-java</Embed-Dependency>
+ -->
+ <Embed-Dependency>*;scope=compile;artifactId=commons-lang|commons-lang3</Embed-Dependency>
+
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+
+
+ </configuration>
+
+ </plugin>
+ </plugins>
+ </build>
+ <description>SLI Provider is the OSGi bundle that exposes the service logic interpreter as a service.</description>
+</project>
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BlockNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BlockNodeExecutor.java
new file mode 100644
index 00000000..f83154d9
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BlockNodeExecutor.java
@@ -0,0 +1,75 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlockNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(BlockNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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.setStatus("success");
+
+ int numOutcomes = node.getNumOutcomes();
+
+ for (int i = 0; i < numOutcomes; i++) {
+ if ("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) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Block - executing outcome " + (i + 1));
+ }
+ while (nextNode != null)
+ {
+ nextNode = svc.executeNode(nextNode, ctx);
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Block - done: no outcome " + (i + 1));
+ }
+ }
+ }
+
+ return (null);
+ }
+
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java
new file mode 100644
index 00000000..0f8719c8
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BreakNodeExecutor.java
@@ -0,0 +1,42 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.BreakNodeException;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BreakNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BreakNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java
new file mode 100644
index 00000000..7b79c19f
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java
@@ -0,0 +1,165 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CallNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(CallNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ String outValue = "not-found";
+
+ SvcLogicGraph myGraph = node.getGraph();
+
+ if (myGraph == null)
+ {
+ LOG.debug("execute: getGraph returned null");
+ }
+ else
+ {
+ LOG.debug("execute: got SvcLogicGraph");
+ }
+
+ 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();
+ LOG.debug("myGraph.getModule() returned "+module);
+ }
+ }
+
+ 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();
+ LOG.debug("myGraph.getRpc() returned "+rpc);
+ }
+ }
+
+ 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();
+
+ LOG.debug("myGraph.getMode() returned "+mode);
+ }
+ }
+
+ String version = null;
+
+ moduleExpr = node.getAttribute("version");
+ if (moduleExpr != null)
+ {
+ version = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx);
+ }
+
+ String parentGraph = ctx.getAttribute("currentGraph");
+ ctx.setAttribute("parentGraph", parentGraph);
+
+ SvcLogicStore store = getStore();
+
+ if (store != null) {
+ SvcLogicGraph calledGraph = store.fetch(module, rpc, version, mode);
+ LOG.debug("Parent " + parentGraph + " is calling child " + calledGraph.toString());
+ ctx.setAttribute("currentGraph", calledGraph.toString());
+ if (calledGraph != null) {
+ svc.execute(calledGraph, ctx);
+
+ outValue = ctx.getStatus();
+ } else {
+ LOG.error("Could not find service logic for [" + module + "," + rpc + "," + version + "," + mode + "]");
+ }
+ }
+ 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("currentGraph", 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");
+ }
+ }
+ ctx.setAttribute("currentGraph", parentGraph);
+ ctx.setAttribute("parentGraph", null);
+
+ return (nextNode);
+
+ }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ConfigureNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ConfigureNodeExecutor.java
new file mode 100644
index 00000000..a3f2874f
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ConfigureNodeExecutor.java
@@ -0,0 +1,248 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicAdaptor;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ConfigureNodeExecutor extends SvcLogicNodeExecutor {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ConfigureNodeExecutor.class);
+
+ public SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+ String adaptorName = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("adaptor"), node, ctx);
+ String outValue = "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);
+
+ Map<String, String> parmMap = new HashMap<String, String>();
+
+ Set<Map.Entry<String, SvcLogicExpression>> parmSet = node
+ .getParameterSet();
+ boolean hasParms = false;
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parmSet
+ .iterator(); iter.hasNext();) {
+ hasParms = true;
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ SvcLogicExpression curExpr = curEnt.getValue();
+ String curExprValue = SvcLogicExpressionResolver.evaluate(curExpr, node, ctx);
+
+ LOG.debug("Parameter "+curName+" = "+curExpr.asParsedExpr()+" resolves to "+curExprValue);
+
+ parmMap.put(curName,curExprValue);
+ }
+
+ if (hasParms) {
+ SvcLogicAdaptor.ConfigStatus confStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+
+ try {
+ confStatus = adaptor.configure(key, parmMap, ctx);
+ } catch (Exception e) {
+ LOG.warn("Caught exception from "+adaptorName+".configure", e);
+ confStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+
+ switch (confStatus) {
+ case SUCCESS:
+ outValue = "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 from "+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 = "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 from "+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 = "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 = "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 from "+adaptorName+".activate", e);
+ activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+ switch (activateStatus) {
+ case SUCCESS:
+ outValue = "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 = "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 from "+adaptorName+".deactivate", e);
+ deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE;
+ }
+ switch (deactivateStatus) {
+ case SUCCESS:
+ outValue = "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 = "failure";
+ }
+ }
+ } else {
+ LOG.warn("Nothing to configure - no parameters passed, and activate attribute is not set");
+ outValue = "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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java
new file mode 100644
index 00000000..081cbcfa
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java
@@ -0,0 +1,101 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeleteNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(DeleteNodeExecutor.class);
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = "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);
+ }
+
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java
new file mode 100644
index 00000000..7ae4d0db
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java
@@ -0,0 +1,161 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ExecuteNodeExecutor extends SvcLogicNodeExecutor {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ExecuteNodeExecutor.class);
+
+ private static final String pluginErrorMessage = "Could not execute plugin. SvcLogic status will be set to failure.";
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 {
+ 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 = new HashMap<String, String>();
+
+ 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.debug("Parameter "+curName+" = "+curExpr.asParsedExpr()+" resolves to "+curExprValue);
+
+ parmMap.put(curName,curExprValue);
+ }
+
+ 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.setStatus("failure");
+ } catch (IllegalAccessException e) {
+ LOG.error(pluginErrorMessage, e);
+ outValue = "failure";
+ ctx.setStatus("failure");
+ } catch (IllegalArgumentException e) {
+ LOG.error(pluginErrorMessage, e);
+ outValue = "failure";
+ ctx.setStatus("failure");
+ }
+ }
+
+ }
+
+ 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 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 "success";
+ }
+
+ } else {
+ return "success";
+ }
+ }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java
new file mode 100644
index 00000000..688a86e5
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java
@@ -0,0 +1,105 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ExistsNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ExistsNodeExecutor.class);
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = "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 = "failure";
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin "
+ + plugin);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java
new file mode 100644
index 00000000..e9fdc55e
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java
@@ -0,0 +1,109 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.BreakNodeException;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ForNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ForNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 ("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.debug("ForNodeExecutor caught break");
+ }
+ return (null);
+ }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java
new file mode 100644
index 00000000..d431a18a
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java
@@ -0,0 +1,134 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GetResourceNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(GetResourceNodeExecutor.class);
+
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = "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 = "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);
+ }
+
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java
new file mode 100644
index 00000000..0df73682
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java
@@ -0,0 +1,103 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IsAvailableNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(IsAvailableNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = "failure";
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("is-available node encountered - looking for resource class "
+ + plugin);
+ }
+
+ 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 = "failure";
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicResource object for plugin "
+ + plugin);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java
new file mode 100644
index 00000000..4c5ee068
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java
@@ -0,0 +1,1186 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+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.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+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();
+
+ @Deprecated
+ public static void setProperties(Properties input) {
+ setYangMappingProperties(input);
+ }
+
+ public static void setYangMappingProperties(Properties properties) {
+ for (Object propNameObj : properties.keySet()) {
+ String propName = (String) propNameObj;
+ MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName));
+ }
+ }
+
+ public static void loadProperties(String propertiesFile) {
+ File file = new File(propertiesFile);
+ Properties properties = new Properties();
+ InputStream input = null;
+ if (file.isFile() && file.canRead()) {
+ try {
+ 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);
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ LOG.error("Failed to close properties file " + 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) {
+ 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();
+
+ LOG.trace("Extracting properties from " + fromClass.getName() + " class");
+ if (fromObj instanceof List) {
+
+ // Class is a List. List should contain yang-generated classes.
+ LOG.trace(fromClass.getName() + " is a 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)) {
+ // Class is yang generated.
+ LOG.trace(fromClass.getName() + " is a Yang-generated class");
+
+ 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;
+ propVal = retValue.toString();
+ props.setProperty(propName, mapEnumeratedValue(fieldName, propVal));
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert Yang-generated enum returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", 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) {
+ propVal = retValue.getValue().toString();
+ LOG.debug("Setting property " + propName + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", 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) {
+ propVal = retValue.getValue().toString();
+ LOG.debug("Setting property " + propName + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+ }
+ } else if (isIpAddress(returnType)) {
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ IpAddress retValue = (IpAddress) m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (retValue != null) {
+ propVal = new String(retValue.getValue());
+ LOG.debug("Setting property " + propName + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + "." + m.getName() + "() to Properties entry", e);
+ }
+ } else if (isIpPrefix(returnType)) {
+ // Save its value
+ try {
+ String propName = propNamePfx + "." + fieldName;
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ IpPrefix retValue = (IpPrefix) m.invoke(fromObj);
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+
+ if (retValue != null) {
+ propVal = new String(retValue.getValue());
+ LOG.debug("Setting property " + propName + " to " + propVal);
+ props.setProperty(propName, propVal);
+
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to convert value 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[]) {
+ LOG.trace(m.getName() + " returns a byte[]");
+ retValue = new String((byte[]) retValue, "UTF-8");
+ LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string " + retValue);
+ }
+ if (!isAccessible) {
+ m.setAccessible(isAccessible);
+ }
+ if (retValue != null) {
+ toProperties(props, propNamePfx + "." + fieldName, retValue, returnType);
+ }
+ } 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)) {
+
+ LOG.trace(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 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[]) {
+ LOG.trace(m.getName() + " returns a byte[]");
+ propVal = new String((byte[]) propValObj, "UTF-8");
+ LOG.trace("Converted byte array " + propNamePfx + "." + fieldName + "to string " + propVal);
+
+ } 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))) {
+ LOG.trace("getValueFIX : " + propNamePfx + " only has getValue() getter - setting " + propNamePfx + " = " + propVal);
+ props.setProperty(propNamePfx, propVal);
+ } else {
+ LOG.trace("getValueFIX : " + propNamePfx + " has " + numGetters + " getter(s), last one found was " + lastGetterName);
+
+ }
+
+ } 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");
+ LOG.trace("Converted byte array " + pfx + "to string " + fromVal);
+ } 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;
+
+ LOG.trace("Saving properties to List<" + elemType.getName() + "> from " + pfx);
+
+ if (props.contains(pfx + "_length")) {
+ try {
+ int listLength = Integer.parseInt(props.getProperty(pfx + "_length"));
+
+ if (listLength > 0) {
+ maxIdx = listLength - 1;
+ }
+ } catch (Exception e) {
+ // Ignore exception
+ }
+ }
+
+ if (maxIdx == -1) {
+ // 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.trace(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.trace("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);
+ }
+ } 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;
+
+ LOG.trace("Saving properties to " + toClass.getName() + " class from " + pfx);
+
+ Ipv4Address addr;
+
+ if (isYangGenerated(toClass)) {
+ // Class is yang generated.
+ LOG.trace(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.trace(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()) {
+ 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) {
+ LOG.trace(propName + " is unset");
+ } else {
+ LOG.trace(propName + " = " + paramValue);
+ }
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(paramClass)) {
+ // Is it an enum?
+ if (paramClass.isEnum()) {
+
+ LOG.trace(m.getName() + " expects an Enum");
+ // 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);
+ }
+
+ LOG.trace("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();
+
+ if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName)) {
+
+ if ((paramValue != null) && (paramValue.length() > 0)) {
+ try {
+ IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue);
+
+ if ("Ipv4Address".equals(simpleName)) {
+ m.invoke(toObj, ipAddr.getIpv4Address());
+ } else if ("Ipv6Address".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);
+ }
+ LOG.trace("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 call " + toClass.getName() + "." + m.getName() + "() with Properties entry", e);
+ }
+ }
+ } else if ("IpPrefix".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 {
+ // 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;
+
+ LOG.trace(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) {
+
+ if (paramValue == null) {
+ try {
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+ LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(null)");
+ 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) {
+ // Ignore exceptions
+ }
+ }
+
+ } 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) {
+
+ try {
+
+ Method buildMethod = builderClass.getMethod("build");
+ LOG.trace("Calling " + paramObj.getClass().getName() + "." + buildMethod.getName() + "()");
+ Object builtObj = buildMethod.invoke(paramObj);
+
+ boolean isAccessible = m.isAccessible();
+ if (!isAccessible) {
+ m.setAccessible(true);
+ }
+
+ LOG.trace("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);
+ }
+
+ if (constObj != null) {
+
+ LOG.trace("Calling " + toObj.getClass().getName() + "." + m.getName() + "(" + constObj.toString() + ")");
+ m.invoke(toObj, constObj);
+ } else {
+ LOG.trace("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);
+ }
+ }
+ }
+ }
+ } else {
+
+ // Setter's argument is not a yang-generated class. See
+ // if it is a List.
+
+ if (List.class.isAssignableFrom(paramClass)) {
+
+ LOG.trace("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.trace("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 entry", e);
+ }
+ }
+ } else {
+
+ // Setter expects something that is not a List and
+ // not yang-generated. Just pass the parameter value
+
+ LOG.trace("Parameter class " + paramClass.getName() + " is not a yang-generated class or a List");
+
+ 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 {
+ LOG.trace("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.trace("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);
+ }
+ }
+ } 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);
+ }
+ }
+
+ public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) {
+ boolean foundValue = false;
+
+ LOG.trace("Analyzing " + toClass.getName() + " class : pfx " + pfx);
+
+ if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) {
+ // Class is yang generated.
+ LOG.trace(toClass.getName() + " is a Yang-generated class");
+
+ if (toClass.getName().endsWith("Key")) {
+ if (Identifier.class.isAssignableFrom(toClass)) {
+ LOG.trace(Identifier.class.getName() + " is assignable from " + toClass.getName());
+ } else {
+
+ LOG.trace(Identifier.class.getName() + " is NOT assignable from " + toClass.getName());
+ }
+ }
+
+ 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()) {
+ LOG.trace("Is " + m.getName() + " method a getter?");
+ if (isGetter(m)) {
+ LOG.trace(m.getName() + " is a getter");
+ Class returnClass = m.getReturnType();
+
+ String fieldName = toLowerHyphen(m.getName().substring(3));
+ fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+
+ String propName = propNamePfx + "." + fieldName;
+
+ // Is the return type a yang generated class?
+ if (isYangGenerated(returnClass)) {
+ // Is it an enum?
+ if (returnClass.isEnum()) {
+
+ LOG.trace(m.getName() + " is an Enum");
+ pstr.print("\n\n * " + propName);
+
+ } else {
+
+ String simpleName = returnClass.getSimpleName();
+
+ if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "IpPrefix".equals(simpleName)) {
+ LOG.trace(m.getName() + " is an " + 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)) {
+
+ LOG.trace("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.trace("Calling printPropertyList on list type (" + elementClass.getName() + "), pfx is (" + pfx + "), toClass is (" + toClass.getName() + ")");
+ 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
+
+ LOG.trace("Parameter class " + returnClass.getName() + " is not a yang-generated class or a List");
+
+ 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 (false);
+ } else {
+ return (c.getName().startsWith("org.opendaylight.yang.gen."));
+ }
+ }
+
+ public static boolean isIpPrefix(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return ("IpPrefix".equals(simpleName));
+ }
+
+ 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 isIpAddress(Class c) {
+
+ if (c == null) {
+ return (false);
+ }
+ String simpleName = c.getSimpleName();
+ return ("IpAddress".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-9])([A-Z]))";
+ String replacement = "$2-$3";
+
+ String retval = str.replaceAll(regex, replacement).toLowerCase();
+
+ LOG.trace("Converting " + inStr + " => " + str + " => " + retval);
+ 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 will strip out all periods, which cannot be in a java enum
+ 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);
+ }
+
+ public static String getFullPropertiesPath(String propertiesFileName) {
+ return "/opt/bvc/controller/configuration/" + propertiesFileName;
+ }
+
+ //This is called when mapping a valid java enumeration back to the yang model value
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java
new file mode 100644
index 00000000..706014a3
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java
@@ -0,0 +1,102 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NotifyNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(NotifyNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = "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 = "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);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java
new file mode 100644
index 00000000..8ba14d27
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java
@@ -0,0 +1,119 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicRecorder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RecordNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(RecordNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node,
+ SvcLogicContext ctx) throws SvcLogicException {
+
+ String plugin = SvcLogicExpressionResolver.evaluate(
+ node.getAttribute("plugin"), node, ctx);
+ String outValue = "failure";
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace(node.getNodeType()
+ + " node encountered - looking for recorder class "
+ + plugin);
+ }
+
+ Map<String, String> parmMap = new HashMap<String, String>();
+
+ Set<Map.Entry<String, SvcLogicExpression>> parmSet = node
+ .getParameterSet();
+ boolean hasParms = false;
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parmSet
+ .iterator(); iter.hasNext();) {
+ hasParms = true;
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ SvcLogicExpression curExpr = curEnt.getValue();
+ String curExprValue = SvcLogicExpressionResolver.evaluate(curExpr,
+ node, ctx);
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("executeRecordNode : parameter " + curName + " = "
+ + curExpr + " => " + curExprValue);
+ }
+ parmMap.put(curName, curExprValue);
+ }
+
+
+ SvcLogicRecorder recorder = getSvcLogicRecorder(plugin);
+
+ if (recorder != null) {
+
+ try {
+ recorder.record(parmMap);
+ } catch (SvcLogicException e) {
+ LOG.error("Caught exception from recorder plugin", e);
+ outValue = "failure";
+ }
+ } else {
+ LOG.warn("Could not find SvcLogicRecorder object for plugin "
+ + plugin);
+ }
+
+ 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.isTraceEnabled()) {
+ LOG.trace("no failure or Other branch found");
+ }
+ }
+ return (nextNode);
+ }
+
+
+
+
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java
new file mode 100644
index 00000000..0d8416cd
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java
@@ -0,0 +1,100 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReleaseNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ReleaseNodeExecutor.class);
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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("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 = "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);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java
new file mode 100644
index 00000000..f0bbda88
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java
@@ -0,0 +1,114 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReserveNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ReserveNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = "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 = "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);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReturnNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReturnNodeExecutor.java
new file mode 100644
index 00000000..5cca4712
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReturnNodeExecutor.java
@@ -0,0 +1,78 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReturnNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(ReturnNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 context attribute " + curName + " to "
+ + curValue);
+ }
+ ctx.setAttribute(curName, curValue);
+ }
+ return null;
+ }
+
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java
new file mode 100644
index 00000000..57eac7f7
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java
@@ -0,0 +1,142 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SaveNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SaveNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = new HashMap<String, String>();
+
+ Set<Map.Entry<String, SvcLogicExpression>> parmSet = node
+ .getParameterSet();
+ boolean hasParms = false;
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parmSet
+ .iterator(); iter.hasNext();) {
+ hasParms = true;
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ SvcLogicExpression curExpr = curEnt.getValue();
+ if (curExpr != null) {
+ String curExprValue = SvcLogicExpressionResolver.evaluate(
+ curExpr, node, ctx);
+
+ LOG.debug("Parameter " + curName + " = "
+ + curExpr.asParsedExpr() + " resolves to "
+ + curExprValue);
+
+ parmMap.put(curName, curExprValue);
+ }
+ }
+
+ 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 = "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);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java
new file mode 100644
index 00000000..013997ed
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java
@@ -0,0 +1,189 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicExpressionFactory;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SetNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SetNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl svc, 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 {
+ 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);
+ }
+ int lhsPfxLength = lhsPrefix.length();
+ HashMap<String, String> parmsToAdd = new HashMap<String,String>();
+
+ for (String sourceVarName : ctx.getAttributeKeySet()) {
+
+ if (sourceVarName.startsWith(rhsRoot)) {
+
+ String targetVar = lhsPrefix
+ + "."
+ + sourceVarName
+ .substring(rhsRoot.length());
+
+ LOG.debug("Copying " + sourceVarName
+ + " value to " + 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
+ String lhsPrefix = lhsVarName.substring(0,
+ lhsVarName.length() - 1);
+ int lhsPfxLength = lhsPrefix.length();
+
+ LinkedList<String> parmsToRemove = new LinkedList<String> ();
+
+ for (String curCtxVarname : ctx.getAttributeKeySet()) {
+
+ if (curCtxVarname.startsWith(lhsPrefix)) {
+ LOG.debug("Unsetting " + curCtxVarname);
+ 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 "
+ + lhsVarName
+ + " already set and only-if-unset is true, so not overriding");
+ }
+ }
+
+ if (setValue) {
+ String curValue = SvcLogicExpressionResolver.evaluate(
+ curEnt.getValue(), node, ctx);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.trace("Parameter value "
+ + curEnt.getValue().asParsedExpr()
+ + " resolves to " + curValue);
+ LOG.debug("Setting context attribute " + lhsVarName
+ + " to " + curValue);
+ }
+ ctx.setAttribute(lhsVarName, curValue);
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java
new file mode 100644
index 00000000..ae42e2c7
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java
@@ -0,0 +1,225 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Properties;
+
+import org.openecomp.sdnc.sli.ConfigurationException;
+import org.openecomp.sdnc.sli.SvcLogicAdaptor;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.openecomp.sdnc.sli.SvcLogicStoreFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mysql.jdbc.Driver;
+
+public class SvcLogicActivator implements BundleActivator {
+
+ private static final String SVCLOGIC_PROP_VAR = "SDNC_SLI_PROPERTIES";
+ private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+ private static final Map<String, SvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, SvcLogicNodeExecutor>() {
+ {
+ 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());
+
+ }
+ };
+
+ private static LinkedList<ServiceRegistration> registrations = new LinkedList<ServiceRegistration>();
+
+ private static HashMap<String, SvcLogicAdaptor> adaptorMap = null;
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicActivator.class);
+
+ private static Properties props = null;
+
+ private static BundleContext bundleCtx = null;
+
+ private static SvcLogicService svcLogicServiceImpl = null;
+
+ @Override
+ public void start(BundleContext ctx) throws Exception {
+
+ LOG.info("Activating SLI");
+
+ bundleCtx = ctx;
+
+ // Read 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()) {
+
+ throw new ConfigurationException(
+ "Missing configuration properties file : "
+ + propFile);
+ }
+ try {
+
+ props.load(new FileInputStream(propFile));
+ } catch (Exception e) {
+ throw new ConfigurationException(
+ "Could not load properties file " + propPath, e);
+
+ }
+
+
+ if (registrations == null) {
+
+ registrations = new LinkedList<ServiceRegistration>();
+ }
+
+ // Advertise SvcLogicService
+ svcLogicServiceImpl = new SvcLogicServiceImpl();
+
+ LOG.info("SLI: Registering service " + SvcLogicService.NAME
+ + " in bundle " + ctx.getBundle().getSymbolicName());
+ ServiceRegistration reg = ctx.registerService(SvcLogicService.NAME,
+ svcLogicServiceImpl, null);
+ registrations.add(reg);
+
+ // Initialize SvcLogicStore
+ try {
+ SvcLogicStore store = getStore();
+ registerNodeTypes(store);
+ } catch (ConfigurationException e) {
+ LOG.warn("Could not initialize SvcLogicScore", e);
+ }
+
+ LOG.info("SLI - done registering services");
+ }
+
+ @Override
+ public void stop(BundleContext ctx) throws Exception {
+
+ if (registrations != null) {
+ for (ServiceRegistration reg : registrations) {
+ ServiceReference regRef = reg.getReference();
+ /* Don't bother to remove node types from table
+ String nodeType = (String) regRef.getProperty("nodeType");
+ if (nodeType != null) {
+ LOG.info("SLI - unregistering node type " + nodeType);
+ store.unregisterNodeType(nodeType);
+ }
+ */
+ reg.unregister();
+ }
+ registrations = null;
+ }
+ }
+
+ public static SvcLogicStore getStore() throws SvcLogicException {
+ // Create and initialize SvcLogicStore object - used to access
+ // saved service logic.
+
+ SvcLogicStore store = null;
+
+ try {
+ Driver dvr = new Driver();
+ store = SvcLogicStoreFactory.getSvcLogicStore(props);
+ } catch (Exception e) {
+ throw new ConfigurationException(
+ "Could not get service logic store", e);
+
+ }
+
+ try {
+ store.init(props);
+ } catch (Exception e) {
+ throw new ConfigurationException(
+ "Could not get service logic store", e);
+ }
+
+ return(store);
+ }
+
+ private static void registerNodeTypes(SvcLogicStore store) throws SvcLogicException {
+
+ if (store == null) {
+ return;
+ }
+ // Advertise built-in node executors
+ LOG.info("SLI : Registering built-in node executors");
+ Hashtable propTable = new Hashtable();
+
+ for (String nodeType : BUILTIN_NODES.keySet()) {
+ LOG.info("SLI - registering node type " + nodeType);
+ propTable.clear();
+ propTable.put("nodeType", nodeType);
+
+ ServiceRegistration reg = bundleCtx.registerService(SvcLogicNodeExecutor.class.getName(),
+ BUILTIN_NODES.get(nodeType), propTable);
+ registrations.add(reg);
+
+ store.registerNodeType(nodeType);
+
+ LOG.info("SLI - registering node executor");
+
+ ((SvcLogicServiceImpl)svcLogicServiceImpl).registerExecutor(nodeType, BUILTIN_NODES.get(nodeType));
+
+ }
+
+ }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicAdaptorFactory.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicAdaptorFactory.java
new file mode 100644
index 00000000..aa8c005a
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicAdaptorFactory.java
@@ -0,0 +1,86 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+
+import org.openecomp.sdnc.sli.SvcLogicAdaptor;
+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 SvcLogicAdaptorFactory {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicAdaptorFactory.class);
+
+ private static HashMap<String, SvcLogicAdaptor> adaptorMap = new HashMap<String, SvcLogicAdaptor>();
+
+ public static void registerAdaptor(SvcLogicAdaptor adaptor) {
+ String name = adaptor.getClass().getName();
+ LOG.info("Registering adaptor " + name);
+ adaptorMap.put(name, adaptor);
+
+ }
+
+ public static void unregisterAdaptor(String name) {
+ if (adaptorMap.containsKey(name)) {
+ LOG.info("Unregistering " + name);
+ adaptorMap.remove(name);
+ }
+ }
+
+ public static SvcLogicAdaptor getInstance(String name) {
+ if (adaptorMap.containsKey(name)) {
+ return (adaptorMap.get(name));
+ } else {
+ BundleContext bctx = null;
+ try
+ {
+ bctx = FrameworkUtil.getBundle(SvcLogicAdaptorFactory.class)
+ .getBundleContext();
+ }
+ catch (Exception e)
+ {
+ LOG.debug("Caught exception trying to locate device adaptor "+name, e);
+ return(null);
+ }
+
+ ServiceReference sref = bctx.getServiceReference(name);
+
+ if (sref != null) {
+ SvcLogicAdaptor adaptor = (SvcLogicAdaptor) bctx
+ .getService(sref);
+
+ if (adaptor != null) {
+ registerAdaptor(adaptor);
+
+ return (adaptor);
+ }
+ return (null);
+ }
+ }
+ return(null);
+ }
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java
new file mode 100644
index 00000000..5c17c799
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java
@@ -0,0 +1,605 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdnc.sli.SvcLogicAtom;
+import org.openecomp.sdnc.sli.SvcLogicAtom.AtomType;
+import org.openecomp.sdnc.sli.SvcLogicBinaryExpression;
+import org.openecomp.sdnc.sli.SvcLogicBinaryExpression.OperatorType;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicFunctionCall;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicVariableTerm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SvcLogicExpressionResolver {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicExpressionResolver.class);
+
+ 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)
+ {
+ LOG.trace("Evaluating context variable $"+varName);
+
+ String varValue = ctx.getAttribute(varName);
+
+ if (varValue == null) {
+ LOG.trace("Context variable $"+varName+" unset - treating as empty string");
+ varValue = "";
+ }
+
+ return (varValue);
+ }
+ SvcLogicExpression parm = node.getParameter(varName);
+ if (parm != null) {
+ LOG.trace("Evaluating value of parameter "+varName+": "+parm.asParsedExpr());
+
+ return (evaluate(parm, node, ctx));
+ }
+ else
+ {
+ 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)
+ {
+ LOG.trace("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand");
+ 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 ("+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 ("+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 ("+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();
+ LOG.debug("Evaluating context variable $"+varName);
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicNodeExecutor.java
new file mode 100644
index 00000000..0c8166ae
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicNodeExecutor.java
@@ -0,0 +1,110 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicAdaptor;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicRecorder;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class SvcLogicNodeExecutor {
+
+ public abstract SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException;
+
+ private static final Logger LOG = LoggerFactory.getLogger(SvcLogicNodeExecutor.class);
+
+ protected String evaluateNodeTest(SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+ if (node == null) {
+ return null;
+ }
+
+ return (SvcLogicExpressionResolver.evaluate(node.getAttribute("test"),
+ node, ctx));
+
+ }
+
+ protected SvcLogicStore getStore() throws SvcLogicException {
+ return SvcLogicActivator.getStore();
+ }
+
+ protected SvcLogicAdaptor getAdaptor(String adaptorName) {
+ return SvcLogicAdaptorFactory.getInstance(adaptorName);
+ }
+
+ protected SvcLogicResource getSvcLogicResource(String plugin) {
+ BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+ .getBundleContext();
+
+ ServiceReference sref = bctx.getServiceReference(plugin);
+ if (sref != null) {
+ SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+ .getService(sref);
+ return resourcePlugin;
+ }
+ else {
+ LOG.warn("Could not find service reference object for plugin " + plugin);
+ return null;
+ }
+ }
+
+ protected SvcLogicRecorder getSvcLogicRecorder(String plugin) {
+ BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+ .getBundleContext();
+
+ ServiceReference sref = bctx.getServiceReference(plugin);
+ if (sref != null) {
+ SvcLogicRecorder resourcePlugin = (SvcLogicRecorder) bctx
+ .getService(sref);
+ return resourcePlugin;
+ }
+ else {
+ return null;
+ }
+ }
+
+ protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName){
+ BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+ .getBundleContext();
+
+ ServiceReference sref = bctx.getServiceReference(pluginName);
+
+ if (sref == null) {
+ LOG.warn("Could not find service reference object for plugin " + pluginName);
+ return null;
+ } else {
+ SvcLogicJavaPlugin plugin = (SvcLogicJavaPlugin) bctx
+ .getService(sref);
+ return plugin;
+ }
+ }
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicService.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicService.java
new file mode 100644
index 00000000..f30b3fc0
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicService.java
@@ -0,0 +1,76 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.Properties;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.openecomp.sdnc.sli.SvcLogicException;
+
+public interface SvcLogicService {
+
+ public static final String NAME = "org.openecomp.sdnc.sli.provider.SvcLogicService";
+
+ // public SvcLogicContext execute(SvcLogicGraph graph, SvcLogicContext ctx) throws SvcLogicException;
+ /**
+ * 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
+ */
+ public 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
+ *
+ *
+ * @deprecated use execute(String module, String rpc, String version, String mode, DOMDataBroker dataBroker) instead
+ */
+ @Deprecated
+ public 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
+ */
+ public Properties execute(String module, String rpc, String version, String mode, Properties parms, DOMDataBroker domDataBroker) throws SvcLogicException;
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java
new file mode 100644
index 00000000..ba929bae
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java
@@ -0,0 +1,273 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.openecomp.sdnc.sli.MetricLogger;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+public class SvcLogicServiceImpl implements SvcLogicService {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicServiceImpl.class);
+
+ private HashMap<String, SvcLogicNodeExecutor> nodeExecutors = null;
+
+ private BundleContext bctx = null;
+
+ private void registerExecutors() {
+
+ LOG.info("Entered register executors");
+ if (bctx == null) {
+ bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
+ }
+
+ if (nodeExecutors == null) {
+ nodeExecutors = new HashMap<String, SvcLogicNodeExecutor>();
+ }
+
+ LOG.info("Opening service tracker");
+ ServiceTracker tracker = new ServiceTracker(bctx,
+ SvcLogicNodeExecutor.class.getName(), null);
+
+ tracker.open();
+
+ ServiceListener listener = new ServiceListener() {
+
+ public void serviceChanged(ServiceEvent ev) {
+ ServiceReference sr = ev.getServiceReference();
+ switch (ev.getType()) {
+ case ServiceEvent.REGISTERED: {
+ registerExecutor(sr);
+ }
+ break;
+ case ServiceEvent.UNREGISTERING: {
+ unregisterExecutor(sr);
+ }
+ break;
+ }
+ }
+ };
+
+ LOG.info("Adding service listener");
+ String filter = "(objectclass=" + SvcLogicNodeExecutor.class.getName()
+ + ")";
+ try {
+ bctx.addServiceListener(listener, filter);
+ ServiceReference[] srl = bctx.getServiceReferences(
+ SvcLogicNodeExecutor.class.getName(), null);
+ for (int i = 0; srl != null && i < srl.length; i++) {
+ listener.serviceChanged(new ServiceEvent(
+ ServiceEvent.REGISTERED, srl[i]));
+ }
+ } catch (InvalidSyntaxException e) {
+ e.printStackTrace();
+ }
+ LOG.info("Done registerExecutors");
+ }
+
+ public void registerExecutor(ServiceReference sr) {
+
+ String nodeName = (String) sr.getProperty("nodeType");
+ if (nodeName != null) {
+
+ SvcLogicNodeExecutor executor = null;
+
+ try {
+ executor = (SvcLogicNodeExecutor) bctx.getService(sr);
+ } catch (Exception e) {
+ LOG.error("Cannot get service executor for " + nodeName);
+ return;
+ }
+
+ registerExecutor(nodeName, executor);
+
+ }
+ }
+
+ public void registerExecutor(String nodeName, SvcLogicNodeExecutor executor)
+ {
+ if (nodeExecutors == null) {
+ nodeExecutors = new HashMap<String, SvcLogicNodeExecutor>();
+ }
+ LOG.info("SLI - registering executor for node type "+nodeName);
+ nodeExecutors.put(nodeName, executor);
+ }
+
+ public void unregisterExecutor(ServiceReference sr) {
+ String nodeName = (String) sr.getProperty("nodeType");
+
+ if (nodeName != null) {
+
+ unregisterExecutor(nodeName);
+
+ }
+
+ }
+
+ public void unregisterExecutor(String nodeName)
+ {
+
+ LOG.info("SLI - unregistering executor for node type "+nodeName);
+ nodeExecutors.remove(nodeName);
+ }
+
+
+
+
+ public SvcLogicContext execute(SvcLogicGraph graph, SvcLogicContext ctx)
+ throws SvcLogicException {
+
+ if (nodeExecutors == null) {
+ registerExecutors();
+ }
+
+ // Set service name in MDC to reference current working directed graph
+ MDC.put(MetricLogger.SERVICE_NAME, graph.getModule()+":"+graph.getRpc()+"/v"+graph.getVersion());
+
+ SvcLogicNode curNode = graph.getRootNode();
+ LOG.info("About to execute graph " + graph.toString());
+
+
+
+ while (curNode != null) {
+ LOG.info("About to execute node # "+curNode.getNodeId()+" ("+curNode.getNodeType()+")");
+
+ SvcLogicNode nextNode = executeNode(curNode, ctx);
+ curNode = nextNode;
+ }
+
+ return (ctx);
+ }
+
+
+ public SvcLogicNode executeNode(SvcLogicNode node, SvcLogicContext ctx)
+ throws SvcLogicException {
+ if (node == null) {
+ return (null);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Executing node " + node.getNodeId());
+ }
+
+ SvcLogicNodeExecutor executor = nodeExecutors.get(node.getNodeType());
+
+ if (executor != null) {
+ LOG.debug("Executing node executor for node type "+node.getNodeType()+" - "+executor.getClass().getName());
+ return (executor.execute(this, node, ctx));
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(node.getNodeType() + " node not implemented");
+ }
+ SvcLogicNode nextNode = node.getOutcomeValue("failure");
+ if (nextNode != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("about to execute failure 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 failure or Other branch found");
+ }
+ }
+ return (nextNode);
+ }
+
+ }
+
+ @Override
+ public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException
+ {
+ SvcLogicStore store = SvcLogicActivator.getStore();
+
+ return (store.hasGraph(module, rpc, version, mode));
+ }
+
+ @Override
+ public Properties execute(String module, String rpc, String version, String mode, Properties props)
+ throws SvcLogicException {
+ return(execute(module, rpc, version, mode, props, null));
+ }
+
+
+ @Override
+ public Properties execute(String module, String rpc, String version, String mode,
+ Properties props, DOMDataBroker domDataBroker) throws SvcLogicException {
+
+
+ // See if there is a service logic defined
+ //
+ SvcLogicStore store = SvcLogicActivator.getStore();
+
+ LOG.info("Fetching service logic from data store");
+ SvcLogicGraph graph = store.fetch(module, rpc, version, mode);
+
+
+
+ if (graph == null)
+ {
+ Properties retProps = new Properties();
+ retProps.setProperty("error-code", "401");
+ retProps.setProperty("error-message", "No service logic found for ["+module+","+rpc+","+version+","+mode+"]");
+ return(retProps);
+
+ }
+
+ SvcLogicContext ctx = new SvcLogicContext(props);
+ ctx.setAttribute("currentGraph", graph.toString());
+ ctx.setAttribute("X-ECOMP-RequestID", MDC.get("X-ECOMP-RequestID"));
+ ctx.setDomDataBroker(domDataBroker);
+
+ execute(graph, ctx);
+
+ return(ctx.toProperties());
+ }
+
+
+
+
+}
diff --git a/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java
new file mode 100644
index 00000000..e8ae7c89
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java
@@ -0,0 +1,63 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SwitchNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SwitchNodeExecutor.class);
+
+ @Override
+
+ public SvcLogicNode execute(SvcLogicServiceImpl 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java
new file mode 100644
index 00000000..9eeab65a
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java
@@ -0,0 +1,136 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UpdateNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(UpdateNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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 = new HashMap<String, String>();
+
+ Set<Map.Entry<String, SvcLogicExpression>> parmSet = node
+ .getParameterSet();
+ boolean hasParms = false;
+
+ for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parmSet
+ .iterator(); iter.hasNext();) {
+ hasParms = true;
+ Map.Entry<String, SvcLogicExpression> curEnt = iter.next();
+ String curName = curEnt.getKey();
+ SvcLogicExpression curExpr = curEnt.getValue();
+ if (curExpr != null) {
+ String curExprValue = SvcLogicExpressionResolver.evaluate(
+ curExpr, node, ctx);
+
+ LOG.debug("Parameter " + curName + " = "
+ + curExpr.asParsedExpr() + " resolves to "
+ + curExprValue);
+
+ parmMap.put(curName, curExprValue);
+ }
+ }
+
+ 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.update(resourceType, key,
+ parmMap, pfx, ctx)) {
+ case SUCCESS:
+ outValue = "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);
+ }
+
+ 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/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/WhileNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/WhileNodeExecutor.java
new file mode 100644
index 00000000..5bbab323
--- /dev/null
+++ b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/WhileNodeExecutor.java
@@ -0,0 +1,75 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.sli.BreakNodeException;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WhileNodeExecutor extends SvcLogicNodeExecutor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WhileNodeExecutor.class);
+
+ @Override
+ public SvcLogicNode execute(SvcLogicServiceImpl 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");
+ }
+ return (null);
+ }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java
new file mode 100644
index 00000000..d1ab4cfd
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/BadPlugin.java
@@ -0,0 +1,56 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.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/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java
new file mode 100644
index 00000000..3d43ee11
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutorTest.java
@@ -0,0 +1,57 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.Map.Entry;
+
+import org.openecomp.sdnc.sli.DuplicateValueException;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.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");
+ execute.execute(new SvcLogicServiceImpl(), new SvcLogicNode(0, "", "", new SvcLogicGraph()), new SvcLogicContext());
+ }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java
new file mode 100644
index 00000000..b9156bcd
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/LunchSelectorPlugin.java
@@ -0,0 +1,78 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.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/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java
new file mode 100644
index 00000000..a4e41bba
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTest.java
@@ -0,0 +1,43 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import junit.framework.TestCase;
+
+public class MdsalHelperTest extends TestCase {
+
+ 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",
+ "ServiceConfigurationOperation"));
+ }
+
+ public void testNegativeSdnProperties() {
+ assertNotSame("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "Synccomplete"));
+ }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java
new file mode 100644
index 00000000..01e333f6
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/MdsalHelperTesterUtil.java
@@ -0,0 +1,37 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import org.openecomp.sdnc.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/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java
new file mode 100644
index 00000000..035cd3e7
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/PluginTest.java
@@ -0,0 +1,106 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+
+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 VoidDummyPlugin();
+
+ 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("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("success",outValue);
+ }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolverTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolverTest.java
new file mode 100644
index 00000000..61815488
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolverTest.java
@@ -0,0 +1,123 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicExprListener;
+import org.openecomp.sdnc.sli.SvcLogicExpression;
+import org.openecomp.sdnc.sli.SvcLogicExpressionFactory;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.provider.SvcLogicExpressionResolver;
+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");
+ }
+ }
+
+}
diff --git a/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicGraphExecutorTest.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicGraphExecutorTest.java
new file mode 100644
index 00000000..2e8b35e1
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicGraphExecutorTest.java
@@ -0,0 +1,212 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+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.openecomp.sdnc.sli.MetricLogger;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicParser;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.openecomp.sdnc.sli.SvcLogicStoreFactory;
+import org.openecomp.sdnc.sli.provider.BlockNodeExecutor;
+import org.openecomp.sdnc.sli.provider.CallNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ConfigureNodeExecutor;
+import org.openecomp.sdnc.sli.provider.DeleteNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ExecuteNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ExistsNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ForNodeExecutor;
+import org.openecomp.sdnc.sli.provider.GetResourceNodeExecutor;
+import org.openecomp.sdnc.sli.provider.IsAvailableNodeExecutor;
+import org.openecomp.sdnc.sli.provider.NotifyNodeExecutor;
+import org.openecomp.sdnc.sli.provider.RecordNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ReleaseNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ReserveNodeExecutor;
+import org.openecomp.sdnc.sli.provider.ReturnNodeExecutor;
+import org.openecomp.sdnc.sli.provider.SaveNodeExecutor;
+import org.openecomp.sdnc.sli.provider.SetNodeExecutor;
+import org.openecomp.sdnc.sli.provider.SvcLogicNodeExecutor;
+import org.openecomp.sdnc.sli.provider.SvcLogicServiceImpl;
+import org.openecomp.sdnc.sli.provider.SwitchNodeExecutor;
+import org.openecomp.sdnc.sli.provider.UpdateNodeExecutor;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import junit.framework.TestCase;
+
+public class SvcLogicGraphExecutorTest extends TestCase {
+ private static final Logger LOG = LoggerFactory
+ .getLogger(SvcLogicGraph.class);
+
+ private static final Map<String, SvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, SvcLogicNodeExecutor>() {
+ {
+ 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());
+
+ }
+ };
+
+ public void testExecute() {
+
+ try {
+ InputStream testStr = getClass().getResourceAsStream("/executor.tests");
+ BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr));
+
+ InputStream propStr = getClass().getResourceAsStream("/svclogic.properties");
+
+ SvcLogicStore store = SvcLogicStoreFactory.getSvcLogicStore(propStr);
+
+ assertNotNull(store);
+
+ store.registerNodeType("switch");
+ store.registerNodeType("block");
+ store.registerNodeType("get-resource");
+ store.registerNodeType("reserve");
+ store.registerNodeType("is-available");
+ store.registerNodeType("exists");
+ store.registerNodeType("configure");
+ store.registerNodeType("return");
+ store.registerNodeType("record");
+ store.registerNodeType("allocate");
+ store.registerNodeType("release");
+ store.registerNodeType("for");
+ store.registerNodeType("set");
+ SvcLogicParser parser = new SvcLogicParser(store);
+
+ // Loop through executor tests
+
+ SvcLogicServiceImpl svc = new SvcLogicServiceImpl();
+
+ for (String nodeType : BUILTIN_NODES.keySet()) {
+
+ LOG.info("SLI - registering node executor for node type "+nodeType);
+
+ 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);
+
+ 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/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java
new file mode 100644
index 00000000..6c8214ab
--- /dev/null
+++ b/sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/VoidDummyPlugin.java
@@ -0,0 +1,38 @@
+/*-
+ * ============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.openecomp.sdnc.sli.provider;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+
+
+
+public class VoidDummyPlugin implements SvcLogicJavaPlugin {
+
+ public void dummy(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ return;
+ }
+
+}
diff --git a/sli/provider/src/test/resources/executor.tests b/sli/provider/src/test/resources/executor.tests
new file mode 100755
index 00000000..e7547e63
--- /dev/null
+++ b/sli/provider/src/test/resources/executor.tests
@@ -0,0 +1,2 @@
+l3sdn_logic_v10.xml:switchTester:test-value=""
+l3sdn_logic_v10.xml:switchTester:test-value="hi" \ No newline at end of file
diff --git a/sli/provider/src/test/resources/expression.tests b/sli/provider/src/test/resources/expression.tests
new file mode 100755
index 00000000..848a0e7a
--- /dev/null
+++ b/sli/provider/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/sli/provider/src/test/resources/l3sdn_logic_v10.xml b/sli/provider/src/test/resources/l3sdn_logic_v10.xml
new file mode 100644
index 00000000..d81b8b78
--- /dev/null
+++ b/sli/provider/src/test/resources/l3sdn_logic_v10.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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.openecomp.org/sdnc/svclogic"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.openecomp.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="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/sli/provider/src/test/resources/simplelogger.properties b/sli/provider/src/test/resources/simplelogger.properties
new file mode 100644
index 00000000..3581395a
--- /dev/null
+++ b/sli/provider/src/test/resources/simplelogger.properties
@@ -0,0 +1,22 @@
+###
+# ============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=========================================================
+###
+
+org.slf4j.simpleLogger.defaultLogLevel=info
diff --git a/sli/provider/src/test/resources/svclogic.properties b/sli/provider/src/test/resources/svclogic.properties
new file mode 100644
index 00000000..fa33146e
--- /dev/null
+++ b/sli/provider/src/test/resources/svclogic.properties
@@ -0,0 +1,26 @@
+###
+# ============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=========================================================
+###
+
+org.openecomp.sdnc.sli.dbtype = jdbc
+org.openecomp.sdnc.sli.jdbc.url = jdbc:mysql://localhost:3306/sdnctl
+org.openecomp.sdnc.sli.jdbc.database = sdnctl
+org.openecomp.sdnc.sli.jdbc.user = sdnctl
+org.openecomp.sdnc.sli.jdbc.password = gamma
diff --git a/sli/recording/pom.xml b/sli/recording/pom.xml
new file mode 100755
index 00000000..4fb4a797
--- /dev/null
+++ b/sli/recording/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<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.openecomp.sdnc.core</groupId>
+ <artifactId>sli</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sli-recording</artifactId>
+ <packaging>bundle</packaging>
+ <name>SLI - Recording</name>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ <scope>compile</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>org.openecomp.sdnc.sli.recording.RecordingActivator</Bundle-Activator>
+ <Export-Package>org.openecomp.sdnc.sli.recording;version=${project.version}</Export-Package>
+ <Import-Package>*</Import-Package>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+
+
+ </configuration>
+
+ </plugin>
+
+
+ </plugins>
+ </build>
+ <description>SLI Recording is an OSGi bundle that implements recording service for the service logic record node.</description>
+</project>
diff --git a/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/FileRecorder.java b/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/FileRecorder.java
new file mode 100644
index 00000000..dc857b25
--- /dev/null
+++ b/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/FileRecorder.java
@@ -0,0 +1,117 @@
+/*-
+ * ============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.openecomp.sdnc.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.openecomp.sdnc.sli.ConfigurationException;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.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");
+ }
+
+ 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);
+ PrintWriter recPrinter = null;
+ 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
+ {
+
+ recPrinter = new PrintWriter(new FileWriter(recordFile, true));
+ recPrinter.println(record);
+ }
+ catch (Exception e)
+ {
+ throw new SvcLogicException("Cannot write record to file", e);
+ }
+ finally
+ {
+ if (recPrinter != null)
+ {
+ recPrinter.close();
+ }
+ }
+
+
+ }
+
+}
+
diff --git a/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/RecordingActivator.java b/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/RecordingActivator.java
new file mode 100644
index 00000000..d6e016af
--- /dev/null
+++ b/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/RecordingActivator.java
@@ -0,0 +1,75 @@
+/*-
+ * ============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.openecomp.sdnc.sli.recording;
+
+import java.util.LinkedList;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class RecordingActivator implements BundleActivator {
+
+ private LinkedList<ServiceRegistration> registrations = new LinkedList<ServiceRegistration>();
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(RecordingActivator.class);
+
+ @Override
+ public void start(BundleContext ctx) throws Exception {
+
+ if (registrations == null)
+ {
+ registrations = new LinkedList<ServiceRegistration>();
+ }
+
+
+ FileRecorder fileRecorder = new FileRecorder();
+ String regName = fileRecorder.getClass().getName();
+ LOG.debug("Registering FileRecorder service "+regName);
+ ServiceRegistration reg =ctx.registerService(regName, fileRecorder, null);
+ registrations.add(reg);
+
+ Slf4jRecorder slf4jRecorder = new Slf4jRecorder();
+ regName = slf4jRecorder.getClass().getName();
+ LOG.debug("Registering Slf4jRecorder service "+regName);
+ reg =ctx.registerService(regName, slf4jRecorder, null);
+ registrations.add(reg);
+
+ }
+
+ @Override
+ public void stop(BundleContext arg0) throws Exception {
+ if (registrations != null) {
+ for (ServiceRegistration reg : registrations) {
+ ServiceReference regRef = reg.getReference();
+ reg.unregister();
+ }
+ registrations = null;
+ }
+ }
+
+}
diff --git a/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/Slf4jRecorder.java b/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/Slf4jRecorder.java
new file mode 100644
index 00000000..5aad6f25
--- /dev/null
+++ b/sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/Slf4jRecorder.java
@@ -0,0 +1,130 @@
+/*-
+ * ============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.openecomp.sdnc.sli.recording;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.openecomp.sdnc.sli.ConfigurationException;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicRecorder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Slf4jRecorder implements SvcLogicRecorder {
+
+
+ public enum Level {
+ ERROR,
+ WARN,
+ INFO,
+ DEBUG,
+ TRACE
+ }
+
+ @Override
+ public void record(Map<String, String> parmMap) throws SvcLogicException {
+ String loggerName = parmMap.get("logger");
+ if (loggerName == null) {
+ loggerName = "Log4jRecorder";
+ }
+
+ 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");
+ }
+
+ Logger logger = LoggerFactory.getLogger(loggerName);
+
+ 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));
+ }
+
+ switch (level) {
+ case ERROR:
+ 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/sli/recording/src/main/resources/svclogic.properties b/sli/recording/src/main/resources/svclogic.properties
new file mode 100644
index 00000000..0cf3b419
--- /dev/null
+++ b/sli/recording/src/main/resources/svclogic.properties
@@ -0,0 +1,26 @@
+###
+# ============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=========================================================
+###
+
+org.openecomp.sdnc.sli.dbtype = jdbc
+org.openecomp.sdnc.sli.jdbc.url = jdbc:mysql://dbhost:3306/sdnctl
+org.openecomp.sdnc.sli.jdbc.database = sdnctl
+org.openecomp.sdnc.sli.jdbc.user = sdnctl
+org.openecomp.sdnc.sli.jdbc.password = gamma
diff --git a/sliPluginUtils/.gitignore b/sliPluginUtils/.gitignore
new file mode 100755
index 00000000..b73caf31
--- /dev/null
+++ b/sliPluginUtils/.gitignore
@@ -0,0 +1,34 @@
+#####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
+
+## Folders which contain auto generated source code ##
+yang-gen-config
+yang-gen-sal
diff --git a/sliPluginUtils/.sonar/checkstyle.xml b/sliPluginUtils/.sonar/checkstyle.xml
new file mode 100755
index 00000000..3fa23153
--- /dev/null
+++ b/sliPluginUtils/.sonar/checkstyle.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"><!-- Generated by Sonar --><module name="Checker"><module name="SuppressionCommentFilter"/><module name="TreeWalker"><module name="FileContentsHolder"/> <module name="ClassFanOutComplexity"><property name="severity" value="warning"/></module><module name="NestedForDepth"><property name="severity" value="warning"/><property name="max" value="1"/></module><module name="ClassDataAbstractionCoupling"><property name="severity" value="warning"/></module></module></module> \ No newline at end of file
diff --git a/sliPluginUtils/.sonar/pmd.xml b/sliPluginUtils/.sonar/pmd.xml
new file mode 100755
index 00000000..80343b3b
--- /dev/null
+++ b/sliPluginUtils/.sonar/pmd.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleset>
+ <rule ref="rulesets/java/naming.xml/BooleanGetMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/j2ee.xml/StaticEJBFieldShouldBeFinal">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/codesize.xml/TooManyMethods">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/DoubleCheckedLocking">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/ExcessiveImports">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode">
+ <priority>2</priority>
+ </rule>
+ <rule ref="rulesets/java/naming.xml/ShortMethodName">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/basic.xml/BooleanInstantiation">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/codesize.xml/TooManyFields">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/coupling.xml/LooseCoupling">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/design.xml/NonThreadSafeSingleton">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/j2ee.xml/DoNotUseThreads">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly">
+ <priority>5</priority>
+ </rule>
+ <rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray">
+ <priority>2</priority>
+ </rule>
+ <rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic">
+ <priority>3</priority>
+ </rule>
+ <rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException">
+ <priority>3</priority>
+ </rule>
+</ruleset>
+
diff --git a/sliPluginUtils/features/pom.xml b/sliPluginUtils/features/pom.xml
new file mode 100755
index 00000000..9d189177
--- /dev/null
+++ b/sliPluginUtils/features/pom.xml
@@ -0,0 +1,127 @@
+<?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">
+
+ <artifactId>sliPluginUtils-features</artifactId>
+ <packaging>jar</packaging>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>sliPluginUtils</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <name>SliPluginUtils Plugin - Features</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliPluginUtils-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${odl.mdsal.features.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ <!-- dependency for opendaylight-karaf-empty for use by testing -->
+ <dependency>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>opendaylight-karaf-empty</artifactId>
+ <version>${odl.karaf.empty.distro.version}</version>
+ <type>zip</type>
+ </dependency>
+ <dependency>
+ <!-- Required for launching the feature tests -->
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-test</artifactId>
+ <version>${odl.commons.opendaylight.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${odl.yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- launches the feature test, which validates that your karaf feature
+ can be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent bundles
+ defined correctly.
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.odlparent</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ -->
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sliPluginUtils/features/src/main/resources/features.xml b/sliPluginUtils/features/src/main/resources/features.xml
new file mode 100644
index 00000000..c7dca2e5
--- /dev/null
+++ b/sliPluginUtils/features/src/main/resources/features.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+ -->
+
+
+<features name="sdnc-sliPluginUtils-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository>
+
+
+ <feature name='sdnc-sliPluginUtils' description="sdnc-sliPluginUtils" version='${project.version}'>
+ <!-- Most applications will have a dependency on the ODL MD-SAL Broker -->
+ <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+ <feature>sdnc-sli</feature>
+ <bundle>mvn:org.openecomp.sdnc.core/sliPluginUtils-provider/${project.version}</bundle>
+ <bundle>mvn:mysql/mysql-connector-java/${mysql.connector.version}</bundle>
+ </feature>
+
+</features>
diff --git a/sliPluginUtils/installer/pom.xml b/sliPluginUtils/installer/pom.xml
new file mode 100755
index 00000000..6520867b
--- /dev/null
+++ b/sliPluginUtils/installer/pom.xml
@@ -0,0 +1,138 @@
+<?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>
+ <artifactId>sliPluginUtils</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sliPluginUtils-installer</artifactId>
+ <name>SLI Plugin Utilities - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>sdnc-sliPluginUtils</application.name>
+ <features.boot>sdnc-sliPluginUtils</features.boot>
+ <features.repositories>mvn:org.openecomp.sdnc.core/sliPluginUtils-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliPluginUtils-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliPluginUtils-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>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</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.openecomp.sdnc</includeGroupIds>
+ <excludeArtifactIds>sli-common,sli-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/sliPluginUtils/installer/src/assembly/assemble_installer_zip.xml b/sliPluginUtils/installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 00000000..85e2e1e8
--- /dev/null
+++ b/sliPluginUtils/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,59 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/sliPluginUtils/installer/src/assembly/assemble_mvnrepo_zip.xml b/sliPluginUtils/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 00000000..bf7805f7
--- /dev/null
+++ b/sliPluginUtils/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,49 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/sliPluginUtils/installer/src/main/resources/scripts/install-feature.sh b/sliPluginUtils/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 00000000..93236c5b
--- /dev/null
+++ b/sliPluginUtils/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+###
+# ============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=========================================================
+###
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+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} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/sliPluginUtils/pom.xml b/sliPluginUtils/pom.xml
new file mode 100755
index 00000000..a14b41ff
--- /dev/null
+++ b/sliPluginUtils/pom.xml
@@ -0,0 +1,41 @@
+<?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/maven-v4_0_0.xsd">
+
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliPluginUtils</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <modelVersion>4.0.0</modelVersion>
+
+
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <name>Service Logic Interface Plugin Utilities</name>
+ <description>A package of static utility functions to be used when developing SLI plugins</description>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>SliPluginUtils-features</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>SliPluginUtils-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <modules>
+ <module>provider</module>
+ <module>features</module>
+ <module>installer</module>
+ </modules>
+</project>
diff --git a/sliPluginUtils/provider/pom.xml b/sliPluginUtils/provider/pom.xml
new file mode 100755
index 00000000..cad7a0bc
--- /dev/null
+++ b/sliPluginUtils/provider/pom.xml
@@ -0,0 +1,85 @@
+<?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">
+
+ <artifactId>sliPluginUtils-provider</artifactId>
+ <packaging>bundle</packaging>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliPluginUtils</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <name>SliPluginUtils Plugin - Provider</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>equinoxSDK381</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>${equinox.osgi.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-library</artifactId>
+ <version>1.3</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.openecomp.sdnc.sli.SliPluginUtils</Bundle-SymbolicName>
+ <Bundle-Activator>org.openecomp.sdnc.sli.SliPluginUtils.SliPluginUtilsActivator</Bundle-Activator>
+ <Export-Package>org.openecomp.sdnc.sli.SliPluginUtils</Export-Package>
+ <Import-Package>org.openecomp.sdnc.*,org.osgi.framework.*,org.slf4j.*,java.net.*</Import-Package>
+ <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|mysql-connector-java|slf4j-api|jcl-over-slf4j</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+</project>
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java
new file mode 100644
index 00000000..39612716
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/DME2.java
@@ -0,0 +1,111 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.util.Map;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * A SvcLogicJavaPlugin that generates DME2 proxy urls using parameters from context memory.
+ */
+public class DME2 implements SvcLogicJavaPlugin {
+ String aafUserName;
+ String aafPassword;
+ String envContext;
+ String routeOffer;
+ String[] proxyUrls;
+ Integer index;
+ String commonServiceVersion;
+ String partner;
+
+ private static final Logger LOG = LoggerFactory.getLogger(DME2.class);
+
+ public void setPartner(String partner) {
+ if (partner != null && partner.length() > 0) {
+ this.partner = partner;
+ }
+ }
+
+ public DME2(String aafUserName, String aafPassword, String envContext, String routeOffer, String[] proxyUrls, String commonServiceVersion) {
+ this.aafUserName = aafUserName;
+ this.aafPassword = aafPassword;
+ this.envContext = envContext;
+ this.routeOffer = routeOffer;
+ this.proxyUrls = proxyUrls;
+ this.index = 0;
+ this.commonServiceVersion = commonServiceVersion;
+ }
+
+ // constructs a URL to contact the proxy which contacts a DME2 service
+ public String constructUrl(String service, String version, String subContext) {
+ StringBuilder sb = new StringBuilder();
+
+ // The hostname is assigned in a round robin fashion
+ sb.append(acquireHostName());
+ sb.append("/service=" + service);
+
+ //If the directedGraph passes an explicit version use that, if not use the commonServiceVersion found in the properties file
+ if (version == null) {
+ version = this.commonServiceVersion;
+ }
+ sb.append("/version=" + version);
+
+ sb.append("/envContext=" + this.envContext);
+ if (this.routeOffer != null && this.routeOffer.length() > 0) {
+ sb.append("/routeOffer=" + this.routeOffer);
+ }
+ if (subContext != null && subContext.length() > 0) {
+ sb.append("/subContext=" + subContext);
+ }
+ sb.append("?dme2.password=" + this.aafPassword);
+ sb.append("&dme2.username=" + this.aafUserName);
+ if (this.partner != null) {
+ sb.append("&dme2.partner=" + this.partner);
+ }
+ sb.append("&dme2.allowhttpcode=true");
+ return (sb.toString());
+ }
+
+ public synchronized String acquireHostName() {
+ String retVal = proxyUrls[index];
+ index++;
+ if (index == this.proxyUrls.length) {
+ index = 0;
+ }
+ return retVal;
+ }
+
+ // Node entry point
+ public void constructUrl(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[] { "service", "outputPath" }, LOG);
+ String completeProxyUrl = constructUrl(parameters.get("service"), parameters.get("version"), parameters.get("subContext"));
+ ctx.setAttribute(parameters.get("outputPath"), completeProxyUrl);
+ }
+
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java
new file mode 100644
index 00000000..c73315f4
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java
@@ -0,0 +1,754 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A utility class used to streamline the interface between Java plugins,
+ * the Service Logic Context, and Directed Graphs.
+ * @version 7.0.1
+ * @see org.openecomp.sdnc.sli.SvcLogicContext
+ */
+public class SliPluginUtils implements SvcLogicJavaPlugin {
+ public enum LogLevel {
+ TRACE, DEBUG, INFO, WARN, ERROR;
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils.class);
+
+
+ // ========== CONSTRUCTORS ==========
+
+ public SliPluginUtils() {}
+
+ public SliPluginUtils( Properties props ) {}
+
+
+
+ // ========== CONTEXT MEMORY FUNCTIONS ==========
+
+ /**
+ * Removes 1 or more elements from a list in context memory.
+ * <p>
+ * Values are removed based on either the index in the list, a key-value
+ * pair, or a list of key-value pairs that all must match in the element.
+ * @param parameters
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException All exceptions are wrapped in
+ * SvcLogicException for compatibility with SLI.
+ * @since 7.0.1
+ */
+ public void ctxListRemove( Map<String,String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ try{
+ LOG.debug( "ENTERING Execute Node \"ctxListRemove\"" );
+
+ // Validate, Log, & read parameters
+ checkParameters(parameters, new String[]{"list_pfx"}, LOG);
+ logExecuteNodeParameters(parameters, LOG, LogLevel.DEBUG);
+ String list_pfx = parameters.get("list_pfx");
+ String param_index = parameters.get("index");
+ String param_key = parameters.get("key");
+ String param_value = parameters.get("value");
+ String param_keys_length = parameters.get("keys_length");
+
+ // Initialize context memory list mimic
+ SvcLogicContextList list;
+
+ // Process based on input parameters:
+ // index: remove object at specific index
+ // key & value: remove all objects with key-value pair
+ // keys_length: remove all objects that match all key-value pairs
+ // in list
+ if( param_index != null ) {
+ // Parse index
+ LOG.trace("executing remove by index logic");
+ int index;
+ try {
+ index = Integer.parseInt(param_index);
+ }
+ catch( NumberFormatException e ) {
+ throw new IllegalArgumentException("\"index\" parameter is not a number. index = " + param_index, e);
+ }
+
+ // Extract list from context memory & remove object @ index
+ LOG.trace("extracting list from context memory");
+ list = SvcLogicContextList.extract(ctx, list_pfx);
+ LOG.trace("removing elements from list");
+ list.remove(index);
+ }
+ else if( param_value != null ) {
+ if( param_key == null ) { param_key = ""; }
+
+ // Extract list from context memory & remove objects with
+ // key-value pair
+ LOG.trace("executing remove by key-value pair logic");
+ LOG.trace("extracting list from context memory");
+ list = SvcLogicContextList.extract(ctx, list_pfx);
+ LOG.trace("removing elements from list");
+ list.remove( param_key, param_value );
+ }
+ else if( param_keys_length != null ) {
+ // Parse keys_length
+ LOG.trace("executing remove by key-value pair list logic");
+ int keys_length;
+ try {
+ keys_length = Integer.parseInt(param_keys_length);
+ }
+ catch( NumberFormatException e ) {
+ throw new IllegalArgumentException("\"keys_length\" parameters is not a number. keys_length = " + param_keys_length, e);
+ }
+
+ // Obtain key-value pairs to check from parameters
+ LOG.trace("reading keys parameter list");
+ HashMap<String,String> keys_values = new HashMap<String,String>();
+ for( int i = 0; i < keys_length; i++ ) {
+ keys_values.put(parameters.get("keys[" + i + "].key"), parameters.get("keys[" + i + "].value"));
+ }
+
+ // Extract list from context memory & remove objects with all
+ // key-value pairs matching
+ LOG.trace("extracting list from context memory");
+ list = SvcLogicContextList.extract(ctx, list_pfx);
+ LOG.trace("removing elements from list");
+ list.remove(keys_values);
+ }
+ else {
+ throw new IllegalArgumentException("Required parameters missing. Requires one of: index, key & value, or keys_length array");
+ }
+
+ // Remove index from list
+ LOG.trace("writing list back into context memory");
+ list.writeToContext(ctx);
+ }
+ catch( Exception e ) {
+ throw new SvcLogicException( "An error occurred in the ctxListRemove Execute node", e );
+ }
+ finally {
+ LOG.debug( "EXITING Execute Node \"ctxListRemove\"" );
+ }
+ }
+
+ /**
+ * ctxSortList
+ * @param parameters - the set of required parameters must contain list and delimiter.
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException if a required parameter is missing an exception is thrown
+ */
+ public void ctxSortList( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ checkParameters(parameters, new String[]{"list","delimiter"}, LOG);
+ ArrayList<SortableCtxListElement> list = new ArrayList<SortableCtxListElement>();
+
+ String[] sort_fields = null;
+ if( parameters.containsKey("sort-fields") ) {
+ sort_fields = parameters.get("sort-fields").split(parameters.get("delimiter"), 0);
+ }
+
+ String ctx_list_str = parameters.get("list");
+ int listSz = getArrayLength(ctx, ctx_list_str);
+
+
+
+ for( int i = 0; i < listSz; i++ ) {
+ list.add( new SortableCtxListElement(ctx, ctx_list_str + '[' + i + ']', sort_fields) );
+ }
+ Collections.sort(list);
+
+ ctxBulkErase(ctx, ctx_list_str);
+ int i = 0;
+ for( SortableCtxListElement list_element : list ) {
+ for( Map.Entry<String,String> entry : list_element.child_elements.entrySet() ) {
+ if( sort_fields == null ) {
+ ctx.setAttribute(ctx_list_str + '[' + i + ']', entry.getValue());
+ }
+ else {
+ ctx.setAttribute(ctx_list_str + '[' + i + "]." + entry.getKey(), entry.getValue());
+ }
+ }
+ i++;
+ }
+ // Reset list length (removed by ctxBulkErase above)
+ ctx.setAttribute(ctx_list_str+"_length", ""+listSz);
+ }
+
+ /**
+ * generates a UUID and writes it to context memory
+ * @param parameters - ctx-destination is a required parameter
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException thrown if a UUID cannot be generated or if ctx-destination is missing or null
+ */
+ public void generateUUID( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ checkParameters(parameters, new String[]{"ctx-destination"}, LOG);
+ ctx.setAttribute(parameters.get("ctx-destination"), UUID.randomUUID().toString() );
+ }
+
+ /**
+ * Provides substring functionality to Directed Graphs.
+ * <p>
+ * Calls either String.substring(String beginIndex) or
+ * String.substring(String beginInded, String endIndex) if the end-index
+ * is present or not.
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>string</td><td>Mandatory</td><td>String to perform substring on</td></tr>
+ * <tr><td>result</td><td>Mandatory</td><td>Key in context memory to populate the resulting string in</td></tr>
+ * <tr><td>begin-index</td><td>Mandatory</td><td>Beginning index to pass to Java substring function</td></tr>
+ * <tr><td>end-index</td><td>Optional</td><td>Ending index to pass to Java substring function. If not included, String.substring(begin) will be called.</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 8.0.1
+ * @see SliPluginUtils#substring(Map, SvcLogicContext)
+ */
+ @Deprecated
+ public void substring( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ try {
+ checkParameters( parameters, new String[]{"string","begin-index","result"}, LOG );
+ final String string = parameters.get("string");
+ final String result = parameters.get("result");
+ final String begin = parameters.get("begin-index");
+ final String end = parameters.get("end-index");
+
+ if( StringUtils.isEmpty(end) ) {
+ ctx.setAttribute( result, string.substring(Integer.parseInt(begin)) );
+ }
+ else {
+ ctx.setAttribute( result, string.substring(Integer.parseInt(begin), Integer.parseInt(end)) );
+ }
+ }
+ catch( Exception e ) {
+ throw new SvcLogicException( "An error occurred while the Directed Graph was performing a substring", e );
+ }
+ }
+
+
+
+ // ========== PUBLIC STATIC UTILITY FUNCTIONS ==========
+
+ /**
+ * Throws an exception and writes an error to the log file if a required
+ * parameters is not found in the parametersMap.
+ * <p>
+ * Use at the beginning of functions that can be called by Directed Graphs
+ * and can take parameters to verify that all parameters have been provided
+ * by the Directed Graph.
+ * @param parametersMap parameters Map passed to this node
+ * @param requiredParams Array of parameters required by the calling function
+ * @param log Reference to Logger to log to
+ * @throws SvcLogicException if a String in the requiredParams array is
+ * not a key in parametersMap.
+ * @since 1.0
+ */
+ public static final void checkParameters(Map<String, String> parametersMap, String[] requiredParams, Logger log) throws SvcLogicException {
+ if( requiredParams == null || requiredParams.length < 1){
+ log.debug("required parameters was empty, exiting early.");
+ return;
+ }
+ if (parametersMap == null || parametersMap.keySet().size() < 1){
+ String errorMessage = "This method requires the parameters [" + StringUtils.join(requiredParams,",") + "], but no parameters were passed in.";
+ log.error(errorMessage);
+ throw new SvcLogicException(errorMessage);
+ }
+
+ for (String param : requiredParams) {
+ if (!parametersMap.containsKey(param)) {
+ String errorMessage = "Required parameter \"" + param + "\" was not found in parameter list.";
+ log.error(errorMessage);
+ log.error("Total list of required parameters is [" + StringUtils.join(requiredParams, ",") + "].");
+ throw new SvcLogicException(errorMessage);
+ }
+ }
+ }
+
+ /**
+ * Removes all key-value pairs with keys that begin with pfx
+ * @param ctx Reference to context memory
+ * @param pfx Prefix of key-value pairs to remove
+ * @since 1.0
+ */
+ public static final void ctxBulkErase( SvcLogicContext ctx, String pfx ) {
+ ArrayList<String> Keys = new ArrayList<String>( ctx.getAttributeKeySet() );
+ for( String key : Keys ) {
+ if( key.startsWith( pfx ) ) {
+ ctx.setAttribute( pfx + key.substring(pfx.length()) , null);
+ }
+ }
+ }
+
+ /**
+ * Copies all context memory key-value pairs that start with src_pfx to
+ * the keys that start with dest_pfx + suffix, where suffix is the result
+ * of {@code key.substring(src_pfx.length())}.
+ * <p>
+ * Does NOT guarantee removal of all keys at the destination before
+ * copying, but will overwrite any destination keys that have a
+ * corresponding source key. Use {@link #ctxBulkErase(SvcLogicContext, String) ctxBulkErase}
+ * before copy to erase destination root before copying from source.
+ * @param ctx Reference to context memory.
+ * @param src_pfx Prefix of the keys to copy values from.
+ * @param dest_pfx Prefix of the keys to copy values to.
+ * @since 1.0
+ */
+ public static final void ctxBulkCopy( SvcLogicContext ctx, String src_pfx, String dest_pfx ) {
+ // Remove trailing period from dest_pfx
+ if( dest_pfx.charAt(dest_pfx.length()-1) == '.' ) {
+ dest_pfx = dest_pfx.substring(0,dest_pfx.length()-1);
+ }
+
+ // For each context key that begins with src_pfx, set the value of the
+ // key dest_pfx + the suffix of the key to the key's value
+ ArrayList<String> Keys = new ArrayList<String>(ctx.getAttributeKeySet());
+ for( String key : Keys ) {
+ if( key.startsWith(src_pfx) ) {
+ // Get suffix (no leading period)
+ String suffix = key.substring(src_pfx.length());
+ if( suffix.charAt(0) == '.') {
+ suffix = suffix.substring(1);
+ }
+
+ // Set destination's value to key's value
+ ctx.setAttribute(dest_pfx + '.' + suffix, ctx.getAttribute(key));
+ }
+ }
+ }
+
+ /**
+ * Creates and returns a {@code Map<String, String>} that is a subset of
+ * context memory where all keys begin with the prefix.
+ * @param ctx Reference to context memory.
+ * @param prefix Returned map's keys should all begin with this value.
+ * @return A {@code Map<String, String>} containing all the key-value pairs
+ * in ctx whose key begins with prefix.
+ */
+ public static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
+ Map<String, String> prefixMap = new HashMap<String, String>();
+
+ for( String key : ctx.getAttributeKeySet() ) {
+ if( key.startsWith(prefix) ) {
+ prefixMap.put( key, ctx.getAttribute(key) );
+ }
+ }
+
+ return prefixMap;
+ }
+
+ /**
+ * Returns true if key's value in context memory is "" or if it doesn't
+ * exist in context memory.
+ * @param ctx Reference to context memory.
+ * @param key Key to search for.
+ * @return true if key's value in context memory is "" or if it doesn't
+ * exist in context memory.
+ * @since 1.0
+ */
+ public static final boolean ctxKeyEmpty( SvcLogicContext ctx, String key ) {
+ String value = ctx.getAttribute(key);
+ return value == null || value.isEmpty();
+ }
+
+ /**
+ * Adds all key-value pairs in the entries Map to context memory.
+ * @param ctx Reference to context memory. Value's {@code toString()}
+ * function is used to add it.
+ * @param entries {@code Map<String, ?>} of key-value pairs to add to
+ * context memory. Value's {@code toString()} function is used to add it.
+ * @return Reference to context memory to be used for function chaining.
+ */
+ public static final SvcLogicContext ctxPutAll( SvcLogicContext ctx, Map<String, ?> entries ) {
+ for( Map.Entry<String, ?> entry : entries.entrySet() ) {
+ ctxSetAttribute( ctx, entry.getKey(), entry.getValue() );
+ //ctx.setAttribute(entry.getKey(), entry.getValue().toString());
+ }
+
+ return ctx;
+ }
+
+ /**
+ * Sets a key in context memory to the output of object's toString(). The
+ * key is deleted from context memory if object is null.
+ * @param ctx Reference to context memory.
+ * @param key Key to set.
+ * @param object Object whose toString() will be the value set
+ */
+ public static final void ctxSetAttribute( SvcLogicContext ctx, String key, Object object ) {
+ if( object == null ) {
+ ctx.setAttribute(key, null);
+ }
+ else {
+ ctx.setAttribute(key, object.toString());
+ }
+ }
+
+ /**
+ * Sets a key in context memory to the output of object's toString().
+ * <p>
+ * The key is deleted from context memory if object is null. The key and
+ * value set in context memory are logged to the Logger at the provided
+ * logLevel level.
+ * @param <O> Any Java object
+ * @param ctx Reference to context memory.
+ * @param key Key to set.
+ * @param obj Object whose toString() will be the value set
+ * @param LOG Logger to log to
+ * @param logLevel level to log at in Logger
+ */
+ public static final <O extends Object> void ctxSetAttribute( SvcLogicContext ctx, String key, O obj, Logger LOG, LogLevel logLevel ) {
+ String value = Objects.toString( obj, null );
+ ctx.setAttribute( key, value );
+ if( logLevelIsEnabled(LOG, logLevel ) ) {
+ if( value == null ) {
+ logMessageAtLevel( LOG, logLevel, "Deleting " + key );
+ }
+ else {
+ logMessageAtLevel( LOG, logLevel, "Setting " + key + " = " + value );
+ }
+ }
+ }
+
+ /**
+ * Utility function used to get an array's length from context memory.
+ * Will return 0 if key doesn't exist in context memory or isn't numeric.
+ * <p>
+ * Use to obtain a context memory array length without having to worry
+ * about throwing a NumberFormatException.
+ * @param ctx Reference to context memory
+ * @param key Key in context memory whose value is the array's length. If
+ * the key doesn't end in "_length", then "_length is appended.
+ * @param log Reference to Logger to log to
+ * @return The array length or 0 if the key is not found in context memory.
+ * @since 1.0
+ */
+ public static final int getArrayLength( SvcLogicContext ctx, String key ) {
+ return getArrayLength(ctx, key, null, null, null);
+ }
+
+ /**
+ * Utility function used to get an array's length from context memory.
+ * Will return 0 if key doesn't exist in context memory or isn't numeric
+ * and print the provided log message to the configured log file.
+ * <p>
+ * Use to obtain a context memory array length without having to worry
+ * about throwing a NumberFormatException.
+ * @param ctx Reference to context memory.
+ * @param key Key in context memory whose value is the array's length. If
+ * the key doesn't end in "_length", then "_length is appended.
+ * @param log Reference to Logger to log to. Doesn't log if null.
+ * @param logLevel Logging level to log the message at if the context
+ * memory key isn't found. Doesn't log if null.
+ * @param log_message Message to log if the context memory key isn't found.
+ * Doesn't log if null.
+ * @return The array length or 0 if the key is not found in context memory.
+ * @since 1.0
+ */
+ public static final int getArrayLength( SvcLogicContext ctx, String key, Logger log, LogLevel logLevel, String log_message ) {
+ String ctxKey = ( key.endsWith("_length") ) ? key : key + "_length";
+ try {
+ return Integer.parseInt(ctx.getAttribute(ctxKey));
+ }
+ catch( NumberFormatException e ) {
+ if( log != null && logLevel != null && log_message != null ) {
+ switch( logLevel ) {
+ case TRACE:
+ log.trace(log_message);
+ case DEBUG:
+ log.debug(log_message);
+ break;
+ case INFO:
+ log.info(log_message);
+ break;
+ case WARN:
+ log.warn(log_message);
+ break;
+ case ERROR:
+ log.error(log_message);
+ break;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Prints sorted context memory key-value pairs to the log file at the log
+ * level. Returns immediately if the log level isn't enabled.
+ * <p>
+ * O(n log(n)) time where n = size of context memory
+ * @param ctx Reference to context memory
+ * @param log Reference to Logger to log to
+ * @param logLevel Logging level to log the context memory key-value pairs
+ * at.
+ * @since 1.0
+ */
+ public static final void logContextMemory( SvcLogicContext ctx, Logger log, LogLevel logLevel ) {
+ logLevelIsEnabled( log, logLevel );
+
+ // Print sorted context memory key-value pairs to the log
+ ArrayList<String> keys = new ArrayList<String>(ctx.getAttributeKeySet());
+ Collections.sort(keys);
+ for( String key : keys ) {
+ logMessageAtLevel( log, logLevel, key + " = " + ctx.getAttribute(key) );
+ }
+ }
+
+
+
+ // ========== PRIVATE FUNCTIONS ==========
+
+ // TODO: javadoc
+ /**
+ *
+ * @param parameters
+ * @param log
+ * @param loglevel
+ * @since 7.0.1
+ */
+ public static final void logExecuteNodeParameters( Map<String,String> parameters, Logger log, LogLevel loglevel ) {
+ logLevelIsEnabled( log, loglevel );
+
+ for( Map.Entry<String,String> param : parameters.entrySet() ) {
+ logMessageAtLevel( log, loglevel, "PARAM: " + param.getKey() + " = " + param.getValue() );
+ }
+ }
+
+ // TODO: javadoc
+ /**
+ * Returns true if the loglevel is enabled. Otherwise, returns false.
+ * @param log Reference to logger
+ * @param loglevel Log level to check if enabled
+ * @return True if the loglevel is enabled. Otherwise, false
+ * @since 7.0.1
+ */
+ private static final boolean logLevelIsEnabled( Logger log, LogLevel loglevel ) {
+ // Return immediately if logging level isn't enabled
+ switch( loglevel ) {
+ case TRACE:
+ if( log.isTraceEnabled() ) { return true; }
+ return false;
+ case DEBUG:
+ if( log.isDebugEnabled() ) { return true; }
+ return false;
+ case INFO:
+ if( log.isInfoEnabled() ) { return true; }
+ return false;
+ case WARN:
+ if( log.isWarnEnabled() ) { return true; }
+ return false;
+ case ERROR:
+ if( log.isErrorEnabled() ) { return true; }
+ return false;
+ default:
+ throw new IllegalArgumentException("Unknown LogLevel: " + loglevel.toString());
+ }
+ }
+
+ // TODO: javadoc
+ /**
+ *
+ * @param log
+ * @param loglevel
+ * @param msg
+ * @since 7.0.1
+ */
+ private static final void logMessageAtLevel( Logger log, LogLevel loglevel, String msg ) {
+ switch( loglevel ) {
+ case TRACE:
+ log.trace(msg);
+ return;
+ case DEBUG:
+ log.debug(msg);
+ return;
+ case INFO:
+ log.info(msg);
+ return;
+ case WARN:
+ log.warn(msg);
+ return;
+ case ERROR:
+ log.error(msg);
+ return;
+ }
+ }
+
+
+
+ // ========== LOCAL CLASSES ==========
+
+ private class SortableCtxListElement implements Comparable<SortableCtxListElement> {
+ HashMap<String,String> child_elements = new HashMap<String,String>();
+ String[] sort_fields;
+
+ public SortableCtxListElement( SvcLogicContext ctx, String root, String[] sort_fields ) {
+ this.sort_fields = sort_fields;
+
+ for( String key : ctx.getAttributeKeySet() ) {
+ if( key.startsWith(root) ) {
+ if( key.length() == root.length() ) {
+ child_elements.put("", ctx.getAttribute(key));
+ break;
+ }
+ else {
+ child_elements.put(key.substring(root.length()+1), ctx.getAttribute(key));
+ }
+ }
+ }
+ }
+
+ @Override
+ public int compareTo(SortableCtxListElement arg0) {
+ if( sort_fields == null ) {
+ return this.child_elements.get("").compareTo(arg0.child_elements.get(""));
+ }
+
+ for( String field : this.sort_fields ) {
+ int result = this.child_elements.get(field).compareTo(arg0.child_elements.get(field));
+ if( result != 0 ) {
+ return result;
+ }
+ }
+
+ return 0;
+ }
+ }
+
+ /**
+ * Creates a file that contains the content of context memory.
+ * @param parameters - must contain the parameter filename
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException thrown if file cannot be created or if parameters are missing
+ */
+ public static void printContext(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ if (parameters == null || parameters.isEmpty()) {
+ throw new SvcLogicException("no parameters passed");
+ }
+
+ checkParameters(parameters, new String[]{"filename"}, LOG);
+
+ String fileName = parameters.get("filename");
+
+
+ try (FileOutputStream fstr = new FileOutputStream(new File(fileName));
+ PrintStream pstr = new PrintStream(fstr, true);)
+ {
+ pstr.println("#######################################");
+ for (String attr : ctx.getAttributeKeySet()) {
+ pstr.println(attr + " = " + ctx.getAttribute(attr));
+ }
+ } catch (Exception e) {
+ throw new SvcLogicException("Cannot write context to file " + fileName, e);
+ }
+
+
+ }
+
+ /**
+ * Checks context memory for a set of required parameters
+ * Every parameter aside from prefix will be treated as mandatory
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>prefix</td><td>Optional</td><td>the prefix will be added to each parameter</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void requiredParameters(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ if (parameters == null || parameters.keySet().size() < 1) {
+ String errorMessage = "requiredParameters should not be called if the parameters hashmap is null or empty!";
+ LOG.error(errorMessage);
+ throw new SvcLogicException(errorMessage);
+ }
+ String prefixValue = null;
+ String prefix = "prefix";
+ if(parameters.containsKey(prefix)){
+ prefixValue = parameters.get(prefix);
+ parameters.remove(prefix);
+ }
+ checkParameters(prefixValue, ctx.getAttributeKeySet(), parameters.keySet(), LOG);
+ }
+
+ private static void checkParameters(String prefixValue, Set<String> ctx, Set<String> parameters, Logger log) throws SvcLogicException {
+ for (String param : parameters) {
+ if (prefixValue != null) {
+ param = prefixValue + param;
+ }
+ if (!ctx.contains(param)) {
+ String errorMessage = "This method requires the parameters [" + StringUtils.join(parameters, ",")
+ + "], but " + param + " was not passed in.";
+ log.error(errorMessage);
+ throw new SvcLogicException(errorMessage);
+ }
+ }
+ }
+
+ /**
+ * is in a different DG invocation just before/after we call NCS and set the state to InProgress
+ */
+ /**
+ * setTime write the current date time to a string located at outputPath
+ * @param parameters - requires outputPath to not be null
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException if a required parameter is missing an exception is thrown
+ */
+ public static void setTime(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException
+ {
+ checkParameters(parameters, new String[] { "outputPath" }, LOG);
+
+ // Set the DateFormat
+ // "2015-03-16T12:18:35.138Z"
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+
+ // Parse the date
+ String ctxVariable = parameters.get("outputPath");
+ try {
+ String dateTime = format.format(new Date());
+ ctx.setAttribute(ctxVariable, dateTime);
+ } catch (Exception ex) {
+ throw new SvcLogicException("problem with setTime", ex);
+ }
+ }
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java
new file mode 100644
index 00000000..e0568ab7
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java
@@ -0,0 +1,95 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SliPluginUtilsActivator implements BundleActivator {
+ @SuppressWarnings("rawtypes") private List<ServiceRegistration> registrations = new LinkedList<ServiceRegistration>();
+
+ private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtilsActivator.class);
+ private static final String SDNC_ROOT_DIR = "SDNC_CONFIG_DIR";
+ private static final String DME2_PROPERTIES_FILE_NAME = "dme2.properties";
+
+ @Override
+ public void start(BundleContext ctx) throws Exception {
+ SliPluginUtils plugin = new SliPluginUtils(new Properties());
+ LOG.info("Registering service " + plugin.getClass().getName());
+ registrations.add(ctx.registerService(plugin.getClass().getName(), plugin, null));
+
+ SliStringUtils sliStringUtils_Plugin = new SliStringUtils();
+ LOG.info("Registering service " + sliStringUtils_Plugin.getClass().getName());
+ registrations.add(ctx.registerService(sliStringUtils_Plugin.getClass().getName(), sliStringUtils_Plugin, null));
+
+ try {
+ String path = System.getenv(SDNC_ROOT_DIR) + File.separator + DME2_PROPERTIES_FILE_NAME;
+ DME2 dmePlugin = initDme2(path);
+ if (dmePlugin != null) {
+ LOG.info("Registering service " + dmePlugin.getClass().getName());
+ registrations.add(ctx.registerService(dmePlugin.getClass().getName(), dmePlugin, null));
+ }
+ } catch (Exception e) {
+ LOG.error("DME2 plugin could not be started", e);
+ }
+ }
+
+ public DME2 initDme2(String pathToDmeProperties) {
+ Properties dme2properties = new Properties();
+ String loadPropertiesErrorMessage = "Couldn't load DME2 properties at path " + pathToDmeProperties;
+ File dme2propertiesFile = new File(pathToDmeProperties);
+
+ try {
+ dme2properties.load(new FileReader(dme2propertiesFile));
+ String proxyUrlProperty = dme2properties.getProperty("proxyUrl");
+ String[] proxyUrls = proxyUrlProperty.split(",");
+ DME2 dmePlugin = new DME2(dme2properties.getProperty("aafUserName"), dme2properties.getProperty("aafPassword"), dme2properties.getProperty("envContext"), dme2properties.getProperty("routeOffer"), proxyUrls, dme2properties.getProperty("commonServiceVersion"));
+ dmePlugin.setPartner(dme2properties.getProperty("partner"));
+ return dmePlugin;
+ } catch (FileNotFoundException e) {
+ LOG.error(loadPropertiesErrorMessage);
+ } catch (IOException e) {
+ LOG.error(loadPropertiesErrorMessage);
+ }
+ LOG.error("Couldn't create DME2 plugin");
+ return null;
+ }
+
+ @Override
+ public void stop(BundleContext ctx) throws Exception {
+ for (@SuppressWarnings("rawtypes") ServiceRegistration registration : registrations) {
+ registration.unregister();
+ registration = null;
+ }
+ }
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java
new file mode 100644
index 00000000..43af6f59
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtils.java
@@ -0,0 +1,396 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicJavaPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A SvcLogicJavaPlugin that exposes java.lang.String functions to DirectedGraph
+ */
+public class SliStringUtils implements SvcLogicJavaPlugin {
+ private static final Logger LOG = LoggerFactory.getLogger(SliStringUtils.class);
+
+ public SliStringUtils() {}
+
+ /**
+ * Provides split functionality to Directed Graphs.
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>original_string</td><td>Mandatory</td><td>String to perform split on</td></tr>
+ * <tr><td>regex</td><td>Mandatory</td><td>the delimiting regular expression</td></tr>
+ * <tr><td>limit</td><td>Optional</td><td>result threshold. See String.split method for further description. Defaults to 0</td></tr>
+ * <tr><td>ctx_memory_result_key</td><td>Mandatory</td><td>Key in context memory to populate the resulting array of strings under</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ * @see String#split(String, int)
+ */
+ public void split( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ final String original_string = parameters.get("original_string");
+ LOG.trace("original_string = " + original_string);
+ final String regex = parameters.get("regex");
+ LOG.trace("regex = " + regex);
+ final String limit_str = parameters.get("limit");
+ LOG.trace("limit_str = " + limit_str);
+ final String ctx_memory_result_key = parameters.get("ctx_memory_result_key");
+ LOG.trace("ctx_memory_result_key = " + ctx_memory_result_key);
+
+ try {
+ // Validation that parameters are not null
+ SliPluginUtils.checkParameters( parameters, new String[]{"original_string","regex","ctx_memory_result_key"}, LOG );
+
+ // Read limit from context memory. Default to 0 if null/empty
+ int limit = 0;
+ if( StringUtils.isNotEmpty(limit_str) ) {
+ try {
+ limit = Integer.parseInt(limit_str);
+ }
+ catch( NumberFormatException e ) {
+ throw new IllegalArgumentException( "The limit parameter of the SliStringUtils.split() function must be a number, empty string, or null", e );
+ }
+ }
+
+ // Call String.split(regex,limit) on string passed in
+ String[] split_string = original_string.split(regex, limit);
+
+ // Populate context memory with results
+ for( int i = 0; i < split_string.length; i++ ) {
+ SliPluginUtils.ctxSetAttribute(ctx, ctx_memory_result_key + '[' + i + ']', split_string[i], LOG, SliPluginUtils.LogLevel.DEBUG);
+ }
+ SliPluginUtils.ctxSetAttribute(ctx, ctx_memory_result_key + "_length", new Integer(split_string.length), LOG, SliPluginUtils.LogLevel.DEBUG);
+ }
+ catch( Exception e ) {
+ // Have error message print parameters
+ throw new SvcLogicException( "An error occurred during SliStringUtils.split() where original_string = " + quotedOrNULL(regex) +
+ " regex = " + quotedOrNULL(regex) +
+ " limit = " + quotedOrNULL(regex) +
+ " ctx_memory_result_key = " + quotedOrNULL(regex), e );
+ }
+ }
+
+ private static String quotedOrNULL( String str ) {
+ return (str == null) ? "NULL" : '"' + str + '"';
+ }
+
+ /**
+ * exposes equalsIgnoreCase to directed graph
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * emits a true or false outcome
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static String equalsIgnoreCase(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+ if(parameters.get("source").equalsIgnoreCase(parameters.get("target"))){
+ return "true";
+ }
+ return "false";
+ }
+
+ /**
+ * exposes toUpperCase to directed graph
+ * writes an upperCase version of source to outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void toUpper(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+ ctx.setAttribute(parameters.get("outputPath"), parameters.get("source").toUpperCase());
+ }
+
+ /**
+ * exposes toLowerCase to directed graph
+ * writes a lowerCase version of source to outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void toLower(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+ ctx.setAttribute(parameters.get("outputPath"), parameters.get("source").toLowerCase());
+ }
+
+ /**
+ * exposes contains to directed graph to test if one string contains another
+ * tests if the source contains the target
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * emits a true or false outcome
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static String contains(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+ if(parameters.get("source").contains(parameters.get("target"))){
+ return "true";
+ }
+ return "false";
+ }
+
+ /**
+ * exposes endsWith to directed graph to test if one string endsWith another string
+ * tests if the source ends with the target
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * emits a true or false outcome
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static String endsWith(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+ if(parameters.get("source").endsWith(parameters.get("target"))){
+ return "true";
+ }
+ return "false";
+ }
+
+ /**
+ * exposes startsWith to directed graph to test if one string endsWith another string
+ * tests if the source ends with the target
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * emits a true or false outcome
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>target</td><td>Mandatory</td><td>target string</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static String startsWith(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","target"}, LOG);
+ if(parameters.get("source").startsWith(parameters.get("target"))){
+ return "true";
+ }
+ return "false";
+ }
+
+ /**
+ * exposes trim to directed graph
+ * writes a trimmed version of the string to the outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void trim(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+ ctx.setAttribute(parameters.get("outputPath"), parameters.get("source").trim());
+ }
+
+ /**
+ * exposes String.length() to directed graph
+ * writes the length of source to outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void getLength(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath"}, LOG);
+ ctx.setAttribute(parameters.get("outputPath"), String.valueOf(parameters.get("source").length()));
+ }
+
+ /**
+ * exposes replace to directed graph
+ * writes the length of source to outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>target</td><td>Mandatory</td><td>The sequence of char values to be replaced</td></tr>
+ * <tr><td>replacement</td><td>Mandatory</td><td>The replacement sequence of char values</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void replace(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[]{"source","outputPath","target","replacement"}, LOG);
+ ctx.setAttribute(parameters.get("outputPath"), (parameters.get("source").replace(parameters.get("target"), parameters.get("replacement"))));
+ }
+
+ /**
+ * Provides substring functionality to Directed Graphs.
+ * <p>
+ * Calls either String.substring(String beginIndex) or
+ * String.substring(String beginInded, String endIndex) if the end-index
+ * is present or not.
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>string</td><td>Mandatory</td><td>String to perform substring on</td></tr>
+ * <tr><td>result</td><td>Mandatory</td><td>Key in context memory to populate the resulting string in</td></tr>
+ * <tr><td>begin-index</td><td>Mandatory</td><td>Beginning index to pass to Java substring function</td></tr>
+ * <tr><td>end-index</td><td>Optional</td><td>Ending index to pass to Java substring function. If not included, String.substring(begin) will be called.</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public void substring( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ try {
+ SliPluginUtils.checkParameters( parameters, new String[]{"string","begin-index","result"}, LOG );
+ final String string = parameters.get("string");
+ final String result = parameters.get("result");
+ final String begin = parameters.get("begin-index");
+ final String end = parameters.get("end-index");
+ if( StringUtils.isEmpty(end) ) {
+ ctx.setAttribute( result, string.substring(Integer.parseInt(begin)) );
+ }
+ else {
+ ctx.setAttribute( result, string.substring(Integer.parseInt(begin), Integer.parseInt(end)) );
+ }
+ }
+ catch( Exception e ) {
+ throw new SvcLogicException( "An error occurred while the Directed Graph was performing a substring", e );
+ }
+ }
+
+ /**
+ * Provides concat functionality to Directed Graphs.
+ * <p>
+ * Will concat target to source and write the result to outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>target</td><td>Mandatory</td><td>The sequence of char values to be replaced</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ * @since 11.0.2
+ */
+ public static void concat( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+ SliPluginUtils.checkParameters( parameters, new String[]{"source","target","outputPath"}, LOG );
+ String result = parameters.get("source").concat(parameters.get("target"));
+ ctx.setAttribute(parameters.get("outputPath"), result);
+ }
+
+ /**
+ * Provides url encoding functionality to Directed Graphs.
+ * <p>
+ * Will url encode the source and write the result to outputPath
+ * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+ * <table border="1">
+ * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+ * <tbody>
+ * <tr><td>source</td><td>Mandatory</td><td>source string</td></tr>
+ * <tr><td>encoding</td><td>Optional</td><td>the name of a supported character encoding, defaulted to UTF-8 if not supplied</td></tr>
+ * <tr><td>outputPath</td><td>Mandatory</td><td>the location in context memory the result is written to</td></tr>
+ * </tbody>
+ * </table>
+ * @param ctx Reference to context memory
+ * @throws SvcLogicException
+ */
+ public static void urlEncode(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+ SliPluginUtils.checkParameters(parameters, new String[] { "source", "outputPath" }, LOG);
+ String encoding = parameters.get("encoding");
+ if (encoding == null) {
+ encoding = "UTF-8";
+ }
+ try {
+ String result = URLEncoder.encode(parameters.get("source"), encoding);
+ ctx.setAttribute(parameters.get("outputPath"), result);
+ } catch (UnsupportedEncodingException e) {
+ throw new SvcLogicException("Url encode failed.", e);
+ }
+ }
+
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java
new file mode 100644
index 00000000..89a4a98f
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java
@@ -0,0 +1,210 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+
+/**
+ * A utility class used to manage list manipulation in the context memory.
+ * @see org.openecomp.sdnc.sli.SvcLogicContext
+ */
+public class SvcLogicContextList {
+ /**
+ * Internal flag indicating if list should be deleted from context memory
+ * when it is copied into the SvcLogicContextList object.
+ */
+ private enum OperType {
+ COPY, EXTRACT
+ }
+
+ // TODO: javadoc
+ protected final String prefix;
+ // TODO: javadoc
+ protected final ArrayList<HashMap<String,String>> list;
+
+
+ // TODO: javadoc
+ public SvcLogicContextList( SvcLogicContext ctx, String list_prefix ) {
+ this(ctx, list_prefix, OperType.COPY);
+ }
+
+ // TODO: javadoc
+ private SvcLogicContextList( SvcLogicContext ctx, String list_prefix, OperType operation ) {
+ this.prefix = list_prefix;
+
+ // Initialize list
+ int capacity = getCtxListLength(ctx, prefix);
+ this.list = new ArrayList<HashMap<String, String>>(capacity);
+ for( int i = 0; i < capacity; i++ ) {
+ this.list.add(i, new HashMap<String,String>());
+ }
+
+ // Populate "elements" in list
+ String prefix_bracket = this.prefix + '[';
+ for (String key : new HashSet<String>(ctx.getAttributeKeySet())) {
+ if( key.startsWith(prefix_bracket) ) {
+ // Extract the index of the list
+ int index = getCtxListIndex(key, this.prefix, capacity);
+
+ // Store the
+ String suffix = key.substring((prefix_bracket + index + ']').length());
+ suffix = suffix.isEmpty() ? suffix : suffix.substring(1);
+ this.list.get(index).put( suffix, ctx.getAttribute(key));
+
+ // If flag to extract set, remove data from context memory as
+ // it is read into this list
+ if( operation == OperType.EXTRACT ) {
+ ctx.setAttribute(key, null);
+ }
+ }
+ }
+
+ // If flag to extract set, remove list _length value from cxt mem
+ if( operation == OperType.EXTRACT ) {
+ ctx.setAttribute(this.prefix + "_length", null);
+ }
+ }
+
+ // TODO: javadoc
+ public static SvcLogicContextList extract( SvcLogicContext ctx, String list_prefix ) {
+ return new SvcLogicContextList(ctx, list_prefix, OperType.EXTRACT);
+ }
+
+
+ // ========== PUBLIC FUNCTIONS ==========
+
+ // TODO: javadoc
+ public HashMap<String,String> get( int index ) {
+ return this.list.get(index);
+ }
+
+ // TODO: javadoc
+ public HashMap<String,String> remove( int index ) {
+ return this.list.remove(index);
+ }
+
+ // TODO: javadoc
+ public void remove( String value ) {
+ remove( "", value );
+ }
+
+ // TODO: javadoc
+ public void remove( String key, String value ) {
+ if( value == null ) {
+ throw new IllegalArgumentException("value cannot be null");
+ }
+
+ ListIterator<HashMap<String,String>> itr = this.list.listIterator();
+ while( itr.hasNext() ) {
+ if( value.equals(itr.next().get(key)) ) {
+ itr.remove();
+ }
+ }
+ }
+
+ // TODO javadoc
+ public void remove( Map<String,String> primary_key ) {
+ ListIterator<HashMap<String,String>> itr = this.list.listIterator();
+ while( itr.hasNext() ) {
+ boolean found = true;
+ HashMap<String,String> list_element = itr.next();
+ for( Map.Entry<String,String> key : primary_key.entrySet() ) {
+ if( !key.getValue().equals(list_element.get(key.getKey())) ) {
+ found = false;
+ break;
+ }
+ }
+
+ if( found ) {
+ itr.remove();
+ }
+ }
+ }
+
+ // TODO: javadoc
+ public int size() {
+ return list.size();
+ }
+
+ // TODO: javadoc
+ public void writeToContext( SvcLogicContext ctx ) {
+ ctx.setAttribute( prefix + "_length", Integer.toString(this.list.size()) );
+
+ for( int i = 0; i < this.list.size(); i++ ) {
+ for( Map.Entry<String,String> entry : this.list.get(i).entrySet() ) {
+ if( entry.getKey().equals("") ) {
+ ctx.setAttribute(prefix + '[' + i + ']', entry.getValue());
+ } else {
+ ctx.setAttribute(prefix + '[' + i + "]." + entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+
+
+
+ // ========== PRIVATE STATIC FUNCTIONS ==========
+
+ // TODO: javadoc
+ private static int getCtxListIndex( String key, String prefix, int list_size ) {
+ int index = getCtxListIndex( key, prefix );
+ if( index >= list_size ) {
+ throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains an index >= the size of the list", new ArrayIndexOutOfBoundsException("index \"" + index + "\" is outside the bounds of the context memory list \"" + prefix + "[]. List Length = " + list_size));
+ } else if (index < 0) {
+ throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains a negative index", new NegativeArraySizeException("index \"" + index + "\" of context memory list is negative"));
+ }
+
+ return index;
+ }
+
+ // TODO: javadoc
+ private static int getCtxListIndex( String key, String prefix ) {
+ String ctx_index_str = StringUtils.substringBetween(key.substring(prefix.length()), "[", "]");
+ try {
+ return Integer.parseInt( ctx_index_str );
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Could not parse index value \"" + ctx_index_str + "\" in context memory key \"" + key + "\"", e);
+ }
+ }
+
+ // TODO: javadoc
+ private static int getCtxListLength( SvcLogicContext ctx, String prefix ) {
+ String _length_key = prefix + "_length";
+ String _length_val_str = ctx.getAttribute(_length_key);
+ try {
+ return Integer.parseInt(_length_val_str);
+ } catch (NumberFormatException e) {
+ if( _length_val_str == null ) {
+ throw new IllegalStateException( "Could not find list length \"" + _length_key + "\" in context memory." );
+ } else {
+ throw new IllegalStateException( "Could not parse index value \"" + _length_val_str + "\" of context memory list length \"" + _length_key + "\"" , e );
+ }
+ }
+ }
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextObject.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextObject.java
new file mode 100644
index 00000000..d79522f0
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextObject.java
@@ -0,0 +1,28 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import org.openecomp.sdnc.sli.SvcLogicContext;
+
+public interface SvcLogicContextObject {
+ public void writeToContext( SvcLogicContext ctx, String root );
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/YesNo.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/YesNo.java
new file mode 100644
index 00000000..4d2fb4c2
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/YesNo.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.openecomp.sdnc.sli.SliPluginUtils.commondatastructures;
+
+/**
+ * An enum found in many Yang models. It is commonly used as a
+ * substitute for boolean.
+ */
+public enum YesNo {
+ N, Y;
+
+ /**
+ * Method overload for {@link #valueOf(String)} for the char primative
+ */
+ public static YesNo valueOf( final char name ) {
+ return YesNo.valueOf( Character.toString(name) );
+ }
+
+ /**
+ * Method overload for {@link #valueOf(String)} for the Character object
+ */
+ public static YesNo valueOf( final Character name ) {
+ if( name == null ) {
+ return null;
+ }
+
+ return YesNo.valueOf( name.toString() );
+ }
+}
diff --git a/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/package-info.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/package-info.java
new file mode 100644
index 00000000..4a81d9a3
--- /dev/null
+++ b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils.commondatastructures;
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java
new file mode 100644
index 00000000..318e4643
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/CheckParametersTest.java
@@ -0,0 +1,116 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CheckParametersTest {
+
+ @Test
+ public void nullRequiredParameters() throws Exception {
+ Map<String, String> parametersMap = new HashMap<String, String>();
+ String[] requiredParams = null;
+ Logger Log = LoggerFactory.getLogger(SliPluginUtils.class);
+ SliPluginUtils.checkParameters(parametersMap, requiredParams, Log);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void emptyParametersMap() throws Exception {
+ Map<String, String> parametersMap = new HashMap<String, String>();
+ String[] requiredParams = new String[] { "param1", "param2", "param3" };
+ Logger Log = LoggerFactory.getLogger(SliPluginUtils.class);
+ SliPluginUtils.checkParameters(parametersMap, requiredParams, Log);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void paramNotFound() throws Exception {
+ Map<String, String> parametersMap = new HashMap<String, String>();
+ parametersMap.put("tst", "me");
+ String[] requiredParams = new String[] { "param1", "parm2", "param3" };
+ Logger Log = LoggerFactory.getLogger(SliPluginUtils.class);
+ SliPluginUtils.checkParameters(parametersMap, requiredParams, Log);
+ }
+
+ @Test
+ public void testSunnyRequiredParameters() throws Exception {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.setAttribute("param1", "hello");
+ ctx.setAttribute("param2", "world");
+ ctx.setAttribute("param3", "!");
+
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("param1", "dog");
+ parameters.put("param2", "cat");
+ parameters.put("param3", "fish");
+
+ SliPluginUtils.requiredParameters(parameters, ctx);
+ }
+
+ @Test
+ public void testSunnyRequiredParametersWithPrefix() throws Exception {
+ String prefixValue = "my.unique.path.";
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.setAttribute(prefixValue + "param1", "hello");
+ ctx.setAttribute(prefixValue + "param2", "world");
+ ctx.setAttribute(prefixValue + "param3", "!");
+
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("prefix", prefixValue);
+ parameters.put("param1", "dog");
+ parameters.put("param2", "cat");
+ parameters.put("param3", "fish");
+
+ SliPluginUtils.requiredParameters(parameters, ctx);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void testRainyMissingRequiredParameters() throws Exception {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.setAttribute("param1", "hello");
+ ctx.setAttribute("param3", "!");
+
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("param1", null);
+ parameters.put("param2", null);
+ parameters.put("param3", null);
+
+ SliPluginUtils.requiredParameters(parameters, ctx);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void testEmptyRequiredParameters() throws Exception {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx.setAttribute("param1", "hello");
+ ctx.setAttribute("param3", "!");
+
+ Map<String, String> parameters = new HashMap<String, String>();
+
+ SliPluginUtils.requiredParameters(parameters, ctx);
+ }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java
new file mode 100644
index 00000000..d66b0114
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/Dme2Test.java
@@ -0,0 +1,109 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SliPluginUtils.DME2;
+import org.openecomp.sdnc.sli.SliPluginUtils.SliPluginUtilsActivator;
+
+public class Dme2Test {
+
+ @Test
+ public void createInstarUrl() {
+ String instarUrl = "http://localhost:25055/service=sample.com/services/eim/v1/rest/version=1702.0/envContext=TEST/routeOffer=DEFAULT/subContext=/enterpriseConnection/getEnterpriseConnectionDetails/v1?dme2.password=fake&dme2.username=user@sample.com";
+ DME2 dme = new DME2("user@sample.com", "fake", "TEST", "DEFAULT", new String[] { "http://localhost:25055" }, "common");
+ String constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(instarUrl, constructedUrl);
+ }
+
+ @Test
+ public void createInstarUrlNoSubContext() {
+ String instarUrl = "http://localhost:25055/service=sample.com/services/eim/v1/rest/version=1702.0/envContext=TEST/routeOffer=DEFAULT?dme2.password=fake&dme2.username=user@sample.com";
+ DME2 dme = new DME2("user@sample.com", "fake", "TEST", "DEFAULT", new String[] { "http://localhost:25055" }, "common");
+ Map<String, String> parameters = new HashMap<String, String>();
+ String constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", parameters.get(null));
+ assertEquals(instarUrl, constructedUrl);
+ }
+
+ @Test
+ public void testRoundRobin() {
+ String[] proxyHostNames = new String[] { "http://one:25055", "http://two:25055", "http://three:25055" };
+ String urlSuffix = "/service=sample.com/services/eim/v1/rest/version=1702.0/envContext=TEST/routeOffer=DEFAULT/subContext=/enterpriseConnection/getEnterpriseConnectionDetails/v1?dme2.password=fake&dme2.username=user@sample.com";
+ DME2 dme = new DME2("user@sample.com", "fake", "TEST", "DEFAULT", proxyHostNames, "common");
+ String constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[0] + urlSuffix, constructedUrl);
+ constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[1] + urlSuffix, constructedUrl);
+ constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[2] + urlSuffix, constructedUrl);
+ constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[0] + urlSuffix, constructedUrl);
+ constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[1] + urlSuffix, constructedUrl);
+ constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[2] + urlSuffix, constructedUrl);
+ constructedUrl = dme.constructUrl("sample.com/services/eim/v1/rest", "1702.0", "/enterpriseConnection/getEnterpriseConnectionDetails/v1");
+ assertEquals(proxyHostNames[0] + urlSuffix, constructedUrl);
+ }
+
+ @Test
+ public void createDme2EndtoEnd() {
+ SliPluginUtilsActivator activator = new SliPluginUtilsActivator();
+ DME2 dme2 = activator.initDme2("src/test/resources/dme2.e2e.properties");
+ assertEquals("user@sample.com", dme2.aafUserName);
+ assertEquals("fake", dme2.aafPassword);
+ assertEquals("UAT", dme2.envContext);
+ assertEquals("UAT", dme2.routeOffer);
+ Assert.assertArrayEquals("http://sample.com:25055,http://sample.com:25055".split(","), dme2.proxyUrls);
+ assertEquals("1702.0", dme2.commonServiceVersion);
+ assertEquals(null, dme2.partner);
+
+ String constructedUrl = dme2.constructUrl("sample.com/restservices/instar/v1/assetSearch", null, "/mySubContext");
+ assertNotNull(constructedUrl);
+ System.out.println(constructedUrl);
+ }
+
+ @Test
+ public void createDme2Prod() {
+ SliPluginUtilsActivator activator = new SliPluginUtilsActivator();
+ DME2 dme2 = activator.initDme2("src/test/resources/dme2.prod.properties");
+ assertEquals("user@sample.com", dme2.aafUserName);
+ assertEquals("fake", dme2.aafPassword);
+ assertEquals("PROD", dme2.envContext);
+ assertEquals("", dme2.routeOffer);
+ Assert.assertArrayEquals("http://sample.com:25055,http://sample.com:25055".split(","), dme2.proxyUrls);
+ assertEquals("1.0", dme2.commonServiceVersion);
+ assertEquals("LPP_PROD", dme2.partner);
+
+ String constructedUrl = dme2.constructUrl("sample.com/restservices/instar/v1/assetSearch", null, "/mySubContext");
+ assertNotNull(constructedUrl);
+ System.out.println(constructedUrl);
+ }
+
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java
new file mode 100644
index 00000000..e69d0867
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctionsTest.java
@@ -0,0 +1,250 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SliPluginUtils_StaticFunctionsTest {
+ private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils_StaticFunctionsTest.class);
+ SliPluginUtils utils = new SliPluginUtils();
+ private SvcLogicContext ctx;
+ private HashMap<String, String> parameters;
+
+ @Before
+ public void setUp() throws Exception {
+ this.ctx = new SvcLogicContext();
+ parameters = new HashMap<String, String>();
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testCtxGetBeginsWith() {
+ ctx.setAttribute("service-data.oper-status.order-status", "InProgress");
+ ctx.setAttribute("service-data.service-information.service-instance-id", "my-instance");
+ ctx.setAttribute("service-data.service-information.service-type", "my-service");
+
+ Map<String, String> entries = SliPluginUtils.ctxGetBeginsWith(ctx, "service-data.service-information");
+
+ assertEquals("my-instance", entries.get("service-data.service-information.service-instance-id"));
+ assertEquals("my-service", entries.get("service-data.service-information.service-type"));
+ assertFalse(entries.containsKey("service-data.oper-status.order-status"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testCtxListRemove_index() throws SvcLogicException {
+ LOG.trace("=== testCtxListRemove_index ===");
+ ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+ ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+ ctx.setAttribute("service-data.vnf-l3_length", "3");
+
+ parameters.put("index", "1");
+ parameters.put("list_pfx", "service-data.vnf-l3");
+
+ utils.ctxListRemove(parameters, ctx);
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ assertEquals("2", ctx.getAttribute("service-data.vnf-l3_length"));
+ assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].vnf-host-name"));
+ assertEquals("device-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].device-host-name"));
+ assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].vnf-host-name"));
+ assertEquals("device-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].device-host-name"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void textCtxListRemove_keyValue() throws SvcLogicException {
+ LOG.trace("=== textCtxListRemove_keyValue ===");
+ ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+ ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+ // 2nd entry
+ ctx.setAttribute("service-data.vnf-l3[3].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[3].device-host-name", "device-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3_length", "4");
+
+ parameters.put("list_pfx", "service-data.vnf-l3");
+ parameters.put("key", "vnf-host-name");
+ parameters.put("value", "vnf-host-name_1");
+
+ utils.ctxListRemove(parameters, ctx);
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ assertEquals("2", ctx.getAttribute("service-data.vnf-l3_length"));
+ assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].vnf-host-name"));
+ assertEquals("device-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].device-host-name"));
+ assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].vnf-host-name"));
+ assertEquals("device-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].device-host-name"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void textCtxListRemove_keyValue_nullkey() throws SvcLogicException {
+ LOG.trace("=== textCtxListRemove_keyValue_nullkey ===");
+ ctx.setAttribute("service-data.vnf-l3[0]", "vnf-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[1]", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[2]", "vnf-host-name_2");
+ ctx.setAttribute("service-data.vnf-l3_length", "3");
+
+ parameters.put("list_pfx", "service-data.vnf-l3");
+ parameters.put("value", "vnf-host-name_1");
+
+ utils.ctxListRemove(parameters, ctx);
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ assertEquals("2", ctx.getAttribute("service-data.vnf-l3_length"));
+ assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0]"));
+ assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1]"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void textCtxListRemove_keyValueList() throws SvcLogicException {
+ LOG.trace("=== textCtxListRemove_keyValueList ===");
+ ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+ ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+ // 2nd entry
+ ctx.setAttribute("service-data.vnf-l3[3].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[3].device-host-name", "device-host-name_1");
+ // entries with only 1 of 2 key-value pairs matching
+ ctx.setAttribute("service-data.vnf-l3[4].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[4].device-host-name", "device-host-name_4");
+ ctx.setAttribute("service-data.vnf-l3[5].vnf-host-name", "vnf-host-name_5");
+ ctx.setAttribute("service-data.vnf-l3[5].device-host-name", "device-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3_length", "6");
+
+ parameters.put("list_pfx", "service-data.vnf-l3");
+ parameters.put("keys_length", "2");
+ parameters.put("keys[0].key", "vnf-host-name");
+ parameters.put("keys[0].value", "vnf-host-name_1");
+ parameters.put("keys[1].key", "device-host-name");
+ parameters.put("keys[1].value", "device-host-name_1");
+
+ utils.ctxListRemove(parameters, ctx);
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ assertEquals("4", ctx.getAttribute("service-data.vnf-l3_length"));
+ assertEquals("vnf-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].vnf-host-name"));
+ assertEquals("device-host-name_0", ctx.getAttribute("service-data.vnf-l3[0].device-host-name"));
+ assertEquals("vnf-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].vnf-host-name"));
+ assertEquals("device-host-name_2", ctx.getAttribute("service-data.vnf-l3[1].device-host-name"));
+ assertEquals("vnf-host-name_1", ctx.getAttribute("service-data.vnf-l3[2].vnf-host-name"));
+ assertEquals("device-host-name_4", ctx.getAttribute("service-data.vnf-l3[2].device-host-name"));
+ assertEquals("vnf-host-name_5", ctx.getAttribute("service-data.vnf-l3[3].vnf-host-name"));
+ assertEquals("device-host-name_1", ctx.getAttribute("service-data.vnf-l3[3].device-host-name"));
+ }
+
+ // TODO: javadoc
+ @Test(expected = SvcLogicException.class)
+ public final void testCtxListRemove_nullListLength() throws SvcLogicException {
+ LOG.trace("=== testCtxListRemove_nullListLength ===");
+ ctx.setAttribute("service-data.vnf-l3[0].vnf-host-name", "vnf-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[0].device-host-name", "device-host-name_0");
+ ctx.setAttribute("service-data.vnf-l3[1].vnf-host-name", "vnf-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[1].device-host-name", "device-host-name_1");
+ ctx.setAttribute("service-data.vnf-l3[2].vnf-host-name", "vnf-host-name_2");
+ ctx.setAttribute("service-data.vnf-l3[2].device-host-name", "device-host-name_2");
+
+ parameters.put("index", "1");
+ parameters.put("list_pfx", "service-data.vnf-l3");
+
+ utils.ctxListRemove(parameters, ctx);
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testCtxPutAll() {
+ HashMap<String, Object> entries = new HashMap<String, Object>();
+ entries.put("service-data.oper-status.order-status", "InProgress");
+ entries.put("service-data.service-information.service-instance-id", "my-instance");
+ entries.put("service-data.request-information.order-number", 1234);
+ entries.put("service-data.request-information.request-id", null);
+
+ SliPluginUtils.ctxPutAll(ctx, entries);
+
+ assertEquals("InProgress", ctx.getAttribute("service-data.oper-status.order-status"));
+ assertEquals("my-instance", ctx.getAttribute("service-data.service-information.service-instance-id"));
+ assertEquals("1234", ctx.getAttribute("service-data.request-information.order-number"));
+ assertFalse(ctx.getAttributeKeySet().contains("service-data.request-information.request-id"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testCtxSetAttribute_LOG() {
+ LOG.debug("=== testCtxSetAttribute_LOG ===");
+ Integer i = new Integer(3);
+ SliPluginUtils.ctxSetAttribute(ctx, "test", i, LOG, SliPluginUtils.LogLevel.TRACE);
+ }
+
+ /*@Test
+ public void printContext() throws SvcLogicException, IOException {
+ String filePath = "/src/test/resources/printContext.txt";
+ parameters.put("filename", filePath);
+ File f = new File(filePath);
+ assert (f.exists());
+ assert (!f.isDirectory());
+ ctx.setAttribute("hello", "world");
+ ctx.setAttribute("name", "value");
+
+ SliPluginUtils.printContext(parameters, ctx);
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ String line = br.readLine();
+ assertEquals("#######################################", line);
+ line = br.readLine();
+ assertEquals("hello = world", line);
+ line = br.readLine();
+ assertEquals("name = value", line);
+ br.close();
+ Files.delete(Paths.get(filePath));
+ }*/
+
+ @Test
+ public void setTime() throws SvcLogicException {
+ String outputPath = "output";
+ parameters.put("outputPath", outputPath);
+ SliPluginUtils.setTime(parameters, ctx);
+ assertNotNull(ctx.getAttribute(outputPath));
+ }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortList.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortList.java
new file mode 100644
index 00000000..b1cae54a
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortList.java
@@ -0,0 +1,96 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Random;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("unused")
+public class SliPluginUtils_ctxSortList {
+ private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils_ctxSortList.class);
+ SliPluginUtils utils = new SliPluginUtils();
+ SvcLogicContext ctx;
+ HashMap<String,String> parameters;
+ Random rand = new Random();
+
+ @Before
+ public void setUp() throws Exception {
+ this.ctx = new SvcLogicContext();
+ this.parameters = new HashMap<String,String>();
+ }
+
+ @Test
+ public final void list_of_containers() throws SvcLogicException {
+ this.parameters.put("list", "input.list");
+ this.parameters.put("sort-fields", "sort-key");
+ this.parameters.put("delimiter",",");
+
+ ctx.setAttribute("input.list_length", "10");
+ for( int i = 0; i < 10; i++ ) {
+ this.ctx.setAttribute("input.list[" + i + "].sort-key", Integer.toString( rand.nextInt(10) ));
+ this.ctx.setAttribute("input.list[" + i + "].value", Integer.toString( rand.nextInt(10) ));
+ }
+
+ LOG.trace("BEFORE SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ utils.ctxSortList(this.parameters, this.ctx);
+
+ LOG.trace("AFTER SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ for( int i = 0; i < 9; i++ ) {
+ assertTrue(this.ctx.getAttribute("input.list[" + i + "].sort-key").compareTo(this.ctx.getAttribute("input.list[" + (i+1) + "].sort-key")) < 1 );
+ }
+ }
+
+ @Test public final void list_of_elements() throws SvcLogicException {
+ this.parameters.put("list", "input.list");
+ this.parameters.put("delimiter",",");
+
+ this.ctx.setAttribute("input.list_length", "10");
+ for( int i = 0; i < 10; i++ ) {
+ this.ctx.setAttribute("input.list[" + i + ']', Integer.toString( rand.nextInt(10) ));
+ }
+
+ LOG.trace("BEFORE SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ utils.ctxSortList(this.parameters, this.ctx);
+
+ LOG.trace("AFTER SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ for( int i = 0; i < 9; i++ ) {
+ assertTrue(this.ctx.getAttribute("input.list[" + i + ']').compareTo(this.ctx.getAttribute("input.list[" + (i+1) + ']')) < 1 );
+ }
+ }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java
new file mode 100644
index 00000000..e2fcb33d
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortListTest.java
@@ -0,0 +1,97 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Random;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("unused")
+public class SliPluginUtils_ctxSortListTest {
+ private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils_ctxSortListTest.class);
+ SliPluginUtils utils = new SliPluginUtils();
+ SvcLogicContext ctx;
+ HashMap<String, String> parameters;
+ Random rand = new Random();
+
+ @Before
+ public void setUp() throws Exception {
+ this.ctx = new SvcLogicContext();
+ this.parameters = new HashMap<String, String>();
+ }
+
+ @Test
+ public final void list_of_containers() throws SvcLogicException {
+ this.parameters.put("list", "input.list");
+ this.parameters.put("sort-fields", "sort-key");
+ this.parameters.put("delimiter", ",");
+
+ ctx.setAttribute("input.list_length", "10");
+ for (int i = 0; i < 10; i++) {
+ this.ctx.setAttribute("input.list[" + i + "].sort-key", Integer.toString(rand.nextInt(10)));
+ this.ctx.setAttribute("input.list[" + i + "].value", Integer.toString(rand.nextInt(10)));
+ }
+
+ LOG.trace("BEFORE SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ utils.ctxSortList(this.parameters, this.ctx);
+
+ LOG.trace("AFTER SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ for (int i = 0; i < 9; i++) {
+ assertTrue(this.ctx.getAttribute("input.list[" + i + "].sort-key").compareTo(this.ctx.getAttribute("input.list[" + (i + 1) + "].sort-key")) < 1);
+ }
+ }
+
+ @Test
+ public final void list_of_elements() throws SvcLogicException {
+ this.parameters.put("list", "input.list");
+ this.parameters.put("delimiter", ",");
+
+ this.ctx.setAttribute("input.list_length", "10");
+ for (int i = 0; i < 10; i++) {
+ this.ctx.setAttribute("input.list[" + i + ']', Integer.toString(rand.nextInt(10)));
+ }
+
+ LOG.trace("BEFORE SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ utils.ctxSortList(this.parameters, this.ctx);
+
+ LOG.trace("AFTER SORT:");
+ SliPluginUtils.logContextMemory(ctx, LOG, SliPluginUtils.LogLevel.TRACE);
+
+ for (int i = 0; i < 9; i++) {
+ assertTrue(this.ctx.getAttribute("input.list[" + i + ']').compareTo(this.ctx.getAttribute("input.list[" + (i + 1) + ']')) < 1);
+ }
+ }
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java
new file mode 100644
index 00000000..d57cefa0
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliStringUtilsTest.java
@@ -0,0 +1,244 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+
+/**
+ * @author km991u
+ *
+ */
+public class SliStringUtilsTest {
+ private SvcLogicContext ctx;
+ private HashMap<String, String> param;
+ private SliStringUtils stringUtils = new SliStringUtils();
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp() throws Exception {
+ this.ctx = new SvcLogicContext();
+ param = new HashMap<String, String>();
+ }
+
+ /**
+ * @throws SvcLogicException
+ * @see SliStringUtils#split(Map, SvcLogicContext)
+ */
+ @Test
+ public final void testSplit() throws SvcLogicException {
+ param.put("original_string", "one ## two ## three");
+ param.put("regex", " ## ");
+ param.put("ctx_memory_result_key", "result");
+
+ stringUtils.split(param, ctx);
+
+ assertThat(ctx.getAttribute("result[0]"), equalTo("one"));
+ assertThat(ctx.getAttribute("result[1]"), equalTo("two"));
+ assertThat(ctx.getAttribute("result[2]"), equalTo("three"));
+ assertThat(ctx.getAttribute("result_length"), equalTo("3"));
+ }
+
+ /**
+ * @throws SvcLogicException
+ * @see SliStringUtils#split(Map, SvcLogicContext)
+ */
+ @Test
+ public final void testSplit_limit() throws SvcLogicException {
+ param.put("original_string", "one ## two ## three");
+ param.put("regex", " ## ");
+ param.put("limit", "2");
+ param.put("ctx_memory_result_key", "result");
+
+ stringUtils.split(param, ctx);
+
+ assertThat(ctx.getAttribute("result[0]"), equalTo("one"));
+ assertThat(ctx.getAttribute("result[1]"), equalTo("two ## three"));
+ assertThat(ctx.getAttribute("result_length"), equalTo("2"));
+ }
+
+ @Test
+ public void equalsIgnoreCaseTrue() throws SvcLogicException {
+ String sourceString = "HeLlOwORLD";
+ String targetSTring = "HELLOWORLD";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("true", SliStringUtils.equalsIgnoreCase(param, ctx));
+ }
+
+ @Test
+ public void equalsIgnoreCaseFalse() throws SvcLogicException {
+ String sourceString = "HeLlOwORLD";
+ String targetSTring = "goodbyeWORLD";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("false", SliStringUtils.equalsIgnoreCase(param, ctx));
+ }
+
+ @Test
+ public void toUpper() throws SvcLogicException {
+ String sourceString = "HeLlOwORLD";
+ param.put("source", sourceString);
+ String path = "my.unique.path.";
+ param.put("outputPath", path);
+ SliStringUtils.toUpper(param, ctx);
+ assertEquals(sourceString.toUpperCase(), ctx.getAttribute(path));
+ }
+
+ @Test
+ public void toLower() throws SvcLogicException {
+ String sourceString = "HeLlOwORLD";
+ param.put("source", sourceString);
+ String path = "my.unique.path.";
+ param.put("outputPath", path);
+ SliStringUtils.toLower(param, ctx);
+ assertEquals(sourceString.toLowerCase(), ctx.getAttribute(path));
+ }
+
+ @Test
+ public void containsTrue() throws SvcLogicException {
+ String sourceString = "Pizza";
+ String targetSTring = "izza";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("true", SliStringUtils.contains(param, ctx));
+ }
+
+ @Test
+ public void containsFalse() throws SvcLogicException {
+ String sourceString = "Pizza";
+ String targetSTring = "muffin";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("false", SliStringUtils.contains(param, ctx));
+ }
+
+ @Test
+ public void endsWithTrue() throws SvcLogicException {
+ String sourceString = "Pizza";
+ String targetSTring = "za";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("true", SliStringUtils.endsWith(param, ctx));
+ }
+
+ @Test
+ public void endsWithFalse() throws SvcLogicException {
+ String sourceString = "Pizza";
+ String targetSTring = "muffin";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("false", SliStringUtils.endsWith(param, ctx));
+ }
+
+ @Test
+ public void trim() throws SvcLogicException {
+ String sourceString = " H E L L O W O R L D";
+ String outputPath = "muffin";
+ param.put("source", sourceString);
+ param.put("outputPath", outputPath);
+ SliStringUtils.trim(param, ctx);
+ assertEquals(sourceString.trim(), ctx.getAttribute(outputPath));
+ }
+
+ @Test
+ public void getLength() throws SvcLogicException {
+ String sourceString = "SomeRandomString";
+ String outputPath = "muffin";
+ param.put("source", sourceString);
+ param.put("outputPath", outputPath);
+ SliStringUtils.getLength(param, ctx);
+ assertEquals(String.valueOf(sourceString.length()), ctx.getAttribute(outputPath));
+ }
+
+ @Test
+ public void startsWithFalse() throws SvcLogicException {
+ String sourceString = "Java";
+ String targetSTring = "DG";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("false", SliStringUtils.startsWith(param, ctx));
+ }
+
+ @Test
+ public void startsWithTrue() throws SvcLogicException {
+ String sourceString = "Java";
+ String targetSTring = "Ja";
+ param.put("source", sourceString);
+ param.put("target", targetSTring);
+ assertEquals("true", SliStringUtils.startsWith(param, ctx));
+ }
+
+ @Test
+ public void replace() throws SvcLogicException {
+ String sourceString = "cat Hello World cat";
+ String old = "cat";
+ String neww = "dog";
+ String outputPath = "out";
+
+ param.put("source", sourceString);
+ param.put("target", old);
+ param.put("replacement", neww);
+ param.put("outputPath", outputPath);
+ SliStringUtils.replace(param, ctx);
+ assertEquals(sourceString.replace(old, neww), ctx.getAttribute(outputPath));
+ }
+
+ @Test
+ public void concat() throws SvcLogicException {
+ String sourceString = "cat";
+ String targetString = "dog";
+ String outputPath = "out";
+
+ param.put("source", sourceString);
+ param.put("target", targetString);
+ param.put("outputPath", outputPath);
+ SliStringUtils.concat(param, ctx);
+ assertEquals(sourceString + targetString, ctx.getAttribute(outputPath));
+ }
+
+ @Test
+ public void urlEncode() throws SvcLogicException {
+ String sourceString = "102/GE100/SNJSCAMCJP8/SNJSCAMCJT4";
+ String outputPath = "out";
+
+ param.put("source", sourceString);
+ param.put("outputPath", outputPath);
+ SliStringUtils.urlEncode(param, ctx);
+ assertEquals("102%2FGE100%2FSNJSCAMCJP8%2FSNJSCAMCJT4", ctx.getAttribute(outputPath));
+ }
+
+}
diff --git a/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextListTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextListTest.java
new file mode 100644
index 00000000..5d7bb249
--- /dev/null
+++ b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextListTest.java
@@ -0,0 +1,307 @@
+/*-
+ * ============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.openecomp.sdnc.sli.SliPluginUtils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.HashMap;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+
+public class SvcLogicContextListTest {
+ //private static final Logger LOG = LoggerFactory.getLogger(SvcLogicContextTest.class);
+ private SvcLogicContext ctx;
+
+ @Before
+ public void setUp() throws Exception {
+ this.ctx = new SvcLogicContext();
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testSvcLogicContextList_SingleValueList() {
+ ctx.setAttribute("list[0]", "0");
+ ctx.setAttribute("list[1]", "1");
+ ctx.setAttribute("list[2]", "2");
+ ctx.setAttribute("list[3]", "3");
+ ctx.setAttribute("list[4]", "4");
+ ctx.setAttribute("list_length", "5");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+
+ // Check that size of list is 5
+ assertEquals(5, list.size());
+
+ // Check that each HashMap has it's list value in the empty string key
+ // and has no other values
+ assertEquals(1, list.get(0).size());
+ assertEquals("0", list.get(0).get(""));
+ assertEquals(1, list.get(1).size());
+ assertEquals("1", list.get(1).get(""));
+ assertEquals(1, list.get(2).size());
+ assertEquals("2", list.get(2).get(""));
+ assertEquals(1, list.get(3).size());
+ assertEquals("3", list.get(3).get(""));
+ assertEquals(1, list.get(4).size());
+ assertEquals("4", list.get(4).get(""));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testSvcLogicContextList_ObjectList() {
+ ctx.setAttribute("list[0].ipv4", "1.1.1.0");
+ ctx.setAttribute("list[0].ipv6", "2001::0");
+ ctx.setAttribute("list[1].ipv4", "1.1.1.1");
+ ctx.setAttribute("list[1].ipv6", "2001::1");
+ ctx.setAttribute("list[2].ipv4", "1.1.1.2");
+ ctx.setAttribute("list[2].ipv6", "2001::2");
+ ctx.setAttribute("list[3].ipv4", "1.1.1.3");
+ ctx.setAttribute("list[3].ipv6", "2001::3");
+ ctx.setAttribute("list[4].ipv4", "1.1.1.4");
+ ctx.setAttribute("list[4].ipv6", "2001::4");
+ ctx.setAttribute("list_length", "5");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+
+ // Check that size of list is 5
+ assertEquals(5, list.size());
+
+ assertEquals(2, list.get(0).size());
+ assertEquals("1.1.1.0", list.get(0).get("ipv4"));
+ assertEquals("2001::0", list.get(0).get("ipv6"));
+ assertEquals(2, list.get(1).size());
+ assertEquals("1.1.1.1", list.get(1).get("ipv4"));
+ assertEquals("2001::1", list.get(1).get("ipv6"));
+ assertEquals(2, list.get(2).size());
+ assertEquals("1.1.1.2", list.get(2).get("ipv4"));
+ assertEquals("2001::2", list.get(2).get("ipv6"));
+ assertEquals(2, list.get(3).size());
+ assertEquals("1.1.1.3", list.get(3).get("ipv4"));
+ assertEquals("2001::3", list.get(3).get("ipv6"));
+ assertEquals(2, list.get(4).size());
+ assertEquals("1.1.1.4", list.get(4).get("ipv4"));
+ assertEquals("2001::4", list.get(4).get("ipv6"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testExtract() {
+ ctx.setAttribute("list[0]", "0");
+ ctx.setAttribute("list[1]", "1");
+ ctx.setAttribute("list[2]", "2");
+ ctx.setAttribute("list[3]", "3");
+ ctx.setAttribute("list[4]", "4");
+ ctx.setAttribute("list_length", "5");
+ ctx.setAttribute("Other", "other");
+
+ SvcLogicContextList list = SvcLogicContextList.extract(ctx, "list");
+
+ // Check that size of list is 5
+ assertEquals(5, list.size());
+
+ // Check that all list values exist in list object
+ assertEquals(1, list.get(0).size());
+ assertEquals("0", list.get(0).get(""));
+ assertEquals(1, list.get(1).size());
+ assertEquals("1", list.get(1).get(""));
+ assertEquals(1, list.get(2).size());
+ assertEquals("2", list.get(2).get(""));
+ assertEquals(1, list.get(3).size());
+ assertEquals("3", list.get(3).get(""));
+ assertEquals(1, list.get(4).size());
+ assertEquals("4", list.get(4).get(""));
+
+ // Check that all list values no longer exist in ctx
+ assertNull(ctx.getAttribute("list[0]"));
+ assertNull(ctx.getAttribute("list[1]"));
+ assertNull(ctx.getAttribute("list[2]"));
+ assertNull(ctx.getAttribute("list[3]"));
+ assertNull(ctx.getAttribute("list[4]"));
+ assertNull(ctx.getAttribute("list_length"));
+
+ // Check that non-list values still exist in ctx
+ assertEquals("other", ctx.getAttribute("Other"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testRemove_int() {
+ ctx.setAttribute("list[0]", "0");
+ ctx.setAttribute("list[1]", "1");
+ ctx.setAttribute("list[2]", "2");
+ ctx.setAttribute("list[3]", "3");
+ ctx.setAttribute("list[4]", "4");
+ ctx.setAttribute("list_length", "5");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+ list.remove(2);
+
+ // Check that size of list is 4 (1 less than original)
+ assertEquals(4, list.size());
+
+ // Check that value was remove from list
+ assertEquals(1, list.get(0).size());
+ assertEquals("0", list.get(0).get(""));
+ assertEquals(1, list.get(1).size());
+ assertEquals("1", list.get(1).get(""));
+ assertEquals(1, list.get(2).size());
+ assertEquals("3", list.get(2).get(""));
+ assertEquals(1, list.get(3).size());
+ assertEquals("4", list.get(3).get(""));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testRemove_StringString() {
+ ctx.setAttribute("list[0].ipv4", "1.1.1.0");
+ ctx.setAttribute("list[0].ipv6", "2001::0");
+ ctx.setAttribute("list[1].ipv4", "1.1.1.1");
+ ctx.setAttribute("list[1].ipv6", "2001::1");
+ ctx.setAttribute("list[2].ipv4", "1.1.1.2");
+ ctx.setAttribute("list[2].ipv6", "2001::2");
+ ctx.setAttribute("list[3].ipv4", "1.1.1.3");
+ ctx.setAttribute("list[3].ipv6", "2001::3");
+ ctx.setAttribute("list[4].ipv4", "1.1.1.4");
+ ctx.setAttribute("list[4].ipv6", "2001::4");
+ ctx.setAttribute("list[5].ipv4", "1.1.1.2");
+ ctx.setAttribute("list[5].ipv6", "2001::2");
+ ctx.setAttribute("list_length", "6");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+ list.remove("ipv4", "1.1.1.2");
+
+ // Check that size of list is 4 (2 less than original)
+ assertEquals(4, list.size());
+
+ // Check that all elements with values ending in 2 were removed
+ assertEquals("1.1.1.0", list.get(0).get("ipv4"));
+ assertEquals("2001::0", list.get(0).get("ipv6"));
+ assertEquals("1.1.1.1", list.get(1).get("ipv4"));
+ assertEquals("2001::1", list.get(1).get("ipv6"));
+ assertEquals("1.1.1.3", list.get(2).get("ipv4"));
+ assertEquals("2001::3", list.get(2).get("ipv6"));
+ assertEquals("1.1.1.4", list.get(3).get("ipv4"));
+ assertEquals("2001::4", list.get(3).get("ipv6"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testRemove_StringString_ValueList() {
+ ctx.setAttribute("list[0]", "5");
+ ctx.setAttribute("list[1]", "6");
+ ctx.setAttribute("list[2]", "7");
+ ctx.setAttribute("list[3]", "8");
+ ctx.setAttribute("list[4]", "9");
+ ctx.setAttribute("list_length", "5");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+ list.remove("", "6");
+
+ // Check that size of list is 4 (1 less than original)
+ assertEquals(4, list.size());
+
+ // Check that value was remove from list
+ assertEquals(1, list.get(0).size());
+ assertEquals("5", list.get(0).get(""));
+ assertEquals(1, list.get(1).size());
+ assertEquals("7", list.get(1).get(""));
+ assertEquals(1, list.get(2).size());
+ assertEquals("8", list.get(2).get(""));
+ assertEquals(1, list.get(3).size());
+ assertEquals("9", list.get(3).get(""));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testRemove_Map() {
+ ctx.setAttribute("list[0].ipv4", "1.1.1.0");
+ ctx.setAttribute("list[0].ipv6", "2001::0");
+ ctx.setAttribute("list[1].ipv4", "1.1.1.1");
+ ctx.setAttribute("list[1].ipv6", "2001::1");
+ ctx.setAttribute("list[2].ipv4", "1.1.1.2");
+ ctx.setAttribute("list[2].ipv6", "2001::2");
+ ctx.setAttribute("list[3].ipv4", "1.1.1.3");
+ ctx.setAttribute("list[3].ipv6", "2001::3");
+ ctx.setAttribute("list[4].ipv4", "1.1.1.4");
+ ctx.setAttribute("list[4].ipv6", "2001::4");
+ ctx.setAttribute("list[5].ipv4", "1.1.1.2");
+ ctx.setAttribute("list[5].ipv6", "2001::2");
+ ctx.setAttribute("list_length", "6");
+
+ HashMap<String,String> remove_key = new HashMap<String,String>();
+ remove_key.put("ipv4", "1.1.1.2");
+ remove_key.put("ipv6", "2001::2");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+ list.remove(remove_key);
+
+ // Check that size of list is 4 (2 less than original)
+ assertEquals(4, list.size());
+
+ // Check that all elements with values ending in 2 were removed
+ assertEquals("1.1.1.0", list.get(0).get("ipv4"));
+ assertEquals("2001::0", list.get(0).get("ipv6"));
+ assertEquals("1.1.1.1", list.get(1).get("ipv4"));
+ assertEquals("2001::1", list.get(1).get("ipv6"));
+ assertEquals("1.1.1.3", list.get(2).get("ipv4"));
+ assertEquals("2001::3", list.get(2).get("ipv6"));
+ assertEquals("1.1.1.4", list.get(3).get("ipv4"));
+ assertEquals("2001::4", list.get(3).get("ipv6"));
+ }
+
+ // TODO: javadoc
+ @Test
+ public final void testWriteToContext() {
+ ctx.setAttribute("list[0]", "0");
+ ctx.setAttribute("list[1]", "1");
+ ctx.setAttribute("list[2]", "2");
+ ctx.setAttribute("list[3]", "3");
+ ctx.setAttribute("list[4]", "4");
+ ctx.setAttribute("list_length", "5");
+ ctx.setAttribute("Other", "other");
+
+ SvcLogicContextList list = new SvcLogicContextList( ctx, "list" );
+
+ // Erase context memory
+ ctx = new SvcLogicContext();
+
+ // Write list back into context memory
+ list.writeToContext(ctx);
+
+ // Check that size of list is 5
+ assertEquals(5, list.size());
+
+ // Check that all list values exist in list object
+ assertEquals("0", ctx.getAttribute("list[0]"));
+ assertEquals("1", ctx.getAttribute("list[1]"));
+ assertEquals("2", ctx.getAttribute("list[2]"));
+ assertEquals("3", ctx.getAttribute("list[3]"));
+ assertEquals("4", ctx.getAttribute("list[4]"));
+ assertEquals("5", ctx.getAttribute("list_length"));
+
+ // Check that old list values aren't in new list
+ assertNull(ctx.getAttribute("Other"));
+ }
+}
diff --git a/sliapi/.gitignore b/sliapi/.gitignore
new file mode 100755
index 00000000..b73caf31
--- /dev/null
+++ b/sliapi/.gitignore
@@ -0,0 +1,34 @@
+#####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
+
+## Folders which contain auto generated source code ##
+yang-gen-config
+yang-gen-sal
diff --git a/sliapi/README.txt b/sliapi/README.txt
new file mode 100755
index 00000000..f9f4a2ab
--- /dev/null
+++ b/sliapi/README.txt
@@ -0,0 +1,35 @@
+======================
+Introduction
+======================
+You have generated an MD-SAL module using the Brocade Archetype.
+
+* You should be able to successfully run 'mvn clean install' on this project.
+* This will produce a .zip file under the karaf.extension directory which you can deploy using
+Brocade's extension deployment mechanism.
+
+======================
+Next Steps:
+======================
+* run a 'mvn clean install' if you haven't already. This will generate some code from the yang models.
+* Modify the model yang file under the model project.
+* Follow the comments in the generated provider class to wire your new provider into the generated
+code.
+* Modify the generated provider model to respond to and handle the yang model. Depending on what
+you added to your model you may need to inherit additional interfaces or make other changes to
+the provider model.
+
+======================
+Generated Bundles:
+======================
+* model
+ - Provides the yang model for your application. This is your primary northbound interface.
+* provider
+ - Provides a template implementation for a provider to respond to your yang model.
+* features
+ - Defines a karaf feature. If you add dependencies on third-party bundles then you will need to
+ modify the features.xml to list out the dependencies.
+* karaf.extension
+ - Bundles all of the jars and third party dependencies (minus ODL dependencies) into a single
+ .zip file with the necessary configuration files to work correctly with the Brocade extension
+ mechanism.
+
diff --git a/sliapi/features/pom.xml b/sliapi/features/pom.xml
new file mode 100755
index 00000000..fcc08eb7
--- /dev/null
+++ b/sliapi/features/pom.xml
@@ -0,0 +1,134 @@
+<?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>
+ <artifactId>sliapi</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sliapi-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-provider</artifactId>
+ <classifier>config</classifier>
+ <type>xml</type>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-provider</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>features-mdsal</artifactId>
+ <version>${odl.mdsal.features.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+
+ <scope>runtime</scope>
+ </dependency>
+
+
+
+ <!-- dependency for opendaylight-karaf-empty for use by testing -->
+ <dependency>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>opendaylight-karaf-empty</artifactId>
+ <version>${odl.karaf.empty.distro.version}</version>
+ <type>zip</type>
+ </dependency>
+
+
+ <dependency>
+ <!-- Required for launching the feature tests-->
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-test</artifactId>
+ <scope>test</scope>
+ <version>${odl.commons.opendaylight.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>features-yangtools</artifactId>
+ <version>${odl.yangtools.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- launches the feature test, which validates that your karaf feature can
+ be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent
+ bundles defined correctly.
+ <plugin>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.odlparent</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/sliapi/features/src/main/resources/features.xml b/sliapi/features/src/main/resources/features.xml
new file mode 100644
index 00000000..630b1115
--- /dev/null
+++ b/sliapi/features/src/main/resources/features.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+ -->
+
+
+<features name="sdnc-sliapi-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository>
+
+ <feature name='sdnc-sliapi' description="sdnc-sliapi" version='${project.version}'>
+ <!-- Most applications will have a dependency on the ODL MD-SAL Broker -->
+ <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+ <feature version="${sdnctl.sli.version}">sdnc-sli</feature>
+ <bundle>mvn:org.openecomp.sdnc.core/sliapi-model/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.sdnc.core/sliapi-provider/${project.version}</bundle>
+ <configfile finalname="etc/opendaylight/karaf/200-sliapiprovider.xml">mvn:org.openecomp.sdnc.core/sliapi-provider/${project.version}/xml/config</configfile>
+ </feature>
+
+</features>
diff --git a/sliapi/installer/pom.xml b/sliapi/installer/pom.xml
new file mode 100755
index 00000000..a0204f3b
--- /dev/null
+++ b/sliapi/installer/pom.xml
@@ -0,0 +1,137 @@
+<?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>
+ <artifactId>sliapi</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sliapi-installer</artifactId>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>sdnc-sliapi</application.name>
+ <features.boot>sdnc-sliapi</features.boot>
+ <features.repositories>mvn:org.openecomp.sdnc.core/sliapi-features/${project.version}/xml/features</features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-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>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</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.openecomp.sdnc.core</includeGroupIds>
+ <excludeArtifactIds>sli-common,sli-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/sliapi/installer/src/assembly/assemble_installer_zip.xml b/sliapi/installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 00000000..85e2e1e8
--- /dev/null
+++ b/sliapi/installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,59 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/sliapi/installer/src/assembly/assemble_mvnrepo_zip.xml b/sliapi/installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 00000000..18700a1b
--- /dev/null
+++ b/sliapi/installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,55 @@
+<!--
+ ============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=========================================================
+ -->
+
+<!-- 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/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+ <files>
+ <file>
+ <source>../provider/src/main/resources/initial/${feature-name}-provider.xml</source>
+ <destName>./etc/opendaylight/karaf/200-${feature-name}provider.xml</destName>
+ </file>
+
+ </files>
+
+</assembly>
diff --git a/sliapi/installer/src/main/resources/scripts/install-feature.sh b/sliapi/installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 00000000..93236c5b
--- /dev/null
+++ b/sliapi/installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+###
+# ============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=========================================================
+###
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+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} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
diff --git a/sliapi/model/pom.xml b/sliapi/model/pom.xml
new file mode 100755
index 00000000..be8c8b3c
--- /dev/null
+++ b/sliapi/model/pom.xml
@@ -0,0 +1,79 @@
+<?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>
+ <artifactId>sliapi</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sliapi-model</artifactId>
+ <packaging>bundle</packaging>
+
+ <build>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${odl.yangtools.yang.maven.plugin.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${odl.sal.api.gen.plugin.version}</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <yangFilesRootDir>${yang.file.directory}</yangFilesRootDir>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>yang-binding</artifactId>
+ <version>${odl.mdsal.yang.binding.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-common</artifactId>
+ <version>${odl.yangtools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ <version>${odl.ietf-inet-types.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types</artifactId>
+ <version>${odl.ietf-yang-types.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sliapi/model/src/main/yang/sliapi.yang b/sliapi/model/src/main/yang/sliapi.yang
new file mode 100755
index 00000000..047fd690
--- /dev/null
+++ b/sliapi/model/src/main/yang/sliapi.yang
@@ -0,0 +1,111 @@
+module SLI-API {
+
+ yang-version 1;
+
+ namespace "org:openecomp:sdnc:sliapi";
+
+ prefix sample;
+
+ import ietf-inet-types { prefix "inet"; revision-date 2010-09-24; }
+
+ organization "openECOMP";
+
+ 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;
+ }
+ }
+
+ 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/sliapi/pom.xml b/sliapi/pom.xml
new file mode 100755
index 00000000..06ee5e0e
--- /dev/null
+++ b/sliapi/pom.xml
@@ -0,0 +1,61 @@
+<?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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+
+ <parent>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sdnc-core</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <packaging>pom</packaging>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <properties>
+ <feature-name>sliapi</feature-name>
+ </properties>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-features</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-provider</artifactId>
+ <version>${project.version}</version>
+ <classifier>config</classifier>
+ <type>xml</type>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+
+ </dependencyManagement>
+
+ <modules>
+ <module>model</module>
+ <module>features</module>
+ <module>provider</module>
+ <module>installer</module>
+ </modules>
+</project>
diff --git a/sliapi/provider/pom.xml b/sliapi/provider/pom.xml
new file mode 100755
index 00000000..b4a6ff0f
--- /dev/null
+++ b/sliapi/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>
+ <artifactId>sliapi</artifactId>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>sliapi-provider</artifactId>
+ <packaging>bundle</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>org.opendaylight.controller.config.yang.config.sliapi.impl</Export-Package>
+ <Import-Package>*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${odl.yangtools.yang.maven.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>config</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+ <additionalConfiguration>
+ <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+ </additionalConfiguration>
+ </generator>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${odl.sal.api.gen.plugin.version}</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-jmx-generator-plugin</artifactId>
+ <version>${odl.yang.jmx.generator.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/sliapi-provider.xml</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sliapi-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ <version>${odl.controller.config.api.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-config</artifactId>
+ <version>${odl.mdsal.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <version>${odl.mdsal.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ <version>${odl.mdsal.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-core-api</artifactId>
+ <version>${odl.mdsal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>${odl.yangtools.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java
new file mode 100644
index 00000000..e05103cd
--- /dev/null
+++ b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java
@@ -0,0 +1,59 @@
+/*-
+ * ============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.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523;
+
+import org.openecomp.sdnc.sliapi.sliapiProvider;
+
+public class SliapiProviderModule extends org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523.AbstractSliapiProviderModule {
+ public SliapiProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public SliapiProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523.SliapiProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+
+ final sliapiProvider provider = new sliapiProvider();
+ provider.setDataBroker( getDataBrokerDependency() );
+ provider.setNotificationService( getNotificationServiceDependency() );
+ provider.setRpcRegistry( getRpcRegistryDependency() );
+ provider.initialize();
+ return new AutoCloseable() {
+
+ @Override
+ public void close() throws Exception {
+ //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION
+ //SERVIE/RPC REGISTRY
+ provider.close();
+ }
+ };
+ }
+
+}
diff --git a/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java
new file mode 100644
index 00000000..fbd20365
--- /dev/null
+++ b/sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java
@@ -0,0 +1,34 @@
+/*-
+ * ============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=========================================================
+ */
+
+/*
+* Generated file
+*
+* Generated from: yang module name: slitester-provider-impl yang module local name: sliapi-provider-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Oct 21 10:42:49 EDT 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523;
+public class SliapiProviderModuleFactory extends org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.provider.impl.rev140523.AbstractSliapiProviderModuleFactory {
+
+}
diff --git a/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java
new file mode 100644
index 00000000..4ad4f016
--- /dev/null
+++ b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java
@@ -0,0 +1,40 @@
+/*-
+ * ============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.openecomp.sdnc.sliapi;
+
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.execute.graph.input.SliParameterBuilder;
+import org.openecomp.sdnc.sli.provider.MdsalHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SliapiHelper extends MdsalHelper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SliapiHelper.class);
+
+ static {
+ ExecuteGraphInputBuilder b1 = new ExecuteGraphInputBuilder();
+ SliParameterBuilder b2 = new SliParameterBuilder();
+
+ }
+
+}
diff --git a/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java
new file mode 100644
index 00000000..705277c6
--- /dev/null
+++ b/sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java
@@ -0,0 +1,557 @@
+/*-
+ * ============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.openecomp.sdnc.sliapi;
+
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.impl.AbstractForwardedDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInput;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInput.Mode;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphInputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphOutput;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.ExecuteGraphOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.HealthcheckOutput;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.HealthcheckOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.SLIAPIService;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.TestResults;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.execute.graph.input.SliParameter;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.test.results.TestResult;
+import org.opendaylight.yang.gen.v1.org.openecomp.sdnc.sliapi.rev161110.test.results.TestResultBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.openecomp.sdnc.sli.provider.SvcLogicService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+
+
+/**
+ * Defines a base implementation for your provider. This class extends from a helper class
+ * which provides storage for the most commonly used components of the MD-SAL. Additionally the
+ * base class provides some basic logging and initialization / clean up methods.
+ *
+ * To use this, copy and paste (overwrite) the following method into the TestApplicationProviderModule
+ * class which is auto generated under src/main/java in this project
+ * (created only once during first compilation):
+ *
+ * <pre>
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+
+ final sliapiProvider provider = new sliapiProvider();
+ provider.setDataBroker( getDataBrokerDependency() );
+ provider.setNotificationService( getNotificationServiceDependency() );
+ provider.setRpcRegistry( getRpcRegistryDependency() );
+ provider.initialize();
+ return new AutoCloseable() {
+
+ @Override
+ public void close() throws Exception {
+ //TODO: CLOSE ANY REGISTRATION OBJECTS CREATED USING ABOVE BROKER/NOTIFICATION
+ //SERVIE/RPC REGISTRY
+ provider.close();
+ }
+ };
+ }
+
+
+ </pre>
+ */
+public class sliapiProvider implements AutoCloseable, SLIAPIService{
+
+ private final Logger LOG = LoggerFactory.getLogger( sliapiProvider.class );
+ private final String appName = "slitester";
+
+ protected DataBroker dataBroker;
+ protected DOMDataBroker domDataBroker;
+ protected NotificationProviderService notificationService;
+ protected RpcProviderRegistry rpcRegistry;
+
+ protected BindingAwareBroker.RpcRegistration<SLIAPIService> rpcRegistration;
+
+ private static String SLIAPI_NAMESPACE = "org:openecomp:sdnc:sliapi";
+ private static String SLIAPI_REVISION = "2016-11-10";
+
+ private static QName TEST_RESULTS_QNAME = null;
+ private static QName TEST_RESULT_QNAME = null;
+ private static QName TEST_ID_QNAME = null;
+ private static QName RESULTS_QNAME = null;
+
+ static {
+
+ TEST_RESULTS_QNAME = QName.create(SLIAPI_NAMESPACE, SLIAPI_REVISION, "test-results");
+ TEST_RESULT_QNAME = QName.create(TEST_RESULTS_QNAME, "test-result");
+ TEST_ID_QNAME = QName.create(TEST_RESULT_QNAME, "test-identifier");
+ RESULTS_QNAME = QName.create(TEST_RESULT_QNAME, "results");
+ }
+
+
+ public sliapiProvider() {
+ this.LOG.info( "Creating provider for " + appName );
+ }
+
+ public void initialize(){
+ LOG.info( "Initializing provider for " + appName );
+ //initialization code goes here.
+
+ rpcRegistration = rpcRegistry.addRpcImplementation(SLIAPIService.class, this);
+ LOG.info( "Initialization complete for " + appName );
+ }
+
+ protected void initializeChild() {
+ //Override if you have custom initialization intelligence
+ }
+
+ @Override
+ public void close() throws Exception {
+ LOG.info( "Closing provider for " + appName );
+ //closing code goes here
+
+ rpcRegistration.close();
+ LOG.info( "Successfully closed provider for " + appName );
+ }
+
+ public void setDataBroker(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ if (dataBroker instanceof AbstractForwardedDataBroker) {
+ domDataBroker = ((AbstractForwardedDataBroker) dataBroker).getDelegate();
+ }
+ if( LOG.isDebugEnabled() ){
+ LOG.debug( "DataBroker set to " + (dataBroker==null?"null":"non-null") + "." );
+ }
+ }
+
+ public void setNotificationService(
+ NotificationProviderService notificationService) {
+ this.notificationService = notificationService;
+ if( LOG.isDebugEnabled() ){
+ LOG.debug( "Notification Service set to " + (notificationService==null?"null":"non-null") + "." );
+ }
+ }
+
+ public void setRpcRegistry(RpcProviderRegistry rpcRegistry) {
+ this.rpcRegistry = rpcRegistry;
+ if( LOG.isDebugEnabled() ){
+ LOG.debug( "RpcRegistry set to " + (rpcRegistry==null?"null":"non-null") + "." );
+ }
+ }
+
+ @Override
+ public Future<RpcResult<ExecuteGraphOutput>> executeGraph(ExecuteGraphInput input) {
+ RpcResult<ExecuteGraphOutput> rpcResult = null;
+
+ SvcLogicService svcLogic = getSvcLogicService();
+ ExecuteGraphOutputBuilder respBuilder = new ExecuteGraphOutputBuilder();
+
+ String calledModule = input.getModuleName();
+ String calledRpc = input.getRpcName();
+ Mode calledMode = input.getMode();
+ String modeStr = "sync";
+
+ if (calledMode == Mode.Async) {
+ modeStr = "async";
+ }
+
+ if (svcLogic == null) {
+ respBuilder.setResponseCode("500");
+ respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
+ respBuilder.setAckFinalIndicator("Y");
+
+ rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
+ return(Futures.immediateFuture(rpcResult));
+ }
+
+
+ try {
+ if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
+ respBuilder.setResponseCode("404");
+ respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
+ respBuilder.setAckFinalIndicator("Y");
+
+ rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
+ return(Futures.immediateFuture(rpcResult));
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
+
+ respBuilder.setResponseCode("500");
+ respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
+ respBuilder.setAckFinalIndicator("Y");
+
+ rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true).withResult(respBuilder.build()).build();
+ return(Futures.immediateFuture(rpcResult));
+ }
+
+ // Load properties
+ Properties parms = new Properties();
+
+ // Pass properties using names from sli-parameters
+ for (SliParameter sliParm : input.getSliParameter()) {
+
+ String propValue = "";
+
+ Boolean boolval = sliParm.isBooleanValue();
+
+ if (boolval != null) {
+ propValue = boolval.toString();
+ } else {
+ Integer intval = sliParm.getIntValue();
+ if (intval != null) {
+ propValue = intval.toString();
+ } else {
+ propValue = sliParm.getStringValue();
+ if (propValue == null) {
+ propValue = "";
+ }
+ }
+ }
+ parms.setProperty(sliParm.getParameterName(), propValue);
+ }
+
+ // Also, pass "meta" properties (i.e. pass SliParameter objects themselves)
+ ExecuteGraphInputBuilder inputBuilder = new ExecuteGraphInputBuilder(input);
+
+ SliapiHelper.toProperties(parms, "input", inputBuilder);
+
+ try {
+ LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
+
+ if (LOG.isTraceEnabled()) {
+ StringBuffer argList = new StringBuffer();
+ argList.append("Parameters : {");
+ Enumeration e = parms.propertyNames();
+ while (e.hasMoreElements()) {
+ String propName = (String) e.nextElement();
+ argList.append(" ("+propName+","+parms.getProperty(propName)+") ");
+ }
+ argList.append("}");
+ LOG.trace(argList.toString());
+ argList = null;
+ }
+
+
+
+ Properties respProps = svcLogic.execute(calledModule, calledRpc,
+ null, modeStr, parms, domDataBroker);
+
+ StringBuilder sb = new StringBuilder("{");
+
+ for (Object key : respProps.keySet()) {
+ String keyValue = (String) key;
+ if (keyValue != null && !"".equals(keyValue) && !keyValue.contains("input.sli-parameter")) {
+ sb.append("\"").append(keyValue).append("\": \"").append(respProps.getProperty(keyValue)).append("\",");
+ }
+ }
+
+ sb.setLength(sb.length() - 1);
+ sb.append("}");
+
+ respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
+ respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));// TODO change response-text to response-message to match other BVC APIs
+ respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
+ respBuilder.setContextMemoryJson(sb.toString());
+
+ TestResultBuilder testResultBuilder = new TestResultBuilder();
+
+ SliapiHelper.toBuilder(respProps, testResultBuilder);
+
+ String testIdentifier = testResultBuilder.getTestIdentifier();
+
+ if ((testIdentifier != null) && (testIdentifier.length() > 0)) {
+
+ // Add test results to config tree
+ LOG.debug("Saving test results for test id "+testIdentifier);
+
+ DomSaveTestResult(testResultBuilder.build(), true, LogicalDatastoreType.CONFIGURATION);
+
+ }
+
+ } catch (Exception e) {
+ LOG.error("Caught exception executing directed graph for"
+ + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
+
+ respBuilder.setResponseCode("500");
+ respBuilder
+ .setResponseMessage("Internal error : caught exception executing directed graph "
+ + calledModule
+ + "/"
+ + calledRpc
+ + "/"
+ + modeStr);
+ respBuilder.setAckFinalIndicator("Y");
+
+ }
+
+ rpcResult = RpcResultBuilder.<ExecuteGraphOutput> status(true)
+ .withResult(respBuilder.build()).build();
+ return (Futures.immediateFuture(rpcResult));
+ }
+
+
+ private SvcLogicService getSvcLogicService() {
+ BundleContext bctx = FrameworkUtil.getBundle(SvcLogicService.class).getBundleContext();
+
+ SvcLogicService svcLogic = null;
+
+ // Get SvcLogicService reference
+ ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME);
+ if (sref != null)
+ {
+ svcLogic = (SvcLogicService) bctx.getService(sref);
+
+ }
+ else
+ {
+ LOG.warn("Cannot find service reference for "+SvcLogicService.NAME);
+
+ }
+
+ return(svcLogic);
+ }
+
+ @Override
+ public Future<RpcResult<HealthcheckOutput>> healthcheck() {
+
+ RpcResult<HealthcheckOutput> rpcResult = null;
+ SvcLogicService svcLogic = getSvcLogicService();
+
+ HealthcheckOutputBuilder respBuilder = new HealthcheckOutputBuilder();
+
+ String calledModule = "sli";
+ String calledRpc = "healthcheck";
+ String modeStr = "sync";
+
+ if (svcLogic == null) {
+ respBuilder.setResponseCode("500");
+ respBuilder.setResponseMessage("Could not locate OSGi SvcLogicService service");
+ respBuilder.setAckFinalIndicator("Y");
+
+ rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
+ return(Futures.immediateFuture(rpcResult));
+ }
+
+ try {
+ if (!svcLogic.hasGraph(calledModule, calledRpc, null, modeStr)) {
+ respBuilder.setResponseCode("404");
+ respBuilder.setResponseMessage("Directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr+" not found");
+
+ respBuilder.setAckFinalIndicator("Y");
+
+ rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true).withResult(respBuilder.build()).build();
+ return(Futures.immediateFuture(rpcResult));
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception looking for directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr, e);
+
+ respBuilder.setResponseCode("500");
+ respBuilder.setResponseMessage("Internal error : could not determine if target graph exists");
+ respBuilder.setAckFinalIndicator("Y");
+
+ rpcResult = RpcResultBuilder.<HealthcheckOutput> failed().withResult(respBuilder.build()).build();
+ return(Futures.immediateFuture(rpcResult));
+ }
+
+ try {
+ LOG.info("Calling directed graph for "+calledModule+"/"+calledRpc+"/"+modeStr);
+
+ Properties parms = new Properties();
+
+ Properties respProps = svcLogic.execute(calledModule, calledRpc,
+ null, modeStr, parms);
+
+ respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
+ respBuilder.setResponseMessage(respProps.getProperty("error-message", ""));
+ respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
+
+ } catch (Exception e) {
+ LOG.error("Caught exception executing directed graph for"
+ + calledModule + ":" + calledRpc + "," + modeStr + ">", e);
+
+ respBuilder.setResponseCode("500");
+ respBuilder
+ .setResponseMessage("Internal error : caught exception executing directed graph "
+ + calledModule
+ + "/"
+ + calledRpc
+ + "/"
+ + modeStr);
+ respBuilder.setAckFinalIndicator("Y");
+
+ }
+
+ rpcResult = RpcResultBuilder.<HealthcheckOutput> status(true)
+ .withResult(respBuilder.build()).build();
+ return (Futures.immediateFuture(rpcResult));
+ }
+
+ private void DomSaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) {
+
+
+ if (domDataBroker == null) {
+ LOG.error("domDataBroker unset - cannot save test result using DOMDataBroker");
+ return;
+ }
+
+ MapEntryNode resultNode = null;
+
+ try {
+ resultNode = toMapEntryNode(entry);
+ } catch (Exception e) {
+ LOG.error("Caught exception trying to create map entry node", e);
+ }
+
+ if (resultNode == null) {
+ LOG.error("Could not convert entry to MapEntryNode");
+ return;
+ }
+
+
+ YangInstanceIdentifier testResultsPid = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(QName.create(TEST_RESULTS_QNAME, "test-result")).build();
+ YangInstanceIdentifier testResultPid = testResultsPid.node(new NodeIdentifierWithPredicates(TEST_RESULT_QNAME, resultNode.getIdentifier().getKeyValues()));
+
+
+
+ int tries = 2;
+ while(true) {
+ try {
+ DOMDataWriteTransaction wtx = domDataBroker.newWriteOnlyTransaction();
+ if (merge) {
+ LOG.info("Merging test identifier "+entry.getTestIdentifier());
+ wtx.merge(storeType, testResultPid, resultNode);
+ } else {
+ LOG.info("Putting test identifier "+entry.getTestIdentifier());
+ wtx.put(storeType, testResultPid, resultNode);
+ }
+ wtx.submit().checkedGet();
+ LOG.trace("Update DataStore succeeded");
+ break;
+ } catch (final TransactionCommitFailedException e) {
+ if(e instanceof OptimisticLockFailedException) {
+ if(--tries <= 0) {
+ LOG.trace("Got OptimisticLockFailedException on last try - failing ");
+ throw new IllegalStateException(e);
+ }
+ LOG.trace("Got OptimisticLockFailedException - trying again ");
+ } else {
+ LOG.trace("Update DataStore failed");
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ }
+
+ private void SaveTestResult(final TestResult entry, boolean merge, LogicalDatastoreType storeType) throws IllegalStateException
+ {
+ // Each entry will be identifiable by a unique key, we have to create that identifier
+ InstanceIdentifier.InstanceIdentifierBuilder<TestResult> testResultIdBuilder =
+ InstanceIdentifier.<TestResults>builder(TestResults.class)
+ .child(TestResult.class, entry.getKey());
+ InstanceIdentifier<TestResult> path = testResultIdBuilder.toInstance();
+ int tries = 2;
+ while(true) {
+ try {
+ WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+ if (merge) {
+ tx.merge(storeType, path, entry);
+ } else {
+ tx.put(storeType, path, entry);
+ }
+ tx.submit().checkedGet();
+ LOG.trace("Update DataStore succeeded");
+ break;
+ } catch (final TransactionCommitFailedException e) {
+ if(e instanceof OptimisticLockFailedException) {
+ if(--tries <= 0) {
+ LOG.trace("Got OptimisticLockFailedException on last try - failing ");
+ throw new IllegalStateException(e);
+ }
+ LOG.trace("Got OptimisticLockFailedException - trying again ");
+ } else {
+ LOG.trace("Update DataStore failed");
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+ }
+
+ private MapEntryNode toMapEntryNode(TestResult testResult) {
+
+
+ YangInstanceIdentifier testResultId = YangInstanceIdentifier.builder().node(TEST_RESULTS_QNAME).node(TEST_RESULT_QNAME).build();
+
+ // Construct results list
+ LinkedList<LeafSetEntryNode<Object>> entryList = new LinkedList<LeafSetEntryNode<Object>>();
+ for (String result : testResult.getResults()) {
+ LeafSetEntryNode<Object> leafSetEntryNode = ImmutableLeafSetEntryNodeBuilder.create()
+ .withNodeIdentifier(new NodeWithValue(RESULTS_QNAME, result))
+ .withValue(result)
+ .build();
+ entryList.add(leafSetEntryNode);
+ }
+ // Construct results LeafSetNode
+ LeafSetNode<?> resultsNode = ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(RESULTS_QNAME)).withValue(entryList).build();
+
+
+
+ // Construct test result ContainerNode with 2 children - test-identifier leaf and results leaf-set
+ MapEntryNode testResultNode = ImmutableNodes.mapEntryBuilder()
+ .withNodeIdentifier(new NodeIdentifierWithPredicates(TEST_RESULT_QNAME, TEST_ID_QNAME, testResult.getTestIdentifier()))
+ .withChild(ImmutableNodes.leafNode(TEST_ID_QNAME, testResult.getTestIdentifier()))
+ .withChild(resultsNode)
+ .build();
+
+ return(testResultNode);
+
+ }
+
+}
diff --git a/sliapi/provider/src/main/resources/initial/sliapi-provider.xml b/sliapi/provider/src/main/resources/initial/sliapi-provider.xml
new file mode 100644
index 00000000..fd2ccbee
--- /dev/null
+++ b/sliapi/provider/src/main/resources/initial/sliapi-provider.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+ -->
+
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+
+ <!-- This xmlns:prefix should match the namespace in the *-provider-impl.yang file
+ The prefix: inside type should match the prefix of the yang file. -->
+ <type xmlns:prefix="org:openecomp:sdnc:sliapi:provider:impl">
+ prefix:sliapi-provider-impl
+ </type>
+ <name>sliapi-provider-impl</name>
+
+ <!-- The following sections contain bindings to services defined in the
+ *-provider-impl yang file. For example the rpc-registry is required
+ because we have a dependency (or augmentation) named "rpc-registry"
+ and which binds to the md-sa-binding-registry. If you remove those
+ dependencies from the yang file then you can remove them from here. -->
+ <rpc-registry>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <name>binding-rpc-broker</name>
+ </rpc-registry>
+
+ <data-broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+ <name>binding-data-broker</name>
+ </data-broker>
+
+ <notification-service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
+ binding:binding-notification-service
+ </type>
+ <name>binding-notification-broker</name>
+ </notification-service>
+ </module>
+
+ </modules>
+ </data>
+
+ </configuration>
+
+ <!-- Required capabilities are basically a listing of all modules that need to be imported before
+ our service can be resolved. Capabilities for dependencies defined above are implied which is
+ why we do not have define a required capability for the data broker, for example. -->
+ <required-capabilities>
+ <capability>org:openecomp:sdnc:sliapi:provider:impl?module=sliapi-provider-impl&amp;revision=2014-05-23</capability>
+ </required-capabilities>
+
+</snapshot>
diff --git a/sliapi/provider/src/main/yang/sliapi-provider-impl.yang b/sliapi/provider/src/main/yang/sliapi-provider-impl.yang
new file mode 100755
index 00000000..b32ff6c3
--- /dev/null
+++ b/sliapi/provider/src/main/yang/sliapi-provider-impl.yang
@@ -0,0 +1,61 @@
+module sliapi-provider-impl {
+
+ yang-version 1;
+ namespace "org:openecomp:sdnc:sliapi:provider:impl";
+ prefix "sliapi-provider-impl";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+ description
+ "This module contains the base YANG definitions for
+ sliapi-provider impl implementation.";
+
+ revision "2014-05-23" {
+ description
+ "Initial revision.";
+ }
+
+ // This is the definition of the service implementation as a module identity.
+ identity sliapi-provider-impl {
+ base config:module-type;
+
+ // Specifies the prefix for generated java classes.
+ config:java-name-prefix sliapiProvider;
+ }
+
+ // Augments the 'configuration' choice node under modules/module.
+ // We consume the three main services, RPCs, DataStore, and Notifications
+ augment "/config:modules/config:module/config:configuration" {
+ case sliapi-provider-impl {
+ when "/config:modules/config:module/config:type = 'sliapi-provider-impl'";
+
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-rpc-registry;
+ }
+ }
+ }
+
+ container notification-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-notification-service;
+ }
+ }
+ }
+
+ container data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity mdsal:binding-async-data-broker;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/site/apt/nodes.apt b/src/site/apt/nodes.apt
new file mode 100644
index 00000000..b8ce9879
--- /dev/null
+++ b/src/site/apt/nodes.apt
@@ -0,0 +1,953 @@
+~~~
+~~ ============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 Interpreter
+ ---
+ Dan Timoney
+ ---
+ 2014-11-12
+ ---
+
+Supported node types
+
+ The following built-in node types are currently supported:
+
+ * Flow Control
+
+ * {{{Block node}<<block>>}}
+
+ * {{{Call node}<<call>>}}
+
+ * {{{For node}<<for>>}}
+
+ * {{{Return node}<<return>>}}
+
+ * {{{Set node}<<set>>}}
+
+ * {{{Switch node}<<switch>>}}
+
+ * Device Management
+
+ * {{{Configure node}<<configure>>}}
+
+ * Java Plugin Support
+
+ * {{{Execute node}<<execute>>}}
+
+ * Recording
+
+ * {{{Record node}<<record>>}}
+
+ * Resource Management
+
+ * {{{Delete node}<<delete>>}}
+
+ * {{{Exists node}<<exists>>}}
+
+ * {{{Get-resource node}<<get-resource>>}}
+
+ * {{{Is-available node}<<is-available>>}}
+
+ * {{{Notify node}<<notify>>}}
+
+ * {{{Release node}<<release>>}}
+
+ * {{{Reserve node}<<reserve>>}}
+
+ * {{{Save node}<<save>>}}
+
+ * {{{Update node}<<update>>}}
+
+
+* Flow Control
+
+** Block node
+
+*** Description
+
+ A <<block>> node is used to executes a set of nodes.
+
+*** Attributes
+
+*--------------*--------------------------------------------+
+| <<atomic>> | if <true>, then if a node returns failure, subsequent nodes will not be executed and nodes already executed will be backed out.
+*--------------*--------------------------------------------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+ None
+
+*** Example
+
++-----------------+
+<block>
+ <record plugin="org.openecomp.sdnc.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>
++-----------------+
+
+
+
+**Call node
+
+*** Description
+
+ A <<call>> node is used to call another graph
+
+*** Attributes
+
+*--------------*-------+
+| <<module>> | Module of directed graph to call. If unset, defaults to that of calling graph
+*--------------*-------+
+| <<rpc>> | rpc of directed graph to call.
+*--------------*-------+
+| <<version>> | version of graph to call, If unset, uses active version.
+*--------------*-------+
+| <<mode>> | mode (sync/async) of graph to call. If unset, defaults to that of calling graph.
+*--------------*-------+
+
+
+
+*** Parameters
+
+ Not applicable
+
+*** Outcomes
+
+*----------*---------+
+| <<success>> | Sub graph returned success
+*----------*---------+
+| <<not-found>> | Graph not found
+*----------*---------+
+| <<failure>> | Subgraph returned success
+*----------*---------+
+ .
+
+*** Example
+
++-------------------+
+<call rpc="svc-topology-reserve" mode="sync" />
++-------------------+
+
+**For node
+
+*** Description
+
+ A <<for>> node provides a fixed iteration looping mechanism, similar to the Java for loop
+
+*** Attributes
+
+*--------------*-------+
+| <<index>> | index variable
+*--------------*-------+
+| <<start>> | initial value
+*--------------*-------+
+| <<end>> | maximum value
+*--------------*-------+
+
+
+*** Parameters
+
+ Not applicable.
+
+*** Outcomes
+
+ Not applicable. The <<status>> node has no outcomes.
+
+*** Example
+
++-------------------+
+<for index="i" start="0" end="`$service-data.universal-cpe-ft.l2-switch-interfaces_length`">
+ <record plugin="org.openecomp.sdnc.sli.recording.Slf4jRecorder">
+ <parameter name="logger" value="message-log"/>
+ <parameter name="level" value="info"/>
+ <parameter name="field1" value="`'current l2-switch-interface name is ' + $service-data.universal-cpe-ft.l2-switch-interfaces[$i].name`"/>
+ </record>
+</for>
++-------------------+
+
+**Return node
+
+*** Description
+
+ A <<return>> node is used to return a status to the invoking MD-SAL application
+
+*** Attributes
+
+*--------------*-------+
+| <<status>> | Status value to return (<success> or <failure>)
+*--------------*-------+
+
+
+*** Parameters
+
+ The following optional parameters may be passed to convey more
+ detailed status information.
+
+*------------*-----------+
+| <<error-code>> | A brief, usually numeric, code indicating the error condition
+*------------*-----------+
+| <<error-message>> | A more detailed error message
+*------------*-----------+
+
+*** Outcomes
+
+ Not applicable. The <<status>> node has no outcomes.
+
+*** Example
+
++-------------------+
+<return status="failure">
+ <parameter name="error-code" value="1542" />
+ <parameter name="error-message" value="Activation failure" />
+</return>
++-------------------+
+
+**Set node
+
+*** Description
+
+ A <<set>> node is used to set one or more values in the execution context
+
+*** Attributes
+
+*--------------*-------+
+| <<only-if-unset>> | If true the set node will only execute if the current value of the target is null
+*--------------*-------+
+
+*** Parameters
+
+ Values to be set are passed as parameters
+
+*** Outcomes
+
+ Not applicable. The <<set>> node has no outcomes.
+
+*** Example
+
++-------------------+
+<set>
+ <parameter name="vlan" value="$network.provider-segmentation-id" />
+</set>
++-------------------+
+
+**Switch node
+
+*** Description
+
+ A <<switch>> node is used to make a decision based on its <<test>> attribute.
+
+*** Attributes
+
+*--------------*-------+
+| <<test>> | Condition to test
+*--------------*-------+
+
+
+*** Parameters
+
+ None
+
+
+*** Outcomes
+
+ Depends on the <<test>> condition
+
+*** Example
+
++-------------------+
+<switch test="$uni-cir-units">
+ <outcome value="Mbps">
+ <reserve plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="resource-emt-clli == $edge-device-clli and speed >= $uni-cir-value"
+ pfx="asePort">
+
+ <outcome value="success">
+ <return status="success">
+ <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1010" />
+ <parameter name="error-message" value="No ports found that match criteria" />
+ </return>
+ </outcome>
+ </reserve>
+ </outcome>
+ <outcome value="Gbps">
+ <reserve plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="resource-emt-clli == $edge-device-clli and speed >= $uni-cir-value*1000"
+ pfx="asePort">
+
+ <outcome value="success">
+ <return status="success">
+ <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1010" />
+ <parameter name="error-message" value="No ports found that match criteria" />
+ </return>
+ </outcome>
+ </reserve>
+ </outcome>
+</switch>
++-------------------+
+
+* Device Management
+
+**Configure node
+
+*** Description
+
+ A <<configure>> node is used to configure a device.
+
+*** Attributes
+
+*--------------*-------+
+| <<adaptor>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<activate>> | Activate device/interface, for devices that support a separate activation step.
+*--------------*-------+
+| <<key>> | SQL-like string specifying criteria for item to configure
+*--------------*-------+
+
+*** Parameters
+
+ Specific to device adaptor.
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Device successfully configured
+*-----------*-------+
+| <<not-found>> | Element to be configured does not exist.
+*-----------*--------+
+| <<not-ready>> | Element is not in a state where it can be configured/activated
+*-----------*-------+
+| <<already-active>> | Attempt to activate element that is already active
+*-----------*-------+
+| <<failure>> | Configure failed for some other reason
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<configure adaptor="org.openecomp.sdnc.sli.adaptor.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.openecomp.sdnc.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>
++-------------------+
+
+* Java Plugin Support
+
+**Execute node
+
+*** Description
+
+ An <<execute>> node is used to execute Java code supplied as a plugin
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of plugin to be used
+*--------------*-------+
+| <<method>> | Name of method in the plugin class to execute. Method must return void, and take 2 arguments: a Map (for parameters) and a SvcLogicContext (to allow plugin read/write access to context memory)
+*--------------*-------+
+
+*** Parameters
+
+ Specific to plugin / method
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Device successfully configured
+*-----------*-------+
+| <<not-found>> | Plugin class could not be loaded
+*-----------*--------+
+| <<unsupported-method>> | Named method taking (Map, SvcLogicContext) could not be found
+*-----------*-------+
+| <<failure>> | Configure failed for some other reason
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<execute plugin="org.openecomp.sdnc.sli.plugin.HelloWorld"
+ method="log">
+ <parameter name="message" value="Hello, world!" />
+ <outcome value="success">
+ <return status="success"/>
+ </outcome>
+ <outcome value="not-found">
+ <return status="failure">
+ <parameter name="error-code" value="1590" />
+ <parameter name="error-message" value="Could not locate plugin" />
+ </return>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure">
+ <parameter name="error-code" value="1542" />
+ <parameter name="error-message" value="Internal error" />
+ </return>
+ </outcome>
+</execute>
++-------------------+
+
+* Recording
+
+** Record node
+
+*** Description
+
+ A <<record>> node is used to record an event. For example, this might be used
+ to log provisioning events.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class to handle recording.
+*--------------*-------+
+
+
+*** Parameters
+
+ Parameters will depend on the plugin being used. For the FileRecorder class,
+ the parameters are as follows
+
+*------------*-----------+
+| <<file>> | The file to which the record should be written
+*------------*-----------+
+| <<field1>> | First field to write. There will be <<field>> parameters for each field to write, from <<field1>> through <<fieldN>>. A special value __TIMESTAMP__ may be assigned to a field to insert the current timestamp
+*------------*-----------+
+
+
+*** Outcomes
+
+*----------*---------+
+| <<success>> | Record successfully written
+*----------*---------+
+| <<failure>> | Record could not be successfully written
+*----------*---------+
+
+*** Example
+
++-------------------+
+<record plugin="org.openecomp.sdnc.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>
++-------------------+
+
+* Resource Management
+
+** Delete node
+
+*** Description
+
+ A <<delete>> node is used to delete a resource from the local resource inventory.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to delete
+*--------------*-------+
+| <<key>> | SQL-like string specifying key to delete
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Resource specified deleted successfully.
+*-----------*-------+
+| <failure>> | Resource specified was not deleted
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<delete plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="uni_circuit_id == $uni-circuit-id">
+ <outcome value="true">
+ <return status="success"/>
+ </outcome>
+ <outcome value="false">
+ <return status="failure"/>
+ </outcome>
+</delete>
++-------------------+
+
+
+** Exists node
+
+*** Description
+
+ An <<exists>> node is used to determine whether a particular
+ instance of a resource exists. For example, this might be
+ used to test whether a particular switch CLLI is provisioned.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to check
+*--------------*-------+
+| <<key>> | SQL-like string specifying key to check for
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+*-----------*-------+
+| <<true>> | Resource specified exists.
+*-----------*-------+
+| <<false>> | Resource specified is unknown
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<exists plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="uni_circuit_id == $uni-circuit-id">
+ <outcome value="true">
+ <return status="success"/>
+ </outcome>
+ <outcome value="false">
+ <return status="failure"/>
+ </outcome>
+</exists>
++-------------------+
+
+** Get-resource node
+
+*** Description
+
+ A <<get-resource>> node is used to retrieve information about a
+ particular resource and make it available to other nodes in the
+ service logic tree. For example, this might be used to
+ retrieve information about a particular uni-port.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to retrieve
+*--------------*-------+
+| <<key>> | SQL-like string specifying criteria for retrieval
+*--------------*-------+
+| <<pfx>> | Prefix to add to context variable names set for data retrieved
+*--------------*-------+
+| <<select>> | String to specify, if key matches multiple entries, which entry should take precedence
+*--------------*-------+
+| <<order-by>> | Prefix to add to context variable names set for data retrieved
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Resource successfully retrieved
+*-----------*-------+
+| <<not-found>> | Resource referenced does not exist
+*-----------*-------+
+| <<failure>> | Resource retrieve failed for some other reason
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<get-resource plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="uni_circuit_id == $uni-circuit-id"
+ pfx="current-port">
+ <outcome value="success">
+ <return status="success"/>
+ </outcome>
+ <outcome value="not-found">
+ <return status="failure"/>
+ </outcome>
+ <outcome value="failure">
+ <return status="failure"/>
+ </outcome>
+</get-resource>
++-------------------+
+
+** Is-available node
+
+*** Description
+
+ An <<is-available>> node is used to determine whether a particular
+ type of resource is available. For example, this might be used to
+ test whether any ports are available for assignment on a particular switch.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to check
+*--------------*-------+
+| <<key>> | SQL-like string specifying key to check for
+*--------------*-------+
+| <<pfx>> | Prefix to add to context variable names set for data retrieved
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+*-----------*-------+
+| <<true>> | Resource requested is available
+*-----------*-------+
+| <<false>> | Resource requested is not available
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<is-available plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="resource-emt-clli == $edge-device-clli and speed >= $uni-cir-value">
+ <outcome value="true">
+ <return status="success"/>
+ </outcome>
+ <outcome value="false">
+ <return status="failure"/>
+ </outcome>
+</is-available>
++-------------------+
+
+** Notify node
+
+*** Description
+
+ A <<notify>> node is used to inform an external application (e.g. A&AI) that a resource was
+ updated.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Identifies resource that was updated
+*--------------*-------+
+| <<action>> | Action that triggered notification to be sent (ADD/UPDATE/DELETE)
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Notification was successful
+*-----------*-------+
+| <<failure>> | Notification failed is not available
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<notify plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ action="ADD">
+ <outcome value="success">
+ <return status="success"/>
+ </outcome>
+ <outcome value="Other">
+ <return status="failure"/>
+ </outcome>
+</notify>
++-------------------+
+
+** Release node
+
+*** Description
+
+ A <<release>> node is used to mark a resource as no longer in use, and thus
+ available for assignment.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to release
+*--------------*-------+
+| <<key>> | SQL-like string specifying key to check of resource to release
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Resource successfully released
+*-----------*-------+
+| <<not-found>> | Resource referenced does not exist
+*-----------*-------+
+| <<failure>> | Resource release failed for some other reason
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<release plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="uni_circuit_id == $uni-circuit-id">
+ <outcome value="success">
+ <return status="success"/>
+ </outcome>
+ <outcome value="not-found">
+ <return status="failure"/>
+ </outcome>
+ <outcome value="failure">
+ <return status="failure"/>
+ </outcome>
+</release>
++-------------------+
+
+
+** Reserve node
+
+*** Description
+
+ A <<reserve>> node is used to reserve a particular
+ type of resource.. For example, this might be used to
+ reserve a port on a particular switch.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to reserve
+*--------------*-------+
+| <<key>> | SQL-like string specifying criteria for reservation
+*--------------*-------+
+| <<select>> | String to specify, if <<key>> matches multiple entries, which entry should take precedence
+*--------------*-------+
+
+*** Parameters
+
+ None
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Resource requested was successfully reserved
+*-----------*-------+
+| <<failure>> | Resource requested was not successfully reserved
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<reserve plugin="org.openecomp.sdnc.sli.resource.samplesvc.SampleServiceResource"
+ resource="ase-port"
+ key="resource-emt-clli == $edge-device-clli and speed >= $uni-cir-value"
+ select="min(speed)">
+ <outcome value="success">
+ <return status="success"/>
+ </outcome>
+ <outcome value="failure">
+ <return status="failure"/>
+ </outcome>
+</reserve>
++-------------------+
+
+** Save node
+
+*** Description
+
+ A <<save>> node is used to save information about a
+ particular resource to persistent storage. For example, this might be used to
+ save information about a particular uni-port.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to save
+*--------------*-------+
+| <<key>> | SQL-like string specifying criteria for retrieval
+*--------------*-------+
+| <<force>> | If "true", save resource even if this resource is already stored in persistent storage
+*--------------*-------+
+| <<pfx>> | Prefix to be prepended to variable names, when attributes are set in SvcLogicContext
+*--------------*-------+
+
+*** Parameters
+
+ Values to save (columns) are specified as parameters, with each name
+ corresponding to a column name and each value corresponding to the
+ value to set.
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Resource successfully saved
+*-----------*-------+
+| <<failure>> | Resource save failed
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<save plugin="`$sample-resource-plugin`" resource="vnf"
+ key="vnf-name = $requests.vnf.vnf-name" force="true"
+ pfx="requests.vnf">
+ <parameter name="vnf-name"
+ value="`$requests.cust-country-code + $requests.cust-id + $requests.cust-city + $requests.cust-state + '001VCE'`" />
+ <parameter name="vnf-type" value="vce" />
+ <parameter name="orchestration-status" value="pending-create" />
+ <parameter name="heat-stack-id" value="`$requests.heat-stack-id`" />
+ <parameter name="mso-catalog-key" value="`$requests.mso-catalog-key`" />
+ <parameter name="oam-ipv4-address" value="`$vce-ipv4-oam-addr.ipv4-addr`" />
+</save>
++-------------------+
+
+** Update node
+
+*** Description
+
+ An <<update>> node is used to update information about a
+ particular resource to persistent storage.
+
+*** Attributes
+
+*--------------*-------+
+| <<plugin>> | Fully qualified Java class of resource adaptor to be used
+*--------------*-------+
+| <<resource>> | Type of resource to update
+*--------------*-------+
+| <<key>> | SQL-like string specifying criteria for retrieval
+*--------------*-------+
+| <<pfx>> | Prefix to be prepended to variable names, when attributes are set in SvcLogicContext
+*--------------*-------+
+
+*** Parameters
+
+ Values to save (columns) are specified as parameters, with each name
+ corresponding to a column name and each value corresponding to the
+ value to set.
+
+*** Outcomes
+
+*-----------*-------+
+| <<success>> | Resource successfully saved
+*-----------*-------+
+| <<failure>> | Resource save failed
+*-----------*-------+
+
+*** Example
+
++-------------------+
+<update plugin="`$sample-resource-plugin`" resource="vnf"
+ key="vnf-name = $requests.vnf.vnf-name"
+ pfx="requests.vnf">
+ <parameter name="vnf-name"
+ value="`$requests.cust-country-code + $requests.cust-id + $requests.cust-city + $requests.cust-state + '001VCE'`" />
+ <parameter name="vnf-type" value="vce" />
+ <parameter name="orchestration-status" value="pending-create" />
+ <parameter name="heat-stack-id" value="`$requests.heat-stack-id`" />
+ <parameter name="mso-catalog-key" value="`$requests.mso-catalog-key`" />
+ <parameter name="oam-ipv4-address" value="`$vce-ipv4-oam-addr.ipv4-addr`" />
+</update>
++-------------------+
+
diff --git a/src/site/site.xml b/src/site/site.xml
new file mode 100644
index 00000000..7da1eb9f
--- /dev/null
+++ b/src/site/site.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ============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=========================================================
+ -->
+
+<project>
+ <body>
+ <links>
+ <item name="Built-in Nodes" href="nodes.html" />
+ </links>
+ <menu ref="modules"/>
+
+ <menu ref="reports"/>
+
+ </body>
+</project>
diff --git a/version.properties b/version.properties
new file mode 100644
index 00000000..f78b4bdf
--- /dev/null
+++ b/version.properties
@@ -0,0 +1,15 @@
+###########################################################
+# Versioning variables
+# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
+# because they are used in Jenkins, whose plug-in doesn't support
+
+
+release_name=1
+sprint_number=1
+feature_revision=2
+
+base_version=${release_name}.${sprint_number}.${feature_revision}
+
+release_version=${base_version}
+snapshot_version=${base_version}-SNAPSHOT
+