Initial commit for OpenECOMP SDN-C N-C core 41/441/1
authorDan Timoney <dtimoney@att.com>
Wed, 15 Feb 2017 19:30:39 +0000 (14:30 -0500)
committerDan Timoney <dtimoney@att.com>
Wed, 15 Feb 2017 19:37:01 +0000 (14:37 -0500)
Change-Id: I30c52795ab821c4fdd18b55d202f10a76a01acfa
Signed-off-by: Dan Timoney <dtimoney@att.com>
200 files changed:
.gitignore [new file with mode: 0755]
.gitreview [new file with mode: 0644]
LICENSE.txt [new file with mode: 0644]
README.md [new file with mode: 0644]
dblib/.gitignore [new file with mode: 0755]
dblib/README.md [new file with mode: 0755]
dblib/features/pom.xml [new file with mode: 0755]
dblib/features/src/main/resources/features.xml [new file with mode: 0755]
dblib/installer/pom.xml [new file with mode: 0755]
dblib/installer/src/assembly/assemble_installer_zip.xml [new file with mode: 0755]
dblib/installer/src/assembly/assemble_mvnrepo_zip.xml [new file with mode: 0755]
dblib/installer/src/main/resources/scripts/install-feature.sh [new file with mode: 0644]
dblib/pom.xml [new file with mode: 0755]
dblib/provider/pom.xml [new file with mode: 0755]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSource.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/CachedDataSourceFactory.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBConfigException.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLIBResourceActivator.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBLibException.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceManager.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DBResourceObserver.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataAccessor.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DataSourceComparator.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DbLibService.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/DblibConfigurationException.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/BaseDBConfiguration.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/DbConfigPool.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JDBCConfiguration.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JndiConfiguration.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractDBResourceManagerFactory.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/AbstractResourceManagerFactory.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/DBConfigFactory.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/factory/FactoryNotDefinedException.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/MySQLCachedDataSource.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/PollingWorker.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitor.java [new file with mode: 0644]
dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/pm/SQLExecutionMonitorObserver.java [new file with mode: 0644]
dblib/provider/src/main/resources/dblib.properties [new file with mode: 0755]
dblib/provider/src/test/resources/dblib.properties [new file with mode: 0755]
example-settings.xml [new file with mode: 0644]
filters/.gitignore [new file with mode: 0755]
filters/.sonar/checkstyle.xml [new file with mode: 0755]
filters/.sonar/pmd.xml [new file with mode: 0755]
filters/README [new file with mode: 0755]
filters/features/pom.xml [new file with mode: 0755]
filters/features/src/main/resources/features.xml [new file with mode: 0644]
filters/installer/pom.xml [new file with mode: 0755]
filters/installer/src/assembly/assemble_installer_zip.xml [new file with mode: 0644]
filters/installer/src/assembly/assemble_mvnrepo_zip.xml [new file with mode: 0644]
filters/installer/src/main/resources/scripts/install-feature.sh [new file with mode: 0644]
filters/pom.xml [new file with mode: 0644]
filters/provider/pom.xml [new file with mode: 0755]
filters/provider/src/main/java/org/openecomp/sdnc/filters/Activator.java [new file with mode: 0644]
filters/provider/src/main/java/org/openecomp/sdnc/filters/LogFilter.java [new file with mode: 0644]
filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java [new file with mode: 0644]
jenkins-settings.xml [new file with mode: 0644]
pom.xml [new file with mode: 0755]
rootpom/pom.xml [new file with mode: 0755]
rootpom/src/site/site.xml [new file with mode: 0644]
rootpom/src/site/site_en.xml [new file with mode: 0644]
sli/.gitignore [new file with mode: 0755]
sli/common/pom.xml [new file with mode: 0755]
sli/common/src/main/antlr4/org/openecomp/sdnc/sli/ExprGrammar.g4 [new file with mode: 0755]
sli/common/src/main/java/org/openecomp/sdnc/sli/ConfigurationException.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/DuplicateValueException.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/MetricLogger.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAdaptor.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicAtom.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicBinaryExpression.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicContext.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicDblibStore.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicException.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprListener.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExprParserErrorListener.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpression.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicExpressionFactory.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicFunctionCall.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicGraph.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJavaPlugin.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicJdbcStore.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicNode.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParser.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicParserException.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicRecorder.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicResource.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStore.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicStoreFactory.java [new file with mode: 0644]
sli/common/src/main/java/org/openecomp/sdnc/sli/SvcLogicVariableTerm.java [new file with mode: 0644]
sli/common/src/main/resources/crAseNetwork.sql [new file with mode: 0644]
sli/common/src/main/resources/svclogic.xsd [new file with mode: 0755]
sli/common/src/main/yang/ase-network.yang [new file with mode: 0755]
sli/common/src/main/yang/ase-type.yang [new file with mode: 0755]
sli/common/src/main/yang/ase.yang [new file with mode: 0755]
sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicContextTest.java [new file with mode: 0644]
sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicExpressionParserTest.java [new file with mode: 0644]
sli/common/src/test/java/org/openecomp/sdnc/sli/SvcLogicParserTest.java [new file with mode: 0644]
sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml [new file with mode: 0644]
sli/common/src/test/resources/EvcPortSvcLogic_v100.xml [new file with mode: 0644]
sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml [new file with mode: 0644]
sli/common/src/test/resources/bad_neutron_logic_v11.xml [new file with mode: 0644]
sli/common/src/test/resources/expression.tests [new file with mode: 0755]
sli/common/src/test/resources/mergetest.xml [new file with mode: 0644]
sli/common/src/test/resources/neutron_logic_v10.xml [new file with mode: 0644]
sli/common/src/test/resources/nonsense.xml [new file with mode: 0644]
sli/common/src/test/resources/parser-bad.tests [new file with mode: 0755]
sli/common/src/test/resources/parser-good.tests [new file with mode: 0755]
sli/common/src/test/resources/simplelogger.properties [new file with mode: 0644]
sli/common/src/test/resources/svclogic.properties [new file with mode: 0644]
sli/common/src/test/resources/svclogic.sh [new file with mode: 0644]
sli/common/src/test/resources/svclogic.xsd [new file with mode: 0755]
sli/features/pom.xml [new file with mode: 0755]
sli/features/src/main/resources/features.xml [new file with mode: 0644]
sli/installer/pom.xml [new file with mode: 0755]
sli/installer/src/assembly/assemble_installer_zip.xml [new file with mode: 0644]
sli/installer/src/assembly/assemble_mvnrepo_zip.xml [new file with mode: 0644]
sli/installer/src/main/resources/scripts/install-feature.sh [new file with mode: 0644]
sli/pom.xml [new file with mode: 0755]
sli/provider/pom.xml [new file with mode: 0755]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/BlockNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ConfigureNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/DeleteNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExecuteNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ExistsNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ForNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/GetResourceNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/IsAvailableNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/MdsalHelper.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/NotifyNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/RecordNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReleaseNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReserveNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ReturnNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SaveNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SetNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicActivator.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicAdaptorFactory.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolver.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicService.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SvcLogicServiceImpl.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/SwitchNodeExecutor.java [new file with mode: 0644]
sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/UpdateNodeExecutor.java [new file with mode: 0644]
sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicExpressionResolverTest.java [new file with mode: 0644]
sli/provider/src/test/java/org/openecomp/sdnc/sli/provider/SvcLogicGraphExecutorTest.java [new file with mode: 0644]
sli/provider/src/test/resources/executor.tests [new file with mode: 0755]
sli/provider/src/test/resources/expression.tests [new file with mode: 0755]
sli/provider/src/test/resources/l3sdn_logic_v10.xml [new file with mode: 0644]
sli/provider/src/test/resources/simplelogger.properties [new file with mode: 0644]
sli/provider/src/test/resources/svclogic.properties [new file with mode: 0644]
sli/recording/pom.xml [new file with mode: 0755]
sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/FileRecorder.java [new file with mode: 0644]
sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/RecordingActivator.java [new file with mode: 0644]
sli/recording/src/main/java/org/openecomp/sdnc/sli/recording/Slf4jRecorder.java [new file with mode: 0644]
sli/recording/src/main/resources/svclogic.properties [new file with mode: 0644]
sliPluginUtils/.gitignore [new file with mode: 0755]
sliPluginUtils/.sonar/checkstyle.xml [new file with mode: 0755]
sliPluginUtils/.sonar/pmd.xml [new file with mode: 0755]
sliPluginUtils/features/pom.xml [new file with mode: 0755]
sliPluginUtils/features/src/main/resources/features.xml [new file with mode: 0644]
sliPluginUtils/installer/pom.xml [new file with mode: 0755]
sliPluginUtils/installer/src/assembly/assemble_installer_zip.xml [new file with mode: 0644]
sliPluginUtils/installer/src/assembly/assemble_mvnrepo_zip.xml [new file with mode: 0644]
sliPluginUtils/installer/src/main/resources/scripts/install-feature.sh [new file with mode: 0644]
sliPluginUtils/pom.xml [new file with mode: 0755]
sliPluginUtils/provider/pom.xml [new file with mode: 0755]
sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java [new file with mode: 0644]
sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtilsActivator.java [new file with mode: 0644]
sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java [new file with mode: 0644]
sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextObject.java [new file with mode: 0644]
sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/YesNo.java [new file with mode: 0644]
sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/commondatastructures/package-info.java [new file with mode: 0644]
sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctions.java [new file with mode: 0644]
sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_ctxSortList.java [new file with mode: 0644]
sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextListTest.java [new file with mode: 0644]
sliapi/.gitignore [new file with mode: 0755]
sliapi/README.txt [new file with mode: 0755]
sliapi/features/pom.xml [new file with mode: 0755]
sliapi/features/src/main/resources/features.xml [new file with mode: 0644]
sliapi/installer/pom.xml [new file with mode: 0755]
sliapi/installer/src/assembly/assemble_installer_zip.xml [new file with mode: 0644]
sliapi/installer/src/assembly/assemble_mvnrepo_zip.xml [new file with mode: 0644]
sliapi/installer/src/main/resources/scripts/install-feature.sh [new file with mode: 0644]
sliapi/model/pom.xml [new file with mode: 0755]
sliapi/model/src/main/yang/sliapi.yang [new file with mode: 0755]
sliapi/pom.xml [new file with mode: 0755]
sliapi/provider/pom.xml [new file with mode: 0755]
sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModule.java [new file with mode: 0644]
sliapi/provider/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/sdnc/sliapi/provider/impl/rev140523/SliapiProviderModuleFactory.java [new file with mode: 0644]
sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/SliapiHelper.java [new file with mode: 0644]
sliapi/provider/src/main/java/org/openecomp/sdnc/sliapi/sliapiProvider.java [new file with mode: 0644]
sliapi/provider/src/main/resources/initial/sliapi-provider.xml [new file with mode: 0644]
sliapi/provider/src/main/yang/sliapi-provider-impl.yang [new file with mode: 0755]
src/site/apt/nodes.apt [new file with mode: 0644]
src/site/site.xml [new file with mode: 0644]
version.properties [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100755 (executable)
index 0000000..8f8f95a
--- /dev/null
@@ -0,0 +1,42 @@
+#####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
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..7f3e165
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.openecomp.org
+port=29418
+project=sdnc/core.git
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644 (file)
index 0000000..3ea5081
--- /dev/null
@@ -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 (file)
index 0000000..be7ec38
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+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 (executable)
index 0000000..b73caf3
--- /dev/null
@@ -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 (executable)
index 0000000..19e3a34
--- /dev/null
@@ -0,0 +1,6 @@
+DBLIB Urility
+---------------------
+
+DBKLIB 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 (executable)
index 0000000..b3fc853
--- /dev/null
@@ -0,0 +1,133 @@
+<?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>1.0.0</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 for opendaylight-karaf-empty for use by testing -->
+               <dependency>
+                       <groupId>org.opendaylight.controller</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.controller</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 (executable)
index 0000000..cc080aa
--- /dev/null
@@ -0,0 +1,17 @@
+<?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>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 (executable)
index 0000000..ba452e3
--- /dev/null
@@ -0,0 +1,136 @@
+<?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>1.0.0</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>
+
+
+    </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>
+                        </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>
+                        </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/dblib/installer/src/assembly/assemble_installer_zip.xml b/dblib/installer/src/assembly/assemble_installer_zip.xml
new file mode 100755 (executable)
index 0000000..4716c7a
--- /dev/null
@@ -0,0 +1,37 @@
+<!-- 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">
+       <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 (executable)
index 0000000..92cd930
--- /dev/null
@@ -0,0 +1,27 @@
+<!-- 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">
+       <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 (file)
index 0000000..16b5be8
--- /dev/null
@@ -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 (executable)
index 0000000..4d02c7d
--- /dev/null
@@ -0,0 +1,126 @@
+<?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>1.0.0</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>1.0.0</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-site-plugin</artifactId>
+                    <version>3.4</version>
+                    <dependencies>
+                        <dependency><!-- add support for ssh/scp -->
+                            <groupId>org.apache.maven.wagon</groupId>
+                            <artifactId>wagon-ssh</artifactId>
+                            <version>1.0</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+                <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 (executable)
index 0000000..c46b2e8
--- /dev/null
@@ -0,0 +1,74 @@
+<?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>1.0.0</version>
+       </parent>
+       <artifactId>dblib-provider</artifactId>
+       <version>1.0.0</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>
+       </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.*</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 (file)
index 0000000..e21e2be
--- /dev/null
@@ -0,0 +1,521 @@
+/*-
+ * ============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.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+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.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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @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 initisalDelay = 5000;
+       private long expectedCompletionTime = 50L;
+       private boolean canTakeOffLine = true;
+       private long unprocessedFailoverThreshold = 3L;
+
+
+       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<String> 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);
+               } 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<String> 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);
+               } finally {
+                       try {
+                               if(connection != null && !connection.isClosed()) {
+                                       connection.close();
+                               }
+                       } catch(Throwable exc) {
+                               // the exception not monitored
+                       } finally {
+                               connection = null;
+                       }
+
+                       monitor.deregisterReguest(testObject);
+               }
+       }
+
+       private CachedRowSet executePreparedStatement(Connection conn, String statement, ArrayList<String> arguments) 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. count=" + 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){
+                                       conn.close();
+                                       conn = null;
+                               }
+                       } catch(Exception exc){
+
+                       }
+               }
+
+               return data;
+       }
+
+       private boolean executeUpdatePreparedStatement(Connection conn, String statement, ArrayList<String> arguments) 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++){
+                                       ps.setObject(i+1, arguments.get(i));
+                               }
+                       }
+                       rs = ps.executeUpdate();
+                   // Point the rowset Cursor to the start
+                       if(LOGGER.isDebugEnabled()){
+                               LOGGER.debug("SQL SUCCESS. count=" + 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){
+                                       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(){
+               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(rs.getInt(1)==1){
+                                       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 initisalDelay;
+       }
+
+       public void setInterval(long value) {
+               interval = value;
+       }
+
+       public void setInitialDelay(long value) {
+               initisalDelay = 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() {
+               CachedRowSet rs = null;
+               boolean isSlave = true;
+               String hostname = "UNDETERMINED";
+               try {
+//                     rs = this.getData("show slave status", new ArrayList<String>());
+//                     while(rs.next()) {
+//                             String master = rs.getString(2);
+//                             LOGGER.debug("database <"+connectionName+"> defines master as " + master);
+//                             if(master == null || master.isEmpty() || master.equals(this.getDbConnectionName())) {
+//                                     isSlave = false;
+//                             } else {
+//                                     isSlave = true;
+//                             }
+//                     }
+
+                       boolean localSlave = true;
+                       rs = this.getData("SELECT @@global.read_only, @@global.hostname", new ArrayList<String>());
+                       while(rs.next()) {
+                               localSlave = rs.getBoolean(1);
+                               hostname = rs.getString(2);
+                       }
+                       isSlave = localSlave;
+               } 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;
+       }
+}
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 (file)
index 0000000..f774748
--- /dev/null
@@ -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;
+
+
+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.config.JndiConfiguration;
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.MySQLCachedDataSource;
+import org.openecomp.sdnc.sli.resource.dblib.jndi.JndiCachedDataSource;
+
+/**
+ * @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 MySQLCachedDataSource.createInstance(config);
+               if(config instanceof JndiConfiguration)
+                       return JndiCachedDataSource.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 (file)
index 0000000..b324e6a
--- /dev/null
@@ -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 (file)
index 0000000..85cf834
--- /dev/null
@@ -0,0 +1,113 @@
+/*-
+ * ============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.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(regName, jdbcDataSource, null);
+               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)
+               {
+                       registration.unregister();
+                       registration = null;
+                       LOG.debug("Deregistering DBResourceManager service");
+               }
+       }
+
+}
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 (file)
index 0000000..cc80741
--- /dev/null
@@ -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 (file)
index 0000000..7f85c42
--- /dev/null
@@ -0,0 +1,940 @@
+/*-
+ * ============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.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.sql.DataSource;
+import javax.sql.rowset.CachedRowSet;
+
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.rowset.providers.RIOptimisticProvider;
+
+/**
+ * @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();
+               
+               try {
+                       RIOptimisticProvider rio  = new RIOptimisticProvider();
+                       LOGGER.info("Class " + rio.getClass().getName() + " found.");
+                       Class clas = this.getClass().getClassLoader().loadClass("com.sun.rowset.providers.RIOptimisticProvider");
+                       if(clas != null) {
+                               LOGGER.info("Class " + rio.getClass().getName() + " found by classloader.");
+                       }
+               } catch(Exception exc) {
+                       LOGGER.info("Failed resolving RIOptimisticProvider class", exc);
+               }
+       }
+
+       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.dblib.DataAccessor#getData(java.lang.String, java.util.ArrayList)
+        */
+       /* (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 {
+               if(recoveryMode)
+                       return requestDataWithRecovery(statement, arguments, preferredDS);
+               else
+                       return requestDataNoRecovery(statement, arguments, preferredDS);
+       }
+
+       private CachedRowSet requestDataWithRecovery(String statement, ArrayList<String> 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 : "+ 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<String> 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.dblib.DataAccessor#writeData(java.lang.String, java.util.ArrayList)
+        */
+       /* (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 {
+               return writeDataNoRecovery(statement, arguments, preferredDS);
+       }
+       
+       CachedDataSource findMaster() {
+               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<String> 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(">> getData : "+ 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 active.getConnection();
+               } 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(Exception exc){
+                       lastException = 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;
+                               }
+                       }
+               } 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 "";
+       }
+
+       private 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 {
+               // TODO Auto-generated method stub
+               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();
+       }
+
+       /*
+       private void runTest(){
+               Thread producer = null;
+
+               producer = new ProducerThread("Prod1");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod2");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod3");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod4");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod5");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod6");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod7");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod8");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Prod9");
+               producer.setDaemon(true);
+               producer.start();
+
+               producer = new ProducerThread("Pro10");
+               producer.setDaemon(true);
+               producer.start();
+
+       }
+
+       private final class ProducerThread extends Thread {
+               private ProducerThread(String threadName) {
+                       super(threadName);
+               }
+
+               public void run()
+               {
+                       String name = null;
+                       for(int i=0; i<(Integer.MAX_VALUE-1); i++)
+                       {
+                                       try {
+                                               name = getPreferredDataSourceName(dsSelector);
+                                               if(name.contains("BACK")){
+                                                       LOGGER.error(this.getName()+": <======      ");
+                                               } else {
+                                                       LOGGER.error(this.getName()+":       ======>");
+                                               }
+                                               CachedRowSet rs = null;
+                                               rs = getData("select 1 from dual", new ArrayList<String>(), name);
+                                               rs.close();
+                                               rs = getData("select 1 from dual", new ArrayList<String>(), name);
+                                               rs.close();
+                                               rs = getData("select 1 from dual", new ArrayList<String>(), name);
+                                               rs.close();
+                                               rs = getData("select 1 from dual", new ArrayList<String>(), name);
+                                               rs.close();
+                                       } catch (Exception e) {
+                                               e.printStackTrace();
+                                       }
+
+                               try {
+                                       Thread.sleep(50L);
+                               } catch (InterruptedException e) {
+                                       e.printStackTrace();
+                               }
+                       }
+                       return;
+               }
+       }
+*/
+}
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 (file)
index 0000000..e06779f
--- /dev/null
@@ -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 (file)
index 0000000..cd054a5
--- /dev/null
@@ -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 (file)
index 0000000..37d6251
--- /dev/null
@@ -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 (file)
index 0000000..25edd1f
--- /dev/null
@@ -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 (file)
index 0000000..17700a5
--- /dev/null
@@ -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/TerminatingCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/TerminatingCachedDataSource.java
new file mode 100644 (file)
index 0000000..234bbed
--- /dev/null
@@ -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 (file)
index 0000000..976b1cf
--- /dev/null
@@ -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 (file)
index 0000000..90ea6bc
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ * ============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 JndiConfiguration[] getJndiDbSourceArray() {
+               return configurations.toArray(new JndiConfiguration[configurations.size()]);
+       }
+
+       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 (file)
index 0000000..cb6ea3e
--- /dev/null
@@ -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/config/JndiConfiguration.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/config/JndiConfiguration.java
new file mode 100644 (file)
index 0000000..292372b
--- /dev/null
@@ -0,0 +1,62 @@
+/*-
+ * ============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 JndiConfiguration extends BaseDBConfiguration{
+
+       public JndiConfiguration(Properties xmlElem) {
+               super(xmlElem);
+               // TODO Auto-generated constructor stub
+       }
+
+       public String getJndiConnectionName() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public String getJndiContextFactory() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public String getJndiURL() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public String getJndiSource() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public void setJndiContextFactory(String jndiContextFactoryStr) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void setJndiURL(String jndiURLStr) {
+               // TODO Auto-generated method stub
+               
+       }
+
+}
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 (file)
index 0000000..e6b1a35
--- /dev/null
@@ -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.factory;
+
+import org.openecomp.sdnc.sli.resource.dblib.jdbc.JdbcDbResourceManagerFactory;
+import org.openecomp.sdnc.sli.resource.dblib.jndi.JNDIDbResourceManagerFactory;
+
+/**
+ * @version $Revision: 1.1 $
+ * Change Log
+ * Author         Date     Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class AbstractDBResourceManagerFactory {
+
+       public static AbstractResourceManagerFactory getFactory(String type) throws FactoryNotDefinedException {
+               
+               if("JNDI".equals(type)){
+                       try {
+                               return JNDIDbResourceManagerFactory.createIntstance();
+                       } catch (Exception e) {
+                       }
+               }
+               // 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 (file)
index 0000000..148ddac
--- /dev/null
@@ -0,0 +1,106 @@
+/*-
+ * ============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.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+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(JndiConfiguration jndiConfig, Set<DBInitTask> tasks){
+                       this.config = jndiConfig;
+                       this.activeTasks = tasks;
+               }
+
+               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())
+                                                       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 (file)
index 0000000..7044082
--- /dev/null
@@ -0,0 +1,103 @@
+/*-
+ * ============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.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.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+
+/**
+ * @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){
+               org.slf4j.LoggerFactory.getLogger(DBConfigFactory.class).info(properties.toString());
+               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) {
+                       org.slf4j.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("JNDI".equalsIgnoreCase(type)) {
+                       config = new JndiConfiguration(props);
+               }
+               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 (file)
index 0000000..e38cd35
--- /dev/null
@@ -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/JdbcDbResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jdbc/JdbcDbResourceManagerFactory.java
new file mode 100644 (file)
index 0000000..0afb621
--- /dev/null
@@ -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<DBInitTask>
+       {
+
+               public MyFutureTask(Callable<CachedDataSource> result) {
+                       super((Callable)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();
+
+               FutureTask<DBInitTask>[] 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 (file)
index 0000000..ebfd473
--- /dev/null
@@ -0,0 +1,220 @@
+/*-
+ * ============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
+        * @param alarmLog 
+        * @param occManager 
+        * @throws Exception 
+        */
+       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/jndi/JNDIDbResourceManagerFactory.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JNDIDbResourceManagerFactory.java
new file mode 100644 (file)
index 0000000..2888bc5
--- /dev/null
@@ -0,0 +1,167 @@
+/*-
+ * ============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.jndi;
+
+import java.sql.SQLException;
+import java.util.HashSet;
+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.config.DbConfigPool;
+import org.openecomp.sdnc.sli.resource.dblib.config.JndiConfiguration;
+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 JNDIDbResourceManagerFactory extends AbstractResourceManagerFactory {
+
+       private static Logger LOGGER = LoggerFactory.getLogger(JNDIDbResourceManagerFactory.class);
+
+       class MyFutureTask extends FutureTask<DBInitTask>
+       {
+
+               public MyFutureTask(Callable<CachedDataSource> result) {
+                       super((Callable)result);
+               }
+               
+       }
+
+       public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager, String sourceName) throws SQLException 
+       {       
+               // here create the data sources objects
+               JndiConfiguration[] list = dbConfig.getJndiDbSourceArray();
+               CachedDataSource[] cachedDS = new CachedDataSource[1];
+
+               for(int i=0, max=list.length; i<max; i++){
+                       if(!sourceName.equals(list[i].getJndiConnectionName()))
+                               continue;
+
+                       JndiConfiguration config = list[i];
+                       CachedDataSource dataSource = CachedDataSourceFactory.createDataSource(config);
+                       cachedDS[0] = dataSource;
+               }
+               return cachedDS;
+       }
+       
+       public CachedDataSource[] initDBResourceManager(DbConfigPool dbConfig, DBResourceManager manager) /* throws Exception */ {
+//             WSConfigManagement ws = WSConfigManagement.getInstance();
+               
+               ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
+               // here create the data sources objects
+               JndiConfiguration[] list = dbConfig.getJndiDbSourceArray();
+               FutureTask<DBInitTask>[] futures = new MyFutureTask[list.length];
+               final Set<DBInitTask> tasks = new HashSet<DBInitTask>();
+               if(LOGGER.isDebugEnabled())
+                       LOGGER.debug("Creating datasources.");
+               for(int i=0, max=list.length; i<max; i++){
+                       JndiConfiguration config = list[i];
+//                     if(manager.getJndiContextFactoryStr()!=null && manager.getJndiContextFactoryStr().trim().length()>0){
+//                             config.setJndiContextFactory(manager.getJndiContextFactoryStr());
+//                     }
+//                     if(manager.getJndiURLStr()!=null && manager.getJndiURLStr().trim().length()>0){
+//                             config.setJndiURL(manager.getJndiURLStr());
+//                     }
+                       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++){
+                                       threadExecutor.execute(futures[i]);
+                               }
+                               // the timeout param is set is seconds. 
+                               long timeout = ((dbConfig.getTimeout() <= 0) ? 60L : dbConfig.getTimeout());
+                               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 = true;
+                                               LOGGER.info("DataSource "+list[i].getJndiConnectionName()+" initialized successfully");
+                                       }
+                               } catch (InterruptedException exc) {
+                                       LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+                               } catch (ExecutionException exc) {
+                                       LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+                               } catch (Exception exc) {
+                                       LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+                               }
+                       } else {
+                               try {
+                                       obj = futures[i].get();
+                                       if(obj instanceof CachedDataSource){
+
+                                               LOGGER.error("DataSource "+((CachedDataSource)obj).getDbConnectionName()+" failed");
+                                       }
+                               } catch (Exception exc) {
+                                       LOGGER.error("DataSource "+list[i].getJndiConnectionName()+" initialization failed", exc);
+                               }
+                       }
+               }
+
+               if(!initialized){
+                       new Error("Failed to initialize DB Library.");
+               }
+               return cachedDS;
+       }
+       
+       public static AbstractResourceManagerFactory createIntstance() {
+               return new JNDIDbResourceManagerFactory();
+       }
+
+}
diff --git a/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java b/dblib/provider/src/main/java/org/openecomp/sdnc/sli/resource/dblib/jndi/JndiCachedDataSource.java
new file mode 100644 (file)
index 0000000..19fa8e9
--- /dev/null
@@ -0,0 +1,131 @@
+/*-
+ * ============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.jndi;
+
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+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.JndiConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * @version $Revision: 1.2 $
+ * Change Log
+ * Author         Date     Comments
+ * ============== ======== ====================================================
+ * Rich Tabedzki
+ */
+public class JndiCachedDataSource extends CachedDataSource
+{
+       private static Logger LOGGER = LoggerFactory.getLogger(JndiCachedDataSource.class);
+       /**
+        * @param alarmLog 
+        * @param jdbcElem
+        * @throws SAXException 
+        * @throws ScpTblUpdateError 
+        */
+       public JndiCachedDataSource(BaseDBConfiguration xmlElem) throws DBConfigException
+       {
+               super(xmlElem);
+       }
+
+       protected void configure(BaseDBConfiguration xmlElem) throws DBConfigException {
+               JndiConfiguration jdbcConfig = (JndiConfiguration)xmlElem;
+       String jndiContextFactoryStr = jdbcConfig.getJndiContextFactory(); 
+       String jndiURLStr = jdbcConfig.getJndiURL();
+       String jndiSourceStr = jdbcConfig.getJndiSource();
+       
+       if(jdbcConfig.getConnTimeout() > 0){
+               this.CONN_REQ_TIMEOUT = jdbcConfig.getConnTimeout();
+       }
+               if(jdbcConfig.getRequestTimeout() > 0){
+                       this.DATA_REQ_TIMEOUT = jdbcConfig.getRequestTimeout();
+               }
+       
+       super.setDbConnectionName(jdbcConfig.getJndiConnectionName());
+       
+       if(jndiContextFactoryStr == null || jndiContextFactoryStr.length() == 0)
+       {
+//             throw new DBConfigException("The jndi configuration is incomplete: jndiContextFactory");
+       }
+       if(jndiURLStr == null || jndiContextFactoryStr.length() == 0)
+       {
+//             throw new ScpTblUpdateError("The jndi configuration is incomplete: jndiURL");
+       }
+       if(jndiSourceStr == null || jndiSourceStr.length() == 0)
+       {
+               throw new DBConfigException("The jndi configuration is incomplete: jndiSource");
+       }
+
+       Properties env = new Properties();
+       Context ctx; 
+               try
+               {
+                       if(jndiContextFactoryStr != null && jndiContextFactoryStr.length() != 0){
+                               env.put(Context.INITIAL_CONTEXT_FACTORY, jndiContextFactoryStr);
+                               ctx = new InitialContext(env);
+                       } else {
+                               ctx = new InitialContext();
+                       }
+                       ds = (javax.sql.DataSource) ctx.lookup (jndiSourceStr);
+                       if(ds == null)
+                       {
+                               this.initialized = false;
+                               LOGGER.error("AS_CONF_ERROR: Failed to initialize DataSource <"+getDbConnectionName()+"> using JNDI <"+jndiSourceStr+">");
+                               return;
+                       } else {
+                               this.initialized = true;
+                               LOGGER.info("JndiCachedDataSource <"+getDbConnectionName()+"> configured successfully.");
+                               return;
+                       }
+               } catch (NamingException exc) {
+                       this.initialized = false;
+                       LOGGER.error("AS_CONF_ERROR" + exc.getMessage());
+
+               } catch(Throwable exc) {
+                       this.initialized = false;
+                       LOGGER.error("AS_CONF_ERROR: " + exc.getMessage());
+               }
+    }
+
+       public static JndiCachedDataSource createInstance(BaseDBConfiguration config) {
+               return new JndiCachedDataSource(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 (file)
index 0000000..de87fa7
--- /dev/null
@@ -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 (file)
index 0000000..c58c9db
--- /dev/null
@@ -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 (file)
index 0000000..1f32975
--- /dev/null
@@ -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 (executable)
index 0000000..3872288
--- /dev/null
@@ -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=sdnctl
+org.openecomp.sdnc.sli.jdbc.password=gamma
+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
\ No newline at end of file
diff --git a/dblib/provider/src/test/resources/dblib.properties b/dblib/provider/src/test/resources/dblib.properties
new file mode 100755 (executable)
index 0000000..e15e37a
--- /dev/null
@@ -0,0 +1,16 @@
+org.openecomp.sdnc.sli.dbtype=jdbc
+
+org.openecomp.sdnc.sli.jdbc.hosts=sdnctldb01
+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
+org.openecomp.sdnc.sli.jdbc.password=password
+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
+
+org.openecomp.dblib.connection.recovery=false
\ No newline at end of file
diff --git a/example-settings.xml b/example-settings.xml
new file mode 100644 (file)
index 0000000..2e7ce64
--- /dev/null
@@ -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://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>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 (executable)
index 0000000..b73caf3
--- /dev/null
@@ -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 (executable)
index 0000000..3fa2315
--- /dev/null
@@ -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 (executable)
index 0000000..80343b3
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ruleset>\r
+  <rule ref="rulesets/java/naming.xml/BooleanGetMethodName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/j2ee.xml/StaticEJBFieldShouldBeFinal">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/codesize.xml/TooManyMethods">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/basic.xml/DoubleCheckedLocking">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/coupling.xml/ExcessiveImports">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode">\r
+    <priority>2</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/naming.xml/ShortMethodName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/basic.xml/BooleanInstantiation">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/codesize.xml/TooManyFields">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/coupling.xml/LooseCoupling">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/design.xml/NonThreadSafeSingleton">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/j2ee.xml/DoNotUseThreads">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly">\r
+    <priority>5</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray">\r
+    <priority>2</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException">\r
+    <priority>3</priority>\r
+  </rule>\r
+</ruleset>\r
+\r
diff --git a/filters/README b/filters/README
new file mode 100755 (executable)
index 0000000..9d69d63
--- /dev/null
@@ -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 (executable)
index 0000000..f3dfe62
--- /dev/null
@@ -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>1.0.0</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.controller</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 (file)
index 0000000..75b780e
--- /dev/null
@@ -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 (executable)
index 0000000..39a00b9
--- /dev/null
@@ -0,0 +1,136 @@
+<?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>1.0.0</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>
+                                               </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>
+                                               </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 (file)
index 0000000..80b2ad1
--- /dev/null
@@ -0,0 +1,58 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..c87b7d3
--- /dev/null
@@ -0,0 +1,48 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..d8d381d
--- /dev/null
@@ -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 (file)
index 0000000..b809abc
--- /dev/null
@@ -0,0 +1,93 @@
+<?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>1.0.0</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>1.0.0</version>
+
+
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-site-plugin</artifactId>
+                    <version>3.4</version>
+                    <dependencies>
+                        <dependency><!-- add support for ssh/scp -->
+                            <groupId>org.apache.maven.wagon</groupId>
+                            <artifactId>wagon-ssh</artifactId>
+                            <version>1.0</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+                <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 (executable)
index 0000000..7b00001
--- /dev/null
@@ -0,0 +1,90 @@
+<?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>1.0.0</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>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 (file)
index 0000000..d246d63
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============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.File;
+import java.io.FileInputStream;
+import java.net.URL;
+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 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 (file)
index 0000000..aa1d530
--- /dev/null
@@ -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
+ */
+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/RequestResponseLoggingFilter.java b/filters/provider/src/main/java/org/openecomp/sdnc/filters/RequestResponseLoggingFilter.java
new file mode 100644 (file)
index 0000000..5fe22b2
--- /dev/null
@@ -0,0 +1,279 @@
+/*-
+ * ============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 java.util.zip.Inflater;
+
+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;
+               }
+
+               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;
+               }
+
+               public int available() {
+                       return bais.available();
+               }
+
+               public int read() {
+                       return bais.read();
+               }
+
+               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();
+
+               }
+
+               public ServletInputStream getInputStream() {
+                       try {
+                               bais = new ByteArrayInputStream(buffer);
+                               bsis = new BufferedServletInputStream(bais);
+                       } catch (Exception ex) {
+                               ex.printStackTrace();
+                       }
+
+                       return bsis;
+               }
+
+               public byte[] getBuffer() {
+                       return buffer;
+               }
+
+       }
+
+       public void init(FilterConfig filterConfig) throws ServletException {
+       }
+
+       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) {
+                       public PrintWriter getWriter() {
+                               return pw.getWriter();
+                       }
+
+                       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);
+
+               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));
+               }
+               }
+       }
+
+       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 (file)
index 0000000..344994f
--- /dev/null
@@ -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 (executable)
index 0000000..93497a0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,147 @@
+<?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.openecomp.org</url>
+    <description>The SDN-C core components contains the SLI, dblib and root pom</description>
+
+    <parent>
+        <groupId>org.openecomp.sdnc.core</groupId>
+        <artifactId>root</artifactId>
+            <version>1.0.0</version>
+            <relativePath>rootpom/pom.xml</relativePath>
+    </parent>
+
+
+
+    <issueManagement>
+        <system>JIRA</system>
+        <url>http://jira.openecomp.org/</url>
+    </issueManagement>
+
+
+    <scm>
+        <connection>scm:git:ssh://git@${openecomp.git.host}/sdnc-code.git</connection>
+        <developerConnection>scm:git:ssh://${openecomp.git.host}:${openecomp.git.port}/${openecomp.git.project}/sdnc-core.git</developerConnection>
+        <url>${openecomp.git.protocol}://${openecomp.git.host}/projects/${openecomp.git.project}/repos/sdnc-core/browse</url>
+    <tag>HEAD</tag>
+  </scm>
+
+    <ciManagement>
+        <system>Jenkins</system>
+        <url>>https://jenkins.openecomp.org/</url>
+    </ciManagement>
+
+
+    <distributionManagement>
+        <site>
+          <id>sdnc-javadoc</id>
+          <url>dav:https://${openecomp.nexus.host}:${openecomp.nexus.port}/repository/sdn-c-javadoc/${project.artifactId}/${project.version}</url>
+        </site>
+    </distributionManagement>
+
+    <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>
+            <!-- Blackduck plugin breaks release build
+            <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>
+    <modules>
+        <module>rootpom</module>
+        <module>dblib</module>
+        <module>filters</module>
+        <module>sli</module>
+        <module>sliPluginUtils</module>
+        <module>sliapi</module>
+    </modules>
+    <organization>
+        <name>AT&amp;T</name>
+    </organization>
+    <version>1.0.0</version>
+
+
+</project>
diff --git a/rootpom/pom.xml b/rootpom/pom.xml
new file mode 100755 (executable)
index 0000000..b1fff92
--- /dev/null
@@ -0,0 +1,723 @@
+<?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.opendaylight.odlparent</groupId>
+    <artifactId>odlparent</artifactId>
+    <version>1.6.2-Beryllium-SR2</version>
+    <relativePath>../../../../../opendaylight/odlparent</relativePath>
+  </parent>
+
+  <profiles>
+    <profile>
+      <id>local-build</id>
+      <activation>
+        <property>
+          <name>internal</name>
+          <value>!false</value>
+        </property>
+      </activation>
+      <properties>
+        <ssl.allowall>true</ssl.allowall>
+        <ssl.insecure>true</ssl.insecure>
+        <openecomp.nexus.host>162.242.254.138</openecomp.nexus.host>
+       <openecomp.nexus.port>8443</openecomp.nexus.port>
+        <openecomp.nexus.release-url>https://${openecomp.nexus.host}:8443/repository/maven-releases/</openecomp.nexus.release-url>
+        <openecomp.nexus.snapshot-url>https://${openecomp.nexus.host}:8443/repository/maven-snapshots/</openecomp.nexus.snapshot-url>
+        <openecomp.git.host>codecloud.web.att.com</openecomp.git.host>
+        <openecomp.git.port>7999</openecomp.git.port>
+        <openecomp.git.project>st_osecomp</openecomp.git.project>
+        <openecomp.git.protocol>http</openecomp.git.protocol>
+      </properties>
+    </profile>
+    <profile>
+      <id>external-build</id>
+      <activation>
+        <property>
+          <name>internal</name>
+          <value>false</value>
+        </property>
+      </activation>
+      <properties>
+        <ssl.allowall>false</ssl.allowall>
+        <ssl.insecure>false</ssl.insecure>
+        <openecomp.nexus.host>ecomp-nexus</openecomp.nexus.host>
+       <openecomp.nexus.port>8443</openecomp.nexus.port>
+        <openecomp.nexus.release-url>https://${openecomp.nexus.host}:8443/repository/maven-releases/</openecomp.nexus.release-url>
+        <openecomp.nexus.snapshot-url>https://${openecomp.nexus.host}:8443/repository/maven-snapshots/</openecomp.nexus.snapshot-url>
+        <openecomp.git.host>10.208.194.49</openecomp.git.host>
+        <openecomp.git.port>443</openecomp.git.port>
+        <openecomp.git.project>openecomp</openecomp.git.project>
+        <openecomp.git.protocol>https</openecomp.git.protocol>
+      </properties>
+    </profile>
+
+  </profiles>
+
+  <properties>
+    <release-tag>R17.01</release-tag>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <bundle.plugin.version>2.5.0</bundle.plugin.version>
+    <java.version.source>1.7</java.version.source>
+    <java.version.target>1.7</java.version.target>
+    <maven.compile.plugin.version>2.5.1</maven.compile.plugin.version>
+    <equinox.osgi.version>3.8.1.v20120830-144521</equinox.osgi.version>
+    <jackson-annotations-version>${jackson.version}</jackson-annotations-version>
+    <jettison.version>1.3.7</jettison.version>
+    <jvnet.jaxb2.version>0.6.4</jvnet.jaxb2.version>
+    <apache.httpcomponents.version>4.4</apache.httpcomponents.version>
+    <antlr.version>4.5.1</antlr.version>
+    <mysql.connector.version>5.1.39</mysql.connector.version>
+    <odl.version>1.6.2-Beryllium-SR2</odl.version>
+    <odl.dlux.version>0.3.2-Beryllium-SR2</odl.dlux.version>
+    <odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version>
+    <odl.mdsal.version>1.3.2-Beryllium-SR2</odl.mdsal.version>
+    <odl.mdsal.features.version>2.0.2-Beryllium-SR2</odl.mdsal.features.version>
+    <odl.mdsal.model.version>0.8.2-Beryllium-SR2</odl.mdsal.model.version>
+    <odl.restconf.version>1.3.2-Beryllium-SR2</odl.restconf.version>
+    <odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version>
+    <odl.controller.model.version>${odl.mdsal.model.version}</odl.controller.model.version>
+    <odl.controller.config.api.version>0.4.2-Beryllium-SR2</odl.controller.config.api.version>
+    <odl.karaf.empty.distro.version>${odl.version}</odl.karaf.empty.distro.version>
+    <odl.commons.opendaylight.version>${odl.version}</odl.commons.opendaylight.version>
+    <odl.ietf-inet-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-inet-types.version>
+    <odl.ietf-yang-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-yang-types.version>
+    <odl.yang.jmx.generator.version>0.4.2-Beryllium-SR2</odl.yang.jmx.generator.version>
+    <odl.yangtools.yang.maven.plugin.version>${odl.yangtools.version}</odl.yangtools.yang.maven.plugin.version>
+    <features.file>features.xml</features.file>
+    <h2database.version>1.4.186</h2database.version>
+    <jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
+    <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
+    <checkstyle.skip>true</checkstyle.skip>
+
+    <sonar.language>java</sonar.language>
+    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+    <sonar.surefire.reportsPath>${project.build.directory}/surefire-reports</sonar.surefire.reportsPath>
+    <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco.exec</sonar.jacoco.reportPath>
+    <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero>
+    <sonar.projectVersion>${project.version}</sonar.projectVersion>
+
+    <sdnc.core.version>1.0.0</sdnc.core.version>
+    <sdnc.adaptors.version>1.0.0</sdnc.adaptors.version>
+    <sdnctl.sli.version>${sdnc.core.version}</sdnctl.sli.version>
+    <sdnctl.aai.service.version>${sdnc.adaptors.version}</sdnctl.aai.service.version>
+    <sdnctl.dblib.version>${sdnc.core.version}</sdnctl.dblib.version>
+    <sdnctl.mdsal.resource.version>${sdnc.adaptors.version}</sdnctl.mdsal.resource.version>
+    <sdnctl.slipluginutils.version>${sdnc.core.version}</sdnctl.slipluginutils.version>
+  </properties>
+
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>pom</packaging>
+  <groupId>org.openecomp.sdnc.core</groupId>
+  <artifactId>root</artifactId>
+  <version>1.0.0</version>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>opendaylight-karaf-empty</artifactId>
+        <version>${odl.karaf.empty.distro.version}</version>
+        <type>zip</type>
+      </dependency>
+
+
+      <dependency>
+        <groupId>org.openecomp.sdnc.core</groupId>
+        <artifactId>sli-common</artifactId>
+        <version>${sdnctl.sli.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.openecomp.sdnc.core</groupId>
+        <artifactId>sli-provider</artifactId>
+        <version>${sdnctl.sli.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.openecomp.sdnc.core</groupId>
+        <artifactId>aai-service-provider</artifactId>
+        <version>${sdnctl.aai.service.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.openecomp.sdnc.core</groupId>
+        <artifactId>dblib-provider</artifactId>
+        <version>${sdnctl.dblib.version}</version>
+      </dependency>
+    </dependencies>
+
+  </dependencyManagement>
+
+
+  <name>SDNC Root</name>
+  <url>http://wiki.openecomp.org</url>
+  <description>Root POM to be used for all SDNC projects</description>
+
+
+  <issueManagement>
+    <system>JIRA</system>
+    <url>https://jira.openecomp.org/</url>
+  </issueManagement>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.10.4</version>
+        <configuration>
+          <failOnError>false</failOnError>
+          <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
+          <docletArtifact>
+            <groupId>org.umlgraph</groupId>
+            <artifactId>umlgraph</artifactId>
+            <version>5.6</version>
+          </docletArtifact>
+          <additionalparam>-views</additionalparam>
+          <useStandardDocletOptions>true</useStandardDocletOptions>
+         <excludePackageNames>org.opendaylight.*</excludePackageNames>
+          <additionalDependencies>
+           <additionalDependency>
+             <groupId>org.opendaylight.odlparent</groupId>
+              <artifactId>odlparent</artifactId>
+              <version>1.6.2-Beryllium-SR2</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.slf4j</groupId>
+              <artifactId>slf4j-api</artifactId>
+              <version>${slf4j.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.antlr</groupId>
+              <artifactId>antlr4</artifactId>
+              <version>${antlr.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.antlr</groupId>
+              <artifactId>antlr4-runtime</artifactId>
+              <version>${antlr.version}</version>
+            </additionalDependency>
+
+            <additionalDependency>
+              <groupId>com.sun.jersey</groupId>
+              <artifactId>jersey-client</artifactId>
+              <version>${jersey.json.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>com.sun.jersey</groupId>
+              <artifactId>jersey-core</artifactId>
+              <version>${jersey.json.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.apache.httpcomponents</groupId>
+              <artifactId>httpcore-osgi</artifactId>
+              <version>${apache.httpcomponents.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.apache.httpcomponents</groupId>
+              <artifactId>httpclient-osgi</artifactId>
+              <version>${apache.httpcomponents.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>com.fasterxml.jackson.core</groupId>
+              <artifactId>jackson-databind</artifactId>
+              <version>${fasterxml.jackson.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>com.fasterxml.jackson.core</groupId>
+              <artifactId>jackson-annotations</artifactId>
+              <version>${fasterxml.jackson.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>com.fasterxml.jackson.core</groupId>
+              <artifactId>jackson-core</artifactId>
+              <version>${fasterxml.jackson.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>commons-lang</groupId>
+              <artifactId>commons-lang</artifactId>
+              <version>${commons.lang.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.opendaylight.mdsal</groupId>
+              <artifactId>yang-binding</artifactId>
+              <version>${odl.yangtools.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.opendaylight.yangtools</groupId>
+              <artifactId>yang-common</artifactId>
+              <version>${odl.yangtools.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.opendaylight.mdsal.model</groupId>
+              <artifactId>ietf-inet-types</artifactId>
+              <version>${odl.ietf-inet-types.version}</version>
+            </additionalDependency>
+            <additionalDependency>
+              <groupId>org.opendaylight.mdsal.model</groupId>
+              <artifactId>ietf-yang-types</artifactId>
+              <version>${odl.ietf-yang-types.version}</version>
+            </additionalDependency>
+          </additionalDependencies>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>javadoc-no-fork</report>
+              <report>test-javadoc-no-fork</report>
+            </reports>
+          </reportSet>
+          <reportSet>
+            <id>aggregate</id>
+            <reports>
+              <report>aggregate</report>
+              <report>test-aggregate</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>2.3</version>
+        <reportSets>
+          <reportSet>
+            <id>aggregate</id>
+            <reports>
+              <report>aggregate</report>
+              <report>test-aggregate</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.17</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-changelog-plugin</artifactId>
+        <version>2.3</version>
+        <reportSets>
+          <reportSet>
+            <id>dual-report</id>
+            <configuration>
+              <type>range</type>
+              <range>30</range>
+            </configuration>
+            <reports>
+              <report>changelog</report>
+              <report>file-activity</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>taglist-maven-plugin</artifactId>
+        <version>2.4</version>
+      </plugin>
+    </plugins>
+  </reporting>
+
+
+  <pluginRepositories>
+    <pluginRepository>
+      <id>openecomp-public</id>
+      <url>http://${openecomp.nexus.host}:8443/repository/maven-public</url>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </pluginRepository>
+    <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>
+    <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>
+<!-- Black Duck plugin dependencies -->
+    <pluginRepository>
+      <id>JCenter</id>
+      <name>JCenter Repository</name>
+      <url>http://jcenter.bintray.com</url>
+    </pluginRepository>
+
+    <pluginRepository>
+      <id>Restlet</id>
+      <name>Restlet Repository</name>
+      <url>http://maven.restlet.com</url>
+    </pluginRepository>
+  </pluginRepositories>
+
+
+  <repositories>
+    <repository>
+      <id>openecomp-public</id>
+      <url>https://${openecomp.nexus.host}:8443/repository/maven-public</url>
+      <releases>
+        <enabled>true</enabled>
+                               <!-- <updatePolicy>always</updatePolicy> <updatePolicy>never</updatePolicy>
+                                       <updatePolicy>daily</updatePolicy> <updatePolicy>interval:in minutes</updatePolicy> -->
+        <updatePolicy>never</updatePolicy>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+        <updatePolicy>always</updatePolicy>
+                               <!-- <updatePolicy>always</updatePolicy> <updatePolicy>never</updatePolicy>
+                                       <updatePolicy>daily</updatePolicy> <updatePolicy>interval:30</updatePolicy> -->
+      </snapshots>
+    </repository>
+    <repository>
+      <id>openecomp-release</id>
+      <name>openecomp-repository-releases</name>
+      <url>${openecomp.nexus.release-url}</url>
+      <releases>
+        <enabled>true</enabled>
+        <updatePolicy>never</updatePolicy>
+      </releases>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+    </repository>
+    <repository>
+      <id>openecomp-snapshot</id>
+      <name>openecomp-repository-snapshots</name>
+      <url>${openecomp.nexus.snapshot-url}</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+    <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>
+    <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>
+
+  <distributionManagement>
+    <site>
+      <id>sdnc-javadoc</id>
+      <url>dav:https://ecomp-nexus:${openecomp.nexus.port}/repository/sdn-c-javadoc/${project.version}</url>
+    </site>
+    <repository>
+      <id>nexus</id>
+      <name>openecomp-repository-releases</name>
+      <url>${openecomp.nexus.release-url}</url>
+    </repository>
+    <snapshotRepository>
+      <id>nexus</id>
+      <name>openecomp-repository-snapshots</name>
+      <url>${openecomp.nexus.snapshot-url}</url>
+    </snapshotRepository>
+  </distributionManagement>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-site-plugin</artifactId>
+          <version>3.6</version>
+          <dependencies>
+            <dependency><!-- add support for ssh/scp -->
+              <groupId>org.apache.maven.wagon</groupId>
+              <artifactId>wagon-ssh</artifactId>
+              <version>1.0</version>
+            </dependency>
+            <dependency>
+              <groupId>org.apache.maven.wagon</groupId>
+              <artifactId>wagon-webdav-jackrabbit</artifactId>
+              <version>2.10</version>
+            </dependency>
+          </dependencies>
+          <executions>
+            <execution>
+              <id>attach-descriptor</id>
+              <goals>
+                <goal>attach-descriptor</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+        <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.codehaus.mojo</groupId>
+        <artifactId>sonar-maven-plugin</artifactId>
+        <version>3.2</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-javadoc-plugin</artifactId>
+          <version>2.10</version>
+          <configuration>
+            <additionalDependencies>
+              <additionalDependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>${slf4j.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.antlr</groupId>
+                <artifactId>antlr4</artifactId>
+                <version>${antlr.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.antlr</groupId>
+                <artifactId>antlr4-runtime</artifactId>
+                <version>${antlr.version}</version>
+              </additionalDependency>
+
+              <additionalDependency>
+                <groupId>com.sun.jersey</groupId>
+                <artifactId>jersey-client</artifactId>
+                <version>${jersey.client.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>com.sun.jersey</groupId>
+                <artifactId>jersey-core</artifactId>
+                <version>${jersey.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpcore-osgi</artifactId>
+                <version>${apache.httpcomponents.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpclient-osgi</artifactId>
+                <version>${apache.httpcomponents.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-databind</artifactId>
+                <version>${jackson.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-annotations</artifactId>
+                <version>${jackson.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-core</artifactId>
+                <version>${jackson.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>commons-lang</groupId>
+                <artifactId>commons-lang</artifactId>
+                <version>${commons.lang.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.opendaylight.mdsal</groupId>
+                       <artifactId>yang-binding</artifactId>
+                       <version>${odl.yangtools.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-common</artifactId>
+                <version>${odl.yangtools.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.opendaylight.mdsal.model</groupId>
+                <artifactId>ietf-inet-types</artifactId>
+                <version>${odl.ietf-inet-types.version}</version>
+              </additionalDependency>
+              <additionalDependency>
+                <groupId>org.opendaylight.mdsal.model</groupId>
+                <artifactId>ietf-yang-types</artifactId>
+                <version>${odl.ietf-yang-types.version}</version>
+              </additionalDependency>
+            </additionalDependencies>
+          </configuration>
+
+          <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>
+
+    <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>
+          <excludes>
+            <exclude>**/*.png</exclude>
+            <exclude>**/*.json</exclude>
+          </excludes>
+
+        </configuration>
+
+        <executions>
+
+          <execution>
+
+            <id>first</id>
+
+            <goals>
+
+              <goal>update-file-header</goal>
+
+            </goals>
+
+            <phase>process-sources</phase>
+
+          </execution>
+
+        </executions>
+
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>properties-maven-plugin</artifactId>
+        <version>1.0.0</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>set-system-properties</goal>
+            </goals>
+            <configuration>
+              <properties>
+                <property>
+                  <name>maven.wagon.http.ssl.allowall</name>
+                  <value>${ssl.allowall}</value>
+                </property>
+                <property>
+                  <name>maven.wagon.http.ssl.insecure</name>
+                  <value>${ssl.insecure}</value>
+                </property>
+              </properties>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>versions-maven-plugin</artifactId>
+        <version>2.3</version>
+      </plugin>
+      <plugin>
+        <artifactId>maven-scm-plugin</artifactId>
+        <version>1.8.1</version>
+        <configuration>
+          <tag>${project.artifactId}-${project.version}</tag>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <organization>
+    <name>OpenECOMP</name>
+  </organization>
+</project>
diff --git a/rootpom/src/site/site.xml b/rootpom/src/site/site.xml
new file mode 100644 (file)
index 0000000..476d6fc
--- /dev/null
@@ -0,0 +1,22 @@
+<?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>
+</project>
diff --git a/rootpom/src/site/site_en.xml b/rootpom/src/site/site_en.xml
new file mode 100644 (file)
index 0000000..476d6fc
--- /dev/null
@@ -0,0 +1,22 @@
+<?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>
+</project>
diff --git a/sli/.gitignore b/sli/.gitignore
new file mode 100755 (executable)
index 0000000..3632ac6
--- /dev/null
@@ -0,0 +1,38 @@
+#####standard .git ignore entries#####\r
+\r
+## IDE Specific Files ##\r
+org.eclipse.core.resources.prefs\r
+.classpath\r
+.project\r
+.settings\r
+.idea\r
+.externalToolBuilders\r
+maven-eclipse.xml\r
+workspace\r
+\r
+## Compilation Files ##\r
+*.class\r
+**/target\r
+target\r
+target-ide\r
+MANIFEST.MF\r
+\r
+## Misc Ignores (OS specific etc) ##\r
+bin/\r
+dist\r
+*~\r
+*.ipr\r
+*.iml\r
+*.iws\r
+classes\r
+out/\r
+.DS_STORE\r
+.metadata\r
+\r
+## antlr4 generated files ##\r
+ExprGrammarBaseListener.java\r
+ExprGrammarLexer.java\r
+ExprGrammarListener.java\r
+ExprGrammarParser.java\r
+ExprGrammar.tokens\r
+ExprGrammarLexer.tokens\r
diff --git a/sli/common/pom.xml b/sli/common/pom.xml
new file mode 100755 (executable)
index 0000000..1f65694
--- /dev/null
@@ -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>1.0.0</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.yangtools.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 (executable)
index 0000000..51f4016
--- /dev/null
@@ -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/ConfigurationException.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/ConfigurationException.java
new file mode 100644 (file)
index 0000000..3ff29e3
--- /dev/null
@@ -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 (file)
index 0000000..2fabbe8
--- /dev/null
@@ -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/MetricLogger.java b/sli/common/src/main/java/org/openecomp/sdnc/sli/MetricLogger.java
new file mode 100644 (file)
index 0000000..f664331
--- /dev/null
@@ -0,0 +1,283 @@
+/*-
+ * ============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 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 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 (file)
index 0000000..9f8038c
--- /dev/null
@@ -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 (file)
index 0000000..f474b04
--- /dev/null
@@ -0,0 +1,169 @@
+/*-
+ * ============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()
+       {
+               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 (file)
index 0000000..5c2626c
--- /dev/null
@@ -0,0 +1,141 @@
+/*-
+ * ============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(" ");
+                       sbuff.append(operands.get(i+1).toString());
+               }
+               
+               return(sbuff.toString());
+
+       }
+       
+       public String asParsedExpr()
+       {
+               
+               List<SvcLogicExpression>operands = getOperands();
+               StringBuffer sbuff = new StringBuffer();
+               StringBuffer closeParens = new StringBuffer();
+               int i = 0;
+               for (OperatorType operator : operators)
+               {
+                       sbuff.append("(");
+                       sbuff.append(operator.getText());
+                       sbuff.append(" ");
+                       sbuff.append(operands.get(i++).asParsedExpr());
+                       closeParens.append(")");
+               }
+               sbuff.append(" ");
+               if (i < operands.size())
+               {
+                       sbuff.append(operands.get(i).asParsedExpr());
+               }
+               else
+               {
+                       sbuff.append("__MISSING_OPERAND__");
+               }
+               sbuff.append(closeParens.toString());
+               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 (file)
index 0000000..c51b19a
--- /dev/null
@@ -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 (file)
index 0000000..5fca466
--- /dev/null
@@ -0,0 +1,531 @@
+/*-
+ * ============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 (Exception e) {
+                       throw new ConfigurationException("SQL query 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 (file)
index 0000000..34dd6bb
--- /dev/null
@@ -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 (file)
index 0000000..49ad0da
--- /dev/null
@@ -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.debug("Pushing expression ["+expr.getClass().getName()+"]");
+               if (curExpr != null)
+               {
+                       exprStack.push(curExpr);
+               }
+               curExpr = expr;
+       }
+       
+       private void popExpr()
+       {
+               if (exprStack.isEmpty())
+               {
+                       LOG.debug("Popping last expression");
+                       topExpr = curExpr;
+               }
+               else
+               {
+                       SvcLogicExpression lastExpr = curExpr;
+                       curExpr = exprStack.pop();
+                       curExpr.addOperand(lastExpr);
+                       LOG.debug("New curExpr is ["+curExpr.getClass().getName()+"]");
+               }
+               
+       }
+       
+       @Override
+       public void enterAtom(AtomContext ctx) {
+               
+               String atomText = ctx.getText();
+               
+               LOG.debug("enterAtom: text = "+atomText);
+
+               
+               SvcLogicAtom newAtom = new SvcLogicAtom(atomText);
+               
+               pushExpr(newAtom);
+       }
+
+
+       @Override
+       public void enterMultExpr(MultExprContext ctx) {
+               LOG.debug("enterMultExpr: text = "+ctx.getText());
+               
+               SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+               pushExpr(curBinExpr);
+               
+               List<TerminalNode> opList = ctx.MULTOP();
+               
+               for (TerminalNode nd : opList)
+               {
+                       LOG.debug("enterMultExpr: operator - "+nd.getText());
+                       curBinExpr.addOperator(nd.getText());
+               }
+
+       }
+
+       @Override
+       public void exitMultExpr(MultExprContext ctx) {
+
+               LOG.debug("exitMultExpr: text = "+ctx.getText());
+
+               popExpr();
+               
+       }
+
+       @Override
+       public void exitAtom(AtomContext ctx) {
+               LOG.debug("exitAtom: text = "+ctx.getText());
+               popExpr();
+       }
+
+       @Override
+       public void enterAddExpr(AddExprContext ctx) {
+               LOG.debug("enterAddExpr: text = "+ctx.getText());
+               List<TerminalNode> opList = ctx.ADDOP();
+               
+
+               SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+               pushExpr(curBinExpr);
+
+               
+               for (TerminalNode nd : opList)
+               {
+                       LOG.debug("enterAddExpr: operator - "+nd.getText());
+                       curBinExpr.addOperator(nd.getText());
+               }
+               
+       }
+
+       @Override
+       public void exitAddExpr(AddExprContext ctx) {
+               LOG.debug("exitAddExpr: text = "+ctx.getText());
+               
+               popExpr();
+       }
+
+       @Override
+       public void enterFuncExpr(FuncExprContext ctx) {
+               LOG.debug("enterFuncExpr: text = "+ctx.getText());
+               LOG.debug("enterFuncExpr - IDENTIFIER : "+ctx.IDENTIFIER().getText());
+               
+               for (ExprContext expr: ctx.expr())
+               {
+                       LOG.debug("enterFuncExpr - expr = "+expr.getText());
+               }
+               
+
+               pushExpr(new SvcLogicFunctionCall(ctx.IDENTIFIER().getText()));
+       }
+
+       @Override
+       public void exitFuncExpr(FuncExprContext ctx) {
+               LOG.debug("exitFuncExpr: text = "+ctx.getText());
+               
+               popExpr();
+       }
+
+       @Override
+       public void enterParenExpr(ParenExprContext ctx) {
+               LOG.debug("enterParenExpr: text = "+ctx.getText());
+               LOG.debug("enterParenExpr: expr = "+ctx.expr().getText());
+       }
+
+       @Override
+       public void exitParenExpr(ParenExprContext ctx) {
+               LOG.debug("exitParenExpr: text = "+ctx.getText());
+       }
+
+       @Override
+       public void enterRelExpr(RelExprContext ctx) {
+               LOG.debug("enterRelExpr: text = "+ctx.getText());
+               
+               List<TerminalNode> opList = ctx.RELOP();
+               
+
+               SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+               pushExpr(curBinExpr);
+
+               
+               for (TerminalNode nd : opList)
+               {
+                       LOG.debug("enterRelExpr: operator - "+nd.getText());
+                       curBinExpr.addOperator(nd.getText());
+               }
+               
+       }
+
+       @Override
+       public void exitRelExpr(RelExprContext ctx) {
+               LOG.debug("exitRelExpr: text = "+ctx.getText());
+               
+               popExpr();
+       }
+
+       @Override
+       public void enterCompareExpr(CompareExprContext ctx) {
+               LOG.debug("enterCompareExpr: text = "+ctx.getText());
+               
+               TerminalNode nd = ctx.COMPAREOP();
+
+               SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression();
+               pushExpr(curBinExpr);
+
+               LOG.debug("enterCompareExpr: operator - "+nd.getText());
+               curBinExpr.addOperator(nd.getText());
+
+       }
+
+       @Override
+       public void exitCompareExpr(CompareExprContext ctx) {
+               LOG.debug("exitCompareExpr : text = "+ctx.getText());
+               
+               popExpr();
+       }
+
+
+       
+       @Override 
+       public void enterConstant(ConstantContext ctx) {
+               LOG.debug("enterConstant: text = "+ctx.getText());
+       }
+
+       @Override
+       public void exitConstant(ConstantContext ctx) {
+               LOG.debug("exitConstant: text = "+ctx.getText());
+       }
+
+
+       @Override
+       public void enterVariable(VariableContext ctx) {
+               LOG.debug("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.debug("exitVariableLead: text ="+ctx.getText());
+       }
+
+       @Override
+       public void enterVariableTerm(VariableTermContext ctx) {
+               LOG.debug("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.debug("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 (file)
index 0000000..ac4591b
--- /dev/null
@@ -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 (file)
index 0000000..509e121
--- /dev/null
@@ -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 (file)
index 0000000..e4d82de
--- /dev/null
@@ -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.debug("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 (file)
index 0000000..b9085e2
--- /dev/null
@@ -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 (file)
index 0000000..9631d68
--- /dev/null
@@ -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 (file)
index 0000000..d3c9d45
--- /dev/null
@@ -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 (file)
index 0000000..e64a2c1
--- /dev/null
@@ -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 (file)
index 0000000..578a691
--- /dev/null
@@ -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 (file)
index 0000000..0359909
--- /dev/null
@@ -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())) {
+            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 (file)
index 0000000..5fd19cc
--- /dev/null
@@ -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 (file)
index 0000000..d0e9361
--- /dev/null
@@ -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 (file)
index 0000000..914444e
--- /dev/null
@@ -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 (file)
index 0000000..ff02718
--- /dev/null
@@ -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 (file)
index 0000000..a12496b
--- /dev/null
@@ -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 (file)
index 0000000..5cec818
--- /dev/null
@@ -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 (file)
index 0000000..b6a5a1f
--- /dev/null
@@ -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 (executable)
index 0000000..614a118
--- /dev/null
@@ -0,0 +1,312 @@
+<?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: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>
+                <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>
+                <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>
+                <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:attribute name="value" 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>
+                <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: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: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>
+                <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: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 (executable)
index 0000000..ae654ae
--- /dev/null
@@ -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 (executable)
index 0000000..2de186e
--- /dev/null
@@ -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 (executable)
index 0000000..0b36a56
--- /dev/null
@@ -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 (file)
index 0000000..ea6e1e1
--- /dev/null
@@ -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 (file)
index 0000000..6ebd6df
--- /dev/null
@@ -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 (file)
index 0000000..2ee65f5
--- /dev/null
@@ -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 (file)
index 0000000..8f6b587
--- /dev/null
@@ -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 (file)
index 0000000..87d4d62
--- /dev/null
@@ -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 (file)
index 0000000..53579ae
--- /dev/null
@@ -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 (file)
index 0000000..8821b66
--- /dev/null
@@ -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 (executable)
index 0000000..bc92495
--- /dev/null
@@ -0,0 +1,15 @@
+$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')
diff --git a/sli/common/src/test/resources/mergetest.xml b/sli/common/src/test/resources/mergetest.xml
new file mode 100644 (file)
index 0000000..0691028
--- /dev/null
@@ -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 (file)
index 0000000..818c4c5
--- /dev/null
@@ -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 (file)
index 0000000..fbdd2cc
--- /dev/null
@@ -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 (executable)
index 0000000..82913af
--- /dev/null
@@ -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 (executable)
index 0000000..0654312
--- /dev/null
@@ -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 (file)
index 0000000..e202c4e
--- /dev/null
@@ -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 (file)
index 0000000..3412166
--- /dev/null
@@ -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 (file)
index 0000000..98459d3
--- /dev/null
@@ -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 (executable)
index 0000000..614a118
--- /dev/null
@@ -0,0 +1,312 @@
+<?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: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>
+                <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>
+                <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>
+                <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:attribute name="value" 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>
+                <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: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: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>
+                <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:schema>
diff --git a/sli/features/pom.xml b/sli/features/pom.xml
new file mode 100755 (executable)
index 0000000..f07aad6
--- /dev/null
@@ -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>1.0.0</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.controller</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.controller</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 (file)
index 0000000..83d5507
--- /dev/null
@@ -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 version="${sdnctl.dblib.version}">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 (executable)
index 0000000..a9dc66b
--- /dev/null
@@ -0,0 +1,147 @@
+<?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>1.0.0</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>
+                                               </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>
+                                               </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 (file)
index 0000000..80b2ad1
--- /dev/null
@@ -0,0 +1,58 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..c87b7d3
--- /dev/null
@@ -0,0 +1,48 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..d8d381d
--- /dev/null
@@ -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 (executable)
index 0000000..2b1bc4a
--- /dev/null
@@ -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>1.0.0</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>1.0.0</version>
+
+
+</project>
diff --git a/sli/provider/pom.xml b/sli/provider/pom.xml
new file mode 100755 (executable)
index 0000000..bfea0e2
--- /dev/null
@@ -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>1.0.0</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 (file)
index 0000000..a70dfc8
--- /dev/null
@@ -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/CallNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/CallNodeExecutor.java
new file mode 100644 (file)
index 0000000..2a0b77a
--- /dev/null
@@ -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);
+               }
+
+               
+               SvcLogicStore store = SvcLogicActivator.getStore();
+               
+               LOG.debug("Calling ["+module+","+rpc+","+version+","+mode+"]");
+               
+               if (store != null)
+               {
+                       SvcLogicGraph calledGraph = store.fetch(module, rpc, version, mode);
+                       
+                       if (calledGraph != null)
+                       {
+                               svc.execute(calledGraph, ctx);
+                               
+                               outValue = ctx.getStatus();
+                       }
+                       else
+                       {
+                               LOG.debug("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");
+                       }
+                       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/ConfigureNodeExecutor.java b/sli/provider/src/main/java/org/openecomp/sdnc/sli/provider/ConfigureNodeExecutor.java
new file mode 100644 (file)
index 0000000..a24b01c
--- /dev/null
@@ -0,0 +1,249 @@
+/*-
+ * ============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 = SvcLogicAdaptorFactory
+                               .getInstance(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 (file)
index 0000000..da8386c
--- /dev/null
@@ -0,0 +1,115 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..d6c7a8d
--- /dev/null
@@ -0,0 +1,138 @@
+/*-
+ * ============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.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.SvcLogicJavaPlugin;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+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 ExecuteNodeExecutor extends SvcLogicNodeExecutor {
+       private static final Logger LOG = LoggerFactory
+                       .getLogger(ExecuteNodeExecutor.class);
+
+       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);
+               }
+               
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(pluginName);
+
+               if (sref == null) {
+                       outValue = "not-found";
+               } else {
+                       SvcLogicJavaPlugin plugin  = (SvcLogicJavaPlugin) bctx
+                                       .getService(sref);
+                       
+                       String methodName = SvcLogicExpressionResolver.evaluate(node.getAttribute("method"),  node, ctx);
+                       
+                       Class pluginClass = plugin.getClass();
+                       
+                       Method pluginMethod = null;
+                       
+                       try {
+                               pluginMethod = pluginClass.getMethod(methodName, Map.class, SvcLogicContext.class);
+                       } catch (Exception e) {
+                               LOG.error("Caught exception looking for method "+pluginName+"."+methodName+"(Map, SvcLogicContext)");
+                       }
+                       
+                       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);
+                                       }
+                                       
+                                       pluginMethod.invoke(plugin, parmMap, ctx);
+                                       
+                                       outValue = "success";
+                               } catch (Exception e) {
+                                       LOG.error("Caught exception executing "+pluginName+"."+methodName, 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);
+       }
+
+}
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 (file)
index 0000000..52bc372
--- /dev/null
@@ -0,0 +1,118 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..e824d85
--- /dev/null
@@ -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.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 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) {
+                       throw new SvcLogicException("Invalid index values [" + startVal
+                                       + "," + endVal + "]");
+               }
+
+               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));
+                                       }
+                               }
+                       }
+               }
+               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 (file)
index 0000000..71fdf3a
--- /dev/null
@@ -0,0 +1,146 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Cound not find service reference 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 (file)
index 0000000..83f08b6
--- /dev/null
@@ -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.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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..af172f9
--- /dev/null
@@ -0,0 +1,1405 @@
+/*-
+ * ============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);
+       public static final String PROPERTIES_FILE="/opt/bvc/controller/configuration/l3sdn.properties";
+       private static Properties properties = new Properties();
+       
+       
+       public static void setProperties(Properties properties) {
+               
+               for (Object propNameObj: properties.keySet()) {
+                       String propName = (String) propNameObj;
+                       MdsalHelper.properties.setProperty(propName, properties.getProperty(propName));
+               }
+       }
+
+       public static void loadProperties() {
+
+               File file = new File(PROPERTIES_FILE); 
+               Properties properties = new Properties();
+               InputStream input = null;
+               if (file.isFile() && file.canRead()) {
+                       try     {
+                               input = new FileInputStream(file);
+                               properties.load(input);
+                               MdsalHelper.setProperties(properties);
+                               LOG.info("Loaded properties from " + PROPERTIES_FILE );
+                       } catch (Exception e) {
+                               LOG.error("Failed to load properties " + PROPERTIES_FILE +"\n",e);
+                       } finally {
+                               if (input != null) {
+                                       try {
+                                               input.close();
+                                       } catch (IOException e) {
+                                               LOG.error("Failed to close properties file " + PROPERTIES_FILE +"\n",e);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       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();
+                                                                       String yangProp = "yang." + fieldName + "." + propVal;
+                                                                       if ( properties.containsKey(yangProp)) {
+                                                                               propVal = properties.getProperty(yangProp);
+                                                                               LOG.trace("Adjusting property " + yangProp + " " + propVal);
+                                                                       }
+                                                                       LOG.debug("Setting property " + propName
+                                                                                       + " to " + propVal);
+                                                                       props.setProperty(propName, propVal);
+                                                               }
+                                                       } catch (Exception e) {
+                                                               LOG.error(
+                                                                               "Caught exception trying to convert Yang-generated enum returned by "
+                                                                                               + fromClass.getName() + "."
+                                                                                               + m.getName()
+                                                                                               + "() to Properties 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,
+                                                                                       toUpperCamelCase(paramValue));
+                                                               } catch (Exception e) {
+                                                                       LOG.error(
+                                                                                       "Caught exception trying to convert field "
+                                                                                                       + propName + " to enum "
+                                                                                                       + paramClass.getName(), e);
+                                                               }
+
+                                                               try {
+                                                                       boolean isAccessible = m.isAccessible();
+                                                                       if (!isAccessible) {
+                                                                               m.setAccessible(true);
+                                                                       }
+
+                                                                       LOG.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);
+       }
+
+       public static String toUpperCamelCase(String inStr) {
+               if (inStr == null) {
+                       return (null);
+               } else if (inStr.length() == 0) {
+                       return(inStr);
+               }
+
+               String[] terms = inStr.split("-");
+               StringBuffer sbuff = new StringBuffer();
+               // Check if string begins with a digit
+               if (Character.isDigit(inStr.charAt(0))) {
+                       sbuff.append('_');
+               }
+               for (String term : terms) {
+                       sbuff.append(term.substring(0, 1).toUpperCase());
+                       if (term.length() > 1) {
+                               sbuff.append(term.substring(1));
+                       }
+               }
+               return (sbuff.toString());
+
+       }
+
+       public static boolean isGetter(Method m) {
+               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);
+       }
+
+}
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 (file)
index 0000000..d80e0f9
--- /dev/null
@@ -0,0 +1,118 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..06fbedf
--- /dev/null
@@ -0,0 +1,129 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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.isDebugEnabled()) {
+                       LOG.debug(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.isDebugEnabled()) {
+                               LOG.debug("executeRecordNode : parameter " + curName + " = "
+                                               + curExpr + " => " + curExprValue);
+                       }
+                       parmMap.put(curName, curExprValue);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicRecorder recorder = (SvcLogicRecorder) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Cound not find service reference 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 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 (file)
index 0000000..f2f85cd
--- /dev/null
@@ -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.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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..a565e07
--- /dev/null
@@ -0,0 +1,127 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..00864b6
--- /dev/null
@@ -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 (file)
index 0000000..f1c9f61
--- /dev/null
@@ -0,0 +1,154 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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 (file)
index 0000000..647340a
--- /dev/null
@@ -0,0 +1,190 @@
+/*-
+ * ============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.IOException;
+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.debug("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 (file)
index 0000000..62c6fde
--- /dev/null
@@ -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.net.URL;
+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());
+
+               }
+       };
+
+       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 (file)
index 0000000..7589f71
--- /dev/null
@@ -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 (file)
index 0000000..1af215f
--- /dev/null
@@ -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.SvcLogicBinaryExpression;
+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.openecomp.sdnc.sli.SvcLogicAtom.AtomType;
+import org.openecomp.sdnc.sli.SvcLogicBinaryExpression.OperatorType;
+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.debug("Evaluating context variable $"+varName);
+                                       
+                                       String varValue = ctx.getAttribute(varName);
+                                       
+                                       if (varValue == null) {
+                                               LOG.debug("Context variable $"+varName+" unset - treating as empty string");
+                                               varValue = "";
+                                       }
+                                               
+                                       return (varValue);
+                               }
+                               SvcLogicExpression parm = node.getParameter(varName);
+                               if (parm != null) {
+                                       LOG.debug("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.debug("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 (file)
index 0000000..931b358
--- /dev/null
@@ -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 org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+
+public abstract class SvcLogicNodeExecutor {
+       
+       public abstract SvcLogicNode execute(SvcLogicServiceImpl svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException;
+
+
+       protected String evaluateNodeTest(SvcLogicNode node, SvcLogicContext ctx)
+                       throws SvcLogicException {
+               if (node == null) {
+                       return null;
+               }
+
+               return (SvcLogicExpressionResolver.evaluate(node.getAttribute("test"),
+                               node, ctx));
+
+       }
+}
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 (file)
index 0000000..6351a2f
--- /dev/null
@@ -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=========================================================
+ */
+
+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.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+
+
+
+
+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 (file)
index 0000000..bd97224
--- /dev/null
@@ -0,0 +1,287 @@
+/*-
+ * ============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);
+
+               }
+               
+               if (nodeExecutors == null) {
+                       LOG.info("Start: registering node executors");
+                       registerExecutors();
+
+                       LOG.info("Done: registering node executors");
+               }
+               
+               LOG.info("About to execute graph " + graph.toString());
+
+               LOG.info("Executing root node");
+               SvcLogicContext ctx = new SvcLogicContext(props);
+               ctx.setDomDataBroker(domDataBroker);
+               SvcLogicNode curNode = graph.getRootNode();
+
+               while (curNode != null) {
+                       LOG.info("About to execute node # "+curNode.getNodeId()+" ("+curNode.getNodeType()+")");
+                       SvcLogicNode nextNode = executeNode(curNode, ctx);
+                       curNode = nextNode;
+               }
+               
+
+               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 (file)
index 0000000..39eda47
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * ============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.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+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 (file)
index 0000000..073bb3f
--- /dev/null
@@ -0,0 +1,148 @@
+/*-
+ * ============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.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+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);
+               }
+
+               BundleContext bctx = FrameworkUtil.getBundle(this.getClass())
+                               .getBundleContext();
+
+               ServiceReference sref = bctx.getServiceReference(plugin);
+
+               if (sref != null) {
+                       SvcLogicResource resourcePlugin = (SvcLogicResource) bctx
+                                       .getService(sref);
+
+                       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);
+                       }
+               } else {
+                       LOG.warn("Could not find service reference 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/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 (file)
index 0000000..ecfa33e
--- /dev/null
@@ -0,0 +1,112 @@
+/*-
+ * ============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.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
+               {
+                       String testExpr = null;
+                       SvcLogicContext ctx = new SvcLogicContext();
+                       SvcLogicGraph graph = new SvcLogicGraph();
+                       SvcLogicNode node = new SvcLogicNode(1, "return", graph);
+                       graph.setRootNode(node);
+                       
+                       while ((testExpr = testsReader.readLine()) != null) {
+                               testExpr = testExpr.trim();
+                               if (testExpr.startsWith("#"))
+                               {
+                                       testExpr = testExpr.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
+                               {
+                                       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);
+                                               }
+                                       }
+                               }
+                       }
+               }
+               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 (file)
index 0000000..aaad43d
--- /dev/null
@@ -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/resources/executor.tests b/sli/provider/src/test/resources/executor.tests
new file mode 100755 (executable)
index 0000000..e7547e6
--- /dev/null
@@ -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 (executable)
index 0000000..c5661c3
--- /dev/null
@@ -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
+$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-segmentation-id
+toUpperCase($network.name)
+toLowerCase($network.name)
+toUpperCase(substr($availability-zone, 0, 5))
+convertBase(1234, 10)
+convertBase(10, 16, 10)
+convertBase(ZZ, 36, 10)
+convertBase(10, 10, 36)
+(0 - 1) * $arg1
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 (file)
index 0000000..c1ae687
--- /dev/null
@@ -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 (file)
index 0000000..5250aa1
--- /dev/null
@@ -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 (file)
index 0000000..3412166
--- /dev/null
@@ -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 (executable)
index 0000000..62750cc
--- /dev/null
@@ -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>1.0.0</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 (file)
index 0000000..928b5ae
--- /dev/null
@@ -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 (file)
index 0000000..8afbddf
--- /dev/null
@@ -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 (file)
index 0000000..f519793
--- /dev/null
@@ -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 (file)
index 0000000..46d4aa6
--- /dev/null
@@ -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 (executable)
index 0000000..b73caf3
--- /dev/null
@@ -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 (executable)
index 0000000..3fa2315
--- /dev/null
@@ -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 (executable)
index 0000000..80343b3
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ruleset>\r
+  <rule ref="rulesets/java/naming.xml/BooleanGetMethodName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/j2ee.xml/StaticEJBFieldShouldBeFinal">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/codesize.xml/TooManyMethods">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/basic.xml/DoubleCheckedLocking">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/coupling.xml/ExcessiveImports">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode">\r
+    <priority>2</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/naming.xml/ShortMethodName">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/basic.xml/BooleanInstantiation">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/codesize.xml/TooManyFields">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/coupling.xml/LooseCoupling">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/design.xml/NonThreadSafeSingleton">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/j2ee.xml/DoNotUseThreads">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly">\r
+    <priority>5</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray">\r
+    <priority>2</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic">\r
+    <priority>3</priority>\r
+  </rule>\r
+  <rule ref="rulesets/java/strictexception.xml/AvoidCatchingGenericException">\r
+    <priority>3</priority>\r
+  </rule>\r
+</ruleset>\r
+\r
diff --git a/sliPluginUtils/features/pom.xml b/sliPluginUtils/features/pom.xml
new file mode 100755 (executable)
index 0000000..9910964
--- /dev/null
@@ -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>1.0.0</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.controller</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.controller</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 (file)
index 0000000..9d823e3
--- /dev/null
@@ -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 (executable)
index 0000000..f84f744
--- /dev/null
@@ -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>sliPluginUtils</artifactId>
+               <groupId>org.openecomp.sdnc.core</groupId>
+               <version>1.0.0</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>
+                                               </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>
+                                               </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 (file)
index 0000000..80b2ad1
--- /dev/null
@@ -0,0 +1,58 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..c87b7d3
--- /dev/null
@@ -0,0 +1,48 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..d8d381d
--- /dev/null
@@ -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 (executable)
index 0000000..b9e7b35
--- /dev/null
@@ -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>1.0.0</version>
+       <packaging>pom</packaging>
+       <modelVersion>4.0.0</modelVersion>
+
+
+       <parent>
+               <groupId>org.openecomp.sdnc.core</groupId>
+               <artifactId>sdnc-core</artifactId>
+               <version>1.0.0</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 (executable)
index 0000000..7c8c7c2
--- /dev/null
@@ -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">
+
+       <artifactId>sliPluginUtils-provider</artifactId>
+       <packaging>bundle</packaging>
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.openecomp.sdnc.core</groupId>
+               <artifactId>sliPluginUtils</artifactId>
+               <version>1.0.0</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>${sdnctl.sli.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>
+       </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/SliPluginUtils.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils.java
new file mode 100644 (file)
index 0000000..71cddb8
--- /dev/null
@@ -0,0 +1,624 @@
+/*-
+ * ============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.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+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<>();
+                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\"" );
+        }
+    }
+
+    // TODO: javadoc
+    public void ctxSortList( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
+        checkParameters(parameters, new String[]{"list","delimiter"}, LOG);
+        ArrayList<SortableCtxListElement> list = new ArrayList<>();
+
+        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);
+    }
+
+    // TODO: javadoc
+    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
+     */
+    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 {
+        for( String param : requiredParams ) {
+            if( !parametersMap.containsKey(param) ) {
+                log.error("Required parameter \"" + param + "\" was not found in parameter list.");
+                throw new SvcLogicException("Required parameter \"" + param + "\" was not found in parameter list");
+            }
+        }
+    }
+
+    /**
+     * 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<>( 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<>(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<>();
+
+        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<>(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[] 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;
+        }
+    }
+}
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 (file)
index 0000000..6ec1214
--- /dev/null
@@ -0,0 +1,88 @@
+/*-
+ * ============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.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 {
+
+//    private static final String SLIPLUGINUTILS_PROP_VAR = "/slipluginutils.properties";
+//    private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
+
+    @SuppressWarnings("rawtypes")
+    private final List<ServiceRegistration> registrations = new LinkedList<>();
+
+    private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtilsActivator.class);
+
+    @Override
+    public void start(BundleContext ctx) throws Exception {
+        // Read properties
+        Properties props = new Properties();
+
+        // ---uncomment below when adding properties file---
+        /*
+        String propDir = System.getenv(SDNC_CONFIG_DIR);
+        if (propDir == null) {
+            throw new ConfigurationException(
+            "Cannot find config file - " + SLIPLUGINUTILS_PROP_VAR + " and " + SDNC_CONFIG_DIR + " unset");
+        }
+        String propPath = propDir + SLIPLUGINUTILS_PROP_VAR;
+
+        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);
+        }
+        */
+
+        SliPluginUtils plugin = new SliPluginUtils(props);
+
+        LOG.info("Registering service "+plugin.getClass().getName());
+        registrations.add(ctx.registerService(plugin.getClass().getName(), plugin, 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/SvcLogicContextList.java b/sliPluginUtils/provider/src/main/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextList.java
new file mode 100644 (file)
index 0000000..9030008
--- /dev/null
@@ -0,0 +1,221 @@
+/*-
+ * ============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<>( 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<>(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 (file)
index 0000000..fc6b71e
--- /dev/null
@@ -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 (file)
index 0000000..7f400ef
--- /dev/null
@@ -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 (file)
index 0000000..526c215
--- /dev/null
@@ -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/SliPluginUtils_StaticFunctions.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SliPluginUtils_StaticFunctions.java
new file mode 100644 (file)
index 0000000..b45fed9
--- /dev/null
@@ -0,0 +1,221 @@
+/*-
+ * ============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 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_StaticFunctions {
+    private static final Logger LOG = LoggerFactory.getLogger(SliPluginUtils_StaticFunctions.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<>();
+    }
+
+    // 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", "USOSTCDALTX0101UJZZ01");
+        ctx.setAttribute("service-data.service-information.service-type", "VMS");
+
+        Map<String, String> entries = SliPluginUtils.ctxGetBeginsWith(ctx, "service-data.service-information");
+
+        assertEquals( "USOSTCDALTX0101UJZZ01", entries.get("service-data.service-information.service-instance-id") );
+        assertEquals( "VMS", 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<>();
+        entries.put("service-data.oper-status.order-status", "InProgress");
+        entries.put("service-data.service-information.service-instance-id", "USOSTCDALTX0101UJZZ01");
+        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( "USOSTCDALTX0101UJZZ01", 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);
+    }
+}
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 (file)
index 0000000..f19359c
--- /dev/null
@@ -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/SvcLogicContextListTest.java b/sliPluginUtils/provider/src/test/java/org/openecomp/sdnc/sli/SliPluginUtils/SvcLogicContextListTest.java
new file mode 100644 (file)
index 0000000..2c1676c
--- /dev/null
@@ -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 (executable)
index 0000000..b73caf3
--- /dev/null
@@ -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 (executable)
index 0000000..f9f4a2a
--- /dev/null
@@ -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 (executable)
index 0000000..d5d768d
--- /dev/null
@@ -0,0 +1,133 @@
+<?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>1.0.0</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.controller</groupId>
+                       <artifactId>opendaylight-karaf-empty</artifactId>
+                       <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.controller</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 (file)
index 0000000..b57116b
--- /dev/null
@@ -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 (executable)
index 0000000..4b61dae
--- /dev/null
@@ -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>1.0.0</version>
+       </parent>
+       <artifactId>sliapi-installer</artifactId>
+       <name>SLI API  - Karaf  Installer</name>
+       <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>
+                                               </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>
+                                               </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 (file)
index 0000000..80b2ad1
--- /dev/null
@@ -0,0 +1,58 @@
+<!--
+  ============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">
+       <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 (file)
index 0000000..9acea51
--- /dev/null
@@ -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=========================================================
+  -->
+
+<!-- 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">
+       <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 (file)
index 0000000..d8d381d
--- /dev/null
@@ -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 (executable)
index 0000000..188e7c2
--- /dev/null
@@ -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>1.0.0</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.yangtools.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.yangtools.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 (executable)
index 0000000..2c77331
--- /dev/null
@@ -0,0 +1,108 @@
+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-text {
+            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 (executable)
index 0000000..1240203
--- /dev/null
@@ -0,0 +1,62 @@
+<?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>1.0.0</version>
+       </parent>
+
+       <packaging>pom</packaging>
+       <groupId>org.openecomp.sdnc.core</groupId>
+       <artifactId>sliapi</artifactId>
+       <version>1.0.0</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 (executable)
index 0000000..9034b27
--- /dev/null
@@ -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>1.0.0</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.yangtools.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>${sdnctl.sli.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.sdnc.core</groupId>
+                       <artifactId>sli-provider</artifactId>
+                       <version>${sdnctl.sli.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 (file)
index 0000000..b72bebe
--- /dev/null
@@ -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 (file)
index 0000000..06c4bab
--- /dev/null
@@ -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 (file)
index 0000000..1c521a1
--- /dev/null
@@ -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 (file)
index 0000000..73cd8c0
--- /dev/null
@@ -0,0 +1,544 @@
+/*-
+ * ============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.setResponseText("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.setResponseText("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.setResponseText("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.isDebugEnabled()) {
+                               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.debug(argList.toString());
+                               argList = null;
+                       }
+
+
+
+                       Properties respProps = svcLogic.execute(calledModule, calledRpc,
+                                       null, modeStr, parms, domDataBroker);
+
+                       respBuilder.setResponseCode(respProps.getProperty("error-code", "0"));
+                       respBuilder.setResponseText(respProps.getProperty("error-message", ""));
+                       respBuilder.setAckFinalIndicator(respProps.getProperty("ack-final", "Y"));
+
+                       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
+                                       .setResponseText("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.setResponseText("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.setResponseText("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.setResponseText("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.setResponseText(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
+                                       .setResponseText("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 (file)
index 0000000..cf0d6f7
--- /dev/null
@@ -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 (executable)
index 0000000..b32ff6c
--- /dev/null
@@ -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 (file)
index 0000000..d71aa4a
--- /dev/null
@@ -0,0 +1,951 @@
+~~~
+~~ ============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="$network.num-segments">
+  <set>
+    <parameter name="$vlanlist" value="eval($vlanlist+','+$network.segment[i].provider-segmentation-id)"/>
+  </set>
+</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 (file)
index 0000000..6e4244d
--- /dev/null
@@ -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 (file)
index 0000000..bd6c0d9
--- /dev/null
@@ -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=0
+sprint_number=1
+feature_revision=2
+
+base_version=${release_name}.${sprint_number}.${feature_revision}
+
+release_version=${base_version}
+snapshot_version=${base_version}-SNAPSHOT
+