diff options
author | 2020-12-01 11:48:20 -0800 | |
---|---|---|
committer | 2020-12-01 11:48:20 -0800 | |
commit | 32fb53c13342d5ad353c839b7ffd0ca85d14bd48 (patch) | |
tree | f1b92068cf7b79d29e96243899e12495abb4795a /core/sli | |
parent | 53eacd8519a535f96d8b4231e48925324f1086dd (diff) |
Migrate sli-core files
Migrate sli-core repo files into new
directory "core".
Signed-off-by: Jessica Wagantall <jwagantall@linuxfoundation.org>
Diffstat (limited to 'core/sli')
163 files changed, 18595 insertions, 0 deletions
diff --git a/core/sli/.gitignore b/core/sli/.gitignore new file mode 100755 index 000000000..3632ac676 --- /dev/null +++ b/core/sli/.gitignore @@ -0,0 +1,38 @@ +#####standard .git ignore entries#####
+
+## IDE Specific Files ##
+org.eclipse.core.resources.prefs
+.classpath
+.project
+.settings
+.idea
+.externalToolBuilders
+maven-eclipse.xml
+workspace
+
+## Compilation Files ##
+*.class
+**/target
+target
+target-ide
+MANIFEST.MF
+
+## Misc Ignores (OS specific etc) ##
+bin/
+dist
+*~
+*.ipr
+*.iml
+*.iws
+classes
+out/
+.DS_STORE
+.metadata
+
+## antlr4 generated files ##
+ExprGrammarBaseListener.java
+ExprGrammarLexer.java
+ExprGrammarListener.java
+ExprGrammarParser.java
+ExprGrammar.tokens
+ExprGrammarLexer.tokens
diff --git a/core/sli/common/pom.xml b/core/sli/common/pom.xml new file mode 100755 index 000000000..201c11bdd --- /dev/null +++ b/core/sli/common/pom.xml @@ -0,0 +1,129 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name> + <description>The SLI Common package includes common classes used by the various SLI subcomponents, as well as classes used by clients to interface with the service logic interpreter</description> + + <properties> + <!-- Ignore deprecated classes in coverage counts --> + <sonar.coverage.exclusions>**/MessageWriter.java</sonar.coverage.exclusions> + + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derby</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-text</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>dblib-provider</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-model</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.logging-analytics</groupId> + <artifactId>logging-slf4j</artifactId> + </dependency> + <!-- log4j dependencies are needed to test MDC in junit tests --> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + </dependency> + <dependency> + <groupId>com.sun.xml.bind</groupId> + <artifactId>jaxb-core</artifactId> + </dependency> + <dependency> + <groupId>com.sun.xml.bind</groupId> + <artifactId>jaxb-impl</artifactId> + </dependency> + <!-- Testing Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.skyscreamer</groupId> + <artifactId>jsonassert</artifactId> + <version>1.5.0</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.antlr</groupId> + <artifactId>antlr4-maven-plugin</artifactId> + <executions> + <execution> + <configuration> + <sourceDirectory>${basedir}/src/main/antlr4</sourceDirectory> + <outputDirectory>${project.basedir}/src/main/java/</outputDirectory> + </configuration> + <id>antlr</id> + <goals> + <goal>antlr4</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/core/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g4 b/core/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g4 new file mode 100755 index 000000000..42563168c --- /dev/null +++ b/core/sli/common/src/main/antlr4/org/onap/ccsdk/sli/core/sli/ExprGrammar.g4 @@ -0,0 +1,67 @@ + +grammar ExprGrammar; + +options { + language = Java; +} + + +COMPAREOP : '==' | '!=' | '>' | '<' | '>=' | '<='; + +RELOP : 'and' | 'or'; + +ADDOP : '+' | '-'; + +MULTOP : '/' | '*'; + +NUMBER : ('0'..'9')+; + +STRING : '\'' ~[']* '\''; + +IDENTIFIER : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*; + +// CONTEXT_VAR : '$' IDENTIFIER; + +WS: [ \n\t\r]+ -> skip; + +constant : NUMBER | STRING ; + +variableLead : ('$')? variableTerm ; + +variableTerm : IDENTIFIER ('[' expr ']')? ; + +variable : variableLead ('.' variableTerm)* ('.')?; + +// variable : CONTEXT_VAR ( '[' expr ']' )? ('.' IDENTIFIER )? ; + +atom : constant | variable; + + +expr : atom + | parenExpr + | multExpr + | addExpr + | compareExpr + | relExpr + | funcExpr; + +parenExpr : '(' expr ')'; + +term : atom | parenExpr | funcExpr; + +multExpr : term (MULTOP term)*; + +addExpr : multExpr (ADDOP multExpr)*; + +compareExpr : addExpr COMPAREOP addExpr; + +relExpr : compareExpr (RELOP expr)*; + +funcExpr : IDENTIFIER '(' expr (',' expr)* ')'; + + + + + + + diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java new file mode 100644 index 000000000..a1c0eafe8 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ActivationEntry.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class ActivationEntry { + String module; + String rpc; + String version; + String mode; + + public ActivationEntry(String module, String rpc, String version, String mode) { + this.module = module; + this.rpc = rpc; + this.version = version; + this.mode = mode; + } + + @Override + public String toString() { + return "ActivationEntry [module=" + module + ", rpc=" + rpc + ", version=" + version + ", mode=" + mode + "]"; + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java new file mode 100644 index 000000000..e1c0e3db5 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/BreakNodeException.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class BreakNodeException extends SvcLogicException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public BreakNodeException() + { + super(); + } + + public BreakNodeException(String message) + { + super(message); + } + + public BreakNodeException(String message, Throwable t) + { + super(message, t); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java new file mode 100644 index 000000000..9283cf650 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CheckSumHelper.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.onap.ccsdk.sli.core.utils.PathValidator; + +import javax.xml.bind.DatatypeConverter; + +public class CheckSumHelper { + + public static String md5SumFromFile(String pathToFile) throws NoSuchAlgorithmException, IOException { + if (!PathValidator.isValidXmlPath(pathToFile)) { + throw new IOException("Invalid XML file name"); + } + byte[] b = Files.readAllBytes(Paths.get(pathToFile)); + return md5SumFromByteArray(b); + } + + private static String md5SumFromByteArray(byte[] input) throws NoSuchAlgorithmException { + byte[] hash = MessageDigest.getInstance("MD5").digest(input); + String hexString = DatatypeConverter.printHexBinary(hash); + return hexString.toLowerCase(); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java new file mode 100644 index 000000000..b1a7320d7 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/CommonConstants.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public interface CommonConstants { + + String SERVICE_LOGIC_STATUS = "SvcLogic.status"; + String JDBC_CONN_ERR = "no jdbc connection"; + String JDBC_STATEMENT_ERR = "could not prepare statement "; + String SVCLOGIC_TABLE = ".SVC_LOGIC"; + String JDBC_SELECT_COUNT = "SELECT count(*) FROM "; + String RESULTSET_CLOSE_ERR = "ResultSet close error: "; + String JDBC_SELECT_GRAPGH = "SELECT graph FROM "; + String JDBC_INSERT = "INSERT INTO "; + String JDBC_DELETE = "DELETE FROM "; + String JDBC_UPDATE = "UPDATE "; + String JDBC_GRAPH_QUERY = " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?"; + String JDBC_ACTIVE_GRAPH_QUERY = " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'"; +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java new file mode 100644 index 000000000..144b99a8a --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ConfigurationException.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class ConfigurationException extends SvcLogicException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ConfigurationException() + { + super(); + } + + public ConfigurationException(String msg) + { + super(msg); + } + + public ConfigurationException(String msg, Throwable t) + { + super(msg, t); + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java new file mode 100644 index 000000000..43f4fe53e --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/DuplicateValueException.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class DuplicateValueException extends SvcLogicException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public DuplicateValueException() + { + super(); + } + + public DuplicateValueException(String message) + { + super(message); + } + + public DuplicateValueException(String message, Throwable t) + { + super(message, t); + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java new file mode 100644 index 000000000..47f6526e9 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ErrorLogger.java @@ -0,0 +1,100 @@ +package org.onap.ccsdk.sli.core.sli;
+
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+public class ErrorLogger {
+ public static final int ERROR_CODE_100 = 100;
+ public static final int ERROR_CODE_200 = 200;
+ public static final int ERROR_CODE_300 = 300;
+ public static final int ERROR_CODE_400 = 400;
+ public static final int ERROR_CODE_500 = 500;
+ public static final int ERROR_CODE_900 = 900;
+
+ private static final String DEFAULT_100_DESCRIPTION = "Permission Error";
+ private static final String DEFAULT_200_DESCRIPTION = "Availability Error or Timeout";
+ private static final String DEFAULT_300_DESCRIPTION = "Data Error";
+ private static final String DEFAULT_400_DESCRIPTION = "Schema Error";
+ private static final String DEFAULT_500_DESCRIPTION = "Business Process Error";
+ private static final String DEFAULT_900_DESCRIPTION = "Unknown Error";
+ private Logger log;
+
+ public ErrorLogger() {
+ this.log = LoggerFactory.getLogger(ErrorLogger.class);
+ }
+
+ public ErrorLogger(Logger log) {
+ this.log = log;
+ }
+
+ public void logError(String message, int errorCode) {
+ createLogEntry(message, errorCode, null, null);
+ }
+
+ public void logError(String message, int errorCode, Exception e) {
+ createLogEntry(message, errorCode, null, e);
+ }
+
+ public void logError(String message, int errorCode, String description) {
+ createLogEntry(message, errorCode, description, null);
+ }
+
+ public void logError(String message, int errorCode, String description, Exception e) {
+ createLogEntry(message, errorCode, description, e);
+ }
+
+ public void createLogEntry(String message, int errorCode, String description, Exception e) {
+ //If the error code isn't valid default it to unknown error code
+ if(!isValidCode(errorCode)) {
+ errorCode = 900;
+ }
+
+ MDC.put(ONAPLogConstants.MDCs.ERROR_CODE, String.valueOf(errorCode));
+
+ if (description == null || description.isEmpty()) {
+ description = getDefaultDescription(errorCode);
+ }
+
+ MDC.put(ONAPLogConstants.MDCs.ERROR_DESC, description);
+ if (e != null) {
+ log.error(message, e);
+ } else {
+ log.error(message);
+ }
+ clearKeys();
+ }
+
+ public boolean isValidCode(int errorCode) {
+ if (errorCode == ERROR_CODE_100 || errorCode == ERROR_CODE_200 || errorCode == ERROR_CODE_300 || errorCode == ERROR_CODE_400 || errorCode == ERROR_CODE_500
+ || errorCode == ERROR_CODE_900) {
+ return true;
+ }
+ return false;
+ }
+
+ public String getDefaultDescription(int errorCode) {
+ if (errorCode == ERROR_CODE_100) {
+ return DEFAULT_100_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_200) {
+ return DEFAULT_200_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_300) {
+ return DEFAULT_300_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_400) {
+ return DEFAULT_400_DESCRIPTION;
+ }
+ if (errorCode == ERROR_CODE_500) {
+ return DEFAULT_500_DESCRIPTION;
+ }
+ return DEFAULT_900_DESCRIPTION;
+ }
+
+ public void clearKeys() {
+ MDC.remove(ONAPLogConstants.MDCs.ERROR_CODE);
+ MDC.remove(ONAPLogConstants.MDCs.ERROR_DESC);
+ }
+}
diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java new file mode 100755 index 000000000..f119c1812 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/ExitNodeException.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class ExitNodeException extends SvcLogicException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ExitNodeException() + { + super(); + } + + public ExitNodeException(String message) + { + super(message); + } + + public ExitNodeException(String message, Throwable t) + { + super(message, t); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java new file mode 100644 index 000000000..5ededb9eb --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MessageWriter.java @@ -0,0 +1,281 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.File; +import java.io.FileInputStream; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Properties; +import javax.sql.rowset.CachedRowSet; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Deprecated +public class MessageWriter { + + private static final Logger LOG = LoggerFactory.getLogger(MessageWriter.class); + + private static final String DBLIB_SERVICE = "org.onap.ccsdk.sli.core.dblib.DBResourceManager"; + private static final String SVCLOGIC_PROP_VAR = "SDNC_SLI_PROPERTIES"; + private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR"; + + private static final String INCOMING_PROPERTY_NAME = "org.onap.ccsdk.sli.MessageWriter.writeIncomingRequests"; + private static final String OUTGOING_PROPERTY_NAME = "org.onap.ccsdk.sli.MessageWriter.writeOutgoingRequests"; + + private static final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + private static DbLibService dbLibService = null; + + private static boolean incomingEnabled = false; + private static boolean outgoingEnabled = false; + + private static boolean initialized = false; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private static void init() { + if (initialized) + return; + + initialized = true; + + // Read properties + Properties props = new Properties(); + String propPath = System.getenv(SVCLOGIC_PROP_VAR); + + if (propPath == null) { + String propDir = System.getenv(SDNC_CONFIG_DIR); + if (propDir == null) { + propDir = "/opt/sdnc/data/properties"; + } + propPath = propDir + "/svclogic.properties"; + LOG.warn("Environment variable " + SVCLOGIC_PROP_VAR + " unset - defaulting to " + propPath); + } + + File propFile = new File(propPath); + + if (!propFile.exists()) { + LOG.warn("Property file does not exist: " + propPath); + } + + try { + props.load(new FileInputStream(propFile)); + } catch (Exception e) { + LOG.warn("Error loading property file: " + propPath, e); + } + + incomingEnabled = Boolean.valueOf(props.getProperty(INCOMING_PROPERTY_NAME, "false")); + outgoingEnabled = Boolean.valueOf(props.getProperty(OUTGOING_PROPERTY_NAME, "false")); + + LOG.info(INCOMING_PROPERTY_NAME + ": " + incomingEnabled); + LOG.info(OUTGOING_PROPERTY_NAME + ": " + outgoingEnabled); + } + + public static void saveOutgoingRequest( + String requestId, + String serviceInstanceId, + String targetUrl, + String request) { + try { + init(); + + if (!outgoingEnabled) + return; + + if (serviceInstanceId == null || serviceInstanceId.trim().length() == 0) + serviceInstanceId = "NA"; + + int seqnum = getLastSequenceNumber("OUTGOING_MESSAGE", requestId) + 1; + String now = df.format(new Date()); + + String sql = "INSERT INTO OUTGOING_MESSAGE (\n" + + " request_id, sequence_number, service_instance_id, target_url, request, start_time)\n" + + "VALUES (?, ?, ?, ?, ?, ?)"; + + ArrayList<String> data = new ArrayList<>(); + data.add(requestId); + data.add(String.valueOf(seqnum)); + data.add(serviceInstanceId); + data.add(targetUrl); + data.add(request); + data.add(now); + + dbLibService.writeData(sql, data, null); + + } catch (Exception e) { + LOG.warn("Failed to save outgoing request for request-id: " + requestId, e); + } + } + + public static void saveOutgoingResponse(String requestId, int httpResponseCode, String response) { + try { + init(); + + if (!outgoingEnabled) + return; + + int seqnum = getLastSequenceNumber("OUTGOING_MESSAGE", requestId); + if (seqnum == 0) { + LOG.warn("Failed to save outgoing response for request-id: " + requestId + + ": Request record not found in OUTGOING_MESSAGE"); + return; + } + + String now = df.format(new Date()); + + String sql = "UPDATE OUTGOING_MESSAGE SET http_response_code = ?, response = ?,\n" + + " duration = timestampdiff(MICROSECOND, start_time, ?) / 1000\n" + + "WHERE request_id = ? AND sequence_number = ?"; + + ArrayList<String> data = new ArrayList<>(); + data.add(String.valueOf(httpResponseCode)); + data.add(response); + data.add(now); + data.add(requestId); + data.add(String.valueOf(seqnum)); + + dbLibService.writeData(sql, data, null); + + } catch (Exception e) { + LOG.warn("Failed to save outgoing response for request-id: " + requestId, e); + } + } + + public static void saveIncomingRequest( + String requestId, + String serviceInstanceId, + String requestHost, + String request) { + try { + init(); + + if (!incomingEnabled) + return; + + if (serviceInstanceId == null || serviceInstanceId.trim().length() == 0) + serviceInstanceId = "NA"; + + int seqnum = getLastSequenceNumber("INCOMING_MESSAGE", requestId) + 1; + String now = df.format(new Date()); + + String sql = "INSERT INTO INCOMING_MESSAGE (\n" + + " request_id, sequence_number, service_instance_id, request_host, request, start_time)\n" + + "VALUES (?, ?, ?, ?, ?, ?)"; + + ArrayList<String> data = new ArrayList<>(); + data.add(requestId); + data.add(String.valueOf(seqnum)); + data.add(serviceInstanceId); + data.add(requestHost); + data.add(request); + data.add(now); + + dbLibService.writeData(sql, data, null); + + } catch (Exception e) { + LOG.warn("Failed to save incoming request for request-id: " + requestId, e); + } + } + + public static void saveIncomingResponse(String requestId, int httpResponseCode, String response) { + try { + init(); + + if (!incomingEnabled) + return; + + int seqnum = getLastSequenceNumber("INCOMING_MESSAGE", requestId); + if (seqnum == 0) { + LOG.warn("Failed to save response for request-id: " + requestId + + ": Request record not found in INCOMING_MESSAGE"); + return; + } + + String now = df.format(new Date()); + + String sql = "UPDATE INCOMING_MESSAGE SET http_response_code = ?, response = ?,\n" + + " duration = timestampdiff(MICROSECOND, start_time, ?) / 1000\n" + + "WHERE request_id = ? AND sequence_number = ?"; + + ArrayList<String> data = new ArrayList<>(); + data.add(String.valueOf(httpResponseCode)); + data.add(response); + data.add(now); + data.add(requestId); + data.add(String.valueOf(seqnum)); + + dbLibService.writeData(sql, data, null); + + } catch (Exception e) { + LOG.warn("Failed to save response for request-id: " + requestId, e); + } + } + + public static String getServiceInstanceId(String requestId) throws SQLException { + init(); + + String sql = "SELECT service_instance_id FROM OUTGOING_MESSAGE WHERE request_id = '" + requestId + + "' ORDER BY sequence_number DESC"; + + CachedRowSet rs = null; + try { + rs = dbLibService.getData(sql, null, null); + if (rs.next()) { + return rs.getString("service_instance_id"); + } + } finally { + if (rs != null) { + try { + rs.close(); + } catch (Exception e) { + LOG.warn("Failed to close CachedRowSet", e); + } + } + } + return null; + } + + private static int getLastSequenceNumber(String tableName, String requestId) throws SQLException { + String sql = "SELECT sequence_number FROM " + tableName + " WHERE request_id = '" + requestId + + "' ORDER BY sequence_number DESC"; + + CachedRowSet rs = null; + try { + rs = dbLibService.getData(sql, null, null); + if (rs.next()) { + return rs.getInt("sequence_number"); + } + } finally { + if (rs != null) { + try { + rs.close(); + } catch (Exception e) { + LOG.warn("Failed to close CachedRowSet", e); + } + } + } + return 0; + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java new file mode 100755 index 000000000..577b73401 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/MetricLogger.java @@ -0,0 +1,165 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +/** + * + */ +package org.onap.ccsdk.sli.core.sli; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.TimeZone; +import java.util.UUID; + +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +/** + * @author dt5972 + * + */ +public class MetricLogger { + + private static final Logger METRIC = LoggerFactory.getLogger("org.onap.ccsdk.sli.core.filters.metric"); + private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE-RETURN"); + private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE"); + + private String lastMsg = null; + + public String getRequestID() { + return MDC.get(ONAPLogConstants.MDCs.REQUEST_ID); + } + + public MetricLogger() { + + } + + @Deprecated + public static String asIso8601(Date date) { + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SS'+00:00'"); + df.setTimeZone(tz); + return df.format(date); + } + + @Deprecated + public static String asIso8601(long tsInMillis) { + return MetricLogger.asIso8601(new Date(tsInMillis)); + } + + @Deprecated + public void logRequest(String svcInstanceId, String svcName, String partnerName, String targetEntity, + String targetServiceName, String targetElement, String msg) { + logRequest(svcInstanceId, targetEntity, targetServiceName, targetElement, msg); + } + + public void logRequest(String svcInstanceId, String targetEntity, String targetServiceName, String targetElement, + String msg) { + String timeNow = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT); + MDC.put(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP, timeNow); + + // If transaction is initialized by an external client this will already be set by the audit servlet filter + // If the transaction is initialized by CCSDK this code will handle generating a new UUID + String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID); + if (requestId == null || requestId.isEmpty()) { + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, UUID.randomUUID().toString()); + } + + String randomInvocationId = UUID.randomUUID().toString(); + MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, randomInvocationId); + MDC.put(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID, randomInvocationId); + + if (svcInstanceId != null) { + MDC.put(ONAPLogConstants.MDCs.SERVICE_INSTANCE_ID, svcInstanceId); + } + if (targetEntity != null) { + MDC.put(ONAPLogConstants.MDCs.TARGET_ENTITY, targetEntity); + } + + if (targetServiceName != null) { + MDC.put(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME, targetServiceName); + } + + if (targetElement != null) { + MDC.put(ONAPLogConstants.MDCs.TARGET_ELEMENT, targetElement); + } + this.lastMsg = msg; + //During invoke status will always be INPROGRESS + MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, ONAPLogConstants.ResponseStatus.INPROGRESS.toString()); + MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME, "0"); + METRIC.info(INVOKE, "Invoke"); + } + + public void logResponse(String statusCode, String responseCode, String responseDescription) { + if (statusCode != null) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE, statusCode); + } + if (responseCode != null) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, responseCode); + } + if (responseDescription != null) { + MDC.put(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION, formatString(responseDescription)); + } + ZonedDateTime endTime = ZonedDateTime.now(ZoneOffset.UTC); + MDC.put(ONAPLogConstants.MDCs.LOG_TIMESTAMP, endTime.format(DateTimeFormatter.ISO_INSTANT)); + try { + DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME; + ZonedDateTime entryTimestamp = + ZonedDateTime.parse(MDC.get(ONAPLogConstants.MDCs.INVOKE_TIMESTAMP), timeFormatter); + String elapedTime = Long.toString(ChronoUnit.MILLIS.between(entryTimestamp, endTime)); + MDC.put(ONAPLogConstants.MDCs.ELAPSED_TIME,elapedTime); + } catch (Exception e) { + //pass + } + METRIC.info(INVOKE_RETURN, formatString(lastMsg)); + resetContext(); + } + + protected String formatString(String str) { + if (str != null) { + str = str.replaceAll("\\R", ""); // this will strip all new line characters + str = str.replaceAll("\\|", "%7C"); // log records should not contain a pipe, encode the pipe character + str = str.replaceAll("\t", " "); // tabs are not allowed, replace with spaces + str = str.replace(",", "\\,"); // comma must be escaped + } + return str; + } + + public static void resetContext() { + MDC.remove(ONAPLogConstants.MDCs.TARGET_ENTITY); + MDC.remove(ONAPLogConstants.MDCs.TARGET_SERVICE_NAME); + MDC.remove(ONAPLogConstants.MDCs.TARGET_ELEMENT); + MDC.remove(ONAPLogConstants.MDCs.RESPONSE_STATUS_CODE); + MDC.remove(ONAPLogConstants.MDCs.RESPONSE_CODE); + MDC.remove(ONAPLogConstants.MDCs.RESPONSE_DESCRIPTION); + MDC.remove(ONAPLogConstants.MDCs.ELAPSED_TIME); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java new file mode 100644 index 000000000..e25aed9f8 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SecurePrinter.java @@ -0,0 +1,123 @@ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.TreeMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SecurePrinter { + private static final Logger LOG = LoggerFactory.getLogger(SecurePrinter.class); + private static final String DEFAULT_FILTER = "password,pass,pswd"; + private static final String REDACTED = "***REDACTED***"; + private static final String FILTER_PROPERTY = "NODE_STRING_FILTER"; + private static final String SEPERATOR = " = "; + private static final String COMMON_ERROR_MESSAGE = "Failed to print properties"; + + private static String[] filterArray; + + public SecurePrinter() { + String filterProperty = System.getProperty(FILTER_PROPERTY); + if (filterProperty != null && !filterProperty.isEmpty() && filterProperty.contains(",")) { + filterArray = filterProperty.split(","); + } else { + filterArray = DEFAULT_FILTER.split(","); + } + } + + private String filterValue(String key, String value) { + String normalizedKey = key.toLowerCase(); + for (String restrictedKey : filterArray) { + if (normalizedKey.contains(restrictedKey)) { + return REDACTED; + } + } + return value; + } + + public void printAttributes(HashMap<String, String> attributes) { + if (LOG.isDebugEnabled()) { + for (Entry<String, String> attribute : attributes.entrySet()) { + String value = filterValue(attribute.getKey(), attribute.getValue()); + LOG.debug(attribute.getKey() + SEPERATOR + value); + } + } + } + + public void printAttributes(HashMap<String, String> attributes, String subpath) { + if (LOG.isDebugEnabled()) { + for (Entry<String, String> attribute : attributes.entrySet()) { + if (attribute.getKey().startsWith(subpath)) { + String value = filterValue(attribute.getKey(), attribute.getValue()); + LOG.debug(attribute.getKey() + SEPERATOR + value); + } + } + } + } + + public void printProperties(Properties props) { + if (LOG.isDebugEnabled()) { + try { + for (Entry<Object, Object> property : props.entrySet()) { + String keyString = (String) property.getKey(); + String valueString = (String) property.getValue(); + String value = filterValue(keyString, valueString); + LOG.debug(keyString + SEPERATOR + value); + } + } catch (Exception e) { + LOG.error(COMMON_ERROR_MESSAGE, e); + } + } + } + + public void printProperties(Properties props, String subpath) { + if (LOG.isDebugEnabled()) { + try { + for (Entry<Object, Object> property : props.entrySet()) { + String keyString = (String) property.getKey(); + if (keyString.startsWith(subpath)) { + String valueString = (String) property.getValue(); + String value = filterValue(keyString, valueString); + LOG.debug(keyString + SEPERATOR + value); + } + } + } catch (Exception e) { + LOG.error(COMMON_ERROR_MESSAGE, e); + } + } + } + + public void printPropertiesAlphabetically(Properties props) { + if (LOG.isDebugEnabled()) { + TreeMap<String, String> sortedMap = new TreeMap(props); + try { + for (Entry<String, String> entry : sortedMap.entrySet()) { + String value = filterValue(entry.getKey(), entry.getValue()); + LOG.debug(entry.getKey() + SEPERATOR + value); + } + } catch (Exception e) { + LOG.error(COMMON_ERROR_MESSAGE, e); + } + } + } + + public void printAttributesToFile(HashMap<String, String> attributes, String fileName) { + try (FileOutputStream fstr = new FileOutputStream(new File(fileName)); + PrintStream pstr = new PrintStream(fstr, true);) { + pstr.println("#######################################"); + for (Entry<String, String> entry : attributes.entrySet()) { + String value = filterValue(entry.getKey(), entry.getValue()); + pstr.println(entry.getKey() + SEPERATOR + value); + } + } catch (Exception e) { + LOG.error("Cannot write context to file.", e); + } + } + +}
\ No newline at end of file diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java new file mode 100644 index 000000000..a76b123ca --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAdaptor.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.Map; + +public interface SvcLogicAdaptor { + + public enum ConfigStatus { + SUCCESS, + ALREADY_ACTIVE, + NOT_FOUND, + NOT_READY, + FAILURE + } + + public ConfigStatus configure(String key, Map<String,String> parameters, SvcLogicContext ctx); + + public ConfigStatus activate(String key, SvcLogicContext ctx); + + public ConfigStatus deactivate(String key, SvcLogicContext ctx); + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java new file mode 100644 index 000000000..b9ad19e25 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicAtom.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class SvcLogicAtom extends SvcLogicExpression { + + public enum AtomType { + NUMBER, + STRING, + IDENTIFIER, + CONTEXT_VAR + + } + + private AtomType atomType; + private String atom; + + + public SvcLogicAtom(String atomType, String atom) + { + this.atomType = AtomType.valueOf(atomType); + this.atom = atom; + + } + + public SvcLogicAtom(String atom) + { + + if (atom == null) + { + this.atomType = null; + this.atom = null; + } + else + { + if (atom.startsWith("$")) + { + this.atomType = AtomType.CONTEXT_VAR; + this.atom = atom.substring(1); + } + else + { + if (Character.isDigit(atom.charAt(0))) + { + this.atomType = AtomType.NUMBER; + this.atom = atom; + } + else if (atom.charAt(0) == '\'') + { + this.atomType = AtomType.STRING; + this.atom = atom.substring(1, atom.length()-1); + } + else + { + this.atomType = AtomType.IDENTIFIER; + this.atom = atom; + + } + + } + } + } + + public AtomType getAtomType() { + return atomType; + } + + public void setAtomType(String newType) + { + atomType = AtomType.valueOf(newType); + } + + public String getAtom() { + return atom; + } + + + + public void setAtomType(AtomType atomType) { + this.atomType = atomType; + } + + public void setAtom(String atom) { + this.atom = atom; + } + + + + public String toString() + { + StringBuffer sbuff = new StringBuffer(); + switch(getAtomType()) + { + case CONTEXT_VAR: + sbuff.append("$"); + case IDENTIFIER: + boolean needDot = false; + for (SvcLogicExpression term: this.getOperands()) + { + if (needDot) + { + sbuff.append("."); + } + sbuff.append(term.toString()); + needDot = true; + } + return sbuff.toString(); + case STRING: + case NUMBER: + default: + return atom; + } + } + + public String asParsedExpr() + { + // simplify debugging output for NUMBER type + if (atomType == AtomType.NUMBER) { + return atom; + } + + StringBuffer sbuff = new StringBuffer(); + + sbuff.append("(atom"); + sbuff.append("<"); + sbuff.append(atomType.toString()); + sbuff.append(">"); + + switch(atomType) + { + case IDENTIFIER: + case CONTEXT_VAR: + for (SvcLogicExpression term : getOperands()) + { + sbuff.append(" "); + sbuff.append(term.asParsedExpr()); + + } + break; + default: + sbuff.append(" "); + sbuff.append(atom); + } + + sbuff.append(")"); + return sbuff.toString(); + } + + + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java new file mode 100644 index 000000000..a990dd950 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicBinaryExpression.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.LinkedList; +import java.util.List; + +public class SvcLogicBinaryExpression extends SvcLogicExpression { + + + public enum OperatorType { + addOp("+"), + subOp("-"), + multOp("*"), + divOp("/"), + equalOp("=="), + ltOp("<"), + leOp("<="), + gtOp(">"), + geOp(">="), + neOp("!="), + andOp("and"), + orOp("or"); + + private String text; + + private OperatorType(String text) + { + this.text = text; + } + + public String getText() + { + return(text); + } + + public static OperatorType fromString(String text) + { + if (text != null) + { + for (OperatorType t : OperatorType.values()) + { + if (text.equalsIgnoreCase(t.getText())) { + + return(t); + } + } + } + return(null); + } + + public String toString() + { + return(text); + } + } + private List<OperatorType> operators; + + public List<OperatorType> getOperators() { + return operators; + } + + public SvcLogicBinaryExpression() + { + operators = new LinkedList<>(); + } + + public void addOperator(String operator) + { + operators.add(OperatorType.fromString(operator)); + } + + + public String toString() + { + + List<SvcLogicExpression>operands = getOperands(); + StringBuffer sbuff = new StringBuffer(); + + sbuff.append(operands.get(0).toString()); + for (int i = 0 ; i < operators.size(); i++) + { + sbuff.append(" "); + sbuff.append(operators.get(i)); + sbuff.append(" "); + if (i + 1 < operands.size()) { + sbuff.append(operands.get(i + 1).toString()); + } else { + // expression incomplete; operand not bound yet + sbuff.append("?"); + } + } + + return(sbuff.toString()); + + } + + public String asParsedExpr() { + + List<SvcLogicExpression> operands = getOperands(); + + if (operators.isEmpty()) { + return operands.get(0).asParsedExpr(); + } else { + StringBuffer sbuff = new StringBuffer(); + // operators in reverse order for left associativity + for (int i = operators.size() - 1; i >= 0; --i) { + sbuff.append("("); + sbuff.append(operators.get(i).getText()); + sbuff.append(" "); + } + for (int i = 0; i < operators.size() + 1; ++i) { + if (i < operands.size()) { + sbuff.append(operands.get(i).asParsedExpr()); + } else { + // expression incomplete; operand not bound yet + sbuff.append("?"); + } + if (i != 0) { + sbuff.append(")"); + } + if (i < operators.size()) { + sbuff.append(" "); + } + } + return sbuff.toString(); + } + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java new file mode 100644 index 000000000..61bfe7c20 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicConstants.java @@ -0,0 +1,7 @@ +package org.onap.ccsdk.sli.core.sli; + +public class SvcLogicConstants { + public final static String SUCCESS = "success"; + public final static String FAILURE = "failure"; + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java new file mode 100644 index 000000000..98cf7e05e --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java @@ -0,0 +1,438 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.*; + +import com.google.gson.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + + +public class SvcLogicContext { + + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicContext.class); + private final SecurePrinter securePrinter = new SecurePrinter(); + public static final String CTX_NULL_VALUE=""; + private static final String LENGTH="_length"; + + private HashMap<String, String> attributes; + + private String status = SvcLogicConstants.SUCCESS; + + public SvcLogicContext() { + this.attributes = new HashMap<>(); + + } + + public SvcLogicContext(Properties props) { + this.attributes = new HashMap<>(); + + if (props.containsKey(CommonConstants.SERVICE_LOGIC_STATUS)) { + this.status = props.getProperty(CommonConstants.SERVICE_LOGIC_STATUS); + } + + for (Object nameObj : props.keySet()) { + String propName = (String) nameObj; + attributes.put(propName, props.getProperty(propName)); + } + } + + public String getAttribute(String name) { + if (attributes.containsKey(name)) { + return attributes.get(name); + } else { + return null; + } + } + + public void setAttribute(String name, String value) { + if (value == null) { + if (attributes.containsKey(name)) { + attributes.remove(name); + } + } else { + attributes.put(name, value); + } + } + + public Set<String> getAttributeKeySet() { + return attributes.keySet(); + } + + public Boolean isSuccess() { + return status.equals(SvcLogicConstants.SUCCESS); + } + + @Deprecated + public String getStatus() { + return status; + } + + @Deprecated + public void setStatus(String status) { + this.status = status; + } + + public void markFailed() { + this.status = SvcLogicConstants.FAILURE; + } + + public void markSuccess() { + this.status = SvcLogicConstants.SUCCESS; + } + + public Properties toProperties() { + Properties props = new Properties(); + + if (status != null) { + props.setProperty(CommonConstants.SERVICE_LOGIC_STATUS, status); + } + + String attrName; + String attrVal; + for (Map.Entry<String, String> entry : attributes.entrySet()) { + attrName = entry.getKey(); + attrVal = entry.getValue(); + if (attrVal == null) { + LOG.warn("attribute {} value is null - setting to empty string", attrName); + props.setProperty(attrName, ""); + } else { + props.setProperty(attrName, attrVal); + } + } + + return props; + } + + public void mergeDocument(String pfx, Document doc) { + String prefix = ""; + + if (pfx != null) { + prefix = pfx; + } + + Element root = doc.getDocumentElement(); + + mergeElement(prefix, root, null); + } + + public void mergeElement(String pfx, Element element, Map<String, Integer> nodeMap) { + + // In XML, cannot tell the difference between containers and lists. + // So, have to treat each element as both (ugly but necessary). + // We do this by passing a nodeMap to be used to count instance of each tag, + // which will be used to set _length and to set index + + LOG.trace("mergeElement({},{},{})", pfx, element.getTagName(), nodeMap); + + String curTagName = element.getTagName(); + String prefix = curTagName; + + if (pfx != null) { + prefix = pfx + "." + prefix; + } + + int myIdx = 0; + + if (nodeMap != null) { + if (nodeMap.containsKey(curTagName)) { + myIdx = nodeMap.get(curTagName); + } + + nodeMap.put(curTagName, myIdx + 1); + this.setAttribute(prefix + "_length", Integer.toString(myIdx + 1)); + } + + NodeList children = element.getChildNodes(); + + int numChildren = children.getLength(); + + Map<String, Integer> childMap = new HashMap<>(); + Map<String, Integer> idxChildMap = new HashMap<>(); + + for (int i = 0; i < numChildren; i++) { + Node curNode = children.item(i); + + if (curNode instanceof Text) { + Text curText = (Text) curNode; + String curTextValue = curText.getTextContent(); + LOG.trace("Setting ctx variable {} = {}", prefix, curTextValue); + this.setAttribute(prefix, curText.getTextContent()); + + + } else if (curNode instanceof Element) { + mergeElement(prefix, (Element) curNode, childMap); + if (nodeMap != null) { + + mergeElement(prefix + "[" + myIdx + "]", (Element) curNode, idxChildMap); + + } + } + } + + } + + public void mergeJson(String pfx, String jsonString) { + + JsonParser jp = new JsonParser(); + JsonElement element = jp.parse(jsonString); + String root = ""; + if ((pfx != null) && (pfx.length() > 0)) { + root = pfx + "."; + } + if (element.isJsonObject()) { + writeJsonObject(element.getAsJsonObject(), root); + } else if (element.isJsonArray()) { + handleJsonArray("", element.getAsJsonArray(), root); + } + } + + + protected void writeJsonObject(JsonObject obj, String root) { + for (Map.Entry<String, JsonElement> entry : obj.entrySet()) { + String key = entry.getKey(); + if (entry.getValue().isJsonObject()) { + writeJsonObject(entry.getValue().getAsJsonObject(), root + key + "."); + } else if (entry.getValue().isJsonArray()) { + JsonArray array = entry.getValue().getAsJsonArray(); + handleJsonArray(key, array, root); + } else { + //Handles when a JSON obj is nested within a JSON obj + if(!root.endsWith(".")){ + root = root + "."; + } + if(entry.getValue().isJsonNull()) { + this.setAttribute(root + key, CTX_NULL_VALUE); + }else { + this.setAttribute(root + key, entry.getValue().getAsString()); + } + } + } + } + + protected void handleJsonArray(String key, JsonArray array, String root) { + this.setAttribute(root + key + LENGTH, String.valueOf(array.size())); + Integer arrayIdx = 0; + for (JsonElement element : array) { + String prefix = root + key + "[" + arrayIdx + "]"; + + if (element.isJsonArray()) { + handleJsonArray(key, element.getAsJsonArray(), prefix); + } else if (element.isJsonObject()) { + writeJsonObject(element.getAsJsonObject(), prefix + "."); + } else if (element.isJsonNull()) { + this.setAttribute(prefix, CTX_NULL_VALUE); + } else if (element.isJsonPrimitive()) { + this.setAttribute(prefix, element.getAsString()); + } + arrayIdx++; + } + } + + + public String resolve(String ctxVarName) { + + if (ctxVarName.indexOf('[') == -1) { + // Ctx variable contains no arrays + return getAttribute(ctxVarName); + } + + // Resolve any array references + StringBuilder sbuff = new StringBuilder(); + String[] ctxVarParts = ctxVarName.split("\\["); + sbuff.append(ctxVarParts[0]); + for (int i = 1; i < ctxVarParts.length; i++) { + if (ctxVarParts[i].startsWith("$")) { + int endBracketLoc = ctxVarParts[i].indexOf(']'); + if (endBracketLoc == -1) { + // Missing end bracket ... give up parsing + LOG.warn("Variable reference {} seems to be missing a ']'", ctxVarName); + return getAttribute(ctxVarName); + } + + String idxVarName = ctxVarParts[i].substring(1, endBracketLoc); + String remainder = ctxVarParts[i].substring(endBracketLoc); + + sbuff.append("["); + sbuff.append(this.getAttribute(idxVarName)); + sbuff.append(remainder); + + } else { + // Index is not a variable reference + sbuff.append("["); + sbuff.append(ctxVarParts[i]); + } + } + + return getAttribute(sbuff.toString()); + } + + public String toJsonString(String pfx) { + JsonParser jp = new JsonParser(); + + String jsonString = this.toJsonString(); + JsonObject jsonRoot = (JsonObject) jp.parse(jsonString); + JsonObject targetJson = jsonRoot.getAsJsonObject(pfx); + if (targetJson == null) { + return(""); + } else { + return(targetJson.toString()); + } + } + + public String toJsonString() { + JsonObject root = new JsonObject(); + JsonElement lastJsonObject = root; + JsonElement currJsonLeaf = root; + + String attrName = null; + String attrVal = null; + + // Sort properties so that arrays will be reconstructed in proper order + TreeMap<String, String> sortedAttributes = new TreeMap<>(); + sortedAttributes.putAll(attributes); + + // Loop through properties, sorted by key + for (Map.Entry<String, String> entry : sortedAttributes.entrySet()) { + attrName = entry.getKey(); + attrVal = entry.getValue(); + + currJsonLeaf = root; + String curFieldName = null; + JsonArray curArray = null; + lastJsonObject = null; + boolean addNeeded = false; + + // Split property names by period and iterate through parts + for (String attrNamePart : attrName.split("\\.")) { + + // Add last object found to JSON tree. Need to handle + // this way because last element found (leaf) needs to be + // assigned the property value. + if (lastJsonObject != null) { + if (addNeeded) { + if (currJsonLeaf.isJsonArray()) { + ((JsonArray) currJsonLeaf).add(lastJsonObject); + } else { + ((JsonObject) currJsonLeaf).add(curFieldName, lastJsonObject); + } + } + currJsonLeaf = (JsonObject) lastJsonObject; + } + addNeeded = false; + // See if current level should be a JsonArray or JsonObject based on + // whether name part contains square brackets. + if (!attrNamePart.contains("[")) { + // This level should be inserted as a JsonObject + curFieldName = attrNamePart; + lastJsonObject = ((JsonObject) currJsonLeaf).get(curFieldName); + if (lastJsonObject == null) { + lastJsonObject = new JsonObject(); + addNeeded = true; + } else if (!lastJsonObject.isJsonObject()) { + LOG.error("Unexpected condition - expecting to find JsonObject, but found " + lastJsonObject.getClass().getName()); + lastJsonObject = new JsonObject(); + addNeeded = true; + } + } else { + // This level should be inserted as a JsonArray. + + String[] curFieldNameParts = attrNamePart.split("[\\[\\]]"); + curFieldName = curFieldNameParts[0]; + int curIndex = Integer.parseInt(curFieldNameParts[1]); + + + curArray = ((JsonObject) currJsonLeaf).getAsJsonArray(curFieldName); + + if (curArray == null) { + // This is the first time we see this array. + // Create a new JsonArray and add it to current + // leaf + curArray = new JsonArray(); + ((JsonObject) currJsonLeaf).add(curFieldName, curArray); + } + + // Current leaf should point to the JsonArray for this level. + // lastJsonObject should point to the array item entry to append + // the next level to - which is a new one if the index value + // isn't the end of the current array. + currJsonLeaf = curArray; + if (curArray.size() == curIndex + 1) { + lastJsonObject = curArray.get(curArray.size() - 1); + } else { + lastJsonObject = new JsonObject(); + addNeeded = true; + } + } + } + + // Done parsing property name. Add the value of this + // property to the current json leaf, either as a property + // or as a string (if the current leaf is a JsonArray) + + if (!curFieldName.endsWith("_length")) { + if (currJsonLeaf.isJsonArray()) { + if ("true".equals(attrVal) || "false".equals(attrVal)) { + ((JsonArray) currJsonLeaf).add(Boolean.valueOf(attrVal)); + } else if ("null".equals(attrVal)) { + ((JsonArray) currJsonLeaf).add(new JsonNull()); + } else { + ((JsonArray) currJsonLeaf).add(attrVal); + } + } else { + if (("true".equals(attrVal) || "false".equals(attrVal))) { + ((JsonObject) currJsonLeaf).addProperty(curFieldName, Boolean.valueOf(attrVal)); + } else if ("null".equals(attrVal)){ + + ((JsonObject) currJsonLeaf).add(curFieldName, new JsonNull()); + } else { + ((JsonObject) currJsonLeaf).addProperty(curFieldName, attrVal); + } + } + } + } + + return (root.toString()); + } + + public void printProperties(Properties props) { + securePrinter.printProperties(props); + } + + public void printAttributes() { + securePrinter.printAttributes(attributes); + } + + public void printProperties(Properties props, String subpath) { + securePrinter.printProperties(props, subpath); + } + + public void printAttributes(String subpath) { + securePrinter.printAttributes(attributes, subpath); + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java new file mode 100644 index 000000000..c6fd8b6a2 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicCrawler.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import static java.nio.file.FileVisitResult.CONTINUE; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; + +public class SvcLogicCrawler extends SimpleFileVisitor<Path> { + + private List<Path> xmlGraphPathList; + private List<Path> activationFilePathList; + + public SvcLogicCrawler() { + xmlGraphPathList = new ArrayList<>(); + activationFilePathList = new ArrayList<>(); + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attr) { + if (attr.isRegularFile()) { + String fileName = file.getFileName().toString(); + if (!file.toString().contains(".git") && !fileName.equals("pom.xml") && !fileName.equals("assemble_zip.xml") && !fileName.equals("assemble_zip_less_config.xml") && !fileName.equals("descriptor.xml")) { + if (fileName.endsWith(".xml")) { + xmlGraphPathList.add(file); + } + else if (fileName.endsWith(".versions")) { + activationFilePathList.add(file); + } + } + } + return CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + return CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + System.err.println("Couldn't visitFile"); + System.err.println(exc.getMessage()); + return CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + String[] skipDirectories = {".git"}; + for (String str : skipDirectories) { + if (dir.endsWith(str)) { + return FileVisitResult.SKIP_SUBTREE; + } + } + return CONTINUE; + } + + public List<Path> getGraphPaths() { + return this.xmlGraphPathList; + } + + public List<Path> getActivationPaths() { + return this.activationFilePathList; + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java new file mode 100644 index 000000000..dc3a560eb --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicDblibStore.java @@ -0,0 +1,332 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Properties; +import javax.sql.rowset.CachedRowSet; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicDblibStore implements SvcLogicStore { + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicDblibStore.class); + private DbLibService dbSvc; + + public SvcLogicDblibStore(DbLibService dbsvc) { + this.dbSvc = dbsvc; + } + + public Connection getConnection() throws SQLException { + return(dbSvc.getConnection()); + } + + @Override + public void init(Properties props) throws ConfigurationException { + if(dbSvc == null) { + LOG.error("SvcLogic cannot acquire DBLIB_SERVICE"); + return; + } + try { + dbSvc.getData("select 1 from DUAL", new ArrayList<String>(), null); + LOG.debug("SQL test was successful"); + } catch (SQLException e) { + LOG.error("Failed SQL test", e); + } + } + + @Override + public boolean hasGraph(String module, String rpc, String version, + String mode) throws SvcLogicException { + boolean retval = false; + CachedRowSet results = null; + String hasVersionGraphSql = "SELECT count(*) FROM SVC_LOGIC" + + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?"; + + String hasActiveGraphSql = "SELECT count(*) FROM SVC_LOGIC" + + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'"; + + ArrayList<String> args = new ArrayList<>(); + args.add(module); + args.add(rpc); + args.add(mode); + + try { + + if (version == null) { + results = dbSvc.getData(hasActiveGraphSql, args, null); + } else { + args.add(version); + results = dbSvc.getData(hasVersionGraphSql, args, null); + } + + if (results.next()) { + int cnt = results.getInt(1); + + if (cnt > 0) { + retval = true; + } + } + } catch (Exception e) { + throw new ConfigurationException("SQL query failed", e); + } finally { + if (results != null) { + try { + results.close(); + } catch (SQLException x) { + LOG.error("Failed to close CachedRowSet", x); + } + } + + } + + return retval; + } + + public SvcLogicGraph fetch(String module, String rpc, String version, + String mode) throws SvcLogicException { + + PreparedStatement fetchGraphStmt = null; + Connection dbConn = null; + SvcLogicGraph retval = null; + ResultSet results = null; + + String fetchVersionGraphSql = "SELECT graph FROM SVC_LOGIC" + + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?"; + + String fetchActiveGraphSql = "SELECT graph FROM SVC_LOGIC" + + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'"; + + + try { + dbConn = dbSvc.getConnection(); + + if (version == null) { + fetchGraphStmt = dbConn.prepareStatement(fetchActiveGraphSql); + } else { + fetchGraphStmt = dbConn.prepareStatement(fetchVersionGraphSql); + } + + fetchGraphStmt.setString(1, module); + fetchGraphStmt.setString(2, rpc); + fetchGraphStmt.setString(3, mode); + if (version != null) { + fetchGraphStmt.setString(4,version); + } + + results = fetchGraphStmt.executeQuery(); + + if (results.next()) { + Blob graphBlob = results.getBlob("graph"); + + ObjectInputStream gStream = new ObjectInputStream(graphBlob.getBinaryStream()); + + Object graphObj = gStream.readObject(); + gStream.close(); + + if (graphObj instanceof SvcLogicGraph) { + retval = (SvcLogicGraph) graphObj; + } else { + throw new ConfigurationException("invalid type for graph (" + + graphObj.getClass().getName()); + + } + + } else { + return null; + } + } catch (Exception e) { + LOG.error("Graph processing failed", e); + throw new ConfigurationException("Graph processing failed: " + e.getMessage()); + } finally { + try { + if (fetchGraphStmt != null) { + fetchGraphStmt.close(); + } + } catch (SQLException e) { + LOG.error("PreparedStatement close error", e); + } + if (results != null) { + try { + results.close(); + } catch (SQLException x) { + LOG.error("ResultSet close error", x); + } + } + try { + if (dbConn != null && !dbConn.isClosed()) { + dbConn.close(); + } + } catch (Exception exc) { + LOG.error("dbConn close error", exc); + } finally { + dbConn = null; + } + + } + + return retval; + } + + public void store(SvcLogicGraph graph) throws SvcLogicException { + + + + String storeGraphSql = "INSERT INTO SVC_LOGIC (module, rpc, version, mode, active, graph, md5sum)" + + " VALUES(?, ?, ?, ?, ?, ?, ?)"; + + if (graph == null) { + throw new SvcLogicException("graph cannot be null"); + } + + byte[] graphBytes = null; + + try (ByteArrayOutputStream byteStr = new ByteArrayOutputStream(); + ObjectOutputStream goutStr = new ObjectOutputStream(byteStr)) { + + goutStr.writeObject(graph); + + graphBytes = byteStr.toByteArray(); + + } catch (Exception e) { + throw new SvcLogicException("could not serialize graph", e); + } + + // If object already stored in database, delete it + if (hasGraph(graph.getModule(), graph.getRpc(), graph.getVersion(), + graph.getMode())) { + delete(graph.getModule(), graph.getRpc(), graph.getVersion(), + graph.getMode()); + } + + Connection dbConn = null; + PreparedStatement storeGraphStmt = null; + try { + dbConn = dbSvc.getConnection(); + boolean oldAutoCommit = dbConn.getAutoCommit(); + dbConn.setAutoCommit(false); + storeGraphStmt = dbConn.prepareStatement(storeGraphSql); + storeGraphStmt.setString(1, graph.getModule()); + storeGraphStmt.setString(2, graph.getRpc()); + storeGraphStmt.setString(3, graph.getVersion()); + storeGraphStmt.setString(4, graph.getMode()); + storeGraphStmt.setString(5, "N"); + storeGraphStmt.setBlob(6, new ByteArrayInputStream(graphBytes)); + storeGraphStmt.setString(7, graph.getMd5sum()); + storeGraphStmt.executeUpdate(); + dbConn.commit(); + dbConn.setAutoCommit(oldAutoCommit); + } catch (Exception e) { + throw new SvcLogicException("Could not write object to database", e); + } finally { + try { + if (storeGraphStmt != null) { + storeGraphStmt.close(); + } + } catch (SQLException e) { + LOG.error("PreparedStatement close error", e); + } + try { + if (dbConn != null && !dbConn.isClosed()) { + dbConn.close(); + } + } catch (Exception exc) { + LOG.error("dbConn close error", exc); + } finally { + dbConn = null; + } + + } + } + + public void delete(String module, String rpc, String version, String mode) + throws SvcLogicException { + String deleteGraphSql = "DELETE FROM SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?"; + + ArrayList<String> args = new ArrayList<>(); + + args.add(module); + args.add(rpc); + args.add(version); + args.add(mode); + + try { + dbSvc.writeData(deleteGraphSql, args, null); + } catch (Exception e) { + throw new SvcLogicException("Could not delete object from database", e); + } + } + + public void activate(SvcLogicGraph graph) throws SvcLogicException { + String deactivateSql = "UPDATE SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?"; + String activateSql = "UPDATE SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND mode = ? AND version = ?"; + + ArrayList<String> args = new ArrayList<>(); + + args.add(graph.getModule()); + args.add(graph.getRpc()); + args.add(graph.getMode()); + + try { + dbSvc.writeData(deactivateSql, args, null); + args.add(graph.getVersion()); + dbSvc.writeData(activateSql, args, null); + } catch (Exception e) { + throw new SvcLogicException("Could not activate graph", e); + } + } + + @Override + public void activate(String module, String rpc, String version, String mode) throws SvcLogicException { + + String deactivateSql = "UPDATE SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?"; + + String activateSql = "UPDATE SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND mode = ? AND version = ?"; + + ArrayList<String> args = new ArrayList<>(); + + args.add(module); + args.add(rpc); + args.add(mode); + + try { + + dbSvc.writeData(deactivateSql, args, null); + + args.add(version); + dbSvc.writeData(activateSql, args, null); + + } catch (Exception e) { + throw new SvcLogicException("Could not activate graph", e); + } + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java new file mode 100644 index 000000000..c03ef9787 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicException.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class SvcLogicException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public SvcLogicException() + { + super(); + } + + public SvcLogicException(String message) + { + super(message); + } + + public SvcLogicException(String message, Throwable t) + { + super(message, t); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java new file mode 100644 index 000000000..a1871951f --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprListener.java @@ -0,0 +1,271 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.LinkedList; +import java.util.List; + +import org.antlr.v4.runtime.tree.TerminalNode; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.AddExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.AtomContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.CompareExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ConstantContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.FuncExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.MultExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ParenExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.RelExprContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.VariableContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.VariableLeadContext; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.VariableTermContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicExprListener extends ExprGrammarBaseListener +{ + + + + + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicExprListener.class); + + private SvcLogicExpression curExpr; + //private SvcLogicExpression topExpr; + private LinkedList<SvcLogicExpression> exprStack; + + public SvcLogicExprListener() + { + exprStack = new LinkedList<>(); + } + + public SvcLogicExpression getParsedExpr() + { + return(curExpr); + } + + private void pushOperand(SvcLogicExpression operand) + { + if (curExpr == null) + { + curExpr = operand; + } + else + { + curExpr.addOperand(operand); + } + } + + private void pushExpr(SvcLogicExpression expr) + { + if (curExpr != null) + { + exprStack.push(curExpr); + } + curExpr = expr; + } + + private void popExpr() + { + if (exprStack.isEmpty()) + { + //topExpr = curExpr; + } + else + { + SvcLogicExpression lastExpr = curExpr; + curExpr = exprStack.pop(); + curExpr.addOperand(lastExpr); + } + + } + + @Override + public void enterAtom(AtomContext ctx) { + String atomText = ctx.getText(); + SvcLogicAtom newAtom = new SvcLogicAtom(atomText); + pushExpr(newAtom); + } + + + @Override + public void enterMultExpr(MultExprContext ctx) { + SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression(); + pushExpr(curBinExpr); + + List<TerminalNode> opList = ctx.MULTOP(); + + for (TerminalNode nd : opList) + { + curBinExpr.addOperator(nd.getText()); + } + + } + + @Override + public void exitMultExpr(MultExprContext ctx) { + popExpr(); + } + + @Override + public void exitAtom(AtomContext ctx) { + popExpr(); + } + + @Override + public void enterAddExpr(AddExprContext ctx) { + List<TerminalNode> opList = ctx.ADDOP(); + + + SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression(); + pushExpr(curBinExpr); + + + for (TerminalNode nd : opList) + { + curBinExpr.addOperator(nd.getText()); + } + + } + + @Override + public void exitAddExpr(AddExprContext ctx) { + popExpr(); + } + + @Override + public void enterFuncExpr(FuncExprContext ctx) { + LOG.trace("enterFuncExpr: text = "+ctx.getText()); + LOG.trace("enterFuncExpr - IDENTIFIER : "+ctx.IDENTIFIER().getText()); + + for (ExprContext expr: ctx.expr()) + { + LOG.trace("enterFuncExpr - expr = "+expr.getText()); + } + + + pushExpr(new SvcLogicFunctionCall(ctx.IDENTIFIER().getText())); + } + + @Override + public void exitFuncExpr(FuncExprContext ctx) { + popExpr(); + } + + @Override + public void enterParenExpr(ParenExprContext ctx) { + LOG.trace("enterParenExpr: text = "+ctx.getText()); + LOG.trace("enterParenExpr: expr = "+ctx.expr().getText()); + } + + @Override + public void exitParenExpr(ParenExprContext ctx) { + LOG.trace("exitParenExpr: text = "+ctx.getText()); + } + + @Override + public void enterRelExpr(RelExprContext ctx) { + List<TerminalNode> opList = ctx.RELOP(); + + + SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression(); + pushExpr(curBinExpr); + + + for (TerminalNode nd : opList) + { + curBinExpr.addOperator(nd.getText()); + } + + } + + @Override + public void exitRelExpr(RelExprContext ctx) { + popExpr(); + } + + @Override + public void enterCompareExpr(CompareExprContext ctx) { + + TerminalNode nd = ctx.COMPAREOP(); + + SvcLogicBinaryExpression curBinExpr = new SvcLogicBinaryExpression(); + pushExpr(curBinExpr); + + curBinExpr.addOperator(nd.getText()); + + } + + @Override + public void exitCompareExpr(CompareExprContext ctx) { + + popExpr(); + } + + + + @Override + public void enterConstant(ConstantContext ctx) { + } + + @Override + public void exitConstant(ConstantContext ctx) { + } + + + @Override + public void enterVariable(VariableContext ctx) { + } + + @Override + public void exitVariable(VariableContext ctx) { + } + + + @Override + public void enterVariableLead(VariableLeadContext ctx) { + } + + @Override + public void exitVariableLead(VariableLeadContext ctx) { + } + + @Override + public void enterVariableTerm(VariableTermContext ctx) { + String name = ctx.getText(); + + int subscrStart = name.indexOf("["); + if (subscrStart > -1) + { + name = name.substring(0, subscrStart); + } + SvcLogicVariableTerm vterm = new SvcLogicVariableTerm(name); + pushExpr(vterm); + } + + @Override + public void exitVariableTerm(VariableTermContext ctx) { + popExpr(); + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java new file mode 100644 index 000000000..03f2a8b0b --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExprParserErrorListener.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; +import org.antlr.v4.runtime.misc.ParseCancellationException; + +public class SvcLogicExprParserErrorListener extends BaseErrorListener { + + private static final SvcLogicExprParserErrorListener instance = new SvcLogicExprParserErrorListener(); + + public static SvcLogicExprParserErrorListener getInstance() { + return(instance); + } + + @Override + public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, + String msg, RecognitionException e) throws ParseCancellationException { + throw new ParseCancellationException(msg); + } + + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java new file mode 100644 index 000000000..81aeb6c37 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpression.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; + + +public abstract class SvcLogicExpression implements Serializable { + + private List<SvcLogicExpression> operands = new LinkedList<>(); + + + public void addOperand(SvcLogicExpression expr) + { + operands.add(expr); + } + + public List<SvcLogicExpression> getOperands() { + return operands; + } + + public int numOperands() + { + return(operands.size()); + } + + public abstract String asParsedExpr(); + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java new file mode 100644 index 000000000..727c84b19 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionFactory.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.antlr.v4.runtime.ANTLRInputStream; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.onap.ccsdk.sli.core.sli.ExprGrammarParser.ExprContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class SvcLogicExpressionFactory { + + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicExpressionFactory.class); + + + public static SvcLogicExpression parse(String exprStr) throws IOException + { + InputStream exprStream = new ByteArrayInputStream(exprStr.getBytes()); + CharStream input = new ANTLRInputStream(exprStream); + ExprGrammarLexer lexer = new ExprGrammarLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + ExprGrammarParser parser = new ExprGrammarParser(tokens); + + lexer.removeErrorListeners(); + lexer.addErrorListener(SvcLogicExprParserErrorListener.getInstance()); + parser.removeErrorListeners(); + parser.addErrorListener(SvcLogicExprParserErrorListener.getInstance()); + + ExprContext expression = null; + + try { + expression = parser.expr(); + } catch (Exception e) { + String errorMsg = e.getMessage(); + + LOG.error(errorMsg); + throw new SvcLogicParserException(errorMsg); + } + + + ParseTreeWalker walker = new ParseTreeWalker(); + SvcLogicExprListener listener = new SvcLogicExprListener(); + walker.walk(listener, expression); + + + return(listener.getParsedExpr()); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java new file mode 100644 index 000000000..8289f16da --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicFunctionCall.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class SvcLogicFunctionCall extends SvcLogicExpression { + + private String functionName; + + public SvcLogicFunctionCall(String functionName) + { + this.functionName = functionName; + } + + public String getFunctionName() { + return functionName; + } + + public void setFunctionName(String functionName) { + this.functionName = functionName; + } + + public String toString() + { + StringBuffer sbuff = new StringBuffer(); + + sbuff.append(functionName); + sbuff.append("("); + boolean needComma = false; + for (SvcLogicExpression operand: getOperands()) + { + if (needComma) + { + sbuff.append(","); + } + else + { + needComma = true; + } + sbuff.append(operand.toString()); + + } + sbuff.append(")"); + return(sbuff.toString()); + } + + public String asParsedExpr() + { + StringBuffer sbuff = new StringBuffer(); + + sbuff.append("("); + sbuff.append(functionName); + for (SvcLogicExpression operand: getOperands()) + { + sbuff.append(" "); + sbuff.append(operand.asParsedExpr()); + } + sbuff.append(")"); + return(sbuff.toString()); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java new file mode 100644 index 000000000..97f2bd7ab --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicGraph.java @@ -0,0 +1,199 @@ +/*- +x * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.PrintStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +public class SvcLogicGraph implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String module = null; + private String rpc = null; + private String mode = null; + private String version = null; + + private String md5sum = null; + + private Map<String, Serializable> attributes; + private Map<String, SvcLogicNode> namedNodes; + private SvcLogicNode rootNode; + + public SvcLogicGraph() + { + attributes = new HashMap<>(); + namedNodes = new HashMap<>(); + rootNode = null; + } + + public String getMd5sum() { + return md5sum; + } + + + public void setMd5sum(String md5sum) { + this.md5sum = md5sum; + } + + + + public String getModule() { + return module; + } + + + public void setModule(String module) { + this.module = module; + } + + + public String getRpc() { + return rpc; + } + + + public void setRpc(String rpc) { + this.rpc = rpc; + } + + + + + public String getMode() { + return mode; + } + + + public void setMode(String mode) { + this.mode = mode; + } + + + public String getVersion() { + return version; + } + + + public void setVersion(String version) { + this.version = version; + } + + + public void setRootNode(SvcLogicNode rootNode) + { + this.rootNode = rootNode; + } + + public SvcLogicNode getRootNode() + { + return(rootNode); + } + + public Serializable getAttribute(String name) + { + if (attributes.containsKey(name)) + { + return(attributes.get(name)); + } + else + { + return(null); + } + + } + + public void setAttribute(String name, Serializable value) throws DuplicateValueException + { + if (attributes.containsKey(name)) + { + throw new DuplicateValueException("Duplicate attribute "+name); + } + + attributes.put(name, value); + } + + public SvcLogicNode getNamedNode(String nodeName) + { + if (namedNodes.containsKey(nodeName)) + { + return(namedNodes.get(nodeName)); + } + else + { + return(null); + } + } + + public void setNamedNode(String nodeName, SvcLogicNode node) throws DuplicateValueException + { + if (namedNodes.containsKey(nodeName)) + { + throw new DuplicateValueException("Duplicate node name "+nodeName); + } + + namedNodes.put(nodeName, node); + } + + + + public void printAsGv(PrintStream pstr) + { + pstr.println("digraph g {"); + pstr.println("START [label=\"START\\n"+module+":"+rpc+"\"];"); + + if (rootNode != null) + { + pstr.println("START -> node"+rootNode.getNodeId()+";"); + rootNode.setVisited(false, true); + rootNode.printAsGv(pstr); + } + pstr.println("}"); + } + + public void printAsXml(PrintStream pstr) + { + pstr.println("<service-logic module='"+getModule()+"' version='"+getVersion()+"'>"); + pstr.println(" <method rpc='"+getRpc()+"' mode='"+getMode()+"'>"); + if (rootNode != null) + { + rootNode.setVisited(false, true); + rootNode.printAsXml(pstr, 2); + } + pstr.println(" </method>"); + pstr.println("</service-logic>"); + } + + @Override + public String toString() { + return "SvcLogicGraph [module=" + module + ", rpc=" + rpc + ", mode=" + mode + ", version=" + version + ", md5sum=" + md5sum + "]"; + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java new file mode 100644 index 000000000..23dff3e6e --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJavaPlugin.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +/** + * A marker interface, used to indicate that a class exposes methods that can be + * called from an <execute> node. Such methods must have the signature: + * void methodName(Map, SvcLogicContext) + */ +public interface SvcLogicJavaPlugin { +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java new file mode 100644 index 000000000..f23456fee --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicJdbcStore.java @@ -0,0 +1,574 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicJdbcStore implements SvcLogicStore { + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicJdbcStore.class); + + private String dbUrl = null; + private String dbName = null; + private String dbUser = null; + private String dbPasswd = null; + private String dbDriver = null; + + private Connection dbConn; + private PreparedStatement hasActiveGraphStmt = null; + private PreparedStatement hasVersionGraphStmt = null; + private PreparedStatement fetchActiveGraphStmt = null; + private PreparedStatement fetchVersionGraphStmt = null; + private PreparedStatement storeGraphStmt = null; + private PreparedStatement deleteGraphStmt = null; + + private PreparedStatement deactivateStmt = null; + private PreparedStatement activateStmt = null; + + private void getConnection() throws ConfigurationException { + + Properties jdbcProps = new Properties(); + + jdbcProps.setProperty("user", dbUser); + jdbcProps.setProperty("password", dbPasswd); + + try { + Driver dvr = new org.mariadb.jdbc.Driver(); + if (dvr.acceptsURL(dbUrl)) { + LOG.debug("Driver com.mysql.jdbc.Driver accepts {}", dbUrl); + } else { + LOG.warn("Driver com.mysql.jdbc.Driver does not accept {}", dbUrl); + } + } catch (SQLException e1) { + LOG.error("Caught exception trying to load com.mysql.jdbc.Driver", e1); + } + + try { + this.dbConn = DriverManager.getConnection(dbUrl, jdbcProps); + } catch (Exception e) { + throw new ConfigurationException("failed to get database connection [" + dbUrl + "]", e); + } + + } + + private void createTable() throws ConfigurationException { + + DatabaseMetaData dbm; + + try { + dbm = dbConn.getMetaData(); + } catch (SQLException e) { + + throw new ConfigurationException("could not get databse metadata", e); + } + + // See if table SVC_LOGIC exists. If not, create it. + Statement stmt = null; + try { + + ResultSet tables = dbm.getTables(null, null, "SVC_LOGIC", null); + if (tables.next()) { + LOG.debug("SVC_LOGIC table already exists"); + } else { + String crTableCmd = "CREATE TABLE " + dbName + ".SVC_LOGIC (" + "module varchar(80) NOT NULL," + + "rpc varchar(80) NOT NULL," + "version varchar(40) NOT NULL," + "mode varchar(5) NOT NULL," + + "active varchar(1) NOT NULL,graph BLOB," + + "modified_timestamp timestamp ," + + "md5sum varchar(128) DEFAULT NULL," + + "CONSTRAINT P_SVC_LOGIC PRIMARY KEY(module, rpc, version, mode))"; + + stmt = dbConn.createStatement(); + stmt.executeUpdate(crTableCmd); + } + } catch (Exception e) { + throw new ConfigurationException("could not create SVC_LOGIC table", e); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + LOG.error("Statement close error ", e); + } + } + } + + // See if NODE_TYPES table exists and, if not, create it + stmt = null; + try { + + ResultSet tables = dbm.getTables(null, null, "NODE_TYPES", null); + if (tables.next()) { + LOG.debug("NODE_TYPES table already exists"); + } else { + String crTableCmd = "CREATE TABLE " + dbName + ".NODE_TYPES (" + "nodetype varchar(80) NOT NULL," + + "CONSTRAINT P_NODE_TYPES PRIMARY KEY(nodetype))"; + + stmt = dbConn.createStatement(); + + stmt.executeUpdate(crTableCmd); + } + } catch (Exception e) { + throw new ConfigurationException("could not create SVC_LOGIC table", e); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + LOG.error("Statement close error ", e); + } + } + } + } + + private void prepStatements() throws ConfigurationException { + + // Prepare statements + String hasVersionGraphSql = CommonConstants.JDBC_SELECT_COUNT + dbName + CommonConstants.SVCLOGIC_TABLE + + CommonConstants.JDBC_GRAPH_QUERY; + + try { + hasVersionGraphStmt = dbConn.prepareStatement(hasVersionGraphSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + hasVersionGraphSql, e); + + } + + String hasActiveGraphSql = CommonConstants.JDBC_SELECT_COUNT + dbName + CommonConstants.SVCLOGIC_TABLE + + CommonConstants.JDBC_ACTIVE_GRAPH_QUERY; + + try { + hasActiveGraphStmt = dbConn.prepareStatement(hasActiveGraphSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + hasVersionGraphSql, e); + + } + + String fetchVersionGraphSql = CommonConstants.JDBC_SELECT_GRAPGH + dbName + CommonConstants.SVCLOGIC_TABLE + + CommonConstants.JDBC_GRAPH_QUERY; + + try { + fetchVersionGraphStmt = dbConn.prepareStatement(fetchVersionGraphSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + fetchVersionGraphSql, e); + + } + + String fetchActiveGraphSql = CommonConstants.JDBC_SELECT_GRAPGH + dbName + CommonConstants.SVCLOGIC_TABLE + + CommonConstants.JDBC_ACTIVE_GRAPH_QUERY; + + try { + fetchActiveGraphStmt = dbConn.prepareStatement(fetchActiveGraphSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + fetchVersionGraphSql, e); + + } + + String storeGraphSql = CommonConstants.JDBC_INSERT + dbName + + ".SVC_LOGIC (module, rpc, version, mode, active, graph, md5sum) VALUES(?, ?, ?, ?, ?, ?, ?)"; + + try { + storeGraphStmt = dbConn.prepareStatement(storeGraphSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + storeGraphSql, e); + } + + String deleteGraphSql = CommonConstants.JDBC_DELETE + dbName + + ".SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?"; + + try { + deleteGraphStmt = dbConn.prepareStatement(deleteGraphSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + deleteGraphSql, e); + } + + String deactivateSql = CommonConstants.JDBC_UPDATE + dbName + + ".SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?"; + + try { + deactivateStmt = dbConn.prepareStatement(deactivateSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + deactivateSql, e); + } + + String activateSql = CommonConstants.JDBC_UPDATE + dbName + + ".SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND version = ? AND mode = ?"; + + try { + activateStmt = dbConn.prepareStatement(activateSql); + } catch (Exception e) { + throw new ConfigurationException(CommonConstants.JDBC_STATEMENT_ERR + activateSql, e); + } + } + + private void initDbResources() throws ConfigurationException { + if ((dbDriver != null) && (dbDriver.length() > 0)) { + + try { + Class.forName(dbDriver); + } catch (Exception e) { + throw new ConfigurationException("could not load driver class " + dbDriver, e); + } + } + getConnection(); + createTable(); + prepStatements(); + } + + + @Override + public void init(Properties props) throws ConfigurationException { + + + dbUrl = props.getProperty("org.onap.ccsdk.sli.jdbc.url"); + if ((dbUrl == null) || (dbUrl.length() == 0)) { + throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.url unset"); + } + + dbName = props.getProperty("org.onap.ccsdk.sli.jdbc.database"); + if ((dbName == null) || (dbName.length() == 0)) { + throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.database unset"); + } + + dbUser = props.getProperty("org.onap.ccsdk.sli.jdbc.user"); + if ((dbUser == null) || (dbUser.length() == 0)) { + throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.user unset"); + } + + + dbPasswd = props.getProperty("org.onap.ccsdk.sli.jdbc.password"); + if ((dbPasswd == null) || (dbPasswd.length() == 0)) { + throw new ConfigurationException("property org.onap.ccsdk.sli.jdbc.password unset"); + } + + dbDriver = props.getProperty("org.onap.ccsdk.sli.jdbc.driver"); + + + initDbResources(); + + } + + private boolean isDbConnValid() { + + boolean isValid = false; + + try { + if (dbConn != null) { + isValid = dbConn.isValid(1); + } + } catch (SQLException e) { + LOG.error("Not a valid db connection: ", e); + } + + return isValid; + } + + @Override + public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException { + + if (!isDbConnValid()) { + + // Try reinitializing + initDbResources(); + + if (!isDbConnValid()) { + throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR); + } + } + + boolean retval = false; + ResultSet results = null; + + PreparedStatement hasGraphStmt; + if (version == null) { + hasGraphStmt = hasActiveGraphStmt; + } else { + hasGraphStmt = hasVersionGraphStmt; + } + + try { + hasGraphStmt.setString(1, module); + hasGraphStmt.setString(2, rpc); + hasGraphStmt.setString(3, mode); + + + if (version != null) { + hasGraphStmt.setString(4, version); + } + boolean oldAutoCommit = dbConn.getAutoCommit(); + dbConn.setAutoCommit(false); + results = hasGraphStmt.executeQuery(); + dbConn.commit(); + dbConn.setAutoCommit(oldAutoCommit); + + if (results.next()) { + int cnt = results.getInt(1); + + if (cnt > 0) { + retval = true; + } + + } + } catch (Exception e) { + throw new ConfigurationException("SQL query failed", e); + } finally { + if (results != null) { + try { + results.close(); + } catch (SQLException x) { + LOG.error(CommonConstants.RESULTSET_CLOSE_ERR, x); + } + } + + } + + return retval; + + } + + @Override + public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException { + + + if (!isDbConnValid()) { + + // Try reinitializing + initDbResources(); + + if (!isDbConnValid()) { + throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR); + } + } + + SvcLogicGraph retval = null; + ResultSet results = null; + + PreparedStatement fetchGraphStmt; + if (version == null) { + fetchGraphStmt = fetchActiveGraphStmt; + } else { + fetchGraphStmt = fetchVersionGraphStmt; + } + try { + fetchGraphStmt.setString(1, module); + fetchGraphStmt.setString(2, rpc); + fetchGraphStmt.setString(3, mode); + + + if (version != null) { + fetchGraphStmt.setString(4, version); + } + boolean oldAutoCommit = dbConn.getAutoCommit(); + dbConn.setAutoCommit(false); + results = fetchGraphStmt.executeQuery(); + dbConn.commit(); + dbConn.setAutoCommit(oldAutoCommit); + + if (results.next()) { + Blob graphBlob = results.getBlob("graph"); + + ObjectInputStream gStream = new ObjectInputStream(graphBlob.getBinaryStream()); + + Object graphObj = gStream.readObject(); + gStream.close(); + + if (graphObj instanceof SvcLogicGraph) { + retval = (SvcLogicGraph) graphObj; + } else { + throw new ConfigurationException("invalid type for graph (" + graphObj.getClass().getName()); + + } + } + + } catch (Exception e) { + throw new ConfigurationException("SQL query failed", e); + } finally { + if (results != null) { + try { + results.close(); + } catch (SQLException x) { + LOG.error(CommonConstants.RESULTSET_CLOSE_ERR, x); + } + } + + } + + return retval; + } + + public void store(SvcLogicGraph graph) throws SvcLogicException { + + + if (!isDbConnValid()) { + + // Try reinitializing + initDbResources(); + + if (!isDbConnValid()) { + throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR); + } + } + + if (graph == null) { + throw new SvcLogicException("graph cannot be null"); + } + + byte[] graphBytes; + + try (ByteArrayOutputStream byteStr = new ByteArrayOutputStream(); + ObjectOutputStream goutStr = new ObjectOutputStream(byteStr)) { + + goutStr.writeObject(graph); + + graphBytes = byteStr.toByteArray(); + + } catch (Exception e) { + throw new SvcLogicException("could not serialize graph", e); + } + + // If object already stored in database, delete it + if (hasGraph(graph.getModule(), graph.getRpc(), graph.getVersion(), graph.getMode())) { + delete(graph.getModule(), graph.getRpc(), graph.getVersion(), graph.getMode()); + } + + try { + boolean oldAutoCommit = dbConn.getAutoCommit(); + dbConn.setAutoCommit(false); + storeGraphStmt.setString(1, graph.getModule()); + storeGraphStmt.setString(2, graph.getRpc()); + storeGraphStmt.setString(3, graph.getVersion()); + storeGraphStmt.setString(4, graph.getMode()); + storeGraphStmt.setString(5, "N"); + storeGraphStmt.setBlob(6, new ByteArrayInputStream(graphBytes)); + storeGraphStmt.setString(7, graph.getMd5sum()); + + storeGraphStmt.executeUpdate(); + dbConn.commit(); + + dbConn.setAutoCommit(oldAutoCommit); + } catch (Exception e) { + throw new SvcLogicException("Could not write object to database", e); + } + } + + @Override + public void delete(String module, String rpc, String version, String mode) throws SvcLogicException { + if (!isDbConnValid()) { + + // Try reinitializing + initDbResources(); + + if (!isDbConnValid()) { + throw new ConfigurationException(CommonConstants.JDBC_CONN_ERR); + } + } + + try { + boolean oldAutoCommit = dbConn.getAutoCommit(); + dbConn.setAutoCommit(false); + deleteGraphStmt.setString(1, module); + deleteGraphStmt.setString(2, rpc); + deleteGraphStmt.setString(3, version); + deleteGraphStmt.setString(4, mode); + + + deleteGraphStmt.executeUpdate(); + dbConn.commit(); + dbConn.setAutoCommit(oldAutoCommit); + } catch (Exception e) { + throw new SvcLogicException("Could not delete object from database", e); + } + } + + @Override + public void activate(SvcLogicGraph graph) throws SvcLogicException { + try { + boolean oldAutoCommit = dbConn.getAutoCommit(); + + dbConn.setAutoCommit(false); + + // Deactivate any current active version + deactivateStmt.setString(1, graph.getModule()); + deactivateStmt.setString(2, graph.getRpc()); + deactivateStmt.setString(3, graph.getMode()); + deactivateStmt.executeUpdate(); + + // Activate this version + activateStmt.setString(1, graph.getModule()); + activateStmt.setString(2, graph.getRpc()); + activateStmt.setString(3, graph.getVersion()); + activateStmt.setString(4, graph.getMode()); + activateStmt.executeUpdate(); + + dbConn.commit(); + + dbConn.setAutoCommit(oldAutoCommit); + + } catch (Exception e) { + throw new SvcLogicException("Could not activate graph", e); + } + } + + @Override + public void activate(String module, String rpc, String version, String mode) throws SvcLogicException { + try { + boolean oldAutoCommit = dbConn.getAutoCommit(); + + dbConn.setAutoCommit(false); + + // Deactivate any current active version + deactivateStmt.setString(1, module); + deactivateStmt.setString(2, rpc); + deactivateStmt.setString(3, mode); + deactivateStmt.executeUpdate(); + + // Activate this version + activateStmt.setString(1, module); + activateStmt.setString(2, rpc); + activateStmt.setString(3, version); + activateStmt.setString(4, mode); + activateStmt.executeUpdate(); + + dbConn.commit(); + + dbConn.setAutoCommit(oldAutoCommit); + + } catch (Exception e) { + throw new SvcLogicException("Could not activate graph", e); + } + } + + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java new file mode 100644 index 000000000..433b723e7 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicLoader.java @@ -0,0 +1,178 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : SDN-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicLoader { + private static final Logger LOGGER = LoggerFactory.getLogger(SvcLogicLoader.class); + protected SvcLogicStore store; + protected String directoryRoot; + protected SvcLogicParser parser; + + public SvcLogicLoader(String directoryRoot, SvcLogicStore store) { + this.store = store; + this.directoryRoot = directoryRoot; + this.parser = new SvcLogicParser(); + } + + public SvcLogicLoader(String directoryRoot, String propFile) { + this.store = SvcLogicParser.getStore(propFile); + this.directoryRoot = directoryRoot; + this.parser = new SvcLogicParser(); + } + + public void loadAndActivate() throws IOException { + SvcLogicCrawler slc = new SvcLogicCrawler(); + Files.walkFileTree(Paths.get(directoryRoot), slc); + loadGraphs(slc.getGraphPaths(), directoryRoot); + List<ActivationEntry> activationEntries = processActivationFiles(slc.getActivationPaths()); + activateGraphs(activationEntries); + } + + protected List<ActivationEntry> processActivationFiles(List<Path> activationPaths) { + List<ActivationEntry> activationEntries = new ArrayList<>(); + for (Path activationFile : activationPaths) { + activationEntries.addAll(getActivationEntries(activationFile)); + } + return activationEntries; + } + + protected void activateGraphs(List<ActivationEntry> activationEntries) { + for (ActivationEntry entry : activationEntries) { + try { + if (store.hasGraph(entry.module, entry.rpc, entry.version, entry.mode)) { + LOGGER.info("Activating SvcLogicGraph [module=" + entry.module + ", rpc=" + entry.rpc + ", mode=" + + entry.mode + ", version=" + entry.version + "]"); + store.activate(entry.module, entry.rpc, entry.version, entry.mode); + } else { + LOGGER.error("hasGraph returned false for " + entry.toString()); + } + } catch (SvcLogicException e) { + LOGGER.error("Failed to call hasGraph for " + entry.toString(), e); + } + } + } + + protected List<ActivationEntry> getActivationEntries(Path activationFilePath) { + List<ActivationEntry> activationEntries = new ArrayList<>(); + int lineNumber = 1; + try (BufferedReader br = Files.newBufferedReader(activationFilePath, StandardCharsets.US_ASCII)) { + String fileRead = br.readLine(); + while (fileRead != null) { + String[] fields = fileRead.split("\\s"); + if (fields.length == 4) { + activationEntries.add(parseActivationEntry(fields)); + } else { + LOGGER.error("Activation entry [" + fileRead + "] is declared at line number " + lineNumber + + " in the file " + activationFilePath + " and is invalid."); + } + fileRead = br.readLine(); + lineNumber++; + } + return activationEntries; + } catch (IOException ioe) { + LOGGER.error("Couldn't read the activation file at " + activationFilePath, ioe); + return new ArrayList<>(); + } + } + + protected void loadGraphs(List<Path> graphPaths, String directoryRoot) { + for (Path graphPath : graphPaths) { + try { + saveGraph(graphPath.toString()); + } catch (Exception e) { + LOGGER.error("Couldn't load graph at " + graphPath, e); + } + } + } + + protected void saveGraph(String xmlFile) throws SvcLogicException { + File f = new File(xmlFile); + if (!f.canRead()) { + throw new ConfigurationException("Cannot read xml file (" + xmlFile + ")"); + } + + LinkedList<SvcLogicGraph> graphs = null; + + try { + graphs = parser.parse(xmlFile); + } catch (Exception e) { + throw new SvcLogicException(e.getMessage(), e); + } + + if (graphs == null) { + throw new SvcLogicException("Could not parse " + xmlFile); + } + + for (Iterator<SvcLogicGraph> iter = graphs.iterator(); iter.hasNext();) { + SvcLogicGraph graph = iter.next(); + try { + LOGGER.info("Saving " + graph.toString() + " to database"); + store.store(graph); + } catch (Exception e) { + throw new SvcLogicException(e.getMessage(), e); + } + } + } + + protected ActivationEntry parseActivationEntry(String[] fileInput) { + return new ActivationEntry(fileInput[0], fileInput[1], fileInput[2], fileInput[3]); + } + + protected String getValue(String raw, String attributeName) { + raw = raw.substring(attributeName.length() + 1); + if (raw.contains(">")) { + raw = raw.substring(0, raw.lastIndexOf('>')); + } + if (raw.endsWith("'")) { + raw = raw.substring(0, raw.lastIndexOf('\'')); + } + if (raw.endsWith("\"")) { + raw = raw.substring(0, raw.lastIndexOf('"')); + } + return raw; + } + + public void bulkActivate() { + Path activationFile = Paths.get(directoryRoot); + List<Path> pathList = new ArrayList<>(1); + pathList.add(activationFile); + List<ActivationEntry> activationEntries = processActivationFiles(pathList); + activateGraphs(activationEntries); + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java new file mode 100644 index 000000000..b0d4fc058 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicNode.java @@ -0,0 +1,457 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +/** + * + */ +package org.onap.ccsdk.sli.core.sli; + +import java.io.IOException; +import java.io.PrintStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; +import java.util.TreeMap; + +import org.apache.commons.text.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicNode implements Serializable { + + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicExprListener.class); + + private static final long serialVersionUID = 2L; + + private String nodeName; + private int nodeId; + private String nodeType; + private boolean visited; + private SvcLogicGraph graph; + + + private HashMap<String, SvcLogicExpression> attributes; + private HashMap<String, SvcLogicNode> outcomes; + private HashMap<String, SvcLogicExpression> parameters; + + public SvcLogicNode(int nodeId, String nodeType, SvcLogicGraph graph) + { + this.nodeId = nodeId; + nodeName = ""; + this.nodeType = nodeType; + this.graph = graph; + attributes = new HashMap<> (); + parameters = new HashMap<> (); + outcomes = null; + + } + + public SvcLogicNode(int nodeId, String nodeType, String nodeName, SvcLogicGraph graph) throws DuplicateValueException + { + this.nodeId = nodeId; + this.nodeName = nodeName; + this.nodeType = nodeType; + this.graph = graph; + attributes = new HashMap<> (); + parameters = new HashMap<> (); + outcomes = null; + graph.setNamedNode(nodeName, this); + } + + + public int getNodeId() + { + return nodeId; + } + + public String getNodeName() + { + return nodeName; + } + + public String getNodeType() + { + return nodeType; + } + + public SvcLogicGraph getGraph() + { + return graph; + } + + public int getNumOutcomes() + { + if (outcomes == null) + { + return 0; + } + else + { + return outcomes.size(); + } + } + + public SvcLogicExpression getAttribute(String name) + { + if (attributes.containsKey(name)) + { + return attributes.get(name); + } + else + { + return null; + } + + } + + public void setAttribute(String name, String value) throws SvcLogicException + { + setAttribute(name, new SvcLogicAtom("STRING", value)); + } + + public void setAttribute(String name, SvcLogicExpression value) throws SvcLogicException + { + if (attributes.containsKey(name)) + { + throw new DuplicateValueException("Duplicate attribute "+name); + } + + attributes.put(name, value); + } + + + public void mapParameter(String name, String value) throws SvcLogicException + { + + if (parameters.containsKey(name)) + { + throw new DuplicateValueException("Duplicate parameter "+name); + } + try + { + SvcLogicExpression parmValue; + if (value == null || value.length() == 0) + { + parmValue = new SvcLogicAtom("STRING", ""); + } + else if (value.trim().startsWith("`")) + { + int lastParen = value.lastIndexOf("`"); + String evalExpr = value.trim().substring(1, lastParen); + parmValue = SvcLogicExpressionFactory.parse(evalExpr); + + } + else + { + if (Character.isDigit(value.charAt(0))) + { + parmValue = new SvcLogicAtom("NUMBER", value); + } + else + { + parmValue = new SvcLogicAtom("STRING", value); + } + } + LOG.debug("Setting parameter "+name+" = "+value+" = "+parmValue.asParsedExpr()); + parameters.put(name, parmValue); + } + catch (IOException e) { + + LOG.error("Invalid parameter value expression ("+value+")"); + throw new SvcLogicException(e.getMessage()); + } + } + + public SvcLogicExpression getParameter(String name) + { + if (parameters.containsKey(name)) + { + return parameters.get(name); + } + else + { + return null; + } + } + + public boolean isVisited() { + return visited; + } + + public void setVisited(boolean visited, boolean recursive) { + this.visited = visited; + + if (recursive) + { + Set<Map.Entry<String, SvcLogicNode>> outcomeSet = getOutcomeSet(); + + if (outcomeSet == null) + { + return; + } + + for (Iterator<Map.Entry<String, SvcLogicNode>> iter = outcomeSet.iterator(); iter.hasNext();) + { + Map.Entry<String, SvcLogicNode> curOutcome = iter.next(); + SvcLogicNode outNode = curOutcome.getValue(); + outNode.setVisited(visited, recursive); + } + } + } + + public void addOutcome(String outcomeValue, SvcLogicNode node) throws SvcLogicException + { + if (outcomes == null) + { + outcomes = new HashMap<>(); + } + + if (outcomeValue.length() == 0) { + outcomeValue = "\"\""; + } + if (outcomes.containsKey(outcomeValue)) + { + throw new DuplicateValueException("Duplicate outcome value "+outcomeValue); + } + + outcomes.put(outcomeValue, node); + } + + public Set<Map.Entry<String, SvcLogicNode>> getOutcomeSet() + { + if (outcomes == null) + { + return new HashSet<>(); + } + + return outcomes.entrySet(); + + } + + public Set<Map.Entry<String, SvcLogicExpression>> getParameterSet() + { + if (parameters == null) + { + return new HashSet<>(); + } + + return parameters.entrySet(); + + } + + public void printAsGv(PrintStream pstr) + { + + if (visited) + { + return; + } + else + { + visited = true; + } + + StringBuffer sbuff = new StringBuffer(); + + sbuff.append("node"); + sbuff.append(nodeId); + sbuff.append(" [ shape=none, margin=0, label=<<table border=\"0\" cellborder=\"1\" align=\"left\">"); + sbuff.append("<tr><td colspan=\"2\"><b>"); + sbuff.append(nodeId); + sbuff.append(" : "); + sbuff.append(nodeType); + sbuff.append("</b></td></tr><th><td><i>Attribute</i></td><td><i>Value</i></td></th>"); + + if (nodeName.length() > 0) + { + sbuff.append("<tr><td>name</td><td>"); + sbuff.append(nodeName); + sbuff.append("</td></tr>"); + } + + Set<Map.Entry<String, SvcLogicExpression>> attrSet = attributes.entrySet(); + for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = attrSet.iterator() ; iter.hasNext();) + { + Map.Entry<String, SvcLogicExpression> curAttr = iter.next(); + sbuff.append("<tr><td>"); + sbuff.append(curAttr.getKey()); + sbuff.append("</td><td>"); + sbuff.append(StringEscapeUtils.escapeHtml3(curAttr.getValue().toString())); + sbuff.append("</td></tr>"); + } + sbuff.append("</table>>];"); + + pstr.println(sbuff.toString()); + + + if (outcomes != null) + { + TreeMap<String, SvcLogicNode> sortedOutcomes = new TreeMap<>(outcomes); + Set<Map.Entry<String, SvcLogicNode>> outcomeSet = sortedOutcomes.entrySet(); + + for (Iterator<Map.Entry<String, SvcLogicNode>> iter = outcomeSet.iterator(); iter.hasNext();) + { + Map.Entry<String, SvcLogicNode> curOutcome = iter.next(); + String outValue = curOutcome.getKey(); + SvcLogicNode outNode = curOutcome.getValue(); + pstr.println("node"+nodeId+" -> node"+outNode.getNodeId()+" [label=\""+outValue+"\"];"); + outNode.printAsGv(pstr); + } + } + } + + public void printAsXml(PrintStream pstr, int indentLvl) + { + if (visited) + { + return; + } + // Print node tag + for (int i = 0 ; i < indentLvl ; i++) + { + pstr.print(" "); + } + pstr.print("<"); + pstr.print(this.getNodeType()); + + Set<Map.Entry<String, SvcLogicExpression>> attrSet = attributes.entrySet(); + for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = attrSet.iterator() ; iter.hasNext();) + { + Map.Entry<String, SvcLogicExpression> curAttr = iter.next(); + pstr.print(" "); + pstr.print(curAttr.getKey()); + pstr.print("='`"); + pstr.print(curAttr.getValue()); + pstr.print("'`"); + } + + if ((parameters == null || parameters.isEmpty()) && + (outcomes == null || outcomes.isEmpty())) + { + pstr.print("/>\n"); + pstr.flush(); + return; + } + else + { + pstr.print(">\n"); + } + + // Print parameters (if any) + if (parameters != null) + { + Set<Map.Entry<String, SvcLogicExpression>> paramSet = parameters.entrySet(); + for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = paramSet.iterator() ; iter.hasNext();) + { + for (int i = 0 ; i < indentLvl+1 ; i++) + { + pstr.print(" "); + } + pstr.print("<parameter"); + Map.Entry<String, SvcLogicExpression> curAttr = iter.next(); + pstr.print(" name='"); + pstr.print(curAttr.getKey()); + pstr.print("' value='`"); + pstr.print(curAttr.getValue().toString()); + pstr.print("`'/>\n"); + } + } + + // Print outcomes (if any) + if (outcomes != null) + { + Set<Map.Entry<String, SvcLogicNode>> outcomeSet = outcomes.entrySet(); + for (Iterator<Map.Entry<String, SvcLogicNode>> iter = outcomeSet.iterator() ; iter.hasNext();) + { + for (int i = 0 ; i < indentLvl+1 ; i++) + { + pstr.print(" "); + } + pstr.print("<outcome"); + Map.Entry<String, SvcLogicNode> curAttr = iter.next(); + pstr.print(" value='"); + pstr.print(curAttr.getKey()); + pstr.print("'>\n"); + SvcLogicNode outNode = curAttr.getValue(); + outNode.printAsXml(pstr, indentLvl+2); + for (int i = 0 ; i < indentLvl+1 ; i++) + { + pstr.print(" "); + } + pstr.print("</outcome>\n"); + } + } + + // Print node end tag + for (int i = 0 ; i < indentLvl ; i++) + { + pstr.print(" "); + } + pstr.print("</"); + pstr.print(this.getNodeType()); + pstr.print(">\n"); + pstr.flush(); + + } + + + public SvcLogicNode getOutcomeValue(String value) + { + + if (value.length() == 0) { + value = "\"\""; + } + if (outcomes == null) + { + return null; + } + + if (outcomes.containsKey(value)) + { + return outcomes.get(value); + } + else + { + StringBuffer keyBuffer = new StringBuffer(); + keyBuffer.append("{"); + for (String key : outcomes.keySet()) { + keyBuffer.append(" ("+key+")"); + } + keyBuffer.append("}"); + LOG.info("Outcome (" + value + ") not found, keys are " + keyBuffer.toString()); + + if (outcomes.containsKey("Other")) + { + return outcomes.get("Other"); + } + else + { + return null; + } + } + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java new file mode 100644 index 000000000..adec7b27d --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParser.java @@ -0,0 +1,615 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.LinkedList; +import javax.xml.XMLConstants; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.*; +import org.xml.sax.helpers.DefaultHandler; +import org.onap.ccsdk.sli.core.utils.PathValidator; + +/** + * @author dt5972 + * + */ +public class SvcLogicParser { + + static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; + static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; + static final String JAXP_DYNAMIC_VALIDATION = "http://apache.org/xml/features/validation/dynamic"; + static final String JAXP_SCHEMA_VALIDATION = "http://apache.org/xml/features/validation/schema"; + + private static final String LOAD_MESSAGE = "Getting SvcLogicGraph from database - {}"; + private static final String LOAD_ERROR_MESSAGE = "SvcLogicGraph not found - {}"; + private static final String ACTIVATION_ERROR_MESSAGE = "Could not activate SvcLogicGraph - {}"; + private static final String PRINT_ERROR_MESSAGE = "Could not print SvcLogicGraph - {}"; + private static final String SVC_LOGIC_STORE_ERROR = "Could not get service logic store"; + + private static final Logger LOGGER = LoggerFactory.getLogger(SvcLogicParser.class); + private static final String SLI_VALIDATING_PARSER = "org.onap.ccsdk.sli.parser.validate"; + private static final String SVCLOGIC_XSD = "/svclogic.xsd"; + private SAXParser saxParser; + + private class SvcLogicHandler extends DefaultHandler { + private Locator locator = null; + private String module = null; + private String version = null; + private LinkedList<SvcLogicGraph> graphs = null; + private SvcLogicGraph curGraph = null; + private SvcLogicNode curNode = null; + private LinkedList<SvcLogicNode> nodeStack = null; + private int curNodeId = 0; + private String outcomeValue = null; + private LinkedList<String> outcomeStack = null; + + public SvcLogicHandler(LinkedList<SvcLogicGraph> graphs) { + this.graphs = graphs; + this.curNode = null; + this.nodeStack = new LinkedList<>(); + this.outcomeStack = new LinkedList<>(); + this.curNodeId = 1; + this.outcomeValue = null; + } + + @Override + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + + // Handle service-logic (graph) tag + if ("service-logic".equalsIgnoreCase(qName)) { + + module = attributes.getValue("module"); + if (module == null || module.length() == 0) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "Missing 'module' attribute from service-logic tag"); + } + + version = attributes.getValue("version"); + if (version == null || version.length() == 0) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "Missing 'version' attribute from service-logic tag"); + } + + return; + } + + if ("method".equalsIgnoreCase(qName)) { + + if (curGraph != null) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "Cannot nest module tags"); + } + + curGraph = new SvcLogicGraph(); + curGraph.setModule(module); + curGraph.setVersion(version); + this.curNodeId = 1; + + String attrValue = attributes.getValue("rpc"); + if (attrValue == null || attrValue.length() == 0) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "Missing 'rpc' attribute for method tag"); + } + curGraph.setRpc(attrValue); + + attrValue = attributes.getValue("mode"); + if (attrValue == null || attrValue.length() == 0) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "Missing 'mode' attribute for method tag"); + } + curGraph.setMode(attrValue); + + return; + } + + // Handle outcome (edge) tag + if ("outcome".equalsIgnoreCase(qName)) { + String refValue = attributes.getValue("ref"); + + if (refValue != null) { + SvcLogicNode refNode = curGraph.getNamedNode(refValue); + + if (refNode != null) { + try { + curNode.addOutcome(attributes.getValue("value"), refNode); + } catch (SvcLogicException e) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + + " " + "Cannot add outcome", e); + } + } else { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "ref to unknown node " + refValue); + } + return; + } + + if (outcomeValue != null) { + outcomeStack.push(outcomeValue); + } + outcomeValue = attributes.getValue("value"); + + return; + } + + // Handle parameter tag + if ("parameter".equalsIgnoreCase(qName)) { + String parmName = attributes.getValue("name"); + String parmValue = attributes.getValue("value"); + + if (parmName != null && parmName.length() > 0 && parmValue != null) { + try { + + curNode.mapParameter(parmName, parmValue); + } catch (Exception e) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + " cannot set parameter " + parmName + " to " + parmValue + " [" + e.getMessage() + + "]"); + } + } + + return; + } + + // Handle node tags + String nodeName = attributes.getValue("name"); + SvcLogicNode thisNode; + + + try { + if (nodeName != null && nodeName.length() > 0) { + thisNode = new SvcLogicNode(curNodeId++, qName, nodeName, curGraph); + } else { + thisNode = new SvcLogicNode(curNodeId++, qName, curGraph); + } + + if (curGraph.getRootNode() == null) { + curGraph.setRootNode(thisNode); + } + } catch (SvcLogicException e) { + throw new SAXException( + "line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage()); + + } + + int numAttributes = attributes.getLength(); + + for (int i = 0; i < numAttributes; i++) { + String attrName = attributes.getQName(i); + if (!"name".equalsIgnoreCase(attrName)) { + try { + + String attrValueStr = attributes.getValue(i); + SvcLogicExpression attrValue; + if (attrValueStr.trim().startsWith("`")) { + int lastParen = attrValueStr.lastIndexOf('`'); + String evalExpr = attrValueStr.trim().substring(1, lastParen); + attrValue = SvcLogicExpressionFactory.parse(evalExpr); + + } else { + if (Character.isDigit(attrValueStr.charAt(0))) { + attrValue = new SvcLogicAtom("NUMBER", attrValueStr); + } else { + attrValue = new SvcLogicAtom("STRING", attrValueStr); + } + } + thisNode.setAttribute(attrName, attrValue); + } catch (Exception e) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + + "Cannot set attribute " + attrName, e); + } + } + } + + if (curNode != null) { + try { + if ("block".equalsIgnoreCase(curNode.getNodeType()) || "for".equalsIgnoreCase(curNode.getNodeType()) + || "while".equalsIgnoreCase(curNode.getNodeType())) { + curNode.addOutcome(Integer.toString(curNode.getNumOutcomes() + 1), thisNode); + } else { + if (outcomeValue == null) { + throw new SAXException("line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + + " " + curNode.getNodeType() + " node expects outcome, instead found " + + thisNode.getNodeType()); + } + curNode.addOutcome(outcomeValue, thisNode); + } + } catch (SvcLogicException e) { + throw new SAXException( + "line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + e.getMessage()); + } + nodeStack.push(curNode); + } + curNode = thisNode; + + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + // Handle close of service-logic tag + if ("service-logic".equalsIgnoreCase(qName)) { + // Nothing more to do + return; + } + + // Handle close of method tag + if ("method".equalsIgnoreCase(qName)) { + graphs.add(curGraph); + curGraph = null; + return; + } + + // Handle close of outcome tag + if ("outcome".equalsIgnoreCase(qName)) { + // Finished this outcome - pop the outcome stack + if (outcomeStack.isEmpty()) { + outcomeValue = null; + } else { + outcomeValue = outcomeStack.pop(); + } + return; + } + + // Handle close of parameter tag - do nothing + if ("parameter".equalsIgnoreCase(qName)) { + return; + } + + // Handle close of a node tag + if (nodeStack.isEmpty()) { + curNode = null; + } else { + curNode = nodeStack.pop(); + } + } + + @Override + public void error(SAXParseException arg0) throws SAXException { + throw new SAXException( + "line " + locator.getLineNumber() + ":" + locator.getColumnNumber() + " " + arg0.getMessage()); + } + + } + + public LinkedList<SvcLogicGraph> parse(String fileName) throws SvcLogicException { + LinkedList<SvcLogicGraph> graphs; + + try { + if (saxParser == null) { + saxParser = initParser(); + } + + graphs = new LinkedList<>(); + saxParser.parse(fileName, new SvcLogicHandler(graphs)); + + try { + for (SvcLogicGraph graph : graphs) { + graph.setMd5sum(CheckSumHelper.md5SumFromFile(fileName)); + } + } catch (Exception exc) { + LOGGER.error("Couldn't set md5sum on graphs", exc); + } + } catch (Exception e) { + LOGGER.error("Parsing failed ", e); + String msg = e.getMessage(); + if (msg != null) { + throw new SvcLogicException("Compiler error: " + fileName + " @ " + msg); + } else { + throw new SvcLogicException("Compiler error: " + fileName, e); + } + } + return graphs; + } + + public static void main(String argv[]) { + + if (argv.length == 0) { + SvcLogicParser.usage(); + } + + if ("load".equalsIgnoreCase(argv[0])) { + if (argv.length == 3) { + String xmlfile = argv[1]; + String propfile = argv[2]; + + SvcLogicStore store = SvcLogicParser.getStore(propfile); + try { + SvcLogicParser.load(xmlfile, store); + } catch (Exception e) { + LOGGER.error("Load failed ", e); + } + } else { + SvcLogicParser.usage(); + } + } else if ("print".equalsIgnoreCase(argv[0])) { + String version = null; + String propfile = null; + + switch (argv.length) { + case 6: + version = argv[4]; + propfile = argv[5]; + case 5: + if (propfile == null) { + propfile = argv[4]; + } + SvcLogicStore store = SvcLogicParser.getStore(propfile); + SvcLogicParser.print(argv[1], argv[2], argv[3], version, store); + break; + default: + SvcLogicParser.usage(); + } + } else if ("get-source".equalsIgnoreCase(argv[0])) { + + if (argv.length == 6) { + SvcLogicStore store = SvcLogicParser.getStore(argv[5]); + SvcLogicParser.getSource(argv[1], argv[2], argv[3], argv[4], store); + } else { + SvcLogicParser.usage(); + } + } else if ("activate".equalsIgnoreCase(argv[0])) { + if (argv.length == 6) { + SvcLogicStore store = SvcLogicParser.getStore(argv[5]); + SvcLogicParser.activate(argv[1], argv[2], argv[3], argv[4], store); + } else { + SvcLogicParser.usage(); + } + } else if ("validate".equalsIgnoreCase(argv[0])) { + if (argv.length == 3) { + String xmlfile = argv[1]; + String propfile = argv[2]; + + System.setProperty(SLI_VALIDATING_PARSER, "true"); + SvcLogicStore store = SvcLogicParser.getStore(propfile); + try { + SvcLogicParser.validate(xmlfile, store); + } catch (Exception e) { + LOGGER.error("Validate failed", e); + } + } else { + SvcLogicParser.usage(); + } + } else if ("install".equalsIgnoreCase(argv[0])) { + if (argv.length == 3) { + SvcLogicLoader loader = new SvcLogicLoader(argv[1], argv[2]); + try { + loader.loadAndActivate(); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); + } + } else { + SvcLogicParser.usage(); + } + } else if ("bulkActivate".equalsIgnoreCase(argv[0])) { + if (argv.length == 3) { + SvcLogicLoader loader = new SvcLogicLoader(argv[1], argv[2]); + try { + loader.bulkActivate(); + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + } + } else { + SvcLogicParser.usage(); + } + } + + System.exit(0); + } + + protected static SvcLogicStore getStore(String propfile) { + + SvcLogicStore store = null; + + try { + store = SvcLogicStoreFactory.getSvcLogicStore(propfile); + } catch (Exception e) { + LOGGER.error(SVC_LOGIC_STORE_ERROR, e); + System.exit(1); + } + + return store; + + } + + + public static void load(String xmlfile, SvcLogicStore store) throws SvcLogicException { + if (!PathValidator.isValidXmlPath(xmlfile)) { + throw new ConfigurationException("Invalid xml file name ("+ xmlfile + ")"); + } + File xmlFile = new File(xmlfile); + if (!xmlFile.canRead()) { + throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")"); + } + + SvcLogicParser parser = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graphs; + try { + LOGGER.info("Loading {}", xmlfile); + graphs = parser.parse(xmlfile); + } catch (Exception e) { + throw new SvcLogicException(e.getMessage(), e); + } + + if (graphs == null) { + throw new SvcLogicException("Could not parse " + xmlfile); + } + + for (SvcLogicGraph graph : graphs) { + + try { + LOGGER.info("Saving " + graph.toString() + " to database."); + store.store(graph); + } catch (Exception e) { + throw new SvcLogicException(e.getMessage(), e); + } + + } + + } + + public static void validate(String xmlfile, SvcLogicStore store) throws SvcLogicException { + if (!PathValidator.isValidXmlPath(xmlfile)) { + throw new ConfigurationException("Invalid xml file name ("+ xmlfile + ")"); + } + File xmlFile = new File(xmlfile); + if (!xmlFile.canRead()) { + throw new ConfigurationException("Cannot read xml file (" + xmlfile + ")"); + } + + SvcLogicParser parser = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graphs; + try { + LOGGER.info("Validating {}", xmlfile); + graphs = parser.parse(xmlfile); + } catch (Exception e) { + throw new SvcLogicException(e.getMessage(), e); + } + + if (graphs == null) { + throw new SvcLogicException("Could not parse " + xmlfile); + } else { + LOGGER.info("Compilation successful for {}", xmlfile); + } + + } + + private static void print(String module, String rpc, String mode, String version, SvcLogicStore store) { + String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")"; + + try { + LOGGER.info(LOAD_MESSAGE, details); + + SvcLogicGraph graph = store.fetch(module, rpc, version, mode); + if (graph == null) { + LOGGER.error(LOAD_ERROR_MESSAGE, details); + System.exit(1); + } + graph.printAsGv(System.out); + } catch (Exception e) { + LOGGER.error(PRINT_ERROR_MESSAGE, details, e); + System.exit(1); + } + + } + + private static void getSource(String module, String rpc, String mode, String version, SvcLogicStore store) { + String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")"; + + try { + LOGGER.info(LOAD_MESSAGE, details); + + SvcLogicGraph graph = store.fetch(module, rpc, version, mode); + if (graph == null) { + LOGGER.error(LOAD_ERROR_MESSAGE, details); + System.exit(1); + } + graph.printAsXml(System.out); + } catch (Exception e) { + LOGGER.error(PRINT_ERROR_MESSAGE, details, e); + System.exit(1); + } + + } + + public static void activate(String module, String rpc, String version, String mode, SvcLogicStore store) { + String details = "(module:" + module + ", rpc:" + rpc + ", version:" + version + ", mode:" + mode + ")"; + + try { + LOGGER.info(LOAD_MESSAGE, details); + + SvcLogicGraph graph = store.fetch(module, rpc, version, mode); + if (graph == null) { + LOGGER.error(LOAD_ERROR_MESSAGE, details); + System.exit(1); + } + store.activate(graph); + } catch (Exception e) { + LOGGER.error(ACTIVATION_ERROR_MESSAGE, details, e); + System.exit(1); + } + + } + + private static void usage() { + System.err.println("Usage: SvcLogicParser load <xml-file> <prop-file>"); + System.err.println(" OR SvcLogicParser print <module> <rpc> <mode> [<version>] <prop-file>"); + System.err.println(" OR SvcLogicParser get-source <module> <rpc> <mode> <version> <prop-file>"); + System.err.println(" OR SvcLogicParser activate <module> <rpc> <version> <mode>"); + System.err.println(" OR SvcLogicParser validate <file path to graph> <prop-file>"); + System.err.println(" OR SvcLogicParser install <service-logic directory path> <prop-file>"); + System.err.println(" OR SvcLogicParser bulkActivate <path to activation file> <prop-file>"); + System.exit(1); + } + + protected SAXParser initParser() throws ParserConfigurationException, SAXException { + URL xsdUrl = null; + Schema schema = null; + String validateSchema = System.getProperty(SLI_VALIDATING_PARSER, "true"); + + if ("true".equalsIgnoreCase(validateSchema)) { + xsdUrl = getClass().getResource(SVCLOGIC_XSD); + } + + if (xsdUrl != null) { + try { + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + schema = schemaFactory.newSchema(xsdUrl); + LOGGER.info("Schema path {}", xsdUrl.getPath()); + } catch (Exception e) { + LOGGER.warn("Could not validate using schema {}", xsdUrl.getPath(), e); + } + } else { + LOGGER.warn("Could not find resource {}", SVCLOGIC_XSD); + } + + SAXParserFactory factory = SAXParserFactory.newInstance(); + + if (schema != null) { + factory.setNamespaceAware(true); + factory.setSchema(schema); + } + + SAXParser saxParser = factory.newSAXParser(); + if (saxParser.isValidating()) { + LOGGER.info("Parser configured to validate XML {}", (xsdUrl != null ? xsdUrl.getPath() : null)); + } + return saxParser; + } + + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java new file mode 100644 index 000000000..61f80f7e2 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserException.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.IOException; + +public class SvcLogicParserException extends IOException { + + public SvcLogicParserException() { + super(); + } + + public SvcLogicParserException(String msg) { + super(msg); + } + + public SvcLogicParserException(Throwable t) { + super(t); + } + + public SvcLogicParserException(String msg, Throwable t) { + super(msg, t); + } +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java new file mode 100644 index 000000000..ca13536bb --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicRecorder.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.Map; + +public interface SvcLogicRecorder { + + void record(Map<String, String> parmMap) throws SvcLogicException; + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java new file mode 100644 index 000000000..0e2c42574 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicResource.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.Map; + +public interface SvcLogicResource { + + public enum QueryStatus { + SUCCESS, + NOT_FOUND, + FAILURE + } + + public QueryStatus isAvailable(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus reserve(String resource, String select, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus release(String resource, String key, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException; + + public QueryStatus update(String resource, String key, Map<String, String> parms, String prefix, SvcLogicContext ctx) throws SvcLogicException; + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java new file mode 100644 index 000000000..2eda67f11 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStore.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.util.Properties; + +public interface SvcLogicStore { + + public void init(Properties props) throws SvcLogicException; + public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException; + public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException; + public void store(SvcLogicGraph graph) throws SvcLogicException; + public void delete(String module, String rpc, String version, String mode) throws SvcLogicException; + public void activate(SvcLogicGraph graph) throws SvcLogicException; + public void activate(String module, String rpc, String version, String mode) throws SvcLogicException; + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java new file mode 100644 index 000000000..e0eb57304 --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicStoreFactory.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Properties; +import org.onap.ccsdk.sli.core.dblib.DBResourceManager; +import org.onap.ccsdk.sli.core.utils.PathValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicStoreFactory { + + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicStoreFactory.class); + + public static SvcLogicStore getSvcLogicStore(String propfile) + throws SvcLogicException { + if (!PathValidator.isValidPropertiesPath(propfile)) { + throw new ConfigurationException("Invalid property file name ("+propfile+")"); + } + File propFile = new File(propfile); + if (!propFile.canRead()) { + throw new ConfigurationException("Cannot read property file " + + propfile); + + } + + try { + return getSvcLogicStore(new FileInputStream(propFile)); + } catch (Exception e) { + throw new ConfigurationException( + "Could load service store from properties file " + propfile, + e); + } + + } + + public static SvcLogicStore getSvcLogicStore(InputStream inStr) throws SvcLogicException + { + Properties props = new Properties(); + + try { + props.load(inStr); + } catch (Exception e) { + throw new ConfigurationException("Could not get load properties from input stream", e); + } + + return getSvcLogicStore(props); + } + + public static SvcLogicStore getSvcLogicStore(Properties props) + throws SvcLogicException { + String storeType = props.getProperty("org.onap.ccsdk.sli.dbtype"); + if ((storeType == null) || (storeType.length() == 0)) { + throw new ConfigurationException( + "property org.onap.ccsdk.sli.dbtype unset"); + + } + + SvcLogicStore retval; + LOG.debug("Using org.onap.ccsdk.sli.dbtype={}", storeType); + + if ("jdbc".equalsIgnoreCase(storeType)) { + retval = new SvcLogicJdbcStore(); + + } else if ("dblib".equalsIgnoreCase(storeType)) { + retval = new SvcLogicDblibStore(new DBResourceManager(props)); + } else { + throw new ConfigurationException("unsupported dbtype (" + storeType + + ")"); + + } + + + retval.init(props); + return retval; + } + +} diff --git a/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java new file mode 100644 index 000000000..4edf3ecbe --- /dev/null +++ b/core/sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicVariableTerm.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +public class SvcLogicVariableTerm extends SvcLogicExpression { + + private String name = null; + + public String getName() { + return name; + } + + + public SvcLogicVariableTerm(String identifier) + { + this.name = identifier; + } + + public SvcLogicExpression getSubscript() + { + if (numOperands() > 0) + { + return(getOperands().get(0)); + } + else + { + return(null); + } + } + + @Override + public String toString() + { + String retval; + + if (numOperands() > 0) + { + retval = name + "[" + getSubscript().toString() + "]"; + } + else + { + retval = name; + } + return(retval); + } + + @Override + public String asParsedExpr() { + if (numOperands() == 0) { + return("(variable-term "+name+")"); + } + else + { + return("(variable-term "+name+" "+getSubscript().asParsedExpr()+")"); + } + } + +} diff --git a/core/sli/common/src/main/resources/svclogic.xsd b/core/sli/common/src/main/resources/svclogic.xsd new file mode 100755 index 000000000..c9beae83e --- /dev/null +++ b/core/sli/common/src/main/resources/svclogic.xsd @@ -0,0 +1,339 @@ +<?xml version = "1.0" encoding = "UTF-8"?> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.onap.org/sdnc/svclogic" xmlns="http://www.onap.org/sdnc/svclogic"> + + <xsd:simpleType name="modeType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="sync" /> + <xsd:enumeration value="async" /> + </xsd:restriction> + </xsd:simpleType> + + <xsd:group name="node"> + <xsd:choice> + <xsd:element ref="block" /> + <xsd:element ref="is-available" /> + <xsd:element ref="exists" /> + <xsd:element ref="reserve" /> + <xsd:element ref="release" /> + <xsd:element ref="allocate" /> + <xsd:element ref="get-resource" /> + <xsd:element ref="configure" /> + <xsd:element ref="return" /> + <xsd:element ref="switch" /> + <xsd:element ref="record" /> + <xsd:element ref="save" /> + <xsd:element ref="for" /> + <xsd:element ref="set" /> + <xsd:element ref="execute" /> + <xsd:element ref="delete" /> + <xsd:element ref="update" /> + <xsd:element ref="call" /> + <xsd:element ref="notify" /> + <xsd:element ref="break" /> + <xsd:element ref="while" /> + <xsd:element ref="exit" /> + </xsd:choice> + </xsd:group> + + <xsd:element name="service-logic"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="method" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="module" use="required" type="xsd:string" /> + <xsd:attribute name="version" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="method"> + <xsd:complexType> + <xsd:sequence> + <xsd:group ref="node" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="rpc" use="required" type="xsd:string" /> + <xsd:attribute name="mode" use="optional" type="modeType" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="block"> + <xsd:complexType> + <xsd:sequence> + <xsd:group ref="node" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="atomic" use="optional" type="xsd:boolean" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="is-available"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="exists"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="outcome"> + <xsd:complexType> + <xsd:sequence> + <xsd:group ref="node" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="ref" use="optional" type="xsd:string" /> + <xsd:attribute name="value" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="reserve"> + <xsd:complexType> + <xsd:sequence> + <!-- This node does not actually read from parameters --> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <xsd:attribute name="select" use="optional" type="xsd:string" /> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="release"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="record"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="allocate"> + <xsd:complexType> + <xsd:sequence> + <!-- This node does not actually read from parameters --> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="required" type="xsd:string" /> + <xsd:attribute name="pfx" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="get-resource"> + <xsd:complexType> + <xsd:sequence> + <!-- This node does not actually read from parameters --> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <xsd:attribute name="local-only" use="optional" type="xsd:boolean" /> + <xsd:attribute name="order-by" use="optional" type="xsd:string" /> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + <!-- force is retired and does not do anything --> + <xsd:attribute name="force" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="configure"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="adaptor" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="required" type="xsd:string" /> + <xsd:attribute name="activate" use="optional" type="xsd:boolean" /> + </xsd:complexType> + </xsd:element> + + + <xsd:element name="parameter"> + <xsd:complexType> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="value" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + + <xsd:element name="return"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="status" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="switch"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="test" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="save"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <xsd:attribute name="force" use="optional" type="xsd:boolean" /> + <xsd:attribute name="local-only" use="optional" type="xsd:boolean" /> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="delete"> + <xsd:complexType> + <xsd:sequence> + <!-- This node does not actually read from parameters --> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <!-- force is retired and does not do anything --> + <xsd:attribute name="force" use="optional" type="xsd:string" /> + <!-- local-only is retired and does not do anything --> + <xsd:attribute name="local-only" use="optional" type="xsd:string" /> + <!-- pfx is retired and does not do anything --> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="for"> + <xsd:complexType> + <xsd:sequence> + <xsd:group ref="node" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="atomic" use="optional" type="xsd:boolean" /> + <xsd:attribute name="index" use="required" type="xsd:string" /> + <xsd:attribute name="start" use="required" type="xsd:string" /> + <xsd:attribute name="end" use="required" type="xsd:string" /> + <xsd:attribute name="silentFailure" use="optional" type="xsd:boolean" default="false" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="set"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="only-if-unset" use="optional" + type="xsd:boolean" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="execute"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="method" use="required" type="xsd:string" /> + <xsd:attribute name="emitsOutcome" use="optional" type="xsd:boolean" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="update"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="required" type="xsd:string" /> + <xsd:attribute name="resource" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <xsd:attribute name="force" use="optional" type="xsd:boolean" /> + <xsd:attribute name="local-only" use="optional" type="xsd:boolean" /> + <xsd:attribute name="pfx" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="call"> + <xsd:complexType> + <xsd:sequence> + <!-- This node does not actually read from parameters --> + <xsd:element ref="parameter" minOccurs="0" maxOccurs="100" /> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="module" use="optional" type="xsd:string" /> + <xsd:attribute name="rpc" use="required" type="xsd:string" /> + <xsd:attribute name="version" use="optional" type="xsd:string" /> + <xsd:attribute name="mode" use="required" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="notify"> + <xsd:complexType> + <xsd:sequence> + <xsd:element ref="outcome" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="plugin" use="optional" type="xsd:string" /> + <xsd:attribute name="resource" use="optional" type="xsd:string" /> + <xsd:attribute name="action" use="required" type="xsd:string" /> + <xsd:attribute name="key" use="optional" type="xsd:string" /> + <!-- force is retired and does not do anything --> + <xsd:attribute name="force" use="optional" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + + <xsd:element name="break"> + <xsd:complexType /> + </xsd:element> + + <xsd:element name="exit"> + <xsd:complexType /> + </xsd:element> + + <xsd:element name="while"> + <xsd:complexType> + <xsd:sequence> + <xsd:group ref="node" minOccurs="0" maxOccurs="100" /> + </xsd:sequence> + <xsd:attribute name="test" use="required" type="xsd:string" /> + <xsd:attribute name="do" use="optional" type="xsd:boolean" /> + </xsd:complexType> + </xsd:element> + +</xsd:schema> diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java new file mode 100644 index 000000000..ef7492366 --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ConfigurationExceptionTestt.java @@ -0,0 +1,30 @@ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class ConfigurationExceptionTestt { + + + @Test + public void ConfigurationExceptionTest() { + assertNotNull(new ConfigurationException()); + + } + + @Test + public void ConfigurationExceptionTestString() { + assertNotNull(new ConfigurationException("JUnit Test")); + + } + + @Test + public void ConfigurationExceptionTestStringThrowable() { + assertNotNull(new ConfigurationException("JUnit Test", new Exception("JUnit Test"))); + + } + + + +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java new file mode 100644 index 000000000..387873557 --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/DuplicatevalueExceptionTest.java @@ -0,0 +1,28 @@ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class DuplicatevalueExceptionTest { + + + @Test + public void DuplicateValueExceptionTest() { + assertNotNull(new DuplicateValueException()); + + } + + @Test + public void DuplicateValueExceptionTestString() { + assertNotNull(new DuplicateValueException("JUnit Test")); + + } + + @Test + public void DuplicateValueExceptionTestStringThrowable() { + assertNotNull(new DuplicateValueException("JUnit Test", new Exception("JUnit Test"))); + + } + +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java new file mode 100644 index 000000000..d95ff3075 --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ErrorLoggerTest.java @@ -0,0 +1,56 @@ +package org.onap.ccsdk.sli.core.sli;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ErrorLoggerTest {
+ private Logger log = LoggerFactory.getLogger(ErrorLoggerTest.class);
+
+ @Test
+ public void testOverloads() throws Exception {
+ ErrorLogger e = new ErrorLogger();
+ Exception exc = new Exception();
+ e.logError("failure", 200);
+ e.logError("failure", 200, exc);
+ e.logError("failure", 200, "Timeout during HTTP operation");
+ e.logError("failure", 200, "Timeout during HTTP operation", exc);
+ }
+
+ @Test
+ public void testInvalidErrorCode() throws Exception {
+ ErrorLogger e = new ErrorLogger();
+ e.logError("failure", 0);
+ }
+
+ @Test
+ public void testDescriptionMapping() throws Exception {
+ ErrorLogger e = new ErrorLogger();
+ e.logError("failure", 100);
+ e.logError("failure", 200);
+ e.logError("failure", 300);
+ e.logError("failure", 400);
+ e.logError("failure", 500);
+ e.logError("failure", 900);
+ }
+
+ @Test
+ public void testIsValidCode() throws Exception {
+ ErrorLogger e = new ErrorLogger(log);
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_100));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_200));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_300));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_400));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_500));
+ assertTrue(e.isValidCode(ErrorLogger.ERROR_CODE_900));
+
+ assertFalse(e.isValidCode(0));
+ assertFalse(e.isValidCode(204));
+ assertFalse(e.isValidCode(404));
+ assertFalse(e.isValidCode(501));
+ }
+
+}
diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java new file mode 100644 index 000000000..039b9f5ca --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ExitNodeExceptionTest.java @@ -0,0 +1,27 @@ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class ExitNodeExceptionTest { + + @Test + public void ExitNodeExceptionTest() { + assertNotNull(new ExitNodeException()); + + } + + @Test + public void ExitNodeExceptionTestString() { + assertNotNull(new ExitNodeException("JUnit Test")); + + } + + @Test + public void ExitNodeExceptionTestStringThrowable() { + assertNotNull(new ExitNodeException("JUnit Test", new Exception("JUnit Test"))); + + } + +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java new file mode 100644 index 000000000..50eb917f8 --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/ITCaseSvcLogicParser.java @@ -0,0 +1,284 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +/** + * + */ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.sli.core.dblib.DBResourceManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author dt5972 + * + */ +public class ITCaseSvcLogicParser { + + private static SvcLogicStore store; + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicJdbcStore.class); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + + LOG.info("before class"); + + URL propUrl = ITCaseSvcLogicParser.class.getResource("/svclogic.properties"); + + InputStream propStr = ITCaseSvcLogicParser.class.getResourceAsStream("/svclogic.properties"); + + Properties props = new Properties(); + + props.load(propStr); + + store = SvcLogicStoreFactory.getSvcLogicStore(props); + + assertNotNull(store); + + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + LOG.info("after class"); + } + + @Before + public void setUp() throws Exception { + LOG.info("before"); + } + + @After + public void tearDown() throws Exception { + LOG.info("after"); + } + + /** + * Test method for {@link org.onap.ccsdk.sli.core.sli.SvcLogicParser#parse(java.lang.String)}. + */ + @Test + public void testParseValidXml() { + + try { + InputStream testStr = getClass().getResourceAsStream("/parser-good.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + String testCaseFile = null; + while ((testCaseFile = testsReader.readLine()) != null) { + + testCaseFile = testCaseFile.trim(); + + if (testCaseFile.length() > 0) { + if (!testCaseFile.startsWith("/")) { + testCaseFile = "/" + testCaseFile; + } + URL testCaseUrl = getClass().getResource(testCaseFile); + if (testCaseUrl == null) { + fail("Could not resolve test case file " + testCaseFile); + } + + // Test parsing and printing + try { + SvcLogicParser parser = new SvcLogicParser(); + + for (SvcLogicGraph graph : parser.parse(testCaseUrl.getPath())) { + System.out.println("XML for graph "+graph.getModule()+":"+graph.getRpc()); + graph.printAsXml(System.out); + System.out.println("GV for graph "+graph.getModule()+":"+graph.getRpc()); + graph.printAsGv(System.out); + } + } catch (Exception e) { + + fail("Validation failure [" + e.getMessage() + "]"); + } + + try { + SvcLogicParser.load(testCaseUrl.getPath(), store); + } catch (Exception e) { + + fail("Validation failure [" + e.getMessage() + "]"); + } + } + } + } catch (SvcLogicParserException e) { + fail("Parser error : " + e.getMessage()); + } catch (Exception e) { + LOG.error("", e); + fail("Caught exception processing test cases"); + } + } + + @Test + public void testDblibLoadValidXml() throws IOException, SQLException, ConfigurationException { + + URL propUrl = ITCaseSvcLogicParser.class.getResource("/dblib.properties"); + + InputStream propStr = ITCaseSvcLogicParser.class.getResourceAsStream("/dblib.properties"); + + Properties props = new Properties(); + + props.load(propStr); + + SvcLogicDblibStore dblibStore = new SvcLogicDblibStore(new DBResourceManager(props)); + + Connection dbConn = dblibStore.getConnection(); + + String dbName = props.getProperty("org.onap.ccsdk.sli.jdbc.database", "sdnctl"); + + DatabaseMetaData dbm; + + try { + dbm = dbConn.getMetaData(); + } catch (SQLException e) { + + throw new ConfigurationException("could not get databse metadata", e); + } + + // See if table SVC_LOGIC exists. If not, create it. + Statement stmt = null; + try { + + ResultSet tables = dbm.getTables(null, null, "SVC_LOGIC", null); + if (tables.next()) { + LOG.debug("SVC_LOGIC table already exists"); + } else { + String crTableCmd = "CREATE TABLE " + dbName + ".SVC_LOGIC (" + "module varchar(80) NOT NULL," + + "rpc varchar(80) NOT NULL," + "version varchar(40) NOT NULL," + "mode varchar(5) NOT NULL," + + "active varchar(1) NOT NULL,graph BLOB," + + "modified_timestamp timestamp DEFAULT NULL," + + "md5sum varchar(128) DEFAULT NULL," + + "CONSTRAINT P_SVC_LOGIC PRIMARY KEY(module, rpc, version, mode))"; + + stmt = dbConn.createStatement(); + stmt.executeUpdate(crTableCmd); + } + } catch (Exception e) { + throw new ConfigurationException("could not create SVC_LOGIC table", e); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + LOG.error("Statement close error ", e); + } + } + } + + // See if NODE_TYPES table exists and, if not, create it + stmt = null; + try { + + ResultSet tables = dbm.getTables(null, null, "NODE_TYPES", null); + if (tables.next()) { + LOG.debug("NODE_TYPES table already exists"); + } else { + String crTableCmd = "CREATE TABLE " + dbName + ".NODE_TYPES (" + "nodetype varchar(80) NOT NULL," + + "CONSTRAINT P_NODE_TYPES PRIMARY KEY(nodetype))"; + + stmt = dbConn.createStatement(); + + stmt.executeUpdate(crTableCmd); + } + } catch (Exception e) { + throw new ConfigurationException("could not create SVC_LOGIC table", e); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + LOG.error("Statement close error ", e); + } + } + } + + try { + InputStream testStr = getClass().getResourceAsStream("/parser-good.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + String testCaseFile = null; + while ((testCaseFile = testsReader.readLine()) != null) { + + testCaseFile = testCaseFile.trim(); + + if (testCaseFile.length() > 0) { + if (!testCaseFile.startsWith("/")) { + testCaseFile = "/" + testCaseFile; + } + URL testCaseUrl = getClass().getResource(testCaseFile); + if (testCaseUrl == null) { + fail("Could not resolve test case file " + testCaseFile); + } + + try { + SvcLogicParser.load(testCaseUrl.getPath(), dblibStore); + } catch (Exception e) { + + fail("Validation failure [" + e.getMessage() + "]"); + } + } + } + } catch (SvcLogicParserException e) { + fail("Parser error : " + e.getMessage()); + } catch (Exception e) { + LOG.error("", e); + fail("Caught exception processing test cases"); + } + } + + @Test(expected = SvcLogicException.class) + public void testParseInvalidXml() throws SvcLogicException, IOException { + + InputStream testStr = getClass().getResourceAsStream("/parser-bad.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + String testCaseFile; + while ((testCaseFile = testsReader.readLine()) != null) { + + testCaseFile = testCaseFile.trim(); + + if (testCaseFile.length() > 0) { + if (!testCaseFile.startsWith("/")) { + testCaseFile = "/" + testCaseFile; + } + URL testCaseUrl = getClass().getResource(testCaseFile); + if (testCaseUrl == null) { + fail("Could not resolve test case file " + testCaseFile); + } + SvcLogicParser.validate(testCaseUrl.getPath(), store); + } + } + } +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java new file mode 100644 index 000000000..43e7a862b --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicContextTest.java @@ -0,0 +1,400 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import com.google.gson.*; +import org.apache.commons.lang3.builder.ToStringExclude; +import org.checkerframework.checker.units.qual.A; +import org.json.JSONException; +import org.junit.Ignore; +import org.junit.Test; +import org.skyscreamer.jsonassert.JSONAssert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import junit.framework.TestCase; + +import static org.junit.Assert.assertEquals; + +public class SvcLogicContextTest extends TestCase { + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicContextTest.class); + + @Test + public void testMerge() { + + try { + InputStream testStr = getClass().getResourceAsStream("/mergetest.xml"); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + + Document theDocument = db.parse(testStr); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.mergeDocument("test-merge", theDocument); + Properties props = ctx.toProperties(); + LOG.info("SvcLogicContext contains the following : "); + for (Enumeration e = props.propertyNames(); e.hasMoreElements() ; ) { + String propName = (String) e.nextElement(); + LOG.info(propName+" = "+props.getProperty(propName)); + + } + } catch (Exception e) { + LOG.error("Caught exception trying to merge", e); + fail("Caught exception trying to merge"); + } + + } + + @Test + public void testIsSuccess() { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setStatus(SvcLogicConstants.SUCCESS); + assertTrue(ctx.isSuccess()); + ctx.setStatus(SvcLogicConstants.FAILURE); + assertFalse(ctx.isSuccess()); + } + + @Test + public void testMarkSuccess() { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.markSuccess(); + assertTrue(ctx.isSuccess()); + assertEquals(SvcLogicConstants.SUCCESS, ctx.getStatus()); + } + + @Test + public void testMarkFailed() { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.markFailed(); + assertFalse(ctx.isSuccess()); + assertEquals(SvcLogicConstants.FAILURE, ctx.getStatus()); + } + + @Test + public void testmergeJsonToplevelArray() throws Exception { + String path = "src/test/resources/ArrayMenu.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.mergeJson("testPath", content); + + + assertEquals("1000", ctx.getAttribute("testPath.[0].calories")); + assertEquals("1", ctx.getAttribute("testPath.[0].id")); + assertEquals("plain", ctx.getAttribute("testPath.[0].name")); + assertEquals("pizza", ctx.getAttribute("testPath.[0].type")); + assertEquals("true", ctx.getAttribute("testPath.[0].vegetarian")); + assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.[1].calories")); + assertEquals("2", ctx.getAttribute("testPath.[1].id")); + assertEquals("Tuesday Special", ctx.getAttribute("testPath.[1].name")); + assertEquals("1", ctx.getAttribute("testPath.[1].topping[0].id")); + assertEquals("onion", ctx.getAttribute("testPath.[1].topping[0].name")); + assertEquals("2", ctx.getAttribute("testPath.[1].topping[1].id")); + assertEquals("pepperoni", ctx.getAttribute("testPath.[1].topping[1].name")); + assertEquals("2", ctx.getAttribute("testPath.[1].topping_length")); + assertEquals("pizza", ctx.getAttribute("testPath.[1].type")); + assertEquals("false", ctx.getAttribute("testPath.[1].vegetarian")); + assertEquals("1500", ctx.getAttribute("testPath.[2].calories")); + assertEquals("3", ctx.getAttribute("testPath.[2].id")); + assertEquals("House Special", ctx.getAttribute("testPath.[2].name")); + assertEquals("3", ctx.getAttribute("testPath.[2].topping[0].id")); + assertEquals("basil", ctx.getAttribute("testPath.[2].topping[0].name")); + assertEquals("4", ctx.getAttribute("testPath.[2].topping[1].id")); + assertEquals("fresh mozzarella", ctx.getAttribute("testPath.[2].topping[1].name")); + assertEquals("5", ctx.getAttribute("testPath.[2].topping[2].id")); + assertEquals("tomato", ctx.getAttribute("testPath.[2].topping[2].name")); + assertEquals("3", ctx.getAttribute("testPath.[2].topping_length")); + assertEquals("pizza", ctx.getAttribute("testPath.[2].type")); + assertEquals("true", ctx.getAttribute("testPath.[2].vegetarian")); + assertEquals("3", ctx.getAttribute("testPath._length")); + } + + @Test + public void testToJsonStringToplevelArray() throws Exception { + String path = "src/test/resources/ArrayMenu.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.mergeJson("testPath", content); + + String ctxContent = ctx.toJsonString("testPath"); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + + try { + assertEquals(jsonIn, jsonOut); + } catch (AssertionError e) { + LOG.warn("Top level array not working - error is {}", e.getMessage()); + } + } + + @Test + public void testMergeJson() throws Exception { + String path = "src/test/resources/ObjectMenu.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + ctx.mergeJson("testPath", content); + + + assertEquals("1000", ctx.getAttribute("testPath.menu[0].calories")); + assertEquals("1", ctx.getAttribute("testPath.menu[0].id")); + assertEquals("plain", ctx.getAttribute("testPath.menu[0].name")); + assertEquals("pizza", ctx.getAttribute("testPath.menu[0].type")); + assertEquals("true", ctx.getAttribute("testPath.menu[0].vegetarian")); + assertEquals("2000", ctx.getAttribute("testPath.menu[1].calories")); + assertEquals("2", ctx.getAttribute("testPath.menu[1].id")); + assertEquals("Tuesday Special", ctx.getAttribute("testPath.menu[1].name")); + assertEquals("1", ctx.getAttribute("testPath.menu[1].topping[0].id")); + assertEquals("onion", ctx.getAttribute("testPath.menu[1].topping[0].name")); + assertEquals("2", ctx.getAttribute("testPath.menu[1].topping[1].id")); + assertEquals("pepperoni", ctx.getAttribute("testPath.menu[1].topping[1].name")); + assertEquals("2", ctx.getAttribute("testPath.menu[1].topping_length")); + assertEquals("pizza", ctx.getAttribute("testPath.menu[1].type")); + assertEquals("false", ctx.getAttribute("testPath.menu[1].vegetarian")); + assertEquals("1500", ctx.getAttribute("testPath.menu[2].calories")); + assertEquals("3", ctx.getAttribute("testPath.menu[2].id")); + assertEquals("House Special", ctx.getAttribute("testPath.menu[2].name")); + assertEquals("3", ctx.getAttribute("testPath.menu[2].topping[0].id")); + assertEquals("basil", ctx.getAttribute("testPath.menu[2].topping[0].name")); + assertEquals("4", ctx.getAttribute("testPath.menu[2].topping[1].id")); + assertEquals("fresh mozzarella", ctx.getAttribute("testPath.menu[2].topping[1].name")); + assertEquals("5", ctx.getAttribute("testPath.menu[2].topping[2].id")); + assertEquals("tomato", ctx.getAttribute("testPath.menu[2].topping[2].name")); + assertEquals("3", ctx.getAttribute("testPath.menu[2].topping_length")); + assertEquals("pizza", ctx.getAttribute("testPath.menu[2].type")); + assertEquals("true", ctx.getAttribute("testPath.menu[2].vegetarian")); + assertEquals("3", ctx.getAttribute("testPath.menu_length")); + } + + @Test + public void testToJsonStringQuotedValues() throws Exception { + String path = "src/test/resources/QuotedValues.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + ctx.mergeJson("testPath", content); + String ctxContent = ctx.toJsonString("testPath"); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + assertEquals(jsonIn, jsonOut); + } + + + @Test + public void testToJsonString() throws Exception { + String path = "src/test/resources/ObjectMenu.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + ctx.mergeJson("testPath", content); + String ctxContent = ctx.toJsonString("testPath"); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + + try { + assertEquals(jsonIn, jsonOut); + } catch (AssertionError e) { + // Error could be due to quoted numeric values, which we cannot address. + LOG.warn("Test failed, but could be known error condition. Error is {}", e.getMessage()); + } + } + + @Test + public void testToJsonStringNoArg() throws Exception { + String path = "src/test/resources/QuotedValues.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + ctx.mergeJson(null, content); + String ctxContent = ctx.toJsonString(); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + assertEquals(jsonIn, jsonOut); + } + + @Test + public void test2dMergeJson() throws Exception { + String path = "src/test/resources/2dArray.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + + ctx.mergeJson("testPath", content); + assertEquals("apple", ctx.getAttribute("testPath.[0][0]")); + assertEquals("orange", ctx.getAttribute("testPath.[0][1]")); + assertEquals("banana", ctx.getAttribute("testPath.[0][2]")); + assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.[0][3]")); + assertEquals("4", ctx.getAttribute("testPath.[0]_length")); + assertEquals("squash", ctx.getAttribute("testPath.[1][0]")); + assertEquals("broccoli", ctx.getAttribute("testPath.[1][1]")); + assertEquals("cauliflower", ctx.getAttribute("testPath.[1][2]")); + assertEquals("3", ctx.getAttribute("testPath.[1]_length")); + assertEquals("2", ctx.getAttribute("testPath._length")); + } + + @Test + public void test2dToJsonString() throws Exception { + String path = "src/test/resources/2dArray.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + + ctx.mergeJson("testPath", content); + String ctxContent = ctx.toJsonString("testPath"); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + + try { + assertEquals(jsonIn, jsonOut); + } catch (AssertionError e) { + LOG.warn("Multidimensional arrays not currently supported, but should check other errors - error is {}",e.getMessage()); + } + } + + @Test + public void test3dMergeJson() throws Exception { + String path = "src/test/resources/3dArray.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + ctx.mergeJson("testPath", content); + assertEquals("a", ctx.getAttribute("testPath.[0][0][0]")); + assertEquals("b", ctx.getAttribute("testPath.[0][0][1]")); + assertEquals("c", ctx.getAttribute("testPath.[0][0][2]")); + assertEquals("3", ctx.getAttribute("testPath.[0][0]_length")); + assertEquals("d", ctx.getAttribute("testPath.[0][1][0]")); + assertEquals("e", ctx.getAttribute("testPath.[0][1][1]")); + assertEquals("f", ctx.getAttribute("testPath.[0][1][2]")); + assertEquals("3", ctx.getAttribute("testPath.[0][1]_length")); + assertEquals("2", ctx.getAttribute("testPath.[0]_length")); + assertEquals("x", ctx.getAttribute("testPath.[1][0][0]")); + assertEquals("y", ctx.getAttribute("testPath.[1][0][1]")); + assertEquals("z", ctx.getAttribute("testPath.[1][0][2]")); + assertEquals("3", ctx.getAttribute("testPath.[1][0]_length")); + assertEquals("1", ctx.getAttribute("testPath.[1]_length")); + assertEquals("2", ctx.getAttribute("testPath._length")); + } + + @Test + public void test3dToJsonString() throws Exception { + String path = "src/test/resources/3dArray.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.mergeJson("testPath", content); + String ctxContent = ctx.toJsonString("testPath"); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + + try { + assertEquals(jsonIn, jsonOut); + } catch (AssertionError e) { + LOG.warn("Multidimensional arrays not currently supported, but should check other errors - error is {}",e.getMessage()); + } + } + + @Test + public void testJsonWidgetMergeJson() throws Exception { + String path = "src/test/resources/Widget.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + + ctx.mergeJson("testPath", content); + assertEquals("false", ctx.getAttribute("testPath.widget.debug")); + assertEquals("center", ctx.getAttribute("testPath.widget.image.alignment")); + assertEquals("150", ctx.getAttribute("testPath.widget.image.hOffset")); + assertEquals("moon", ctx.getAttribute("testPath.widget.image.name")); + assertEquals("images/moon.png", ctx.getAttribute("testPath.widget.image.src")); + assertEquals("150", ctx.getAttribute("testPath.widget.image.vOffset")); + assertEquals("center", ctx.getAttribute("testPath.widget.text.alignment")); + assertEquals("Click Me", ctx.getAttribute("testPath.widget.text.data")); + assertEquals("350", ctx.getAttribute("testPath.widget.text.hOffset")); + assertEquals("text1", ctx.getAttribute("testPath.widget.text.name")); + assertEquals("21", ctx.getAttribute("testPath.widget.text.size")); + assertEquals("bold", ctx.getAttribute("testPath.widget.text.style")); + assertEquals(SvcLogicContext.CTX_NULL_VALUE, ctx.getAttribute("testPath.widget.text.vOffset")); + assertEquals("300", ctx.getAttribute("testPath.widget.window.height")); + assertEquals("main_window", ctx.getAttribute("testPath.widget.window.name")); + assertEquals("ONAP Widget", ctx.getAttribute("testPath.widget.window.title")); + assertEquals("200", ctx.getAttribute("testPath.widget.window.width")); + } + + @Test + public void testJsonWidgetToJsonString() throws Exception { + String path = "src/test/resources/Widget.json"; + String content = new String(Files.readAllBytes(Paths.get(path))); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.mergeJson("testPath", content); + String ctxContent = ctx.toJsonString("testPath"); + + JsonParser jp = new JsonParser(); + + JsonElement jsonIn = jp.parse(content); + JsonElement jsonOut = jp.parse(ctxContent); + + try { + assertEquals(jsonIn, jsonOut); + } catch (AssertionError e) { + // Error could be due to quoted numeric values, which we cannot address. + LOG.warn("Test failed, but could be known error condition. Error is {}",e.getMessage()); + } + } +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java new file mode 100644 index 000000000..80df10cee --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicExpressionParserTest.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import junit.framework.TestCase; + +public class SvcLogicExpressionParserTest extends TestCase { + + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicExprListener.class); + + public void testParse() { + try + { + InputStream testStr = getClass().getResourceAsStream("/expression.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + + String testExpr = null; + while ((testExpr = testsReader.readLine()) != null) { + + SvcLogicExpression parsedExpr = SvcLogicExpressionFactory.parse(testExpr); + if (parsedExpr == null) + { + fail("parse("+testExpr+") returned null"); + } + else + { + LOG.info("test expression = ["+testExpr+"] ; parsed expression = ["+parsedExpr.asParsedExpr()+"]"); + + } + } + } + catch (Exception e) + { + e.printStackTrace(); + fail("Caught exception processing test cases"); + } + } + +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java new file mode 100644 index 000000000..f9d33cb16 --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/SvcLogicParserExceptionTest.java @@ -0,0 +1,34 @@ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class SvcLogicParserExceptionTest { + + @Test + public void SvcLogicParserExceptionTest() { + assertNotNull(new SvcLogicParserException()); + + } + + @Test + public void SvcLogicParserExceptionTestString() { + assertNotNull(new SvcLogicParserException("JUnit Test")); + + } + + @Test + public void SvcLogicParserExceptionTestThrowable() { + assertNotNull(new SvcLogicParserException(new Exception("JUnit Test"))); + + } + + @Test + public void SvcLogicParserExceptionTestStringThrowable() { + assertNotNull(new SvcLogicParserException("JUnit Test", new Exception("JUnit Test"))); + + } + + +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java new file mode 100755 index 000000000..37d2fc8c5 --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestMetricLogger.java @@ -0,0 +1,85 @@ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.*; +import java.util.Date; +import java.util.UUID; + +import org.junit.Before; +import org.junit.Test; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.MDC; + +public class TestMetricLogger { + + MetricLogger logger; + + @Before + public void setUp() throws Exception { + logger = new MetricLogger(); + MetricLogger.resetContext(); + } + + @Test + public final void testGetRequestID() { + UUID uuid = UUID.randomUUID(); + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, uuid.toString()); + assertEquals(uuid.toString(),logger.getRequestID()); + } + + @Test + public final void testAsIso8601Date() { + logger.asIso8601(new Date()); + } + + @Test + public final void testAsIso8601Long() { + logger.asIso8601(System.currentTimeMillis()); + } + + @Test + public void formatString() { + String output = logger.formatString("\n"); + assertEquals("",output); + output = logger.formatString("|"); + assertEquals("%7C",output); + output = logger.formatString(null); + assertEquals(null,output); + output = logger.formatString("\t"); + assertEquals(" ", output); + output = logger.formatString("one,two,three,"); + assertEquals("one\\,two\\,three\\,", output); + } + + @Test + public void generateInvocationId() { + logger.logRequest("svcInstance1", "svcName", "svcPartner", "targetEntity", "targetServiceName", "targetVirtualEntity", "hello-world"); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID)); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID)); + } + + @Test + public void generateRequestId() { + logger.logRequest("svcInstance1", "svcName", "svcPartner", "targetEntity", "targetServiceName", "targetVirtualEntity", "hello-world"); + assertNotNull(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)); + } + + @Test + public void overrideInvocationId() { + String oldUUID = UUID.randomUUID().toString(); + MDC.put(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID, oldUUID); + MDC.put(ONAPLogConstants.MDCs.INVOCATION_ID, oldUUID); + + logger.logRequest("svcInstance1", "svcName", "svcPartner", "targetEntity", "targetServiceName", "targetVirtualEntity", "hello-world"); + String newUUID = MDC.get(ONAPLogConstants.MDCs.CLIENT_INVOCATION_ID); + assertFalse(oldUUID.equals(newUUID)); + newUUID = MDC.get(ONAPLogConstants.MDCs.INVOCATION_ID); + assertFalse(oldUUID.equals(newUUID)); + } + + @Test + public void persistRequestId() { + String oldUUID = UUID.randomUUID().toString(); + MDC.put(ONAPLogConstants.MDCs.REQUEST_ID, oldUUID); + assertEquals(oldUUID, MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)); + } +} diff --git a/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java new file mode 100644 index 000000000..2dd83e86d --- /dev/null +++ b/core/sli/common/src/test/java/org/onap/ccsdk/sli/core/sli/TestSvcLogicLoader.java @@ -0,0 +1,38 @@ +package org.onap.ccsdk.sli.core.sli; + +import static org.junit.Assert.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Properties; +import org.junit.Test; + +public class TestSvcLogicLoader { + + @Test + public void testLoadAndActivate() throws IOException, SvcLogicException { + URL propUrl = ITCaseSvcLogicParser.class.getResource("/svclogic.properties"); + + InputStream propStr = ITCaseSvcLogicParser.class.getResourceAsStream("/svclogic.properties"); + + Properties props = new Properties(); + + props.load(propStr); + + SvcLogicStore store = SvcLogicStoreFactory.getSvcLogicStore(props); + + File graphDirectory = new File(getClass().getClassLoader().getResource("graphs").getFile()); + + if (graphDirectory == null) { + fail("Cannot find graphs directory"); + } + SvcLogicLoader loader = new SvcLogicLoader(graphDirectory.getAbsolutePath(), store); + loader.loadAndActivate(); + + + } + + + +} diff --git a/core/sli/common/src/test/resources/2dArray.json b/core/sli/common/src/test/resources/2dArray.json new file mode 100644 index 000000000..2a94b46f4 --- /dev/null +++ b/core/sli/common/src/test/resources/2dArray.json @@ -0,0 +1,4 @@ +[
+ ["apple", "orange", "banana", null],
+ ["squash", "broccoli", "cauliflower"]
+]
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/3dArray.json b/core/sli/common/src/test/resources/3dArray.json new file mode 100644 index 000000000..149955596 --- /dev/null +++ b/core/sli/common/src/test/resources/3dArray.json @@ -0,0 +1,4 @@ +[
+ [["a","b","c"], ["d","e","f"]],
+ [["x","y","z"]]
+]
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/ArrayMenu.json b/core/sli/common/src/test/resources/ArrayMenu.json new file mode 100644 index 000000000..26a24f292 --- /dev/null +++ b/core/sli/common/src/test/resources/ArrayMenu.json @@ -0,0 +1,41 @@ +[{
+ "id": "1",
+ "type": "pizza",
+ "name": "plain",
+ "calories": 1000,
+ "vegetarian": true
+ }, {
+ "id": "2",
+ "type": "pizza",
+ "name": "Tuesday Special",
+ "calories": null,
+ "vegetarian": false,
+ "topping":
+ [{
+ "id": "1",
+ "name": "onion"
+ }, {
+ "id": "2",
+ "name": "pepperoni"
+ }
+ ]
+ }, {
+ "id": "3",
+ "type": "pizza",
+ "name": "House Special",
+ "calories": 1500,
+ "vegetarian": true,
+ "topping":
+ [{
+ "id": "3",
+ "name": "basil"
+ }, {
+ "id": "4",
+ "name": "fresh mozzarella"
+ }, {
+ "id": "5",
+ "name": "tomato"
+ }
+ ]
+ }
+]
diff --git a/core/sli/common/src/test/resources/EmbeddedEscapedJson.json b/core/sli/common/src/test/resources/EmbeddedEscapedJson.json new file mode 100644 index 000000000..dbb6d8d3a --- /dev/null +++ b/core/sli/common/src/test/resources/EmbeddedEscapedJson.json @@ -0,0 +1,16 @@ +{
+ "input": {
+ "parameters":
+ [{
+ "name": "escapedJsonObject",
+ "value": "[{\"id\":\"0.2.0.0\/16\"},{\"id\":\"ge04::\/64\"}]"
+ }, {
+ "name": "password",
+ "value": "Hello\/World"
+ }, {
+ "name": "resourceName",
+ "value": "The\t\"Best\"\tName"
+ }
+ ]
+ }
+}
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/EscapedJson.json b/core/sli/common/src/test/resources/EscapedJson.json new file mode 100644 index 000000000..a7719e819 --- /dev/null +++ b/core/sli/common/src/test/resources/EscapedJson.json @@ -0,0 +1 @@ +{\"widget\":{\"debug\":false,\"window\":{\"title\":\"ONAP Widget\",\"name\":\"main_window\",\"width\":200,\"height\":300},\"image\":{\"src\":\"images\/moon.png\",\"name\":\"moon\",\"hOffset\":150,\"vOffset\":150,\"alignment\":\"center\"},\"text\":{\"data\":\"Click Me\",\"size\":21,\"style\":\"bold\",\"name\":\"text1\",\"hOffset\":350,\"vOffset\":200,\"alignment\":\"center\"}}}
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml b/core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml new file mode 100644 index 000000000..708823efc --- /dev/null +++ b/core/sli/common/src/test/resources/EvcActivateSvcLogic_v100.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="ase" version="1.0.0"> + + + <method rpc="ase-evc-activation" mode="sync"> + <configure adaptor="org.onap.ccsdl.sli.adaptors.emt.EmtAdaptor" + key="$evc-name" activate="true"> + <parameter name="circuit.name" value="$evc-name" /> + <parameter name="topology" value="$topology" /> + <parameter name="leg1.uniCircuitId" value="$evc-leg[0].evc-access-name" /> + <parameter name="leg2.uniCircuitId" value="$evc-leg[1].evc-access-name" /> + <outcome value="success"> + <return status="success" /> + </outcome> + <outcome value="already-active"> + <return status="failure"> + <parameter name="error-code" value="1590" /> + <parameter name="error-message" value="`Circuit already active`" /> + </return> + </outcome> + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1542" /> + <parameter name="error-message" value="Activation failure" /> + </return> + </outcome> + </configure> + </method> + + <method rpc="ase-evc-disconnect-request" mode="sync"> + <configure adaptor="org.onap.ccsdk.sli.adaptors.emt.EmtAdaptor" + key="$evc-name" activate="false"> + <outcome value="success"> + <return status="success" /> + </outcome> + + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1542" /> + <parameter name="error-message" value="De-activation failure" /> + </return> + </outcome> + </configure> + </method> + + +</service-logic> diff --git a/core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml b/core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml new file mode 100644 index 000000000..9a1a14708 --- /dev/null +++ b/core/sli/common/src/test/resources/EvcPortSvcLogic_v100.xml @@ -0,0 +1,263 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="ase" version="1.0.0"> + + <!-- Reserve a port. Returns uni-circuit-id of reserved ase-port --> + <method rpc="ase-port-reserve" mode="sync"> + <switch test="$uni-cir-units"> + <outcome value="Mbps"> + <reserve plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-port" + key="resource-emt-clli == $edge-device-clli and speed >= $uni-cir-value" + pfx="asePort"> + + + <outcome value="success"> + <block> + <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder"> + <parameter name="file" value="/tmp/sample_r1.log" /> + <parameter name="field1" value="__TIMESTAMP__"/> + <parameter name="field2" value="RESERVED"/> + <parameter name="field3" value="$asePort.uni_circuit_id"/> + </record> + <return status="success"> + <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" /> + </return> + </block> + + </outcome> + + <outcome value="not-found"> + <return status="failure"> + <parameter name="error-code" value="1010" /> + <parameter name="error-message" value="No ports found that match criteria" /> + </return> + </outcome> + + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1010" /> + <parameter name="error-message" + value="Error encountered trying to reserve port" /> + </return> + </outcome> + + </reserve> + </outcome> + <outcome value="Gbps"> + <reserve plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-port" + key="resource-emt-clli == $edge-device-clli and speed >= 1000 * $uni-cir-value" + pfx="asePort"> + + + <outcome value="success"> + <block> + <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder"> + <parameter name="file" value="/tmp/sample_r1.log" /> + <parameter name="field1" value="__TIMESTAMP__"/> + <parameter name="field2" value="RESERVED"/> + <parameter name="field3" value="$asePort.uni_circuit_id"/> + </record> + <return status="success"> + <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" /> + </return> + </block> + </outcome> + + <outcome value="not-found"> + <return status="failure"> + <parameter name="error-code" value="1010" /> + <parameter name="error-message" value="No ports found that match criteria" /> + </return> + </outcome> + <outcome value=""> + <return status="failure"> + <parameter name="error-code" value="1012" /> + <parameter name="error-message" + value="Error encountered trying to reserve port" /> + </return> + </outcome> + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1010" /> + <parameter name="error-message" + value="Error encountered trying to reserve port" /> + </return> + </outcome> + </reserve> + </outcome> + </switch> + </method> + + <!-- One step provisioning/activation command. Allocates a local resource, + then configures it on device --> + <method rpc="ase-port-activate-request" mode="sync"> + + <allocate plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-port" key="uni-circuit-id == $uni-circuit-id" pfx="asePort"> + + <outcome value="success"> + <configure adaptor="org.onap.ccsdk.sli.adaptors.emt.EmtAdaptor" + key="$uni-circuit-id" activate="true"> + <parameter name="circuit.id" value="$uni-circuit-id" /> + <parameter name="subscriber.name" value="$subscriber-name" /> + <parameter name="emt.clli" value="$edge-device-clli" /> + <parameter name="port.tagging" value="$port-tagging" /> + <parameter name="port.mediaSpeed" value="$media-speed" /> + <parameter name="location.state" value="$uni-location-state" /> + <parameter name="location.city" value="$uni-location-city" /> + <parameter name="cosCategory" value="$cos-category" /> + <parameter name="gosProfile" value="$gos-profile" /> + <parameter name="lldp" value="$asePort.resource-lldp" /> + <parameter name="mtu" value="$asePort.resource-mtu" /> + <outcome value="success"> + <block> + <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder"> + <parameter name="file" value="/tmp/sample_r1.log" /> + <parameter name="field1" value="__TIMESTAMP__"/> + <parameter name="field2" value="ACTIVE"/> + <parameter name="field3" value="$uni-circuit-id"/> + </record> + <return status="success"> + <parameter name="edge-device-clli" value="$asePort.resource-emt-clli" /> + </return> + </block> + + </outcome> + <outcome value="already-active"> + <return status="failure"> + <parameter name="error-code" value="1590" /> + <parameter name="error-message" value="Port already active" /> + </return> + </outcome> + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1542" /> + <parameter name="error-message" value="Activation failure" /> + </return> + </outcome> + </configure> + </outcome> + + <outcome value="not-found"> + + <return status="failure"> + <parameter name="error-code" value="1220" /> + <parameter name="error-message" value="Circuit not found" /> + </return> + + </outcome> + + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1230" /> + <parameter name="error-message" value="Error occurred trying to find circuit" /> + </return> + </outcome> + </allocate> + </method> + + + + <!-- Change provisioning w/o activation --> + <method rpc="ase-change-port-prov-request" mode="sync"> + <allocate plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-port" key="uni-circuit-id == $uni-circuit-id" pfx="asePort"> + + <outcome value="success"> + <return status="success"> + <parameter name="edge-device-clli" value="$asePort.resource-emt-clli" /> + </return> + </outcome> + + <outcome value="not-found"> + <return status="failure"> + <parameter name="error-code" value="1220" /> + <parameter name="error-message" value="Circuit not found" /> + </return> + </outcome> + + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1230" /> + <parameter name="error-message" value="Error occurred trying to find circuit" /> + </return> + </outcome> + </allocate> + </method> + + + + + <!-- Release port --> + + <method rpc="ase-release-port-request" mode="sync"> + <exists plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-evc" key="uni-circuit-id == $uni-circuit-id"> + + <outcome value="true"> + <return status="failure"> + <parameter name="error-code" value="1130" /> + <parameter name="error-message" + value="Cannot release port - used in existing EVC" /> + </return> + </outcome> + <outcome value="false"> + <release plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-port" key="uni-circuit-id == $uni-circuit-id"> + <outcome value="success"> + <block> + <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder"> + <parameter name="file" value="/tmp/sample_r1.log" /> + <parameter name="field1" value="__TIMESTAMP__"/> + <parameter name="field2" value="RELEASED"/> + <parameter name="field3" value="$uni-circuit-id"/> + </record> + <return status="success"/> + </block> + </outcome> + + <outcome value="not-found"> + <return status="failure"> + <parameter name="error-code" value="1110" /> + <parameter name="error-message" value="No port found for this uni-circuit-id" /> + </return> + </outcome> + + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1130" /> + <parameter name="error-message" + value="Error encountered trying to release port" /> + </return> + </outcome> + </release> + </outcome> + </exists> + </method> + +</service-logic> + diff --git a/core/sli/common/src/test/resources/JsonObject.json b/core/sli/common/src/test/resources/JsonObject.json new file mode 100644 index 000000000..0578368f8 --- /dev/null +++ b/core/sli/common/src/test/resources/JsonObject.json @@ -0,0 +1,5 @@ +{
+ "aaa": "123",
+ "bbb": "xyz",
+ "c.d": "abc"
+}
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/ObjectMenu.json b/core/sli/common/src/test/resources/ObjectMenu.json new file mode 100644 index 000000000..56f842d48 --- /dev/null +++ b/core/sli/common/src/test/resources/ObjectMenu.json @@ -0,0 +1,43 @@ +{
+ "menu": [{
+ "id": "1",
+ "type": "pizza",
+ "name": "plain",
+ "calories": 1000,
+ "vegetarian": true
+ }, {
+ "id": "2",
+ "type": "pizza",
+ "name": "Tuesday Special",
+ "calories": 2000,
+ "vegetarian": false,
+ "topping":
+ [{
+ "id": "1",
+ "name": "onion"
+ }, {
+ "id": "2",
+ "name": "pepperoni"
+ }
+ ]
+ }, {
+ "id": "3",
+ "type": "pizza",
+ "name": "House Special",
+ "calories": 1500,
+ "vegetarian": true,
+ "topping":
+ [{
+ "id": "3",
+ "name": "basil"
+ }, {
+ "id": "4",
+ "name": "fresh mozzarella"
+ }, {
+ "id": "5",
+ "name": "tomato"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/sli/common/src/test/resources/QuotedValues.json b/core/sli/common/src/test/resources/QuotedValues.json new file mode 100644 index 000000000..8bf91c66b --- /dev/null +++ b/core/sli/common/src/test/resources/QuotedValues.json @@ -0,0 +1,43 @@ +{
+ "menu": [{
+ "id": "1",
+ "type": "pizza",
+ "name": "plain",
+ "calories": "1000",
+ "vegetarian": true
+ }, {
+ "id": "2",
+ "type": "pizza",
+ "name": "Tuesday Special",
+ "calories": "2000",
+ "vegetarian": false,
+ "topping":
+ [{
+ "id": "1",
+ "name": "onion"
+ }, {
+ "id": "2",
+ "name": "pepperoni"
+ }
+ ]
+ }, {
+ "id": "3",
+ "type": "pizza",
+ "name": "House Special",
+ "calories": "1500",
+ "vegetarian": true,
+ "topping":
+ [{
+ "id": "3",
+ "name": "basil"
+ }, {
+ "id": "4",
+ "name": "fresh mozzarella"
+ }, {
+ "id": "5",
+ "name": "tomato"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml b/core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml new file mode 100644 index 000000000..cee027f75 --- /dev/null +++ b/core/sli/common/src/test/resources/ReleasePortSvcLogic_v101.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="ase" version="1.0.1"> + + <!-- Updated release port logic : deactivate the released port on the EMT --> + <method rpc="ase-release-port-request" mode="sync"> + <exists plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-evc" key="uni-circuit-id == $uni-circuit-id"> + + <outcome value="true"> + <return status="failure"> + <parameter name="error-code" value="1130" /> + <parameter name="error-message" + value="Cannot release port - used in existing EVC" /> + </return> + </outcome> + <outcome value="false"> + <release plugin="org.onap.ccsdk.sli.adaptors.sample.SampleResource" + resource="ase-port" key="uni-circuit-id == $uni-circuit-id"> + <outcome value="success"> + <configure adaptor="org.onap.ccsdk.sli.adaptors.emt.EmtAdaptor" + key="$uni-circuit-id" activate="false"> + + <outcome value="success"> + <block> + <record plugin="org.onap.ccsdk.sli.core.sli.recording.FileRecorder"> + <parameter name="file" value="/tmp/sample_r1.log" /> + <parameter name="field1" value="__TIMESTAMP__" /> + <parameter name="field2" value="RELEASED" /> + <parameter name="field3" value="$uni-circuit-id" /> + </record> + <return status="success"> + <parameter name="uni-circuit-id" value="$asePort.uni_circuit_id" /> + </return> + </block> + </outcome> + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1130" /> + <parameter name="error-message" + value="Error encountered trying to de-activate port" /> + </return> + </outcome> + </configure> + </outcome> + + <outcome value="not-found"> + <return status="failure"> + <parameter name="error-code" value="1110" /> + <parameter name="error-message" value="No port found for this uni-circuit-id" /> + </return> + </outcome> + + <outcome value="Other"> + <return status="failure"> + <parameter name="error-code" value="1130" /> + <parameter name="error-message" + value="Error encountered trying to release port" /> + </return> + </outcome> + </release> + </outcome> + </exists> + </method> + +</service-logic> + diff --git a/core/sli/common/src/test/resources/Widget.json b/core/sli/common/src/test/resources/Widget.json new file mode 100644 index 000000000..6b90907ce --- /dev/null +++ b/core/sli/common/src/test/resources/Widget.json @@ -0,0 +1,27 @@ +{
+ "widget": {
+ "debug": false,
+ "window": {
+ "title": "ONAP Widget",
+ "name": "main_window",
+ "width": 200,
+ "height": 300
+ },
+ "image": {
+ "src": "images/moon.png",
+ "name": "moon",
+ "hOffset": 150,
+ "vOffset": 150,
+ "alignment": "center"
+ },
+ "text": {
+ "data": "Click Me",
+ "size": 21,
+ "style": "bold",
+ "name": "text1",
+ "hOffset": 350,
+ "vOffset": null,
+ "alignment": "center"
+ }
+ }
+}
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/bad_neutron_logic_v11.xml b/core/sli/common/src/test/resources/bad_neutron_logic_v11.xml new file mode 100644 index 000000000..e6ec8614b --- /dev/null +++ b/core/sli/common/src/test/resources/bad_neutron_logic_v11.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="neutron" version="1.0.0"> + + <method rpc="canCreateNetwork" mode="sync"> + <switch test="true"> + <return status="success"> + <parameter name="error-code" value="200" /> + </return> + </switch> + </method> + + <method rpc="networkCreated" mode="sync"> + <switch test="`(length($network.segment[0].provider-physical-network) >= 5) and (substr($network.segment[0].provider-physical-network,0,5) == 'dvspg')`"> + <outcome value="true"> + <block> + <set> + <parameter name="vlanlist" value="`$network.segment[0].provider-segmentation-id`"/> + </set> + <for index="i" start="1" end="`$network.num-segments`"> + <set> + <parameter name="vlanlist" value="`$vlanlist+','+$network.segment[$i].provider-segmentation-id`"/> + </set> + </for> + + <switch test="true"> + <return status="success"/> + </switch> + </block> + </outcome> + <outcome value="Other"> + <return status="success"> + <parameter name="error-code" value="200"/> + </return> + </outcome> + </switch> + </method> + +</service-logic> diff --git a/core/sli/common/src/test/resources/dblib.properties b/core/sli/common/src/test/resources/dblib.properties new file mode 100755 index 000000000..f08dce7a0 --- /dev/null +++ b/core/sli/common/src/test/resources/dblib.properties @@ -0,0 +1,14 @@ +org.onap.ccsdk.sli.dbtype=jdbc +org.onap.ccsdk.sli.jdbc.hosts=sdnctldb01,sdnctldb02 +org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:test;create=true +org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver +org.onap.ccsdk.sli.jdbc.database=test +org.onap.ccsdk.sli.jdbc.user=test +org.onap.ccsdk.sli.jdbc.password=test +org.onap.ccsdk.sli.jdbc.connection.name=sdnctldb01 + +org.onap.ccsdk.sli.jdbc.connection.timeout=50 +org.onap.ccsdk.sli.jdbc.request.timeout=100 +org.onap.ccsdk.sli.jdbc.limit.init=10 +org.onap.ccsdk.sli.jdbc.limit.min=10 +org.onap.ccsdk.sli.jdbc.limit.max=20 diff --git a/core/sli/common/src/test/resources/expression.tests b/core/sli/common/src/test/resources/expression.tests new file mode 100755 index 000000000..c352e9b08 --- /dev/null +++ b/core/sli/common/src/test/resources/expression.tests @@ -0,0 +1,19 @@ +$uni-circuit-id +$asePort +length($uni-circuit-id) > 0 +$asePort.uni-circuit-id +$uni-cir-units * 1000 * 100 / 100 +$uni-cir-units / 1000 +$uni-cir-units - 100 +$uni-cir-units + 100 +(value * 3 - $arg1 > 0) and (length($uni-circuit-id) == 0) +'pg-'+$network.name +$network.segment[0].provider-physical-network +length($network_segment[0].provider-physical-network) >= 5 +substr($network_segment[0].provider-physical-network,0,5) == 'dvspg' +length($network_segment[0].provider-physical-network) >= 5 and substr($network_segment[0].provider-physical-network,0,5) == 'dvspg' +(length($network_segment[0].provider-physical-network) >= 5) and (substr($network_segment[0].provider-physical-network,0,5) == 'dvspg') +4-2-2 +1+1 +1 +1+2*3-4 diff --git a/core/sli/common/src/test/resources/graphs/sliapi/graph.versions b/core/sli/common/src/test/resources/graphs/sliapi/graph.versions new file mode 100644 index 000000000..d72920a43 --- /dev/null +++ b/core/sli/common/src/test/resources/graphs/sliapi/graph.versions @@ -0,0 +1 @@ +sli healthcheck 1.0.0 sync diff --git a/core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml b/core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml new file mode 100644 index 000000000..d512f546f --- /dev/null +++ b/core/sli/common/src/test/resources/graphs/sliapi/sli_healthcheck.xml @@ -0,0 +1,27 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" module='sli' version='1.0.0'><method rpc='healthcheck' mode='sync'> +<set> +<parameter name='error-code' value='200' /> +<parameter name='error-message' value='SDN-C is healthy'/> +<parameter name='ack-final' value='Y'/> +</set></method></service-logic> diff --git a/core/sli/common/src/test/resources/l3sdn_logic_v10.xml b/core/sli/common/src/test/resources/l3sdn_logic_v10.xml new file mode 100644 index 000000000..58a420f9e --- /dev/null +++ b/core/sli/common/src/test/resources/l3sdn_logic_v10.xml @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============LICENSE_START======================================================= + ONAP : CCSDK ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required + by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. ============LICENSE_END========================================================= --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="neutron" version="1.0.0"> + + <method rpc="canCreateNetwork" mode="sync"> + <return status="success"> + <parameter name="error-code" value="200" /> + </return> + </method> + + <method rpc="switchTester" mode="sync"> + + <switch test="`$test-value`"> + <outcome value=""> + <return status="success"> + <parameter name="visited-outcome" value="empty string" /> + </return> + </outcome> + <outcome value="Other"> + <return status="success"> + <parameter name="visited-outcome" value="Other" /> + </return> + </outcome> + </switch> + + + </method> + + <method rpc="forRecordTester" mode="sync"> + <for index="i" start="0" end="1"> + <record plugin="org.onap.ccsdk.sli.core.sli.provider.DummyRecorder"> + <parameter name="level" value="INFO"/> + <parameter name="field1" value="`forRecordTester message $i`"/> + </record> + </for> + </method> + + <method rpc="whileNodeTester" mode="sync"> + <while test="`$test-value`"> + <break/> + </while> + + </method> + + <method rpc="resourceTester" mode="sync"> + <block> + <set> + <parameter name='resource-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' /> + </set> + + <save plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"> + <parameter name="sample-key" value="resourceTester.status"/> + <parameter name="sample-value" value="FAILED"/> + </save> + + <update plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"> + <parameter name="sample-key" value="resourceTester.status"/> + <parameter name="sample-value" value="PASSED"/> + </update> + + <get-resource plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'" pfx="sample"/> + + <exists plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <is-available plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <release plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + + <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <notify plugin="`$resource-plugin`" resource="sample" action="RESERVE"/> + + <delete plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + + + </block> + </method> + + <method rpc="configureTester" mode="sync"> + <block> + <set> + <parameter name='configure-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' /> + </set> + <configure adaptor="`$configure-plugin`" key="dummy" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="FAILURE" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="dummy" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="FAILURE" activate="false"> + <parameter name="field1" value="1"/> + </configure> + + </block> + </method> + + + <method rpc="javaPluginTester" mode="sync"> + <block> + <set> + <parameter name='java-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' /> + </set> + <execute plugin="`$java-plugin`" method="dummy"/> + </block> + </method> + + <method rpc="allNodesTester" mode="sync"> + <block> + <set> + <parameter name='resource-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' /> + <parameter name='configure-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' /> + <parameter name='java-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' /> + + </set> + + <call rpc="switchTester" mode="sync" /> + + <call rpc="forRecordTester" mode="sync"/> + + <call rpc="resourceTester" mode="sync"/> + + <call rpc="configureTester" mode="sync"/> + + <call rpc="javaPluginTester" mode="sync"/> + + <call rpc="whileNodeTester" mode="sync"/> + + </block> + </method> + + <method rpc="networkCreated" mode="sync"> + <switch + test="length($network.segment[0].provider-physical-network) >= 5 and substr($network.segment[0].provider-physical-network,0,5) == 'dvspg'"> + <outcome value="true"> + <block> + <set> + <parameter name="$vlanlist" + value="$network.segment[0].provider-segmentation-id" /> + </set> + <for index="i" start="1" end="$network.num-segments"> + <set> + <parameter name="$vlanlist" + value="eval($vlanlist+','+$network.segment[i].provider-segmentation-id)" /> + </set> + </for> + + </block> + </outcome> + <outcome value="Other"> + <return status="success"> + <parameter name="error-code" value="200" /> + </return> + </outcome> + </switch> + </method> + +</service-logic> diff --git a/core/sli/common/src/test/resources/log4j2.properties b/core/sli/common/src/test/resources/log4j2.properties new file mode 100644 index 000000000..3a5d8ef76 --- /dev/null +++ b/core/sli/common/src/test/resources/log4j2.properties @@ -0,0 +1,39 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2020 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +status = error +name = PropertiesConfig + +filters = threshold + +filter.threshold.type = ThresholdFilter +filter.threshold.level = debug + +appenders = console + +appender.console.type = Console +appender.console.name = STDOUT +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n + +rootLogger.level = debug +rootLogger.appenderRefs = stdout +rootLogger.appenderRef.stdout.ref = STDOUT diff --git a/core/sli/common/src/test/resources/mergetest.xml b/core/sli/common/src/test/resources/mergetest.xml new file mode 100644 index 000000000..95c26da27 --- /dev/null +++ b/core/sli/common/src/test/resources/mergetest.xml @@ -0,0 +1,54 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<multicast-parameters xmlns="org.onap.sdnc:test"> + <vpn-v4-multicast-enabled>Y</vpn-v4-multicast-enabled> + <v4-multicast> + <v4-pim-ssm-default-range>Y</v4-pim-ssm-default-range> + <v4-data-mdt>11.11.11.11</v4-data-mdt> + <v4-data-mdt-wildcard-mask>2.2.2.2</v4-data-mdt-wildcard-mask> + <max-routes-limit>100</max-routes-limit> + <v4-default-mdt>1.1.1.1</v4-default-mdt> + <v4-pim-sm-static-override>N</v4-pim-sm-static-override> + <v4-pim-ssm-groups> + <v4-pim-ssm-group-address>4.4.4.4</v4-pim-ssm-group-address> + </v4-pim-ssm-groups> + <v4-pim-ssm-groups> + <v4-pim-ssm-group-address>3.3.3.3</v4-pim-ssm-group-address> + </v4-pim-ssm-groups> + <v4-static-rp-triplet> + <rp-address>8.8.8.8</rp-address> + <c-groups> + <c-group-address-prefix>10.10.10.10</c-group-address-prefix> + </c-groups> + <c-groups> + <c-group-address-prefix>9.9.9.9</c-group-address-prefix> + </c-groups> + </v4-static-rp-triplet> + <v4-static-rp-triplet> + <rp-address>7.7.7.7</rp-address> + <c-groups> + <c-group-address-prefix>6.6.6.6</c-group-address-prefix> + </c-groups> + <c-groups> + <c-group-address-prefix>5.5.5.5</c-group-address-prefix> + </c-groups> + </v4-static-rp-triplet> + </v4-multicast> +</multicast-parameters> diff --git a/core/sli/common/src/test/resources/neutron_logic_v10.xml b/core/sli/common/src/test/resources/neutron_logic_v10.xml new file mode 100644 index 000000000..74088036b --- /dev/null +++ b/core/sli/common/src/test/resources/neutron_logic_v10.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="neutron" version="1.0.0"> + + <method rpc="canCreateNetwork" mode="sync"> + <return status="success"> + <parameter name="error-code" value="200" /> + </return> + </method> + + <method rpc="networkCreated" mode="sync"> + <switch test="`(length($network.segment[0].provider-physical-network) >= 5) and (substr($network.segment[0].provider-physical-network,0,5) == 'dvspg')`"> + <outcome value="true"> + <block> + <set> + <parameter name="vlanlist" value="`$network.segment[0].provider-segmentation-id`"/> + </set> + <for index="i" start="1" end="`$network.num-segments`"> + <set> + <parameter name="vlanlist" value="`$vlanlist+','+$network.segment[$i].provider-segmentation-id`"/> + </set> + </for> + + </block> + </outcome> + <outcome value="Other"> + <return status="success"> + <parameter name="error-code" value="200"/> + </return> + </outcome> + </switch> + </method> + +</service-logic> diff --git a/core/sli/common/src/test/resources/nonsense.xml b/core/sli/common/src/test/resources/nonsense.xml new file mode 100644 index 000000000..c30c6bfc6 --- /dev/null +++ b/core/sli/common/src/test/resources/nonsense.xml @@ -0,0 +1,24 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<non> +<sense>Hello world</sense> +</non> diff --git a/core/sli/common/src/test/resources/parser-bad.tests b/core/sli/common/src/test/resources/parser-bad.tests new file mode 100755 index 000000000..82913afc2 --- /dev/null +++ b/core/sli/common/src/test/resources/parser-bad.tests @@ -0,0 +1,3 @@ +bad_neutron_logic_v11.xml +EvcActivateSvcLogic_v100.xml +nonsense.xml
\ No newline at end of file diff --git a/core/sli/common/src/test/resources/parser-good.tests b/core/sli/common/src/test/resources/parser-good.tests new file mode 100755 index 000000000..4147fdb62 --- /dev/null +++ b/core/sli/common/src/test/resources/parser-good.tests @@ -0,0 +1,3 @@ +ReleasePortSvcLogic_v101.xml +neutron_logic_v10.xml +l3sdn_logic_v10.xml diff --git a/core/sli/common/src/test/resources/simplelogger.properties b/core/sli/common/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..73e4d3a99 --- /dev/null +++ b/core/sli/common/src/test/resources/simplelogger.properties @@ -0,0 +1,24 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +org.slf4j.simpleLogger.defaultLogLevel=info +org.slf4j.simplelogger.log.org.onap.ccsdk.sli.core.sli.SvcLogicContext=debug +org.slf4j.simplelogger.log.SvcLogicContext=debug diff --git a/core/sli/common/src/test/resources/svclogic.properties b/core/sli/common/src/test/resources/svclogic.properties new file mode 100644 index 000000000..426960f76 --- /dev/null +++ b/core/sli/common/src/test/resources/svclogic.properties @@ -0,0 +1,27 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +org.onap.ccsdk.sli.dbtype = jdbc +org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:sdnctl;create=true +org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver +org.onap.ccsdk.sli.jdbc.database = sdnctl +org.onap.ccsdk.sli.jdbc.user = test +org.onap.ccsdk.sli.jdbc.password = test diff --git a/core/sli/common/src/test/resources/svclogic.sh b/core/sli/common/src/test/resources/svclogic.sh new file mode 100644 index 000000000..67977c3d9 --- /dev/null +++ b/core/sli/common/src/test/resources/svclogic.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +MYSQL_JDBC_DRIVER=${MYSQL_JDBC_DRIVER:-/home/ubuntu/mysql-connector-java-5.1.38.1.jar} +SLI_COMMON_TARGETDIR=${SLI_COMMON_TARGETDIR:-/home/ubuntu/opendaylight/plugins} +#SLI_COMMON_TARGETDIR=${SLI_COMMON_TARGETDIR:-/home/ubuntu/git/sdnctl/sli/common/target} +SLI_VERSION=${SLI_VERSION:-1.1.0-SNAPSHOT} +SLI_COMMON_JAR=${SLI_COMMON_JAR:=${SLI_COMMON_TARGETDIR}/sli-common-${SLI_VERSION}.jar} + +echo SLI_COMMON_JAR is $SLI_COMMON_JAR + +java -cp ${CLASSPATH}:${MYSQL_JDBC_DRIVER}:${SLI_COMMON_JAR} org.onap.ccsdk.sli.core.sli.SvcLogicParser $* diff --git a/core/sli/installer/pom.xml b/core/sli/installer/pom.xml new file mode 100755 index 000000000..40776bdcf --- /dev/null +++ b/core/sli/installer/pom.xml @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-installer</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name> + + <properties> + <application.name>ccsdk-sli</application.name> + <features.boot>${application.name}</features.boot> + <features.repositories>mvn:org.onap.ccsdk.sli.core/${features.boot}/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>dblib-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + <version>${project.version}</version> + </dependency> + + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <attach>true</attach> + <finalName>${application.name}-${project.version}-installer</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + <appendAssemblyId>false</appendAssemblyId> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <includeGroupIds>org.onap.ccsdk.sli.core</includeGroupIds> + <excludeArtifactIds>utils-provider,dblib-provider</excludeArtifactIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals><!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/core/sli/installer/src/assembly/assemble_installer_zip.xml b/core/sli/installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..2d3c0606d --- /dev/null +++ b/core/sli/installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>bin</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml b/core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..6a21012dc --- /dev/null +++ b/core/sli/installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,42 @@ +<!-- ============LICENSE_START======================================================= + ONAP : CCSDK + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required + by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. + ============LICENSE_END========================================================= --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>repo</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level as this + file is suppose to be unzip on top of a karaf distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/core/sli/installer/src/main/resources/scripts/install-feature.sh b/core/sli/installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..74b95b5c8 --- /dev/null +++ b/core/sli/installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} feature:install ${features.boot} diff --git a/core/sli/model/pom.xml b/core/sli/model/pom.xml new file mode 100755 index 000000000..0b859e7d2 --- /dev/null +++ b/core/sli/model/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-model</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name> + + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId> + <artifactId>rfc6991</artifactId> + </dependency> + + + </dependencies> +</project> diff --git a/core/sli/model/src/main/yang/sliapi.yang b/core/sli/model/src/main/yang/sliapi.yang new file mode 100755 index 000000000..a7d52928b --- /dev/null +++ b/core/sli/model/src/main/yang/sliapi.yang @@ -0,0 +1,123 @@ +module SLI-API { + + yang-version 1; + + namespace "org:onap:ccsdk:sli:core:sliapi"; + + prefix sample; + + import ietf-inet-types { prefix "inet"; revision-date 2013-07-15; } + + organization "ONAP"; + + contact + "Dan Timoney"; + + description + "Defines API to service logic interpreter"; + + revision "2016-11-10" { + description + "REST API to Service Logic Interpreter"; + } + + grouping parameter-setting { + description + "Parameter setting"; + + leaf parameter-name { + type string; + description "Parameter name"; + } + + leaf int-value { + type int32; + } + leaf string-value { + type string; + } + leaf boolean-value { + type boolean; + } + leaf ipaddress-value { + type inet:ip-address; + } + leaf ipprefix-value { + type inet:ip-prefix; + } + leaf port-number { + type inet:port-number; + } + leaf dscp { + type inet:dscp; + } + } + + grouping response-fields { + leaf response-code { + type string; + } + leaf ack-final-indicator { + type string; + } + leaf response-message { + type string; + } + leaf context-memory-json { + type string; + } + } + + container test-results { + description "Test results"; + + list test-result { + key "test-identifier"; + + leaf test-identifier { + type string; + } + + leaf-list results { + type string; + } + } + } + + rpc execute-graph { + description " Method to add a new parameter."; + input { + + leaf module-name { + type string; + } + + leaf rpc-name { + type string; + } + + leaf mode { + type enumeration { + enum sync; + enum async; + } + } + + list sli-parameter { + key "parameter-name"; + uses parameter-setting; + } + } + + output { + uses response-fields; + } + } + + rpc healthcheck { + output { + uses response-fields; + } + } + +} diff --git a/core/sli/model/src/main/yang/test-model@2019-07-23.yang b/core/sli/model/src/main/yang/test-model@2019-07-23.yang new file mode 100755 index 000000000..fc8e8b007 --- /dev/null +++ b/core/sli/model/src/main/yang/test-model@2019-07-23.yang @@ -0,0 +1,210 @@ +module test-model { + + yang-version 1; + + namespace "org:onap:ccsdk:sli:core:testmodel"; + + prefix sample; + + import ietf-inet-types { prefix "inet"; revision-date 2013-07-15; } + + organization "ONAP"; + + contact + "Test Author"; + + description + "A test model not used in business flows"; + + revision "2019-07-23" { + description + "First release of the test model"; + } + + identity sample-identity { + description + "Base identity"; + } + + typedef percentage { + type uint8 { + range "0 .. 100"; + } + description "represents a percentage"; + } + + grouping builtin { + leaf sample-binary { + type binary; + } + leaf sample-bits { + type bits{ + bit fan-running { + position 0; + } + bit hd-led { + position 1; + } + bit power-led { + position 2; + } + } + } + leaf sample-boolean { + type boolean; + } + leaf sample-decimal64 { + type decimal64{ + fraction-digits 1; + } + } + leaf sample-empty { + type empty; + } + leaf sample-enumeration { + type enumeration{ + enum "shelf.slot.port"; + enum "not available"; + enum "CURRENTLY_AVAILABLE"; + enum "200OK"; + enum "hyphen-separated-value"; + } + } + leaf sample-identityref { + type identityref { + base "sample-identity"; + } + } + leaf sample-int8 { + type int8; + } + leaf sample-int16 { + type int16; + } + leaf sample-int32 { + type int32; + } + leaf sample-int64 { + type int64; + } + leaf sample-leafref { + type leafref { + path "../sample-boolean"; + } + } + leaf sample-string { + type string; + } + leaf sample-uint8 { + type uint8; + } + leaf sample-uint16 { + type uint16; + } + leaf sample-uint32 { + type uint32; + } + leaf sample-uint64 { + type uint64; + } + leaf sample-union { + type union { + type int32; + type enumeration { + enum "unbounded"; + } + } + } + leaf percent-completed { + type percentage; + } + } + + grouping inet-types-grouping { + leaf ip-version { + type inet:ip-version; + } + leaf dscp { + type inet:dscp; + } + leaf port-number { + type inet:port-number; + } + leaf ipv6-flow-label { + type inet:ipv6-flow-label; + } + leaf as-number { + type inet:as-number; + } + leaf ip-address { + type inet:ip-address; + } + leaf ipv4-address { + type inet:ipv4-address; + } + leaf ipv6-address { + type inet:ipv6-address; + } + leaf ip-address-no-zone { + type inet:ip-address-no-zone; + } + leaf ipv4-address-no-zone { + type inet:ipv4-address-no-zone; + } + leaf ipv6-address-no-zone { + type inet:ipv6-address-no-zone; + } + leaf ip-prefix { + type inet:ip-prefix; + } + leaf ipv4-prefix { + type inet:ipv4-prefix; + } + leaf ipv6-prefix { + type inet:ipv6-prefix; + } + leaf domain-name { + type inet:domain-name; + } + leaf host { + type inet:host; + } + leaf uri { + type inet:uri; + } + anyxml data; + } + + container sample-container { + leaf customer-name { + type string; + } + + leaf-list customer-nicknames { + type string; + } + + container login { + leaf message { + type string; + description + "Message given at start of login session"; + } + + list customer-addresses { + key "address-name"; + leaf address-name { + type string; + } + leaf street-address { + type string; + } + leaf state { + type string; + } + } + } + uses builtin; + uses inet-types-grouping; + } +} diff --git a/core/sli/pom.xml b/core/sli/pom.xml new file mode 100755 index 000000000..cfb7656d1 --- /dev/null +++ b/core/sli/pom.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>odlparent-lite</artifactId> + <version>2.1.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>ccsdk-sli-core :: sli</name> + <description>The Service Logic Interpreter (SLI) allows service planners to design the flow of logic within the SDN controller in an XML format, without a need for custom Java code. </description> + <organization> + <name>ONAP</name> + </organization> + + <modules> + <module>provider-base</module> + <module>model</module> + <module>common</module> + <module>provider</module> + <module>installer</module> + </modules> +</project> diff --git a/core/sli/provider-base/pom.xml b/core/sli/provider-base/pom.xml new file mode 100644 index 000000000..eedce9154 --- /dev/null +++ b/core/sli/provider-base/pom.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider-base</artifactId> + <version>1.1.1-SNAPSHOT</version> + + <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <sonar.coverage.jacoco.xmlReportPaths>${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml,${project.reporting.outputDirectory}/jacoco-it/jacoco.xml,../provider/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>dblib-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <!-- Testing Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + + </dependencies> +</project> diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java new file mode 100644 index 000000000..031beba2a --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/AbstractSvcLogicNodeExecutor.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractSvcLogicNodeExecutor { + protected SvcLogicResolver resolver; + public abstract SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException; + + private static final Logger LOG = LoggerFactory.getLogger(AbstractSvcLogicNodeExecutor.class); + protected static final String PARAMETER_DEBUG_PATTERN = "Parameter: ({}) resolves to: ({}) which came from the expression: ({})"; + protected static final String SETTING_DEBUG_PATTERN = "Setting context attribute: ({}) to: ({}) which came from the expression: ({})"; + + protected String evaluateNodeTest(SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + if (node == null) { + return null; + } + + return (SvcLogicExpressionResolver.evaluate(node.getAttribute("test"), + node, ctx)); + + } + + public void setResolver(SvcLogicResolver resolver) { + this.resolver = resolver; + } + + protected SvcLogicAdaptor getAdaptor(String adaptorName) { + return resolver.getSvcLogicAdaptor(adaptorName); + } + + protected SvcLogicResource getSvcLogicResource(String resourceName) { + return resolver.getSvcLogicResource(resourceName); + } + + protected SvcLogicRecorder getSvcLogicRecorder(String recorderName) { + return resolver.getSvcLogicRecorder(recorderName); + } + + protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName){ + return resolver.getSvcLogicJavaPlugin(pluginName); + } + + protected SvcLogicNode getNextNode(SvcLogicNode node, String outValue) { + SvcLogicNode nextNode = node.getOutcomeValue(outValue); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("about to execute " + outValue + " branch"); + } + return (nextNode); + } + + nextNode = node.getOutcomeValue("Other"); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("about to execute Other branch"); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("no " + outValue + " or Other branch found"); + } + } + return (nextNode); + } + + protected Map<String, String> getResolvedParameters(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException{ + Map<String, String> parmMap = new HashMap<>(); + + Set<Map.Entry<String, SvcLogicExpression>> parmSet = node + .getParameterSet(); + + for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parmSet + .iterator(); iter.hasNext();) { + Map.Entry<String, SvcLogicExpression> curEnt = iter.next(); + String curName = curEnt.getKey(); + + SvcLogicExpression curExpr = curEnt.getValue(); + String curExprValue = SvcLogicExpressionResolver.evaluate(curExpr, node, ctx); + LOG.trace(PARAMETER_DEBUG_PATTERN, curName, curExprValue, curExpr); + parmMap.put(curName, curExprValue); + } + + return parmMap; + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java new file mode 100644 index 000000000..7079e263b --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BlockNodeExecutor.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BlockNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory + .getLogger(BlockNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + SvcLogicExpression atomicExpr = node.getAttribute("atomic"); + String atomicStr = SvcLogicExpressionResolver.evaluate(atomicExpr, node, ctx); + boolean isAtomic = "true".equalsIgnoreCase(atomicStr); + + // Initialize status to success so that at least one outcome will execute + ctx.markSuccess(); + + int numOutcomes = node.getNumOutcomes(); + + for (int i = 0; i < numOutcomes; i++) { + if (SvcLogicConstants.FAILURE.equals(ctx.getStatus()) && isAtomic) { + LOG.info("Block - stopped executing nodes due to failure status"); + return(null); + } + + SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1)); + if (nextNode != null) { + + while (nextNode != null) + { + nextNode = svc.executeNode(nextNode, ctx); + } + } + } + + return (null); + } + + + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java new file mode 100644 index 000000000..603d7abc5 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/BreakNodeExecutor.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.BreakNodeException; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BreakNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(BreakNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + String message = "BreakNodeExecutor encountered break with nodeId " + node.getNodeId(); + LOG.debug(message); + throw new BreakNodeException(message); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java new file mode 100644 index 000000000..766826f7d --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/CallNodeExecutor.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CallNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory + .getLogger(CallNodeExecutor.class); + private static final String CURRENT_GRAPH="currentGraph"; + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String outValue = "not-found"; + + SvcLogicGraph myGraph = node.getGraph(); + + if (myGraph == null) + { + LOG.debug("execute: getGraph returned null"); + } + + SvcLogicExpression moduleExpr = null; + + String module = null; + + moduleExpr = node.getAttribute("module"); + if (moduleExpr != null) + { + module = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx); + } + + if ((module == null) || (module.length() == 0)) + { + if (myGraph != null) + { + module = myGraph.getModule(); + } + } + + SvcLogicExpression rpcExpr = null; + String rpc = null; + rpcExpr = node.getAttribute("rpc"); + if (rpcExpr != null) + { + rpc = SvcLogicExpressionResolver.evaluate(rpcExpr, node, ctx); + } + + if ((rpc == null) || (rpc.length() == 0)) + { + if (myGraph != null) + { + rpc = myGraph.getRpc(); + } + } + + String mode = null; + + moduleExpr = node.getAttribute("mode"); + if (moduleExpr != null) + { + mode = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx); + } + + if ((mode == null) || (mode.length() == 0)) + { + if (myGraph != null) + { + mode = myGraph.getMode(); + } + } + + String version = null; + + moduleExpr = node.getAttribute("version"); + if (moduleExpr != null) + { + version = SvcLogicExpressionResolver.evaluate(moduleExpr, node, ctx); + } + + String parentGraph = ctx.getAttribute(CURRENT_GRAPH); + ctx.setAttribute("parentGraph", parentGraph); + + SvcLogicStore store = svc.getStore(); + String errorMessage = "Parent " + parentGraph + " failed to call child [" + module + "," + rpc + "," + version + "," + mode + "] because the graph could not be found"; + boolean graphWasCalled = false; + if (store != null) { + SvcLogicGraph calledGraph = store.fetch(module, rpc, version, mode); + if (calledGraph != null) { + LOG.debug("Parent " + parentGraph + " is calling child " + calledGraph.toString()); + ctx.setAttribute(CURRENT_GRAPH, calledGraph.toString()); + svc.execute(calledGraph, ctx); + outValue = ctx.getStatus(); + graphWasCalled = true; + } else { + LOG.debug(errorMessage); + } + } else { + LOG.debug("Could not get SvcLogicStore reference"); + } + + SvcLogicNode nextNode = node.getOutcomeValue(outValue); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("about to execute " + outValue + " branch"); + } + ctx.setAttribute(CURRENT_GRAPH, parentGraph); + return (nextNode); + } + + nextNode = node.getOutcomeValue("Other"); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("about to execute Other branch"); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("no " + outValue + " or Other branch found"); + } + } + + if (graphWasCalled == false) { + if (node.getOutcomeValue("catch") != null) { + nextNode = node.getOutcomeValue("catch"); + LOG.debug("graph could not be called, but catch node was found and will be executed"); + } else { + LOG.debug("graph could not be called and no catch node was found, throwing exception"); + throw new SvcLogicException(errorMessage); + } + } + + ctx.setAttribute(CURRENT_GRAPH, parentGraph); + ctx.setAttribute("parentGraph", null); + + return (nextNode); + + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java new file mode 100644 index 000000000..a0e3af189 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ConfigureNodeExecutor.java @@ -0,0 +1,242 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConfigureNodeExecutor extends AbstractSvcLogicNodeExecutor { + private static final Logger LOG = LoggerFactory + .getLogger(ConfigureNodeExecutor.class); + private static final String CAUGHT_EXCEPTION_MSG="Caught exception from "; + private static final String ALREADY_ACTIVE= "already-active"; + private static final String NOT_FOUND= "not-found"; + + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + + String adaptorName = SvcLogicExpressionResolver.evaluate( + node.getAttribute("adaptor"), node, ctx); + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("configure node encountered - looking for adaptor " + + adaptorName); + } + + SvcLogicAdaptor adaptor = getAdaptor(adaptorName); + + if (adaptor != null) { + String activate = SvcLogicExpressionResolver.evaluate( + node.getAttribute("activate"), node, ctx); + String key = SvcLogicExpressionResolver.evaluate( + node.getAttribute("key"), node, ctx); + + boolean hasParms = false; + + Map<String, String> parmMap = getResolvedParameters(node,ctx); + if(!parmMap.isEmpty()) { + hasParms = true; + } + + if (hasParms) { + SvcLogicAdaptor.ConfigStatus confStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + + try { + confStatus = adaptor.configure(key, parmMap, ctx); + } catch (Exception e) { + LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".configure", e); + confStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + } + + switch (confStatus) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + if ((activate != null) && (activate.length() > 0)) { + if ("true".equalsIgnoreCase(activate)) { + SvcLogicAdaptor.ConfigStatus activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + + try { + activateStatus = adaptor.activate(key, ctx); + } catch (Exception e) { + + LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".activate", e); + activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + } + switch (activateStatus) { + case SUCCESS: + break; + case ALREADY_ACTIVE: + outValue = ALREADY_ACTIVE; + break; + case NOT_FOUND: + outValue = NOT_FOUND; + break; + case NOT_READY: + outValue = "not-ready"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } else if ("false".equalsIgnoreCase(activate)) { + SvcLogicAdaptor.ConfigStatus deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + + try { + deactivateStatus = adaptor.deactivate(key, ctx); + } catch (Exception e) { + + LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".deactivate", e); + deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + } + switch (deactivateStatus) { + case SUCCESS: + break; + case ALREADY_ACTIVE: + outValue = ALREADY_ACTIVE; + break; + case NOT_FOUND: + outValue = NOT_FOUND; + break; + case NOT_READY: + outValue = "not-ready"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } + } + break; + case ALREADY_ACTIVE: + outValue = ALREADY_ACTIVE; + break; + case NOT_FOUND: + outValue = NOT_FOUND; + break; + case NOT_READY: + outValue = "not-ready"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } else { + if ((activate != null) && (activate.length() > 0)) { + if ("true".equalsIgnoreCase(activate)) { + SvcLogicAdaptor.ConfigStatus activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + try { + activateStatus = adaptor.activate(key, ctx); + } catch (Exception e) { + LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".activate", e); + activateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + } + switch (activateStatus) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case ALREADY_ACTIVE: + outValue = ALREADY_ACTIVE; + break; + case NOT_FOUND: + outValue = NOT_FOUND; + break; + case NOT_READY: + outValue = "not-ready"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } else if ("false".equalsIgnoreCase(activate)) { + SvcLogicAdaptor.ConfigStatus deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + + try { + deactivateStatus = adaptor.deactivate(key, ctx); + } catch (Exception e) { + LOG.warn(CAUGHT_EXCEPTION_MSG+adaptorName+".deactivate", e); + deactivateStatus = SvcLogicAdaptor.ConfigStatus.FAILURE; + } + switch (deactivateStatus) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case ALREADY_ACTIVE: + outValue = ALREADY_ACTIVE; + break; + case NOT_FOUND: + outValue = NOT_FOUND; + break; + case NOT_READY: + outValue = "not-ready"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } + } else { + LOG.warn("Nothing to configure - no parameters passed, and activate attribute is not set"); + outValue = SvcLogicConstants.SUCCESS; + } + } + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("Adaptor for " + adaptorName + " not found"); + } + } + + SvcLogicNode nextNode = node.getOutcomeValue(outValue); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("about to execute " + outValue + " branch"); + } + return (nextNode); + } + + nextNode = node.getOutcomeValue("Other"); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("about to execute Other branch"); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("no " + outValue + " or Other branch found"); + } + } + return (nextNode); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java new file mode 100644 index 000000000..00f0629cb --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/DeleteNodeExecutor.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeleteNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(DeleteNodeExecutor.class); + private static final String FAILURE=SvcLogicConstants.FAILURE; + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + + String outValue = FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("delete node encountered - looking for resource class " + plugin); + } + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + if (resourcePlugin != null) { + try { + switch (resourcePlugin.delete(resourceType, key, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java new file mode 100644 index 000000000..b23662a6c --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutor.java @@ -0,0 +1,127 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExecuteNodeExecutor extends AbstractSvcLogicNodeExecutor { + private static final Logger LOG = LoggerFactory + .getLogger(ExecuteNodeExecutor.class); + private static final String FAILURE=SvcLogicConstants.FAILURE; + + private static final String pluginErrorMessage = "Could not execute plugin. SvcLogic status will be set to failure."; + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + + String pluginName = SvcLogicExpressionResolver.evaluate( + node.getAttribute("plugin"), node, ctx); + String outValue = FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("execute node encountered - looking for plugin " + + pluginName); + } + + SvcLogicJavaPlugin plugin = getSvcLogicJavaPlugin(pluginName); + + if (plugin == null) { + outValue = "not-found"; + } else { + + String methodName = evaluate(node.getAttribute("method"), node, ctx); + + Class pluginClass = plugin.getClass(); + + Method pluginMethod = null; + + try { + LOG.debug("executing method {} on plugin {}", methodName, pluginName); + pluginMethod = pluginClass.getMethod(methodName, Map.class, SvcLogicContext.class); + } catch (NoSuchMethodException e) { + LOG.error(pluginErrorMessage, e); + } + + if (pluginMethod == null) { + outValue = "unsupported-method"; + } else { + try { + + + Map<String, String> parmMap = getResolvedParameters(node,ctx); + Object o = pluginMethod.invoke(plugin, parmMap, ctx); + String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx); + + outValue = mapOutcome(o, emitsOutcome); + + } catch (InvocationTargetException e) { + if(e.getCause() != null){ + LOG.error(pluginErrorMessage, e.getCause()); + }else{ + LOG.error(pluginErrorMessage, e); + } + outValue = FAILURE; + ctx.markFailed(); + } catch (IllegalAccessException e) { + LOG.error(pluginErrorMessage, e); + outValue = FAILURE; + ctx.markFailed(); + } catch (IllegalArgumentException e) { + LOG.error(pluginErrorMessage, e); + outValue = FAILURE; + ctx.markFailed(); + } + } + + } + return (getNextNode(node, outValue)); + } + + protected String evaluate(SvcLogicExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + return SvcLogicExpressionResolver.evaluate(node.getAttribute("method"), node, ctx); + } + + public String mapOutcome(Object o, String emitsOutcome) { + if (emitsOutcome != null) { + Boolean nodeEmitsOutcome = Boolean.valueOf(emitsOutcome); + if (nodeEmitsOutcome) { + return (String) o; + } else { + return SvcLogicConstants.SUCCESS; + } + } else { + return SvcLogicConstants.SUCCESS; + } + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java new file mode 100644 index 000000000..ca12e35d8 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExistsNodeExecutor.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExistsNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(ExistsNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx); + + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("exists node encountered - looking for resource class " + plugin); + } + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + + if (resourcePlugin != null) { + try { + switch (resourcePlugin.exists(resourceType, key, pfx, ctx)) { + case SUCCESS: + outValue = "true"; + break; + case NOT_FOUND: + outValue = "false"; + break; + case FAILURE: + default: + outValue = "false"; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java new file mode 100644 index 000000000..828e10152 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ExitNodeExecutor.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.ExitNodeException; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExitNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(ExitNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + String message = "ExitNodeExecutor encountered exit with nodeId " + node.getNodeId(); + LOG.debug(message); + throw new ExitNodeException(message); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java new file mode 100644 index 000000000..2d9721c7f --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ForNodeExecutor.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.BreakNodeException; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ForNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory + .getLogger(ForNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + + SvcLogicExpression atomicExpr = node.getAttribute("atomic"); + String atomicStr = SvcLogicExpressionResolver.evaluate(atomicExpr, node, ctx); + boolean isAtomic = !("false".equalsIgnoreCase(atomicStr)); + + int numOutcomes = node.getNumOutcomes(); + String idxVar = SvcLogicExpressionResolver.evaluate( + node.getAttribute("index"), node, ctx); + String startVal = SvcLogicExpressionResolver.evaluate( + node.getAttribute("start"), node, ctx); + String endVal = SvcLogicExpressionResolver.evaluate( + node.getAttribute("end"), node, ctx); + + LOG.debug("Executing "+ (isAtomic ? "atomic" : "non-atomic") + " for loop - for (int " + idxVar + " = " + startVal + + "; " + idxVar + " < " + endVal + "; " + idxVar + "++)"); + + int startIdx = 0; + int endIdx = 0; + + try { + startIdx = Integer.parseInt(startVal); + endIdx = Integer.parseInt(endVal); + } catch (NumberFormatException e) { + SvcLogicExpression silentFailureExpr = node.getAttribute("silentFailure"); + String silentFailure = SvcLogicExpressionResolver.evaluate(silentFailureExpr, node, ctx); + boolean isSilentFailure = Boolean.parseBoolean(silentFailure); + String message = "Invalid index values [" + startVal + "," + endVal + "]"; + if(!isSilentFailure){ + throw new SvcLogicException(message); + }else{ + LOG.debug(message + ". Not exiting because silentFailure was set to true."); + return(null); + } + } + + try { + for (int ctr = startIdx; ctr < endIdx; ctr++) { + + ctx.setAttribute(idxVar, "" + ctr); + + for (int i = 0; i < numOutcomes; i++) { + + if (SvcLogicConstants.FAILURE.equals(ctx.getStatus()) && isAtomic) { + LOG.info("For - stopped executing nodes due to failure status"); + return(null); + } + + SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1)); + if (nextNode != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("For - executing outcome " + (i + 1)); + } + SvcLogicNode innerNextNode = nextNode; + while (innerNextNode != null) { + innerNextNode = svc.executeNode(innerNextNode, ctx); + } + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("For - done: no outcome " + (i + 1)); + } + } + } + } + } catch (BreakNodeException br) { + LOG.trace("ForNodeExecutor caught break" + br.getMessage()); + } + return (null); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java new file mode 100644 index 000000000..f7cfc66d2 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/GetResourceNodeExecutor.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GetResourceNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(GetResourceNodeExecutor.class); + + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx); + + String localOnlyStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("local-only"), node, ctx); + + // Note: for get-resource, only refresh from A&AI if the DG explicitly set + // local-only to false. Otherwise, just read from local database. + boolean localOnly = true; + + if ("false".equalsIgnoreCase(localOnlyStr)) { + localOnly = false; + } + + SvcLogicExpression selectExpr = node.getAttribute("select"); + String select = null; + + if (selectExpr != null) { + select = SvcLogicExpressionResolver.evaluateAsKey(selectExpr, node, ctx); + } + + SvcLogicExpression orderByExpr = node.getAttribute("order-by"); + String orderBy = null; + + if (orderByExpr != null) { + orderBy = SvcLogicExpressionResolver.evaluateAsKey(orderByExpr, node, ctx); + } + + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug(node.getNodeType() + " node encountered - looking for resource class " + plugin); + } + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + + if (resourcePlugin != null) { + try { + switch (resourcePlugin.query(resourceType, localOnly, select, key, pfx, orderBy, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java new file mode 100644 index 000000000..d33312784 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolver.java @@ -0,0 +1,52 @@ +package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+
+public class HashMapResolver implements SvcLogicResolver {
+ Map<String, SvcLogicResource> svcLogicResourceMap = new HashMap<String, SvcLogicResource>();
+ Map<String, SvcLogicJavaPlugin> svcLogicJavaPluginMap = new HashMap<String, SvcLogicJavaPlugin>();
+ Map<String, SvcLogicAdaptor> adaptorMap = new HashMap<String, SvcLogicAdaptor>();
+ Map<String, SvcLogicRecorder> recorderMap = new HashMap<String, SvcLogicRecorder>();
+
+ @Override
+ public SvcLogicResource getSvcLogicResource(String resourceName) {
+ return svcLogicResourceMap.get(resourceName);
+ }
+
+ @Override
+ public SvcLogicRecorder getSvcLogicRecorder(String recorderName) {
+ return recorderMap.get(recorderName);
+ }
+
+ @Override
+ public SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) {
+ return svcLogicJavaPluginMap.get(pluginName);
+ }
+
+ @Override
+ public SvcLogicAdaptor getSvcLogicAdaptor(String adaptorName) {
+ return adaptorMap.get(adaptorName);
+ }
+
+ public void addSvcLogicAdaptor(String adaptorName, SvcLogicAdaptor adaptor) {
+ adaptorMap.put(adaptorName, adaptor);
+ }
+
+ public void addSvcLogicRecorder(String recorderName, SvcLogicRecorder recorder) {
+ recorderMap.put(recorderName, recorder);
+ }
+
+ public void addSvcLogicSvcLogicJavaPlugin(String pluginName, SvcLogicJavaPlugin plugin) {
+ svcLogicJavaPluginMap.put(pluginName, plugin);
+ }
+
+ public void addSvcLogicResource(String resourceName, SvcLogicResource resource) {
+ svcLogicResourceMap.put(resourceName, resource);
+ }
+
+}
diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java new file mode 100644 index 000000000..ddf464fe7 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStore.java @@ -0,0 +1,66 @@ +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InMemorySvcLogicStore implements SvcLogicStore { + private static final Logger logger = LoggerFactory.getLogger(InMemorySvcLogicStore.class); + public Map<String, SvcLogicGraph> graphStore; + + public InMemorySvcLogicStore() { + graphStore = new HashMap<String, SvcLogicGraph>(); + } + + @Override + public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException { + String storeId = new String(module + ":" + rpc); + return graphStore.containsKey(storeId); + } + + @Override + public SvcLogicGraph fetch(String module, String rpc, String version, String mode) throws SvcLogicException { + String storeId = new String(module + ":" + rpc); + return graphStore.get(storeId); + } + + @Override + public void store(SvcLogicGraph graph) throws SvcLogicException { + if (graph != null) { + String storeId = new String(graph.getModule() + ":" + graph.getRpc()); + graphStore.put(storeId, graph); + logger.info(graph.toString() + " stored in InMemorySvcLogicStore."); + } + } + + @Override + public void init(Properties props) throws SvcLogicException { + // noop + } + + @Override + public void delete(String module, String rpc, String version, String mode) throws SvcLogicException { + String storeId = new String(module + ":" + rpc); + if (graphStore.containsKey(storeId)) { + graphStore.remove(storeId); + } + } + + @Override + public void activate(SvcLogicGraph graph) throws SvcLogicException { + // noop + } + + @Override + public void activate(String module, String rpc, String version, String mode) throws SvcLogicException { + // noop + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java new file mode 100644 index 000000000..1d6e34e85 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/IsAvailableNodeExecutor.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IsAvailableNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(IsAvailableNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx); + + String outValue = SvcLogicConstants.FAILURE; + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + + if (resourcePlugin != null) { + try { + switch (resourcePlugin.isAvailable(resourceType, key, pfx, ctx)) { + case SUCCESS: + outValue = "true"; + break; + case NOT_FOUND: + outValue = "false"; + break; + case FAILURE: + default: + outValue = "false"; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java new file mode 100644 index 000000000..fb560db5f --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/NotifyNodeExecutor.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NotifyNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(NotifyNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String action = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("action"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("release node encountered - looking for resource class " + plugin); + } + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + if (resourcePlugin != null) { + try { + switch (resourcePlugin.notify(resourceType, action, key, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java new file mode 100644 index 000000000..2dd5a081e --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/RecordNodeExecutor.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RecordNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(RecordNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String outValue = SvcLogicConstants.FAILURE; + + Map<String, String> parmMap = getResolvedParameters(node,ctx); + + SvcLogicRecorder recorder = getSvcLogicRecorder(plugin); + if (recorder != null) { + try { + recorder.record(parmMap); + } catch (SvcLogicException e) { + LOG.error("Caught exception from recorder plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicRecorder object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java new file mode 100644 index 000000000..ee06031d6 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReleaseNodeExecutor.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ReleaseNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(ReleaseNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("release node encountered - looking for resource class " + plugin); + } + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + if (resourcePlugin != null) { + try { + switch (resourcePlugin.release(resourceType, key, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java new file mode 100644 index 000000000..d22d36ebb --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReserveNodeExecutor.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ReserveNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(ReserveNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx); + + + SvcLogicExpression selectExpr = node.getAttribute("select"); + String select = null; + + if (selectExpr != null) { + select = SvcLogicExpressionResolver.evaluateAsKey(selectExpr, node, ctx); + } + + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("reserve node encountered - looking for resource class " + plugin); + } + + + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + + if (resourcePlugin != null) { + + try { + switch (resourcePlugin.reserve(resourceType, select, key, pfx, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java new file mode 100644 index 000000000..8ee465774 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/ReturnNodeExecutor.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ReturnNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory + .getLogger(ReturnNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + + String status = SvcLogicExpressionResolver.evaluate( + node.getAttribute("status"), node, ctx); + + if (status != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Returning status " + status); + } + ctx.setStatus(status); + } else { + if (LOG.isWarnEnabled()) { + LOG.warn("Return node has no status attribute set"); + } + } + + Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node + .getParameterSet(); + + for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet + .iterator(); iter.hasNext();) { + Map.Entry<String, SvcLogicExpression> curEnt = iter.next(); + String curName = curEnt.getKey(); + String curValue = SvcLogicExpressionResolver.evaluate( + curEnt.getValue(), node, ctx); + + if (LOG.isDebugEnabled()) { + LOG.debug(SETTING_DEBUG_PATTERN, curName, curValue, curEnt.getValue()); + } + ctx.setAttribute(curName, curValue); + } + return null; + } + + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java new file mode 100644 index 000000000..b0b70f1f2 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SaveNodeExecutor.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SaveNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(SaveNodeExecutor.class); + private static final String FAILURE= SvcLogicConstants.FAILURE; + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + String forceStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("force"), node, ctx); + String localOnlyStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("local-only"), node, ctx); + String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx); + + boolean force = "true".equalsIgnoreCase(forceStr); + boolean localOnly = "true".equalsIgnoreCase(localOnlyStr); + + Map<String, String> parmMap = getResolvedParameters(node,ctx); + + String outValue = FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("save node encountered - looking for resource class " + plugin); + } + + + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + + if (resourcePlugin != null) { + + try { + switch (resourcePlugin.save(resourceType, force, localOnly, key, parmMap, pfx, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java new file mode 100644 index 000000000..7e07d29bf --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutor.java @@ -0,0 +1,179 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpressionFactory; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SetNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(SetNodeExecutor.class); + protected final String arrayPattern = "\\[\\d*\\]"; + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + execute(node,ctx); + return null; + } + + public void execute(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + String ifunsetStr = SvcLogicExpressionResolver.evaluate(node.getAttribute("only-if-unset"), node, ctx); + + boolean ifunset = "true".equalsIgnoreCase(ifunsetStr); + + Set<Map.Entry<String, SvcLogicExpression>> parameterSet = node.getParameterSet(); + + for (Iterator<Map.Entry<String, SvcLogicExpression>> iter = parameterSet.iterator(); iter.hasNext();) { + Map.Entry<String, SvcLogicExpression> curEnt = iter.next(); + String curName = curEnt.getKey(); + String lhsVarName = curName; + + // Resolve LHS of assignment (could contain index variables) + try { + // Backticks symbolize the variable should be handled as an expression instead of as a variable + if (curName.trim().startsWith("`")) { + int lastParen = curName.lastIndexOf("`"); + String evalExpr = curName.trim().substring(1, lastParen); + SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(evalExpr); + lhsVarName = SvcLogicExpressionResolver.evaluate(lhsExpr, node, ctx); + } else { + SvcLogicExpression lhsExpr = SvcLogicExpressionFactory.parse(curName); + lhsVarName = SvcLogicExpressionResolver.resolveVariableName(lhsExpr, node, ctx); + } + } catch (Exception e) { + LOG.warn("Caught exception trying to resolve variable name (" + curName + ")", e); + } + + boolean setValue = true; + + if (curName.endsWith(".")) { + // Copy subtree - value should be a variable name + SvcLogicExpression curValue = curEnt.getValue(); + + if (curValue != null) { + String rhsRoot = curValue.toString(); + + if ((rhsRoot != null) && (rhsRoot.length() > 0)) { + if (rhsRoot.endsWith(".")) { + rhsRoot = rhsRoot.substring(0, rhsRoot.length() - 1); + } + + // SDNGC-2321 : rhsRoot is variable name, possibly with subscript(s) to be resolved + try { + SvcLogicExpression rhsExpr = SvcLogicExpressionFactory.parse(rhsRoot); + rhsRoot = SvcLogicExpressionResolver.resolveVariableName(rhsExpr, node, ctx); + } catch (Exception e) { + LOG.warn("Caught exception trying to resolve variable name (" + rhsRoot + ")", e); + } + + // See if the parameters are reversed (copying service-data to input) .. this + // was done as a workaround to earlier issue + if (curName.endsWith("-input.") && rhsRoot.startsWith("service-data")) { + LOG.warn("Arguments appear to be reversed .. will copy input to service-data instead"); + lhsVarName = rhsRoot + "."; + rhsRoot = curName.substring(0, curName.length() - 1); + } + + rhsRoot = rhsRoot + "."; + String lhsPrefix = lhsVarName; + + if (lhsPrefix.endsWith(".")) { + lhsPrefix = lhsPrefix.substring(0, lhsPrefix.length() - 1); + } + + HashMap<String, String> parmsToAdd = new HashMap<>(); + + for (String sourceVarName : ctx.getAttributeKeySet()) { + if (sourceVarName.startsWith(rhsRoot)) { + String targetVar = lhsPrefix + "." + sourceVarName.substring(rhsRoot.length()); + LOG.debug("Copying {} value to {}", sourceVarName, targetVar); + parmsToAdd.put(targetVar, ctx.getAttribute(sourceVarName)); + } + } + for (String newParmName : parmsToAdd.keySet()) { + ctx.setAttribute(newParmName, parmsToAdd.get(newParmName)); + } + } else { + // If RHS is empty, unset attributes in LHS + LinkedList<String> parmsToRemove = new LinkedList<>(); + String prefix = lhsVarName + "."; + String arrayPrefix = lhsVarName + "["; + //Clear length value in case an array exists with this prefix + String lengthParamName = lhsVarName + "_length"; + LOG.debug("Unsetting {} because prefix {} is being cleared.", lengthParamName, prefix); + + for (String curCtxVarname : ctx.getAttributeKeySet()) { + String curCtxVarnameMatchingValue = curCtxVarname; + //Special handling for reseting array values, strips out brackets and any numbers between the brackets + //when testing if a context memory value starts with a prefix + if(!prefix.contains("[") && curCtxVarnameMatchingValue.contains("[")) { + curCtxVarnameMatchingValue = curCtxVarname.replaceAll(arrayPattern, "") + "."; + } + if (curCtxVarnameMatchingValue.startsWith(prefix)) { + LOG.debug("Unsetting {} because matching value {} starts with the prefix {}", curCtxVarname, curCtxVarnameMatchingValue, prefix); + parmsToRemove.add(curCtxVarname); + }else if (curCtxVarnameMatchingValue.startsWith(lengthParamName)) { + LOG.debug("Unsetting {} because matching value {} starts with the lengthParamName {}", curCtxVarname, curCtxVarnameMatchingValue, lengthParamName); + parmsToRemove.add(curCtxVarname); + }else if (curCtxVarnameMatchingValue.startsWith(arrayPrefix)) { + LOG.debug("Unsetting {} because matching value {} starts with the arrayPrefix {}", curCtxVarname, curCtxVarnameMatchingValue, arrayPrefix); + parmsToRemove.add(curCtxVarname); + } + } + for (String parmName : parmsToRemove) { + ctx.setAttribute(parmName, null); + } + } + } + } else { + if (ifunset) { + String ctxValue = ctx.getAttribute(lhsVarName); + if ((ctxValue != null) && (ctxValue.length() > 0)) { + setValue = false; + LOG.debug("Attribute {} already set and only-if-unset is true, so not overriding", lhsVarName); + } + } + if (setValue) { + String curValue = SvcLogicExpressionResolver.evaluate(curEnt.getValue(), node, ctx); + if (LOG.isDebugEnabled()) { + LOG.debug(SETTING_DEBUG_PATTERN, lhsVarName, curValue, curEnt.getValue()); + } + ctx.setAttribute(lhsVarName, curValue); + } + } + } + } +} + diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java new file mode 100644 index 000000000..a3507947f --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolver.java @@ -0,0 +1,603 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.onap.ccsdk.sli.core.sli.SvcLogicAtom; +import org.onap.ccsdk.sli.core.sli.SvcLogicBinaryExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicFunctionCall; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicVariableTerm; +import org.onap.ccsdk.sli.core.sli.SvcLogicAtom.AtomType; +import org.onap.ccsdk.sli.core.sli.SvcLogicBinaryExpression.OperatorType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicExpressionResolver { + + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicExpressionResolver.class); + private static final String INVALID_EXPRESSION_MSG= "Invalid expression ("; + private static final String EXPRESSION_DEBUG_PATTERN = "Expression: ({}) resolves to: (${}) which has the value: ({})"; + + public static String evaluate(SvcLogicExpression expr, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + if (expr == null) { + return (null); + } + + if (expr instanceof SvcLogicAtom) { + SvcLogicAtom atom = (SvcLogicAtom) expr; + + AtomType atomType = atom.getAtomType(); + switch (atomType) { + case NUMBER: + case STRING: + return (atom.toString()); + case CONTEXT_VAR: + case IDENTIFIER: + + String varName = resolveVariableName(atom, node, ctx); + + if (atomType == AtomType.CONTEXT_VAR) + { + String varValue = ctx.getAttribute(varName); + if (varValue == null) { + LOG.trace("Context variable: ($"+varName+") unset - treating as empty string"); + varValue = ""; + } + LOG.trace(EXPRESSION_DEBUG_PATTERN, expr, varName, varValue); + return (varValue); + } + + SvcLogicExpression parm = node.getParameter(varName); + if (parm != null) { + String value = evaluate(parm, node, ctx); + LOG.trace(EXPRESSION_DEBUG_PATTERN, expr, varName, value); + return value; + } + else { + LOG.trace(EXPRESSION_DEBUG_PATTERN, expr, varName, varName); + return(varName); + } + default: + return(null); + } + + } else if (expr instanceof SvcLogicBinaryExpression) { + SvcLogicBinaryExpression binExpr = (SvcLogicBinaryExpression) expr; + List<OperatorType> operators = binExpr.getOperators(); + if (operators.isEmpty()) + { + List<SvcLogicExpression> operands = binExpr.getOperands(); + if (operands.size() == 1) + { + return(evaluate(operands.get(0), node, ctx)); + } + else + { + if (operands.isEmpty()) + { + LOG.error("SvcLogicBinaryExpression has no operators and no operands - evaluating value as null"); + } + else + { + LOG.error("SvcLogicBinaryExpression has no operators and "+operands.size()+" operands - evaluating value as null"); + } + return(null); + } + } + switch (operators.get(0)) { + case addOp: + case subOp: + case multOp: + case divOp: + return(evalArithExpression(binExpr, node, ctx)); + case equalOp: + case neOp: + case ltOp: + case leOp: + case gtOp: + case geOp: + return (evalCompareExpression(binExpr, node, ctx)); + case andOp: + case orOp: + return(evalLogicExpression(binExpr, node, ctx)); + + default: + return(null); + } + } + else if (expr instanceof SvcLogicFunctionCall) + { + return(evalFunctionCall((SvcLogicFunctionCall)expr, node, ctx)); + } + else + { + throw new SvcLogicException("Unrecognized expression type ["+expr+"]"); + } + } + + private static String evalArithExpression(SvcLogicBinaryExpression binExpr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + List<SvcLogicExpression> operands = binExpr.getOperands(); + List<OperatorType> operators = binExpr.getOperators(); + if (operands.size() != (operators.size()+1)) + { + throw new SvcLogicException(INVALID_EXPRESSION_MSG+binExpr+")"); + } + String retval = evaluate(operands.get(0), node, ctx); + String retsval = retval; + long retlval = 0; + boolean valueIsLong = false; + + int i = 1; + try + { + + if ((retval.length() > 0) && StringUtils.isNumeric(retval)) + { + retlval = Long.parseLong(retval); + valueIsLong = true; + } + for (OperatorType operator: operators) + { + String curOperandValue = evaluate(operands.get(i++), node, ctx); + switch(operator) { + case addOp: + retsval = retsval + curOperandValue; + if (valueIsLong) + { + if ((curOperandValue.length() > 0) && StringUtils.isNumeric(curOperandValue) ) + { + retlval = retlval + Long.parseLong(curOperandValue); + } + else + { + valueIsLong = false; + } + } + break; + case subOp: + retlval = retlval - Long.parseLong(curOperandValue); + break; + case multOp: + retlval = retlval * Long.parseLong(curOperandValue); + break; + case divOp: + retlval = retlval / Long.parseLong(curOperandValue); + break; + } + + } + } + catch (NumberFormatException e1) + { + throw new SvcLogicException("Illegal value in arithmetic expression", e1); + } + + if (valueIsLong) + { + return("" + retlval); + } + else + { + return(retsval); + } + + } + + + + private static String evalCompareExpression(SvcLogicBinaryExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException + { + + List<OperatorType> operators = expr.getOperators(); + List<SvcLogicExpression> operands = expr.getOperands(); + + if ((operators.size() != 1) || (operands.size() != 2)) + { + throw new SvcLogicException ("Invalid comparison expression : "+expr); + } + + OperatorType operator = operators.get(0); + String op1Value = evaluate(operands.get(0), node, ctx); + String op2Value = evaluate(operands.get(1), node, ctx); + + if ((StringUtils.isNotEmpty(op1Value) && StringUtils.isNumeric(op1Value) && StringUtils.isNotEmpty(op2Value) && StringUtils.isNumeric(op2Value))) + { + try + { + double op1dbl = Double.parseDouble(op1Value); + double op2dbl = Double.parseDouble(op2Value); + + switch(operator) + { + case equalOp: + return(Boolean.toString(op1dbl == op2dbl)); + case neOp: + return(Boolean.toString(op1dbl != op2dbl)); + case ltOp: + return(Boolean.toString(op1dbl < op2dbl)); + case leOp: + return(Boolean.toString(op1dbl <= op2dbl)); + case gtOp: + return(Boolean.toString(op1dbl > op2dbl)); + case geOp: + return(Boolean.toString(op1dbl >= op2dbl)); + default: + return(null); + } + } + catch (NumberFormatException e) + { + throw new SvcLogicException("Caught exception trying to compare numeric values", e); + } + } + else + { + + int compResult = 0; + + if (op1Value == null) { + compResult = -1; + } else if (op2Value == null ) { + compResult = 1; + } else { + compResult = op1Value.compareToIgnoreCase(op2Value); + } + + switch(operator) + { + case equalOp: + return(Boolean.toString(compResult == 0)); + case neOp: + return(Boolean.toString(compResult != 0)); + case ltOp: + return(Boolean.toString(compResult < 0)); + case leOp: + return(Boolean.toString(compResult <= 0)); + case gtOp: + return(Boolean.toString(compResult > 0)); + case geOp: + return(Boolean.toString(compResult >= 0)); + default: + return(null); + } + } + + } + + private static String evalLogicExpression(SvcLogicBinaryExpression expr, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException + { + boolean retval; + + List<SvcLogicExpression> operands = expr.getOperands(); + List<OperatorType> operators = expr.getOperators(); + + if (operands.size() != (operators.size()+1)) + { + throw new SvcLogicException(INVALID_EXPRESSION_MSG+expr+")"); + } + + try + { + retval = Boolean.parseBoolean(evaluate(operands.get(0), node, ctx)); + int i = 1; + for (OperatorType operator : operators) + { + if (operator == OperatorType.andOp) + { + retval = retval && Boolean.parseBoolean(evaluate(operands.get(i++), node, ctx)); + } + else + { + + retval = retval || Boolean.parseBoolean(evaluate(operands.get(i++), node, ctx)); + } + + } + } + catch (Exception e) + { + throw new SvcLogicException(INVALID_EXPRESSION_MSG+expr+")"); + } + + + return(Boolean.toString(retval)); + } + + private static String evalFunctionCall(SvcLogicFunctionCall func, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException + { + String funcName = func.getFunctionName(); + List<SvcLogicExpression> operands = func.getOperands(); + + if ("length".equalsIgnoreCase(funcName)) + { + + if (operands.size() == 1) + { + String opValue = evaluate(operands.get(0), node, ctx); + return(""+opValue.length()); + } + else + { + throw new SvcLogicException("Invalid call to length() function"); + } + } + else if ("substr".equalsIgnoreCase(funcName)) + { + if (operands.size() == 3) + { + String op1Value = evaluate(operands.get(0), node, ctx); + String op2Value = evaluate(operands.get(1), node, ctx); + String op3Value = evaluate(operands.get(2), node, ctx); + + if (!StringUtils.isNumeric(op2Value) || !StringUtils.isNumeric(op3Value)) + { + throw new SvcLogicException("Invalid arguments to substr() function"); + } + + try + { + return(op1Value.substring(Integer.parseInt(op2Value), Integer.parseInt(op3Value))); + } + catch (Exception e) + { + throw new SvcLogicException("Caught exception trying to take substring", e); + } + } + else + { + + throw new SvcLogicException("Invalid call to substr() function"); + } + + } + else if ("toUpperCase".equalsIgnoreCase(funcName)) + { + if (operands.size() == 1) + { + String opValue = evaluate(operands.get(0), node, ctx); + if (opValue != null) { + return(opValue.toUpperCase()); + } else { + return(""); + } + } + else + { + throw new SvcLogicException("Invalid call to toUpperCase() function"); + } + } + else if ("toLowerCase".equalsIgnoreCase(funcName)) + { + if (operands.size() == 1) + { + String opValue = evaluate(operands.get(0), node, ctx); + if (opValue != null) { + return(opValue.toLowerCase()); + } else { + return(""); + } + } + else + { + throw new SvcLogicException("Invalid call to toLowerCase() function"); + } + } + else if ("convertBase".equalsIgnoreCase(funcName)) { + int fromBase = 10; + int toBase = 10; + String srcString = ""; + + if (operands.size() == 2) + { + fromBase = 10; + srcString = evaluate(operands.get(0), node, ctx); + toBase = Integer.parseInt(evaluate(operands.get(1), node, ctx)); + } else if (operands.size() == 3) { + + srcString = evaluate(operands.get(0), node, ctx); + fromBase = Integer.parseInt(evaluate(operands.get(1), node, ctx)); + toBase = Integer.parseInt(evaluate(operands.get(2), node, ctx)); + } else { + throw new SvcLogicException("Invalid call to convertBase() function"); + } + + long srcValue = Long.parseLong(srcString, fromBase); + return(Long.toString(srcValue, toBase)); + } + else + { + throw new SvcLogicException("Unrecognized function ("+funcName+")"); + } + + } + + public static String evaluateAsKey(SvcLogicExpression expr, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + if (expr == null) { + return (null); + } + + + + if (expr instanceof SvcLogicAtom) { + SvcLogicAtom atom = (SvcLogicAtom) expr; + + AtomType atomType = atom.getAtomType(); + StringBuffer varNameBuff = new StringBuffer(); + switch (atomType) { + case NUMBER: + return (atom.toString()); + case STRING: + return("'"+atom.toString()+"'"); + case CONTEXT_VAR: + case IDENTIFIER: + boolean needDot = false; + for (SvcLogicExpression term : atom.getOperands()) + { + if (needDot) + { + varNameBuff.append("."); + } + if (term instanceof SvcLogicVariableTerm) + { + SvcLogicVariableTerm vterm = (SvcLogicVariableTerm) term; + varNameBuff.append(vterm.getName()); + if (vterm.numOperands() > 0) + { + varNameBuff.append("["); + varNameBuff.append(evaluate(vterm.getSubscript(), node, ctx)); + varNameBuff.append("]"); + + } + } + else + { + varNameBuff.append(term.toString()); + } + needDot = true; + } + + String varName = varNameBuff.toString(); + String ctxValue = ctx.getAttribute(varName); + if (ctxValue == null) + { + return(null); + } + if (StringUtils.isNumeric(ctxValue)) + { + return(ctxValue); + } + else + { + return("'"+ctxValue+"'"); + } + + default: + return(null); + } + + } else if (expr instanceof SvcLogicBinaryExpression) { + SvcLogicBinaryExpression binExpr = (SvcLogicBinaryExpression) expr; + List<OperatorType> operators = binExpr.getOperators(); + List<SvcLogicExpression> operands = binExpr.getOperands(); + if (operators.isEmpty()) + { + if (operands.size() == 1) + { + LOG.debug("SvcLogicBinaryExpression as no operator and one operand - evaluating its operand"); + return(evaluateAsKey(operands.get(0), node, ctx)); + } + else + { + if (operands.isEmpty()) + { + LOG.error("SvcLogicBinaryExpression has no operators and no operands - evaluating value as null"); + } + else + { + LOG.error("SvcLogicBinaryExpression has no operators and "+operands.size()+" operands - evaluating value as null"); + } + return(null); + } + } + StringBuffer sbuff = new StringBuffer(); + sbuff.append(evaluateAsKey(operands.get(0), node, ctx)); + int i = 1; + for (OperatorType operator : operators) + { + sbuff.append(" "); + sbuff.append(operator.toString()); + sbuff.append(" "); + sbuff.append(evaluateAsKey(operands.get(i++), node,ctx)); + } + return(sbuff.toString()); + } + else if (expr instanceof SvcLogicFunctionCall) + { + StringBuffer sbuff = new StringBuffer(); + SvcLogicFunctionCall funcCall = (SvcLogicFunctionCall) expr; + sbuff.append(funcCall.getFunctionName()); + sbuff.append("("); + boolean needComma = false; + for (SvcLogicExpression operand : funcCall.getOperands()) + { + if (needComma) + { + sbuff.append(","); + } + else + { + needComma = true; + } + sbuff.append(evaluateAsKey(operand, node, ctx)); + } + sbuff.append(")"); + return(sbuff.toString()); + } + else + { + throw new SvcLogicException("Unrecognized expression type ["+expr+"]"); + } + } + + public static String resolveVariableName(SvcLogicExpression atom, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException + { + StringBuffer varNameBuff = new StringBuffer(); + + boolean needDot = false; + for (SvcLogicExpression term : atom.getOperands()) + { + if (needDot) + { + varNameBuff.append("."); + } + if (term instanceof SvcLogicVariableTerm) + { + SvcLogicVariableTerm vterm = (SvcLogicVariableTerm) term; + varNameBuff.append(vterm.getName()); + if (vterm.numOperands() > 0) + { + varNameBuff.append("["); + varNameBuff.append(evaluate(vterm.getSubscript(), node, ctx)); + varNameBuff.append("]"); + } + } + else + { + varNameBuff.append(term.toString()); + } + needDot = true; + } + return(varNameBuff.toString()); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java new file mode 100644 index 000000000..fc108f951 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicPropertiesProvider.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.Properties; + +public interface SvcLogicPropertiesProvider { + + public Properties getProperties();; +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java new file mode 100644 index 000000000..08b675958 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicResolver.java @@ -0,0 +1,17 @@ +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; + +public interface SvcLogicResolver { + + abstract SvcLogicResource getSvcLogicResource(String resourceName); + + abstract SvcLogicRecorder getSvcLogicRecorder(String recorderName); + + abstract SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName); + + abstract SvcLogicAdaptor getSvcLogicAdaptor(String adaptorName); +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java new file mode 100644 index 000000000..3bade8132 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceBase.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.Properties; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicStore; + +public interface SvcLogicServiceBase { + + + /** + * Check for existence of a directed graph + * @param module - module name + * @param rpc - rpc name + * @param version - version. If null, looks for active version + * @param mode - mode (sync/async) + * @return true if directed graph found, false otherwise + * @throws SvcLogicException + */ + boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException; + + /** + * Execute a directed graph + * + * @param module - module name + * @param rpc - rpc name + * @param version - version. If null, use active version + * @param mode - mode (sync/async) + * @param parms - parameters, used to set SvcLogicContext attributes + * @return final values of attributes from SvcLogicContext, as Properties + * @throws SvcLogicException + * + * + */ + Properties execute(String module, String rpc, String version, String mode, Properties parms) throws SvcLogicException; + /** + * Execute a directed graph + * + * @param module - module name + * @param rpc - rpc name + * @param version - version. If null, use active version + * @param mode - mode (sync/async) + * @param ctx - parameters, as a SvcLogicContext object + * @return final values of attributes from SvcLogicContext, as Properties + * @throws SvcLogicException + * + * + */ + SvcLogicContext execute(String module, String rpc, String version, String mode, SvcLogicContext ctx) throws SvcLogicException; + + SvcLogicStore getStore() throws SvcLogicException; + + SvcLogicContext execute(SvcLogicGraph calledGraph, SvcLogicContext ctx) throws SvcLogicException; + + SvcLogicNode executeNode(SvcLogicNode nextNode, SvcLogicContext ctx) throws SvcLogicException; + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java new file mode 100644 index 000000000..75673f756 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicServiceImplBase.java @@ -0,0 +1,180 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import org.onap.ccsdk.sli.core.sli.ExitNodeException; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicStore; +import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +public class SvcLogicServiceImplBase implements SvcLogicServiceBase { + protected SvcLogicResolver resolver; + protected static final Map<String, AbstractSvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, AbstractSvcLogicNodeExecutor>() { + { + put("block", new BlockNodeExecutor()); + put("call", new CallNodeExecutor()); + put("configure", new ConfigureNodeExecutor()); + put("delete", new DeleteNodeExecutor()); + put("execute", new ExecuteNodeExecutor()); + put("exists", new ExistsNodeExecutor()); + put("for", new ForNodeExecutor()); + put("get-resource", new GetResourceNodeExecutor()); + put("is-available", new IsAvailableNodeExecutor()); + put("notify", new NotifyNodeExecutor()); + put("record", new RecordNodeExecutor()); + put("release", new ReleaseNodeExecutor()); + put("reserve", new ReserveNodeExecutor()); + put("return", new ReturnNodeExecutor()); + put("save", new SaveNodeExecutor()); + put("set", new SetNodeExecutor()); + put("switch", new SwitchNodeExecutor()); + put("update", new UpdateNodeExecutor()); + put("break", new BreakNodeExecutor()); + put("while", new WhileNodeExecutor()); + put("exit", new ExitNodeExecutor()); + } + }; + + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicServiceImplBase.class); + protected HashMap<String, AbstractSvcLogicNodeExecutor> nodeExecutors = null; + protected Properties properties; + protected SvcLogicStore store; + protected static final String CURRENT_GRAPH="currentGraph"; + + public SvcLogicServiceImplBase(SvcLogicStore store, SvcLogicResolver resolver) { + this.store = store; + this.resolver = resolver; + } + + protected void registerExecutors() { + for (String nodeType : BUILTIN_NODES.keySet()) { + registerExecutor(nodeType, BUILTIN_NODES.get(nodeType)); + } + } + + public void registerExecutor(String nodeName, AbstractSvcLogicNodeExecutor executor) { + if (nodeExecutors == null) { + nodeExecutors = new HashMap<>(); + } + executor.setResolver(resolver); + nodeExecutors.put(nodeName, executor); + } + + public void unregisterExecutor(String nodeName) { + nodeExecutors.remove(nodeName); + } + + public SvcLogicContext execute(SvcLogicGraph graph, SvcLogicContext ctx) throws SvcLogicException { + if (nodeExecutors == null) { + registerExecutors(); + } + + MDC.put(CURRENT_GRAPH, graph.toString()); + + SvcLogicNode curNode = graph.getRootNode(); + LOG.info("About to execute graph {}", graph.toString()); + try { + while (curNode != null) { + SvcLogicNode nextNode = executeNode(curNode, ctx); + curNode = nextNode; + } + } catch (ExitNodeException e) { + LOG.debug("SvcLogicServiceImpl caught ExitNodeException"); + } + MDC.remove("nodeId"); + MDC.remove(CURRENT_GRAPH); + + return (ctx); + } + + public SvcLogicNode executeNode(SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + if (node == null) { + return (null); + } + + LOG.info("About to execute node #{} {} node in graph {}", node.getNodeId(), node.getNodeType(), node.getGraph().toString()); + + AbstractSvcLogicNodeExecutor executor = nodeExecutors.get(node.getNodeType()); + + if (executor != null) { + MDC.put("nodeId", node.getNodeId() + " (" + node.getNodeType() + ")"); + return (executor.execute(this, node, ctx)); + } else { + throw new SvcLogicException("Attempted to execute a node of type " + node.getNodeType() + ", but no executor was registered for this type"); + } + } + + @Override + public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException { + return (store.hasGraph(module, rpc, version, mode)); + } + + @Override + public Properties execute(String module, String rpc, String version, String mode, Properties props) + throws SvcLogicException { + + SvcLogicContext ctx = new SvcLogicContext(props); + + return(execute(module, rpc, version, mode, ctx).toProperties()); + } + + @Override + public SvcLogicContext execute(String module, String rpc, String version, String mode, SvcLogicContext ctx) throws SvcLogicException { + SvcLogicGraph graph = store.fetch(module, rpc, version, mode); + + if (ctx == null) { + ctx = new SvcLogicContext(); + } + + if (graph == null) { + ctx.setAttribute("error-code", "401"); + ctx.setAttribute("error-message", + "No service logic found for [" + module + "," + rpc + "," + version + "," + mode + "]"); + return (ctx); + } + + + + ctx.setAttribute(CURRENT_GRAPH, graph.toString()); + // To support legacy code we should not stop populating X-ECOMP-RequestID + ctx.setAttribute("X-ECOMP-RequestID", MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)); + execute(graph, ctx); + return (ctx); + } + + @Override + public SvcLogicStore getStore() throws SvcLogicException { + return this.store; + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java new file mode 100644 index 000000000..2186a38e0 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/SwitchNodeExecutor.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SwitchNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory + .getLogger(SwitchNodeExecutor.class); + + @Override + + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + + + String testResult = evaluateNodeTest(node, ctx); + + if (LOG.isDebugEnabled()) { + LOG.debug("Executing switch node"); + + + LOG.debug("test expression (" + node.getAttribute("test") + + ") evaluates to " + testResult); + } + + SvcLogicNode nextNode = node.getOutcomeValue(testResult); + + if (LOG.isDebugEnabled()) { + if (nextNode != null) { + LOG.debug("Next node to execute is node " + nextNode.getNodeId()); + } else { + LOG.debug("No next node found"); + } + } + return (nextNode); + + } +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java new file mode 100644 index 000000000..c22c573cd --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/UpdateNodeExecutor.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UpdateNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(UpdateNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) + throws SvcLogicException { + + String plugin = SvcLogicExpressionResolver.evaluate(node.getAttribute("plugin"), node, ctx); + String resourceType = SvcLogicExpressionResolver.evaluate(node.getAttribute("resource"), node, ctx); + String key = SvcLogicExpressionResolver.evaluateAsKey(node.getAttribute("key"), node, ctx); + String pfx = SvcLogicExpressionResolver.evaluate(node.getAttribute("pfx"), node, ctx); + + + Map<String, String> parmMap = getResolvedParameters(node,ctx); + + String outValue = SvcLogicConstants.FAILURE; + + if (LOG.isDebugEnabled()) { + LOG.debug("save node encountered - looking for resource class " + plugin); + } + + + SvcLogicResource resourcePlugin = getSvcLogicResource(plugin); + + + if (resourcePlugin != null) { + + try { + switch (resourcePlugin.update(resourceType, key, parmMap, pfx, ctx)) { + case SUCCESS: + outValue = SvcLogicConstants.SUCCESS; + break; + case NOT_FOUND: + outValue = "not-found"; + break; + case FAILURE: + default: + outValue = SvcLogicConstants.FAILURE; + } + } catch (SvcLogicException e) { + LOG.error("Caught exception from resource plugin", e); + outValue = SvcLogicConstants.FAILURE; + } + } else { + LOG.warn("Could not find SvcLogicResource object for plugin " + plugin); + } + return (getNextNode(node, outValue)); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java new file mode 100644 index 000000000..3078b3437 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/provider/base/WhileNodeExecutor.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import org.onap.ccsdk.sli.core.sli.BreakNodeException; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WhileNodeExecutor extends AbstractSvcLogicNodeExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(WhileNodeExecutor.class); + + @Override + public SvcLogicNode execute(SvcLogicServiceBase svc, SvcLogicNode node, SvcLogicContext ctx) throws SvcLogicException { + + String testResult = evaluateNodeTest(node, ctx); + SvcLogicExpression silentFailureExpr = node.getAttribute("do"); + String doWhile = SvcLogicExpressionResolver.evaluate(silentFailureExpr, node, ctx); + if ("true".equals(doWhile)) { + LOG.debug("While loop will execute once regardless of expression because do is set to true"); + } + + try { + while ("true".equals(testResult) || "true".equals(doWhile)) { + if (!"true".equals(doWhile)) { + LOG.debug("Test expression (" + node.getAttribute("test") + ") evaluates to true, executing loop."); + } + int numOutcomes = node.getNumOutcomes() + 1; + for (int i = 0; i < numOutcomes; i++) { + SvcLogicNode nextNode = node.getOutcomeValue("" + (i + 1)); + if (nextNode != null) { + while (nextNode != null) { + nextNode = svc.executeNode(nextNode, ctx); + } + } else { + if ("true".equals(doWhile)) { + LOG.debug("Do executed, will only execute again if test expression is true."); + doWhile = "false"; + } + testResult = evaluateNodeTest(node, ctx); + LOG.debug("test expression (" + node.getAttribute("test") + ") evaluates to " + testResult); + } + } + } + LOG.debug("testResult was " + testResult + " which is not equal to true, exiting while loop."); + } catch (BreakNodeException e) { + LOG.debug("WhileNodeExecutor caught break" + e.getMessage()); + } + return (null); + } + +} diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java new file mode 100644 index 000000000..7d690e745 --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/FileRecorder.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.recording; + +import java.io.File; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.TimeZone; + +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.utils.PathValidator; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder; + + +public class FileRecorder implements SvcLogicRecorder { + + @Override + public void record(Map<String, String> parmMap) throws SvcLogicException { + + String fileName = parmMap.get("file"); + if (fileName == null) + { + throw new ConfigurationException("No file parameter specified"); + } + + if (!PathValidator.isValidFilePath(fileName)) { + throw new ConfigurationException("Invalid file name ("+fileName+")"); + } + + String record = parmMap.get("record"); + if (record == null) + { + String delimiter = parmMap.get("delimiter"); + if (delimiter == null) + { + delimiter = "|"; + } + + int idx = 1; + boolean moreFields = true; + while (moreFields) + { + String curField = parmMap.get("field"+idx++); + if (curField == null) + { + moreFields = false; + } + else + { + if (record == null) + { + record = delimiter; + } + record = record + curField + delimiter; + } + } + } + + if (record == null) + { + throw new ConfigurationException("No record/fields passed in record node"); + } + + File recordFile = new File(fileName); + Date now = new Date(); + + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat dateFmt = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss:SS'+00:00'"); + dateFmt.setTimeZone(tz); + if (record.indexOf("__TIMESTAMP__") != -1) + { + record = record.replaceFirst("__TIMESTAMP__", dateFmt.format(now)); + } + + try ( FileWriter fileWriter = new FileWriter(recordFile, true); + PrintWriter recPrinter = new PrintWriter(fileWriter)) + { + recPrinter.println(record); + } + catch (Exception e) + { + throw new SvcLogicException("Cannot write record to file", e); + } + } + +} + diff --git a/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java new file mode 100644 index 000000000..4f67c5d9a --- /dev/null +++ b/core/sli/provider-base/src/main/java/org/onap/ccsdk/sli/core/sli/recording/Slf4jRecorder.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.recording; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.TimeZone; + +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.sli.ErrorLogger; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Slf4jRecorder implements SvcLogicRecorder { + protected DateFormat dateFmt; + protected static final String messageLogName = "message-log"; + + public enum Level { + ERROR, + WARN, + INFO, + DEBUG, + TRACE + } + + protected Logger defaultLogger = LoggerFactory.getLogger(Slf4jRecorder.class); + protected Logger messageLogger = LoggerFactory.getLogger(messageLogName); + + public Slf4jRecorder() { + TimeZone tz = TimeZone.getTimeZone("UTC"); + dateFmt = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss:SS'+00:00'"); + dateFmt.setTimeZone(tz); + } + + @Override + public void record(Map<String, String> parmMap) throws SvcLogicException { + String lvl = parmMap.get("level"); + if (lvl == null) { + lvl = "INFO"; + } + + Level level = Level.INFO; + + try { + level = Level.valueOf(lvl.toUpperCase()); + } catch (Exception e) {} + + + + String record = parmMap.get("record"); + if (record == null) + { + String delimiter = parmMap.get("delimiter"); + if (delimiter == null) + { + delimiter = "|"; + } + + int idx = 1; + boolean moreFields = true; + while (moreFields) + { + String curField = parmMap.get("field"+idx++); + if (curField == null) + { + moreFields = false; + } + else + { + if (record == null) + { + record = delimiter; + } + record = record + curField + delimiter; + } + } + } + + if (record == null) + { + throw new ConfigurationException("No record/fields passed in record node"); + } + + String loggerName = parmMap.get("logger"); + Logger logger = null; + if (loggerName == null) { + logger = defaultLogger; + }else { + if(loggerName.equals(messageLogName)){ + logger = messageLogger; + }else { + logger = LoggerFactory.getLogger(loggerName); + } + } + + Date now = new Date(); + + if (record.indexOf("__TIMESTAMP__") != -1) + { + record = record.replaceFirst("__TIMESTAMP__", dateFmt.format(now)); + } + + switch (level) { + case ERROR: + String errorCode = parmMap.get("errorCode"); + String errorDescription = parmMap.get("errorDescription"); + + if ((errorCode != null && !errorCode.isEmpty()) + || (errorDescription != null && !errorDescription.isEmpty())) { + ErrorLogger e = new ErrorLogger(logger); + + Integer integerCode = 0; + try { + integerCode = Integer.valueOf(errorCode); + } catch (NumberFormatException nfe) { + // do nothing + } + e.createLogEntry(record, integerCode, errorDescription, null); + } else { + logger.error(record); + } + break; + case WARN: + logger.warn(record); + break; + case INFO: + logger.info(record); + break; + case DEBUG: + logger.debug(record); + break; + case TRACE: + logger.trace(record); + } + } + +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java new file mode 100644 index 000000000..6c5877ebc --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/BadPlugin.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.Map; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; + + +public class BadPlugin implements SvcLogicJavaPlugin { + public String selectLunch(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException { + String day = parameters.get("day"); + if (day == null || day.length() < 1) { + throw new SvcLogicException("What day is it?"); + } + switch (day) { + case ("monday"): { + return "pizza"; + } + case ("tuesday"): { + return "soup"; + } + case ("wednesday"): { + return "salad"; + } + case ("thursday"): { + return "sushi"; + } + case ("friday"): { + return "bbq"; + } + } + throw new SvcLogicException("Lunch cannot be served"); + } +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java new file mode 100644 index 000000000..9a929387f --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/ExecuteNodeExecutorTest.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.Properties; +import org.onap.ccsdk.sli.core.sli.DuplicateValueException; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import junit.framework.TestCase; + +public class ExecuteNodeExecutorTest extends TestCase { + public class MockExecuteNodeExecutor extends ExecuteNodeExecutor { + + protected SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) { + return (SvcLogicJavaPlugin) new LunchSelectorPlugin(); + } + + protected String evaluate(SvcLogicExpression expr, SvcLogicNode node, + SvcLogicContext ctx) throws SvcLogicException { + return "selectLunch"; + } + } + + public void testBadPlugin() throws DuplicateValueException, SvcLogicException { + LunchSelectorPlugin p = new LunchSelectorPlugin(); + MockExecuteNodeExecutor execute = new MockExecuteNodeExecutor(); + SvcLogicNode node = new SvcLogicNode(0, "", "", new SvcLogicGraph()); + node.setAttribute("method", "selectLunch"); + SvcLogicPropertiesProvider resourceProvider = new SvcLogicPropertiesProvider() { + + public Properties getProperties() { + return new Properties(); + }; + }; + + + execute.execute(new SvcLogicServiceImplBase(null, null), new SvcLogicNode(0, "", "", new SvcLogicGraph()), + new SvcLogicContext()); + } + +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java new file mode 100644 index 000000000..3534d5f90 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/GraphTests.java @@ -0,0 +1,61 @@ +package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+import org.onap.ccsdk.sli.core.sli.SvcLogicParser;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GraphTests {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GraphTests.class);
+ private static final SvcLogicStore store = new InMemorySvcLogicStore();
+ private static final HashMapResolver resolver = new HashMapResolver();
+ private static final SvcLogicServiceBase svc = new SvcLogicServiceImplBase(store, resolver);
+ private static final SvcLogicParser p = new SvcLogicParser();
+ // Write a very simple recorder so record nodes can be used during debugging
+ private static final SvcLogicRecorder recorder = new SvcLogicRecorder() {
+ @Override
+ public void record(Map<String, String> map) throws SvcLogicException {
+ map.remove("level");
+ for (Entry<String, String> entry : map.entrySet()) {
+ LOG.debug(entry.getKey() + " = " + entry.getValue());
+ }
+ }
+ };
+
+ @Test
+ public void testBreakNode() throws Exception {
+ // This graph as a for node that will loop with start 0 and end 999
+ // in the loop idx is printed and variable "a" is incremented by 1
+ // there is an if block in the loop that when a equals 2 a break node should execute and break out of the for
+ // loop
+ SvcLogicContext ctx = executeGraph("src/test/resources/breakGraph.xml");
+ assertTrue(ctx.isSuccess());
+ assertEquals("2", ctx.getAttribute("idx")); // the break should happen when idx equals 2
+ assertEquals("3", ctx.getAttribute("a")); // incrementing a happens before the break so a should be idx + 1
+ }
+
+ public SvcLogicContext executeGraph(String pathToGraph) throws SvcLogicException {
+ return executeGraph(pathToGraph, new SvcLogicContext());
+ }
+
+ public SvcLogicContext executeGraph(String pathToGraph, SvcLogicContext context) throws SvcLogicException {
+ resolver.addSvcLogicRecorder("org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder", recorder);
+ LinkedList<SvcLogicGraph> graphList = p.parse(pathToGraph);
+ SvcLogicGraph graph = graphList.get(0);
+ store.store(graph);
+ store.activate(graph);
+ return svc.execute(graph, context);
+ }
+
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java new file mode 100644 index 000000000..5a2140696 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/HashMapResolverTest.java @@ -0,0 +1,51 @@ +package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertNotNull;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource;
+
+public class HashMapResolverTest {
+ @Mock
+ SvcLogicResource myResource;
+
+ @Mock
+ SvcLogicRecorder myRecorder;
+
+ @Mock
+ SvcLogicJavaPlugin myJavaPlugin;
+
+ @Mock
+ SvcLogicAdaptor myAdaptor;
+
+ @Rule
+ public MockitoRule mockitoRule = MockitoJUnit.rule();
+
+ @Test
+ public void simpleTest() throws Exception {
+
+ HashMapResolver resolver = new HashMapResolver();
+ String resourceKey = "simple.resource";
+ String recorderKey = "simple.record";
+ String pluginKey = "simple.plugin";
+ String adaptorKey = "simple.adaptor";
+
+ resolver.addSvcLogicAdaptor(adaptorKey, myAdaptor);
+ resolver.addSvcLogicRecorder(recorderKey, myRecorder);
+ resolver.addSvcLogicResource(resourceKey, myResource);
+ resolver.addSvcLogicSvcLogicJavaPlugin(pluginKey, myJavaPlugin);
+
+ assertNotNull(resolver.getSvcLogicAdaptor(adaptorKey));
+ assertNotNull(resolver.getSvcLogicJavaPlugin(pluginKey));
+ assertNotNull(resolver.getSvcLogicRecorder(recorderKey));
+ assertNotNull(resolver.getSvcLogicResource(resourceKey));
+
+
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java new file mode 100644 index 000000000..5f8757aa2 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/InMemorySvcLogicStoreTest.java @@ -0,0 +1,35 @@ +package org.onap.ccsdk.sli.core.sli.provider.base;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import java.util.Properties;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicGraph;
+
+public class InMemorySvcLogicStoreTest {
+ @Test
+ public void simpleTest() throws Exception {
+ InMemorySvcLogicStore store = new InMemorySvcLogicStore();
+ store.init(new Properties());
+ SvcLogicGraph graph = new SvcLogicGraph();
+ String module = "TEST";
+ String rpc = "NOTIFICATION";
+ String mode = "sync";
+ String version = "1";
+
+ graph.setModule(module);
+ graph.setRpc(rpc);
+ graph.setMode(mode);
+ graph.setVersion(version);
+
+ store.store(graph);
+ assertTrue(store.hasGraph(module, rpc, version, mode));
+ assertNotNull(store.fetch(module, rpc, version, mode));
+ store.activate(graph);
+ store.activate(module, rpc, version, mode);
+
+ store.delete(module, rpc, version, mode);
+ assertNull(store.fetch(module, rpc, version, mode));
+ }
+}
diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java new file mode 100644 index 000000000..0f4cab748 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/LunchSelectorPlugin.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.util.Map; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; + + + +public class LunchSelectorPlugin implements SvcLogicJavaPlugin { + public class UnknownLunchDayException extends Exception{ + + public UnknownLunchDayException(String string) { + super(string); + } + + } + class Sandwhich { + String meat; + String cheese; + + public Sandwhich(String meat, String cheese) { + this.meat = meat; + this.cheese = cheese; + } + } + + public String selectLunch(Map<String, String> parameters, SvcLogicContext ctx) throws Exception { + String day = parameters.get("day"); + if (day == null || day.length() < 1) { + throw new UnknownLunchDayException("What day is it?"); + } + switch (day) { + case ("monday"): { + return "pizza"; + } + case ("tuesday"): { + return "soup"; + } + case ("wednesday"): { + return "salad"; + } + case ("thursday"): { + return "sushi"; + } + case ("friday"): { + return "bbq"; + } + } + throw new SvcLogicException("Lunch cannot be served"); + } + + public Sandwhich makeLunch(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException { + return new Sandwhich("ham", "american"); + } +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java new file mode 100644 index 000000000..b154ecf01 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/PluginTest.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import org.onap.ccsdk.sli.core.sli.SvcLogicConstants; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.provider.base.ExecuteNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicExpressionResolver; + +import junit.framework.TestCase; + +public class PluginTest extends TestCase { + + // The existing plugins work just like a VoidDummyPlugin + // They will return null simply because they are all void + // The attribute emitsOutcome will not be present, the expected outcome is success when no exception is thrown by the plugin + public void testOldPlugin() throws Exception { + ExecuteNodeExecutor executor = new ExecuteNodeExecutor(); + SvcLogicJavaPlugin plugin = new SvcLogicJavaPlugin() { + public void dummy(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException { + return; + } + }; + + Class pluginClass = plugin.getClass(); + Method pluginMethod = pluginClass.getMethod("dummy", Map.class, SvcLogicContext.class); + Map<String, String> parmMap = new HashMap<String, String>(); + SvcLogicContext ctx = new SvcLogicContext(); + Object o = pluginMethod.invoke(plugin, parmMap, ctx); + + SvcLogicGraph graph = new SvcLogicGraph(); + SvcLogicNode node = new SvcLogicNode(1, "return", graph); + String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx); + String outValue = executor.mapOutcome(o, emitsOutcome); + assertEquals(SvcLogicConstants.SUCCESS,outValue); + } + + //Newer plugins can set the attribute emitsOutcome to true, if so they should return a string + //The string represents the outcome value + public void testNewPlugin() throws Exception { + ExecuteNodeExecutor executor = new ExecuteNodeExecutor(); + SvcLogicJavaPlugin plugin = new LunchSelectorPlugin(); + + Class pluginClass = plugin.getClass(); + Method pluginMethod = pluginClass.getMethod("selectLunch", Map.class, SvcLogicContext.class); + + Map<String, String> parmMap = new HashMap<String, String>(); + SvcLogicContext ctx = new SvcLogicContext(); + + parmMap.put("day", "monday"); + Object o = pluginMethod.invoke(plugin, parmMap, ctx); + SvcLogicGraph graph = new SvcLogicGraph(); + SvcLogicNode node = new SvcLogicNode(1, "return", graph); + node.setAttribute("emitsOutcome", "true"); + String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx); + String outValue = executor.mapOutcome(o, emitsOutcome); + assertEquals("pizza", outValue); + + parmMap.put("day", "tuesday"); + outValue = (String) pluginMethod.invoke(plugin, parmMap, ctx); + o = pluginMethod.invoke(plugin, parmMap, ctx); + outValue = executor.mapOutcome(o, emitsOutcome); + assertEquals("soup",outValue); + + } + + //APPC had some legacy plugins returning objects which should not be treated as outcomes + //The attribute emitsOutcome will not be set + //The outcome should be success as it has always been + public void testObjPlugin() throws Exception{ + ExecuteNodeExecutor executor = new ExecuteNodeExecutor(); + SvcLogicJavaPlugin plugin = new LunchSelectorPlugin(); + + Class pluginClass = plugin.getClass(); + Method pluginMethod = pluginClass.getMethod("makeLunch", Map.class, SvcLogicContext.class); + + Map<String, String> parmMap = new HashMap<String, String>(); + SvcLogicContext ctx = new SvcLogicContext(); + Object o = pluginMethod.invoke(plugin, parmMap, ctx); + SvcLogicGraph graph = new SvcLogicGraph(); + SvcLogicNode node = new SvcLogicNode(1, "return", graph); + String emitsOutcome = SvcLogicExpressionResolver.evaluate(node.getAttribute("emitsOutcome"), node, ctx); + String outValue = executor.mapOutcome(o, emitsOutcome); + assertEquals(SvcLogicConstants.SUCCESS,outValue); + } + +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java new file mode 100644 index 000000000..115989a80 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SetNodeExecutorTest.java @@ -0,0 +1,220 @@ +package org.onap.ccsdk.sli.core.sli.provider.base; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import java.util.LinkedList; +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.SvcLogicParser; +import org.onap.ccsdk.sli.core.sli.provider.base.SetNodeExecutor; + +public class SetNodeExecutorTest { + @Test + public void clearProperties() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertNull(ctx.getAttribute("si.field1")); + assertNull(ctx.getAttribute("si.field2")); + assertNull(ctx.getAttribute("si.field3")); + assertNull(ctx.getAttribute("si.subarray[0]")); + assertNull(ctx.getAttribute("si.subarray[1]")); + assertNull(ctx.getAttribute("si.subarray[2]")); + assertNull(ctx.getAttribute("si.subarray_length")); + assertEquals("6", ctx.getAttribute("search1")); + assertEquals("KeepMe!", ctx.getAttribute("simonSays")); + } + + @Test + public void clearMultipleArrayProperties() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearMultipleArrayValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertNull(ctx.getAttribute("si[0].field1")); + assertNull(ctx.getAttribute("si[1].field2")); + assertNull(ctx.getAttribute("si[2].field3")); + assertNull(ctx.getAttribute("si_length")); + assertNull(ctx.getAttribute("si[0].subarray[0]")); + assertNull(ctx.getAttribute("si[0].subarray[1]")); + assertNull(ctx.getAttribute("si[0].subarray[2]")); + assertNull(ctx.getAttribute("si[0].subarray_length")); + assertEquals("6", ctx.getAttribute("search1")); + assertEquals("KeepMe!", ctx.getAttribute("simonSays")); + } + + @Test + public void clearSingleArrayProperties() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearSingleArrayValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertNull(ctx.getAttribute("si[0].field1")); + assertNull(ctx.getAttribute("si[0].subarray[0]")); + assertNull(ctx.getAttribute("si[0].subarray[1]")); + assertNull(ctx.getAttribute("si[0].subarray[2]")); + assertNull(ctx.getAttribute("si[0].subarray_length")); + + // TODO: This is just setting up elements as null but note reducing the size of Array. + assertEquals("3",ctx.getAttribute("si_length")); + + assertEquals("2",ctx.getAttribute("si[1].field2")); + assertEquals("3", ctx.getAttribute("si[2].field3")); + assertEquals("6", ctx.getAttribute("search1")); + assertEquals("KeepMe!", ctx.getAttribute("simonSays")); + } + + @Test + public void clearSingleSubArrayProperties() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearSingleSubArrayValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertEquals("1",ctx.getAttribute("tmp.si[0].field1")); + assertEquals("2",ctx.getAttribute("tmp.si[1].field2")); + assertEquals("3", ctx.getAttribute("tmp.si[2].field3")); + assertEquals("3", ctx.getAttribute("tmp.si_length")); + + assertEquals("a",ctx.getAttribute("tmp.si[0].subarray[0]")); + + // TODO: This is setting up element as Empty instead null + //assertNull(ctx.getAttribute("tmp.si[0].subarray[1]")); + assertEquals("", ctx.getAttribute("tmp.si[0].subarray[1]")); + + assertEquals("c", ctx.getAttribute("tmp.si[0].subarray[2]")); + assertEquals("3", ctx.getAttribute("tmp.si[0].subarray_length")); + + assertEquals("x",ctx.getAttribute("tmp.si[1].subarray[0]")); + assertEquals("y",ctx.getAttribute("tmp.si[1].subarray[1]")); + assertEquals("z", ctx.getAttribute("tmp.si[1].subarray[2]")); + assertEquals("3", ctx.getAttribute("tmp.si[1].subarray_length")); + + assertEquals("6", ctx.getAttribute("search1")); + assertEquals("KeepMe!", ctx.getAttribute("simonSays")); + } + + @Test + public void clearSubArrayProperties() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearSubArrayValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertEquals("1", ctx.getAttribute("si[0].field1")); + assertEquals("2",ctx.getAttribute("si[1].field2")); + assertEquals("3", ctx.getAttribute("si[2].field3")); + assertEquals("3", ctx.getAttribute("si_length")); + assertNull(ctx.getAttribute("si[0].subarray[0]")); + assertNull(ctx.getAttribute("si[0].subarray[1]")); + assertNull(ctx.getAttribute("si[0].subarray[2]")); + assertNull(ctx.getAttribute("si[0].subarray_length")); + + assertEquals("6", ctx.getAttribute("search1")); + assertEquals("KeepMe!", ctx.getAttribute("simonSays")); + } + + @Test + public void arrayPattern() { + SetNodeExecutor sne = new SetNodeExecutor(); + String source = "one.two[0].three[0].four"; + assertEquals("one.two.three.four", source.replaceAll(sne.arrayPattern, "")); + } + + @Test + public void subtreeCopy() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/copyValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertEquals("1", ctx.getAttribute("si.field1")); + assertEquals("2", ctx.getAttribute("si.field2")); + assertEquals("3", ctx.getAttribute("si.field3")); + assertEquals("1", ctx.getAttribute("rootTwo.field1")); + assertEquals("2", ctx.getAttribute("rootTwo.field2")); + assertEquals("3", ctx.getAttribute("rootTwo.field3")); + } + + @Test + public void clearNestedSubArrayProperties() throws Exception { + SetNodeExecutor sne = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/clearNestedSubArrayValues.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); + SvcLogicNode nodeOne = root.getOutcomeValue("1"); + SvcLogicNode nodeTwo = root.getOutcomeValue("2"); + + sne.execute(nodeOne, ctx); + sne.execute(nodeTwo, ctx); + + assertEquals("1", ctx.getAttribute("tmp.si[0].field1")); + assertEquals("2",ctx.getAttribute("tmp.si[1].field2")); + assertEquals("3", ctx.getAttribute("tmp.si[2].field3")); + assertEquals("3", ctx.getAttribute("tmp.si_length")); + + assertNull(ctx.getAttribute("tmp.si[0].subarray[0]")); + assertNull(ctx.getAttribute("tmp.si[0].subarray[1]")); + assertNull(ctx.getAttribute("tmp.si[0].subarray[2]")); + assertNull(ctx.getAttribute("tmp.si[0].subarray_length")); + + assertEquals("x", ctx.getAttribute("tmp.si[1].subarray[0]")); + assertEquals("y",ctx.getAttribute("tmp.si[1].subarray[1]")); + assertEquals("z", ctx.getAttribute("tmp.si[1].subarray[2]")); + assertEquals("3", ctx.getAttribute("tmp.si[1].subarray_length")); + + assertEquals("6", ctx.getAttribute("search1")); + assertEquals("KeepMe!", ctx.getAttribute("simonSays")); + } + +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java new file mode 100644 index 000000000..054b38d0f --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/provider/base/SvcLogicExpressionResolverTest.java @@ -0,0 +1,280 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider.base; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.LinkedList; + +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicExprListener; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpression; +import org.onap.ccsdk.sli.core.sli.SvcLogicExpressionFactory; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicNode; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicExpressionResolver; +import org.onap.ccsdk.sli.core.sli.SvcLogicParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import junit.framework.Assert; +import junit.framework.TestCase; + +public class SvcLogicExpressionResolverTest extends TestCase { + + + private static final Logger LOG = LoggerFactory + .getLogger(SvcLogicExpressionResolver.class); + + public void testEvaluate() + { + InputStream testStr = getClass().getResourceAsStream("/expression.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + + try + { + SvcLogicContext ctx = new SvcLogicContext(); + SvcLogicGraph graph = new SvcLogicGraph(); + SvcLogicNode node = new SvcLogicNode(1, "return", graph); + graph.setRootNode(node); + + String line = null; + int lineNo = 0; + while ((line = testsReader.readLine()) != null) { + ++lineNo; + if (line.startsWith("#")) + { + String testExpr = line.trim().substring(1).trim(); + String[] nameValue = testExpr.split("="); + String name = nameValue[0].trim(); + String value = nameValue[1].trim(); + + if (name.startsWith("$")) + { + LOG.info("Setting context attribute "+name+" = "+value); + ctx.setAttribute(name.substring(1), value); + } + else + { + + LOG.info("Setting node attribute "+name+" = "+value); + node.setAttribute(name, value); + + } + } + else + { + // if the line contains #, what comes before is the expression to evaluate, and what comes after + // is the expected value + String[] substrings = line.split("#"); + String expectedValue = substrings.length > 1 ? substrings[1].trim() : null; + String testExpr = substrings[0].trim(); + + LOG.info("Parsing expression "+testExpr); + SvcLogicExpression expr = SvcLogicExpressionFactory.parse(testExpr); + if (expr == null) + { + fail("Unable to parse expression "+testExpr); + } + else + { + LOG.info("Evaluating parsed expression "+expr.asParsedExpr()); + String exprValue = SvcLogicExpressionResolver.evaluate(expr, node, ctx); + if (exprValue == null) + { + fail("Unable to evaluate expression "+testExpr); + } + else + { + LOG.info("Expression " + testExpr + " evaluates to " + exprValue); + if (expectedValue != null) { + Assert.assertEquals("Line " + lineNo + ": " + testExpr, expectedValue, exprValue); + } + } + } + } + } + } + catch (Exception e) + { + LOG.error("Caught exception", e); + fail("Caught exception"); + } + } + + public void testSvcLogicExpressions() throws Exception { + SwitchNodeExecutor switchNodeExecutor = new SwitchNodeExecutor(); + SetNodeExecutor setNodeExecutor = new SetNodeExecutor(); + SvcLogicContext ctx = new SvcLogicContext(); + SvcLogicParser slp = new SvcLogicParser(); + LinkedList<SvcLogicGraph> graph = slp.parse("src/test/resources/expressions.xml"); + SvcLogicNode root = graph.getFirst().getRootNode(); +//Test a set node that makes use of arithmetic operations +/* +<set> + <parameter name='add' value='`1 + 1`' /> + <parameter name='sub' value='`2 - 1`' /> + <parameter name='div' value='`6 / 2`' /> + <parameter name='multi' value='`2 * 2`' /> + <parameter name='addDoubleQuotes' value="`1 + 1`" /> + <parameter name='subDoubleQuotes' value="`2 - 1`" /> + <parameter name='divDoubleQuotes' value="`6 / 2`" /> + <parameter name='multiDoubleQuotes' value="`2 * 2`" /> +</set> +*/ +//the node matching outcome value 1 comes from parsing the block of xml above + ctx.setAttribute("a", "5"); + ctx.setAttribute("b", "3"); + setNodeExecutor.execute(root.getOutcomeValue("1"), ctx); + assertEquals("2", ctx.getAttribute("add")); + assertEquals("1", ctx.getAttribute("sub")); + assertEquals("3", ctx.getAttribute("div")); + assertEquals("4", ctx.getAttribute("multi")); + assertEquals("2", ctx.getAttribute("addDoubleQuotes")); + assertEquals("1", ctx.getAttribute("subDoubleQuotes")); + assertEquals("3", ctx.getAttribute("divDoubleQuotes")); + assertEquals("4", ctx.getAttribute("multiDoubleQuotes")); + +//Test a set node that makes use of string concatenation +/* +<set> + <parameter name='varA' value='`$a + $b`' /> + <parameter name='varB' value='`$a + 'literal' `' /> + <parameter name='varC' value='`'literal' + $b `' /> + <parameter name='varD' value='`'too' + 'literal'`' /> + <parameter name='varADoubleQuotes' value="`$a + $b`" /> + <parameter name='varBDoubleQuotes' value="`$a +'literal' `" /> + <parameter name='varCDoubleQuotes' value="`'literal' + $b `" /> + <parameter name='varDDoubleQuotes' value="`'too' + 'literal'`" /> +</set> +*/ +//the node matching outcome value 2 comes from parsing the block of xml above + ctx.setAttribute("a", "cat"); + ctx.setAttribute("b", "dog"); + setNodeExecutor.execute(root.getOutcomeValue("2"), ctx); + assertEquals("catdog", ctx.getAttribute("varA")); + assertEquals("catliteral", ctx.getAttribute("varB")); + assertEquals("literaldog", ctx.getAttribute("varC")); + assertEquals("tooliteral", ctx.getAttribute("varD")); + assertEquals("catdog", ctx.getAttribute("varADoubleQuotes")); + assertEquals("catliteral", ctx.getAttribute("varBDoubleQuotes")); + assertEquals("literaldog", ctx.getAttribute("varCDoubleQuotes")); + assertEquals("tooliteral", ctx.getAttribute("varDDoubleQuotes")); + +//Shows how backticks interact with + operator +/* +<set> + <parameter name='testOne' value='`1 + 1`' /> + <parameter name='testThree' value='"1" +"1"' /> + <parameter name='testFour' value='`$portNumber + $slot + $shelf`' /> + <parameter name='testOneDoubleQuotes' value="`1 + 1`" /> + <parameter name='testThreeDoubleQuotes' value="'1' +'1'" /> + <parameter name='testFourDoubleQuotes' value="`$portNumber + $slot + $shelf`" /> +</set> +*/ +//the node matching outcome value 3 comes from parsing the block of xml above + ctx.setAttribute("portNumber", "2"); + ctx.setAttribute("slot", "3"); + ctx.setAttribute("shelf", "1"); + + setNodeExecutor.execute(root.getOutcomeValue("3"), ctx); + assertEquals("2", ctx.getAttribute("testOne")); + assertEquals("\"1\" +\"1\"", ctx.getAttribute("testThree")); + assertEquals("6", ctx.getAttribute("testFour")); + assertEquals("2", ctx.getAttribute("testOneDoubleQuotes")); + assertEquals("'1' +'1'", ctx.getAttribute("testThreeDoubleQuotes")); + assertEquals("6", ctx.getAttribute("testFourDoubleQuotes")); + + ctx.setAttribute("a", "5"); + ctx.setAttribute("b", "3"); + + // series of switch statements showing and or != > < >= == <= + // the XML for the node is commented above the line that evaluates that node, the switch statements are single line + + //<switch test="`'PIZZA' == 'NOTPIZZA' or $a != $b`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("4"), ctx)); + + //<switch test="`'PIZZA' == 'PIZZA' and $a != $b`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("5"), ctx)); + + //<switch test="`'PIZZA' == 'NOTPIZZA' or $a >= $b`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("6"), ctx)); + + //<switch test="`'PIZZA' == 'PIZZA' and $b < $a`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("7"), ctx)); + + //<switch test="`'PIZZA' == 'PIZZA'`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("8"), ctx)); + + //<switch test="`$a == $b`" /> + assertEquals("false",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("9"), ctx)); + + //<switch test="`'PIZZA' == 'NOTPIZZA'`" /> + assertEquals("false",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("10"), ctx)); + + //<switch test="`'PIZZA' != 'PIZZA'`" /> + assertEquals("false",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("11"), ctx)); + + //<switch test="`'PIZZA' != 'NOTPIZZA'`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("12"), ctx)); + + //<switch test='`$a != $b`' /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("13"), ctx)); + + //<switch test='`1 < 2`' /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("14"), ctx)); + + //<switch test='`2 <= 2`' /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("15"), ctx)); + + //<switch test='`3 > 2`' /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("16"), ctx)); + + //<switch test='`2 >= 2`' /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("17"), ctx)); + + // Series of switch statements that show the effect of using backticks + + ctx.setAttribute("literalStartingWithDollarSign", "DONT READ ME!"); + //<switch test='$literalStartingWithDollarSign'/> + assertEquals("$literalStartingWithDollarSign",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("18"), ctx)); + + ctx.setAttribute("dollarSignFollowedByVariableSurroundedinBackticks", "README"); + //<switch test='$literalStartingWithDollarSign'/> + assertEquals("README",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("19"), ctx)); + + ctx.setAttribute("a", "2"); + ctx.setAttribute("b", "2"); + //<switch test='`$a == $b`' /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("20"), ctx)); + + //<switch test="`$a == $b`" /> + assertEquals("true",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("21"), ctx)); + + //<switch test='$a == $b' /> + assertEquals("$a == $b",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("22"), ctx)); + + //<switch test="$a == $b" /> + assertEquals("$a == $b",switchNodeExecutor.evaluateNodeTest(root.getOutcomeValue("23"), ctx)); + } +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java new file mode 100644 index 000000000..d0cc83182 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestFileRecorder.java @@ -0,0 +1,49 @@ +/** + * + */ +package org.onap.ccsdk.sli.core.sli.recording; + +import static org.junit.Assert.fail; + +import java.util.HashMap; + +import org.junit.Before; +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +/** + * @author dt5972 + * + */ +public class TestFileRecorder { + private FileRecorder recorder; + + @Before + public void setUp() { + recorder = new FileRecorder(); + } + + /** + * Test method for + * {@link org.onap.ccsdk.sli.core.sli.recording.FileRecorder#record(java.util.Map)}. + */ + @Test + public void testRecord() { + HashMap<String, String> parms = new HashMap<>(); + parms.put("file", "/dev/null"); + parms.put("field1", "hi"); + try { + recorder.record(parms); + } catch (SvcLogicException e) { + fail("Caught SvcLogicException : " + e.getMessage()); + } + } + + @Test(expected = Exception.class) + public void testRecordForEmptyFileName() throws Exception { + HashMap<String, String> parms = new HashMap<>(); + parms.put("field1", "hi"); + recorder.record(parms); + } + +} diff --git a/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java new file mode 100644 index 000000000..c696f25b5 --- /dev/null +++ b/core/sli/provider-base/src/test/java/org/onap/ccsdk/sli/core/sli/recording/TestSlf4jRecorder.java @@ -0,0 +1,33 @@ +/** + * + */ +package org.onap.ccsdk.sli.core.sli.recording; + +import static org.junit.Assert.*; +import java.util.HashMap; +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; + +/** + * @author dt5972 + * + */ +public class TestSlf4jRecorder { + + /** + * Test method for {@link org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder#record(java.util.Map)}. + */ + @Test + public void testRecord() { + Slf4jRecorder recorder = new Slf4jRecorder(); + + HashMap<String,String> parms = new HashMap<>(); + parms.put("field1","hi"); + try { + recorder.record(parms); + } catch (SvcLogicException e) { + fail("Caught SvcLogicException : "+e.getMessage()); + } + } + +} diff --git a/core/sli/provider-base/src/test/resources/breakGraph.xml b/core/sli/provider-base/src/test/resources/breakGraph.xml new file mode 100644 index 000000000..e2b89e84f --- /dev/null +++ b/core/sli/provider-base/src/test/resources/breakGraph.xml @@ -0,0 +1,26 @@ +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='JUNIT' version='1'>
+ <method rpc='BREAK' mode='sync'>
+ <block>
+ <set>
+ <parameter name='a' value='0' />
+ </set>
+ <for index='idx' start='0' end='999' >
+ <record plugin="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder">
+ <parameter name="logger" value="message-log" />
+ <parameter name="level" value="error" />
+ <parameter name="field1" value="`$idx`" />
+ </record>
+ <set>
+ <parameter name='a' value='`$a + 1`' />
+ </set>
+ <switch test="`$idx == 2`">
+ <outcome value='true'>
+ <break/>
+ </outcome>
+ </switch>
+ </for>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml b/core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml new file mode 100644 index 000000000..8f40058f1 --- /dev/null +++ b/core/sli/provider-base/src/test/resources/clearMultipleArrayValues.xml @@ -0,0 +1,23 @@ +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si[0].field1' value='1' />
+ <parameter name='si[1].field2' value='2' />
+ <parameter name='si[2].field3' value='3' />
+ <parameter name='si_length' value='3' />
+ <parameter name='si[0].subarray[0]' value='a' />
+ <parameter name='si[0].subarray[1]' value='b' />
+ <parameter name='si[0].subarray[2]' value='c' />
+ <parameter name='si[0].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si.' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml b/core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml new file mode 100644 index 000000000..a80b3e56c --- /dev/null +++ b/core/sli/provider-base/src/test/resources/clearNestedSubArrayValues.xml @@ -0,0 +1,27 @@ +<service-logic + xmlns='http://www.onap.org/sdnc/svclogic' + xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'> + <method rpc='test-dg' mode='sync'> + <block> + <set> + <parameter name='tmp.si[0].field1' value='1' /> + <parameter name='tmp.si[1].field2' value='2' /> + <parameter name='tmp.si[2].field3' value='3' /> + <parameter name='tmp.si_length' value='3' /> + <parameter name='tmp.si[0].subarray[0]' value='a' /> + <parameter name='tmp.si[0].subarray[1]' value='b' /> + <parameter name='tmp.si[0].subarray[2]' value='c' /> + <parameter name='tmp.si[0].subarray_length' value='3' /> + <parameter name='tmp.si[1].subarray[0]' value='x' /> + <parameter name='tmp.si[1].subarray[1]' value='y' /> + <parameter name='tmp.si[1].subarray[2]' value='z' /> + <parameter name='tmp.si[1].subarray_length' value='3' /> + <parameter name='search1' value='6' /> + <parameter name='simonSays' value='KeepMe!' /> + </set> + <set> + <parameter name='tmp.si[0].subarray.' value='' /> + </set> + </block> + </method> +</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml b/core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml new file mode 100644 index 000000000..56781a066 --- /dev/null +++ b/core/sli/provider-base/src/test/resources/clearSingleArrayValues.xml @@ -0,0 +1,23 @@ +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si[0].field1' value='1' />
+ <parameter name='si[1].field2' value='2' />
+ <parameter name='si[2].field3' value='3' />
+ <parameter name='si_length' value='3' />
+ <parameter name='si[0].subarray[0]' value='a' />
+ <parameter name='si[0].subarray[1]' value='b' />
+ <parameter name='si[0].subarray[2]' value='c' />
+ <parameter name='si[0].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si[0].' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml b/core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml new file mode 100644 index 000000000..22f14f37b --- /dev/null +++ b/core/sli/provider-base/src/test/resources/clearSingleSubArrayValues.xml @@ -0,0 +1,27 @@ +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='tmp.si[0].field1' value='1' />
+ <parameter name='tmp.si[1].field2' value='2' />
+ <parameter name='tmp.si[2].field3' value='3' />
+ <parameter name='tmp.si_length' value='3' />
+ <parameter name='tmp.si[0].subarray[0]' value='a' />
+ <parameter name='tmp.si[0].subarray[1]' value='b' />
+ <parameter name='tmp.si[0].subarray[2]' value='c' />
+ <parameter name='tmp.si[0].subarray_length' value='3' />
+ <parameter name='tmp.si[1].subarray[0]' value='x' />
+ <parameter name='tmp.si[1].subarray[1]' value='y' />
+ <parameter name='tmp.si[1].subarray[2]' value='z' />
+ <parameter name='tmp.si[1].subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='tmp.si[0].subarray[1]' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/clearSubArrayValues.xml b/core/sli/provider-base/src/test/resources/clearSubArrayValues.xml new file mode 100644 index 000000000..cb25f38af --- /dev/null +++ b/core/sli/provider-base/src/test/resources/clearSubArrayValues.xml @@ -0,0 +1,24 @@ +<service-logic + xmlns='http://www.onap.org/sdnc/svclogic' + xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'> + <method rpc='test-dg' mode='sync'> + <block> + <set> + <parameter name='si[0].field1' value='1' /> + <parameter name='si[1].field2' value='2' /> + <parameter name='si[2].field3' value='3' /> + <parameter name='si_length' value='3' /> + <parameter name='si[0].subarray[0]' value='a' /> + <parameter name='si[0].subarray[1]' value='b' /> + <parameter name='si[0].subarray[2]' value='c' /> + <parameter name='si[0].subarray_length' value='3' /> + <parameter name='search1' value='6' /> + <parameter name='simonSays' value='KeepMe!' /> + </set> + <set> + <parameter name='si[0].subarray.' value='' /> + <!-- <parameter name='si.subarray.' value='' /> --> + </set> + </block> + </method> +</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/clearValues.xml b/core/sli/provider-base/src/test/resources/clearValues.xml new file mode 100644 index 000000000..dc7f5c8a2 --- /dev/null +++ b/core/sli/provider-base/src/test/resources/clearValues.xml @@ -0,0 +1,22 @@ +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si.field1' value='1' />
+ <parameter name='si.field2' value='2' />
+ <parameter name='si.field3' value='3' />
+ <parameter name='si.subarray[0]' value='a' />
+ <parameter name='si.subarray[1]' value='b' />
+ <parameter name='si.subarray[2]' value='c' />
+ <parameter name='si.subarray_length' value='3' />
+ <parameter name='search1' value='6' />
+ <parameter name='simonSays' value='KeepMe!' />
+ </set>
+ <set>
+ <parameter name='si.' value='' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/copyValues.xml b/core/sli/provider-base/src/test/resources/copyValues.xml new file mode 100644 index 000000000..f56f7140a --- /dev/null +++ b/core/sli/provider-base/src/test/resources/copyValues.xml @@ -0,0 +1,16 @@ +<service-logic
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='si.field1' value='1' />
+ <parameter name='si.field2' value='2' />
+ <parameter name='si.field3' value='3' />
+ </set>
+ <set>
+ <parameter name='rootTwo.' value='si.' />
+ </set>
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/expression.tests b/core/sli/provider-base/src/test/resources/expression.tests new file mode 100644 index 000000000..848a0e7a4 --- /dev/null +++ b/core/sli/provider-base/src/test/resources/expression.tests @@ -0,0 +1,24 @@ +# $uni-circuit-id = abc123 +# $uni-cir-units = 10 +# value = 1 +# $arg1 = 2 +# $network.name = vCE0001.in +# $network.segment[0].provider-segmentation-id = 1212 +# $network.segment[1].provider-segmentation-id = 1213 +# $availability-zone = mtsnj-esx-az01 +length($uni-circuit-id) > 0 # true +$uni-cir-units * 1000 * 100 / 100 # 10000 +$uni-cir-units / 1000 # 0 +$uni-cir-units - 100 # -90 +$uni-cir-units + 100 # 110 +(value * 3 - $arg1 > 0) and (length($uni-circuit-id) == 0) # true +'pg-'+$network.name # pg-vCE0001.in +$network.segment[0].provider-segmentation-id # 1212 +toUpperCase($network.name) # VCE0001.IN +toLowerCase($network.name) # vce0001.in +toUpperCase(substr($availability-zone, 0, 5)) # MTSNJ +convertBase(1234, 10) # 1234 +convertBase(10, 16, 10) # 16 +convertBase(ZZ, 36, 10) # 1295 +convertBase(10, 10, 36) # a +(0 - 1) * $arg1 # -1 diff --git a/core/sli/provider-base/src/test/resources/expressions.xml b/core/sli/provider-base/src/test/resources/expressions.xml new file mode 100755 index 000000000..79118570c --- /dev/null +++ b/core/sli/provider-base/src/test/resources/expressions.xml @@ -0,0 +1,55 @@ +<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='TEST-DG' version='1.0.0'>
+ <method rpc='test-dg' mode='sync'>
+ <block>
+ <set>
+ <parameter name='add' value='`1 + 1`' />
+ <parameter name='sub' value='`2 - 1`' />
+ <parameter name='div' value='`6 / 2`' />
+ <parameter name='multi' value='`2 * 2`' />
+ <parameter name='addDoubleQuotes' value="`1 + 1`" />
+ <parameter name='subDoubleQuotes' value="`2 - 1`" />
+ <parameter name='divDoubleQuotes' value="`6 / 2`" />
+ <parameter name='multiDoubleQuotes' value="`2 * 2`" />
+ </set>
+ <set>
+ <parameter name='varA' value='`$a + $b`' />
+ <parameter name='varB' value='`$a + 'literal' `' />
+ <parameter name='varC' value='`'literal' + $b `' />
+ <parameter name='varD' value='`'too' + 'literal'`' />
+ <parameter name='varADoubleQuotes' value="`$a + $b`" />
+ <parameter name='varBDoubleQuotes' value="`$a +'literal' `" />
+ <parameter name='varCDoubleQuotes' value="`'literal' + $b `" />
+ <parameter name='varDDoubleQuotes' value="`'too' + 'literal'`" />
+ </set>
+ <set>
+ <parameter name='testOne' value='`1 + 1`' />
+ <parameter name='testThree' value='"1" +"1"' />
+ <parameter name='testFour' value='`$portNumber + $slot + $shelf`' />
+ <parameter name='testOneDoubleQuotes' value="`1 + 1`" />
+ <parameter name='testThreeDoubleQuotes' value="'1' +'1'" />
+ <parameter name='testFourDoubleQuotes' value="`$portNumber + $slot + $shelf`" />
+ </set>
+ <switch test="`'PIZZA' == 'NOTPIZZA' or $a != $b`" />
+ <switch test="`'PIZZA' == 'PIZZA' and $a != $b`" />
+ <switch test="`'PIZZA' == 'NOTPIZZA' or $a >= $b`" />
+ <switch test="`'PIZZA' == 'PIZZA' and $b < $a`" />
+ <switch test="`'PIZZA' == 'PIZZA'`" />
+ <switch test="`$a == $b`" />
+ <switch test="`'PIZZA' == 'NOTPIZZA'`" />
+ <switch test="`'PIZZA' != 'PIZZA'`" />
+ <switch test="`'PIZZA' != 'NOTPIZZA'`" />
+ <switch test='`$a != $b`' />
+ <switch test='`1 < 2`' />
+ <switch test='`2 <= 2`' />
+ <switch test='`3 > 2`' />
+ <switch test='`2 >= 2`' />
+ <switch test='$literalStartingWithDollarSign' />
+ <switch test='`$dollarSignFollowedByVariableSurroundedinBackticks`' />
+ <switch test='`$a == $b`' />
+ <switch test="`$a == $b`" />
+ <switch test='$a == $b' />
+ <switch test="$a == $b" />
+ </block>
+ </method>
+</service-logic>
\ No newline at end of file diff --git a/core/sli/provider-base/src/test/resources/simplelogger.properties b/core/sli/provider-base/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..07ab67f70 --- /dev/null +++ b/core/sli/provider-base/src/test/resources/simplelogger.properties @@ -0,0 +1,22 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +org.slf4j.simpleLogger.defaultLogLevel=info diff --git a/core/sli/provider/pom.xml b/core/sli/provider/pom.xml new file mode 100755 index 000000000..3d5c389c4 --- /dev/null +++ b/core/sli/provider/pom.xml @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>2.1.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider</artifactId> + <version>1.1.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>ccsdk-sli-core :: sli :: ${project.artifactId}</name> + <description>SLI Provider is the OSGi bundle that exposes the service logic interpreter as a service.</description> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>dblib-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-model</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-common</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>sli-provider-base</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId> + <artifactId>rfc6991</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.bgpcep</groupId> + <artifactId>bgp-concepts</artifactId> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-core-api</artifactId> + <scope>provided</scope> + </dependency> + <!-- Testing Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derby</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <DynamicImport-Package>*</DynamicImport-Package> + </instructions> + </configuration> + </plugin> + <!-- Jacoco / Sonar --> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>${jacoco.version}</version> + <executions> + <execution> + <id>aggregate-report</id> + <phase>verify</phase> + <goals> + <goal>report-aggregate</goal> + </goals> + <configuration> + <dataFileIncludes> + target/code-coverage/jacoco-ut.exec, + target/code-coverage/jacoco-it.exec, + ../provider-base/target/code-coverage/jacoco-ut.exec, + ../provider-base/target/code-coverage/jacoco-it.exec + </dataFileIncludes> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java new file mode 100755 index 000000000..d3ab6c33a --- /dev/null +++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelper.java @@ -0,0 +1,1274 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisherBuilder; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MdsalHelper { + + private static final Logger LOG = LoggerFactory.getLogger(MdsalHelper.class); + private static Properties yangMappingProperties = new Properties(); + private static final String IP_ADDRESS="IpAddress"; + private static final String IPV4_ADDRESS="Ipv4Address"; + private static final String IPV6_ADDRESS="Ipv6Address"; + + private static final String IP_PREFIX="IpPrefix"; + private static final String SETTING_PROPERTY="Setting property "; + private static final String BUILDER="-builder"; + + @Deprecated + public static void setProperties(Properties input) { + setYangMappingProperties(input); + } + + @Deprecated + public static void setYangMappingProperties(Properties properties) { + for (Object propNameObj : properties.keySet()) { + String propName = (String) propNameObj; + MdsalHelper.yangMappingProperties.setProperty(propName, properties.getProperty(propName)); + } + } + + @Deprecated + public static void loadProperties(String propertiesFile) { + File file = new File(propertiesFile); + Properties properties = new Properties(); + if (file.isFile() && file.canRead()) { + try (InputStream input = new FileInputStream(file)) { + properties.load(input); + MdsalHelper.setYangMappingProperties(properties); + LOG.info("Loaded properties from " + propertiesFile); + } catch (Exception e) { + LOG.error("Failed to load properties " + propertiesFile + "\n", e); + } + } else { + LOG.error("Failed to load the properties file " + propertiesFile + "\n"); + LOG.error("Either isFile or canRead returned false for " + propertiesFile + "\n"); + } + } + + public static Properties toProperties(Properties props, Object fromObj) { + return toProperties(props, fromObj, false); + } + + public static Properties toProperties(Properties props, Object fromObj, Boolean useLegacyEnumerationMapping) { + Class fromClass = null; + + if (fromObj != null) { + fromClass = fromObj.getClass(); + } + return toProperties(props, "", fromObj, fromClass, useLegacyEnumerationMapping); + } + + public static Properties toProperties(Properties props, String pfx, Object fromObj) { + return toProperties(props, pfx, fromObj, false); + } + + public static Properties toProperties(Properties props, String pfx, Object fromObj, Boolean useLegacyEnumerationMapping) { + Class fromClass = null; + + if (fromObj != null) { + fromClass = fromObj.getClass(); + } + + return toProperties(props, pfx, fromObj, fromClass, useLegacyEnumerationMapping); + } + + public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass) { + return toProperties(props, pfx, fromObj, fromClass, false); + } + + public static Properties toProperties(Properties props, String pfx, Object fromObj, Class fromClass, Boolean useLegacyEnumerationMapping) { + + if (fromObj == null) { + return props; + } + String simpleTypeName = fromObj.getClass().getTypeName(); + simpleTypeName = simpleTypeName.substring(simpleTypeName.lastIndexOf(".") + 1); + + if (classHasSpecialHandling(simpleTypeName)) { + try { + + Method m = fromClass.getMethod(getStringValueMethod(simpleTypeName), null); + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object retValue = m.invoke(fromObj); + if (retValue != null) { + String propVal = null; + if (IP_ADDRESS.equals(simpleTypeName) || IP_PREFIX.equals(simpleTypeName) + || IPV4_ADDRESS.equals(simpleTypeName) || IPV6_ADDRESS.equals(simpleTypeName)) { + propVal = (String) retValue; + } else if ("Dscp".equals(simpleTypeName)) { + propVal = String.valueOf((short) retValue); + } else if ("PortNumber".equals(simpleTypeName)) { + propVal = String.valueOf((Integer) retValue); + } + LOG.debug(SETTING_PROPERTY + pfx + " to " + propVal); + props.setProperty(pfx, propVal); + } + } catch (Exception e) { + LOG.error("Caught exception trying to convert value returned by " + fromClass.getName() + + ".getValue() to Properties entry", e); + } + } else if (fromObj instanceof List) { + List fromList = (List) fromObj; + + for (int i = 0; i < fromList.size(); i++) { + toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass, useLegacyEnumerationMapping); + } + props.setProperty(pfx + "_length", Integer.toString(fromList.size())); + + } else if (isYangGenerated(fromClass)) { + // Class is yang generated. + + String propNamePfx = null; + + // If called from a list (so prefix ends in ']'), don't + // add class name again + if (pfx.endsWith("]")) { + propNamePfx = pfx; + } else { + if ((pfx != null) && (pfx.length() > 0)) { + propNamePfx = pfx; + } else { + propNamePfx = toLowerHyphen(fromClass.getSimpleName()); + } + + if (propNamePfx.endsWith(BUILDER)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length()); + } + + if (propNamePfx.endsWith("-impl")) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); + } + } + + // Iterate through getter methods to figure out values we need to + // save from + + int numGetters = 0; + String lastGetterName = null; + String propVal = null; + + for (Method m : fromClass.getMethods()) { + if (isGetter(m)) { + + numGetters++; + lastGetterName = m.getName(); + + Class returnType = m.getReturnType(); + String fieldName; + if (m.getName().startsWith("get")) { + fieldName = toLowerHyphen(m.getName().substring(3)); + } else { + + fieldName = toLowerHyphen(m.getName().substring(2)); + } + + fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); + + // Is the return type a yang generated class? + if (isYangGenerated(returnType)) { + // Is it an enum? + if (returnType.isEnum()) { + // Return type is a typedef. Save its value. + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + Object retValue = m.invoke(fromObj); + + if (!isAccessible) { + m.setAccessible(isAccessible); + } + if (retValue != null) { + String propName = propNamePfx + "." + fieldName; + if (useLegacyEnumerationMapping) { + propVal = retValue.toString(); + props.setProperty(propName, mapEnumeratedValue(fieldName, propVal)); + } else { + Method method = retValue.getClass().getMethod("getName"); + String yangValue = (String) method.invoke(retValue); + props.setProperty(propName, yangValue); + } + + } + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert Yang-generated enum returned by " + + fromClass.getName() + "." + m.getName() + "() to Properties entry", + e); + } + } else { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object retValue = m.invoke(fromObj); + + if (retValue instanceof byte[]) { + retValue = new String((byte[]) retValue, "UTF-8"); + } + if (!isAccessible) { + m.setAccessible(isAccessible); + } + if (retValue != null) { + toProperties(props, propNamePfx + "." + fieldName, retValue, returnType, useLegacyEnumerationMapping); + } + } catch (Exception e) { + + if (m.getName().equals("getKey")) { + LOG.trace("Caught " + e.getClass().getName() + + " exception trying to convert results from getKey() - ignoring"); + } else { + LOG.error("Caught exception trying to convert Yang-generated class returned by" + + fromClass.getName() + "." + m.getName() + "() to Properties entry", e); + } + } + } + } else if (returnType.equals(Class.class)) { + + } else if (List.class.isAssignableFrom(returnType)) { + + // This getter method returns a list. + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object retList = m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + // Figure out what type of elements are stored in + // this array. + Type paramType = m.getGenericReturnType(); + Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0]; + toProperties(props, propNamePfx + "." + fieldName, retList, (Class) elementType, useLegacyEnumerationMapping); + } catch (Exception e) { + LOG.error("Caught exception trying to convert List returned by " + fromClass.getName() + "." + + m.getName() + "() to Properties entry", e); + } + + } else { + + // Method returns something that is not a List and not + // yang-generated. + // Save its value + try { + String propName = propNamePfx + "." + fieldName; + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object propValObj = m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + + if (propValObj != null) { + if (propValObj instanceof byte[]) { + propVal = new String((byte[]) propValObj, "UTF-8"); + } else { + propVal = propValObj.toString(); + } + LOG.debug(SETTING_PROPERTY + propName + " to " + propVal); + props.setProperty(propName, propVal); + + } + } catch (Exception e) { + if (m.getName().equals("getKey")) { + LOG.trace("Caught " + e.getClass().getName() + + " exception trying to convert results from getKey() - ignoring"); + } else { + LOG.error("Caught exception trying to convert value returned by" + fromClass.getName() + + "." + m.getName() + "() to Properties entry", e); + } + } + } + + } + } + + // End of method loop. If there was only one getter, named + // "getValue", then + // set value identified by "prefix" to that one value. + if ((numGetters == 1) && ("getValue".equals(lastGetterName))) { + props.setProperty(propNamePfx, propVal); + } + } else { + // Class is not yang generated and not a list + // It must be an element of a leaf list - set "prefix" to value + String fromVal = null; + if (fromObj instanceof byte[]) { + try { + fromVal = new String((byte[]) fromObj, "UTF-8"); + } catch (Exception e) { + LOG.warn("Caught exception trying to convert " + pfx + " from byte[] to String", e); + fromVal = fromObj.toString(); + } + + } else { + fromVal = fromObj.toString(); + } + LOG.debug(SETTING_PROPERTY + pfx + " to " + fromVal); + props.setProperty(pfx, fromVal); + } + + return (props); + } + + public static Object toBuilder(Properties props, Object toObj) { + + return (toBuilder(props, "", toObj)); + } + + public static List toList(Properties props, String pfx, List toObj, Class elemType) { + + int maxIdx = -1; + boolean foundValue = false; + + if (props.containsKey(pfx + "_length")) { + try { + int listLength = Integer.parseInt(props.getProperty(pfx + "_length")); + + if (listLength > 0) { + maxIdx = listLength - 1; + } + } catch (NumberFormatException e) { + LOG.info("Invalid input for length ", e); + } + } + + String arrayKey = pfx + "["; + int arrayKeyLength = arrayKey.length(); + if (maxIdx == -1) { + // Figure out array size + for (Object pNameObj : props.keySet()) { + String key = (String) pNameObj; + + if (key.startsWith(arrayKey)) { + String idxStr = key.substring(arrayKeyLength); + int endloc = idxStr.indexOf("]"); + if (endloc != -1) { + idxStr = idxStr.substring(0, endloc); + } + try { + int curIdx = Integer.parseInt(idxStr); + if (curIdx > maxIdx) { + maxIdx = curIdx; + } + } catch (Exception e) { + LOG.error("Illegal subscript in property {}", key, e); + } + + } + } + } + + for (int i = 0; i <= maxIdx; i++) { + + String curBase = pfx + "[" + i + "]"; + + if (isYangGenerated(elemType)) { + + if (isIpAddress(elemType)) { + + String curValue = props.getProperty(curBase, ""); + + if ((curValue != null) && (curValue.length() > 0)) { + toObj.add(IpAddressBuilder.getDefaultInstance(curValue)); + foundValue = true; + } + } else if (isIpv4Address(elemType)) { + String curValue = props.getProperty(curBase, ""); + + if ((curValue != null) && (curValue.length() > 0)) { + toObj.add(new Ipv4Address(curValue)); + foundValue = true; + } + + } else if (isIpv6Address(elemType)) { + String curValue = props.getProperty(curBase, ""); + + if ((curValue != null) && (curValue.length() > 0)) { + toObj.add(new Ipv6Address(curValue)); + foundValue = true; + } + } else if (isIpPrefix(elemType)) { + + String curValue = props.getProperty(curBase, ""); + + if ((curValue != null) && (curValue.length() > 0)) { + toObj.add(IpPrefixBuilder.getDefaultInstance(curValue)); + foundValue = true; + } + } else if (isPortNumber(elemType)) { + + String curValue = props.getProperty(curBase, ""); + + if ((curValue != null) && (curValue.length() > 0)) { + toObj.add(PortNumber.getDefaultInstance(curValue)); + foundValue = true; + } + } else if (isDscp(elemType)) { + + String curValue = props.getProperty(curBase, ""); + + if ((curValue != null) && (curValue.length() > 0)) { + toObj.add(Dscp.getDefaultInstance(curValue)); + foundValue = true; + } + } else { + String builderName = elemType.getName() + "Builder"; + try { + Class builderClass = Class.forName(builderName); + Object builderObj = builderClass.newInstance(); + Method buildMethod = builderClass.getMethod("build"); + builderObj = toBuilder(props, curBase, builderObj, true); + if (builderObj != null) { + Object builtObj = buildMethod.invoke(builderObj); + toObj.add(builtObj); + foundValue = true; + } + + } catch (ClassNotFoundException e) { + LOG.warn("Could not find builder class {}", builderName, e); + } catch (Exception e) { + LOG.error("Caught exception trying to populate list from {}", pfx, e); + } + } + } else { + // Must be a leaf list + String curValue = props.getProperty(curBase, ""); + + toObj.add(curValue); + + if ((curValue != null) && (curValue.length() > 0)) { + foundValue = true; + } + } + + } + + if (foundValue) { + return (toObj); + } else { + return (null); + } + + } + + public static Object toBuilder(Properties props, String pfx, Object toObj) { + return (toBuilder(props, pfx, toObj, false)); + } + + public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) { + + Class toClass = toObj.getClass(); + boolean foundValue = false; + + Ipv4Address addr; + + if (isYangGenerated(toClass)) { + // Class is yang generated. + String propNamePfx = null; + if (preservePfx) { + propNamePfx = pfx; + } else { + + if ((pfx != null) && (pfx.length() > 0)) { + propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName()); + } else { + propNamePfx = toLowerHyphen(toClass.getSimpleName()); + } + + if (propNamePfx.endsWith(BUILDER)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length()); + } + + if (propNamePfx.endsWith("-impl")) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); + } + } + + if (toObj instanceof Identifier) { + return (toObj); + } + + // Iterate through getter methods to figure out values we need to + // set + + for (Method m : toClass.getMethods()) { + if (isSetter(m)) { + Class paramTypes[] = m.getParameterTypes(); + Class paramClass = paramTypes[0]; + + String fieldName = toLowerHyphen(m.getName().substring(3)); + fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); + + String propName = propNamePfx + "." + fieldName; + + String paramValue = props.getProperty(propName); + if (paramValue == null) { + + } else if ("".equals(paramValue)) { + LOG.trace(propName + " was set to the empty string, setting it to null"); + paramValue = null; + } else { + + } + + // Is the return type a yang generated class? + if (isYangGenerated(paramClass)) { + // Is it an enum? + if (paramClass.isEnum()) { + + // Param type is a typedef. + if ((paramValue != null) && (paramValue.length() > 0)) { + Object paramObj = null; + + try { + paramObj = Enum.valueOf(paramClass, toJavaEnum(paramValue)); + } catch (Exception e) { + LOG.error("Caught exception trying to convert field " + propName + " to enum " + + paramClass.getName(), e); + } + + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + m.invoke(toObj, paramObj); + + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error("Caught exception trying to create Yang-generated enum expected by" + + toClass.getName() + "." + m.getName() + "() from Properties entry", e); + } + } + } else { + + String simpleName = paramClass.getSimpleName(); + + if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName) + || IP_ADDRESS.equals(simpleName)) { + + + if ((paramValue != null) && (paramValue.length() > 0)) { + try { + IpAddress ipAddr = IpAddressBuilder.getDefaultInstance(paramValue); + + if (IPV4_ADDRESS.equals(simpleName)) { + m.invoke(toObj, ipAddr.getIpv4Address()); + } else if (IPV6_ADDRESS.equals(simpleName)) { + m.invoke(toObj, ipAddr.getIpv6Address()); + + } else { + m.invoke(toObj, ipAddr); + } + foundValue = true; + } catch (Exception e) { + LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + + "(" + paramValue + ")", e); + + } + } else { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + m.invoke(toObj, paramValue); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error("Caught exception trying to call " + toClass.getName() + "." + + m.getName() + "() with Properties entry", e); + } + } + } else if (IP_PREFIX.equals(simpleName)) { + if ((paramValue != null) && (paramValue.length() > 0)) { + try { + IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(paramValue); + m.invoke(toObj, ipPrefix); + foundValue = true; + } catch (Exception e) { + LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + + "(" + paramValue + ")", e); + } + } + } else if ("PortNumber".equals(simpleName)) { + if ((paramValue != null) && (paramValue.length() > 0)) { + try { + PortNumber portNumber = PortNumber.getDefaultInstance(paramValue); + m.invoke(toObj, portNumber); + foundValue = true; + } catch (Exception e) { + LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + + "(" + paramValue + ")", e); + } + } + } else if ("Dscp".equals(simpleName)) { + if ((paramValue != null) && (paramValue.length() > 0)) { + try { + Dscp dscp = Dscp.getDefaultInstance(paramValue); + m.invoke(toObj, dscp); + foundValue = true; + } catch (Exception e) { + LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + + "(" + paramValue + ")", e); + } + } + } else if ("RouteDistinguisher".equals(simpleName)) { + if ((paramValue != null) && (paramValue.length() > 0)) { + try { + RouteDistinguisher routeDistinguisher = RouteDistinguisherBuilder.getDefaultInstance(paramValue); + m.invoke(toObj, routeDistinguisher); + foundValue = true; + } catch (Exception e) { + LOG.error("Caught exception calling " + toClass.getName() + "." + m.getName() + + "(" + paramValue + ")", e); + } + } + } + else { + // setter expects a yang-generated class. Need + // to + // create a builder to set it. + + String builderName = paramClass.getName() + "Builder"; + Class builderClass = null; + Object builderObj = null; + Object paramObj = null; + + Object constObj = null; + + try { + builderClass = Class.forName(builderName); + builderObj = builderClass.newInstance(); + paramObj = toBuilder(props, propNamePfx, builderObj); + } catch (ClassNotFoundException e) { + LOG.trace("Builder class {} not found catching ClassNotFoundException and trying other methods", + builderName); + if (paramValue == null) { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + m.invoke(toObj, new Object[] { null }); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e1) { + LOG.error("Caught exception trying to cally" + toClass.getName() + "." + + m.getName() + "() with Properties entry", e1); + } + } else { + try { + // See if I can find a constructor I + // can + // use + Constructor[] constructors = paramClass.getConstructors(); + // Is there a String constructor? + for (Constructor c : constructors) { + Class[] cParms = c.getParameterTypes(); + if ((cParms != null) && (cParms.length == 1)) { + if (String.class.isAssignableFrom(cParms[0])) { + constObj = c.newInstance(paramValue); + } + } + } + + if (constObj == null) { + // Is there a Long constructor? + for (Constructor c : constructors) { + Class[] cParms = c.getParameterTypes(); + if ((cParms != null) && (cParms.length == 1)) { + if (Long.class.isAssignableFrom(cParms[0])) { + constObj = c.newInstance(Long.parseLong(paramValue)); + } + } + } + + } + + if (constObj == null) { + + // Last chance - see if + // parameter class has a static + // method + // getDefaultInstance(String) + try { + Method gm = + paramClass.getMethod("getDefaultInstance", String.class); + + int gmodifier = gm.getModifiers(); + if (Modifier.isStatic(gmodifier)) { + // Invoke static + // getDefaultInstance(String) + paramObj = gm.invoke(null, paramValue); + } + + } catch (Exception gme) { + LOG.info("Unable to find static method getDefaultInstance for " + + "class {}", paramClass.getSimpleName(), gme); + } + } + + } catch (Exception e1) { + LOG.warn( + "Could not find a suitable constructor for " + paramClass.getName(), + e1); + } + + if (constObj == null) { + LOG.warn("Could not find builder class " + builderName + + " and could not find a String or Long constructor or static " + + "getDefaultInstance(String) - trying just to set passing paramValue"); + + } + } + } catch (Exception e) { + LOG.error("Caught exception trying to create builder " + builderName, e); + } + + if (paramObj != null && builderClass != null) { + + try { + Method buildMethod = builderClass.getMethod("build"); + + Object builtObj = buildMethod.invoke(paramObj); + + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + m.invoke(toObj, builtObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error("Caught exception trying to set Yang-generated class expected by" + + toClass.getName() + "." + m.getName() + "() from Properties entry", + e); + } + } else { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + if (constObj != null) { + m.invoke(toObj, constObj); + } else { + m.invoke(toObj, paramValue); + } + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error("Caught exception trying to convert value returned by" + + toClass.getName() + "." + m.getName() + "() to Properties entry", e); + } + } + } + } + } else { + + // Setter's argument is not a yang-generated class. See + // if it is a List. + + if (List.class.isAssignableFrom(paramClass)) { + // Figure out what type of args are in List and pass + // that to toList(). + + Type paramType = m.getGenericParameterTypes()[0]; + Type elementType = ((ParameterizedType) paramType).getActualTypeArguments()[0]; + Object paramObj = new LinkedList(); + try { + paramObj = toList(props, propName, (List) paramObj, (Class) elementType); + } catch (Exception e) { + LOG.error("Caught exception trying to create list expected as argument to {}.{}", + toClass.getName(), m.getName(), e); + } + + if (paramObj != null) { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + m.invoke(toObj, paramObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error("Caught exception trying to convert List returned by" + toClass.getName() + + "." + m.getName() + "() to Properties entry", e); + } + } + } else { + + // Setter expects something that is not a List and + // not yang-generated. Just pass the parameter value + if ((paramValue != null) && (paramValue.length() > 0)) { + + Object constObj = null; + + try { + // See if I can find a constructor I can use + Constructor[] constructors = paramClass.getConstructors(); + // Is there a String constructor? + for (Constructor c : constructors) { + Class[] cParms = c.getParameterTypes(); + if ((cParms != null) && (cParms.length == 1)) { + if (String.class.isAssignableFrom(cParms[0])) { + constObj = c.newInstance(paramValue); + } + } + } + + if (constObj == null) { + // Is there a Long constructor? + for (Constructor c : constructors) { + Class[] cParms = c.getParameterTypes(); + if ((cParms != null) && (cParms.length == 1)) { + if (Long.class.isAssignableFrom(cParms[0])) { + constObj = c.newInstance(Long.parseLong(paramValue)); + } + } + } + + } + + if (constObj != null) { + try { + m.invoke(toObj, constObj); + foundValue = true; + } catch (Exception e2) { + LOG.error("Caught exception trying to call " + m.getName(), e2); + } + } else { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + m.invoke(toObj, paramValue); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error("Caught exception trying to convert value returned by" + + toClass.getName() + "." + m.getName() + "() to Properties entry", + e); + } + } + } catch (Exception e1) { + LOG.warn("Could not find a suitable constructor for " + paramClass.getName(), e1); + } + + } + } + } + } // End of section handling "setter" method + } // End of loop through Methods + } // End of section handling yang-generated class + + if (foundValue) { + return (toObj); + } else { + return (null); + } + } + + private static boolean classHasSpecialHandling(String simpleName) { + if (IP_ADDRESS.equals(simpleName) || IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName) + || IP_PREFIX.equals(simpleName) || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) { + return true; + } + return false; + } + + private static String getStringValueMethod(String simpleName){ + if (IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName)) { + return("stringValue"); + } else { + return("getValue"); + } + } + + public static void printPropertyList(PrintStream pstr, String pfx, Class toClass) { + boolean foundValue = false; + + if (isYangGenerated(toClass) && (!Identifier.class.isAssignableFrom(toClass))) { + // Class is yang generated. + String propNamePfx = null; + if (pfx.endsWith("]")) { + propNamePfx = pfx; + } else { + + if ((pfx != null) && (pfx.length() > 0)) { + propNamePfx = pfx + "." + toLowerHyphen(toClass.getSimpleName()); + } else { + propNamePfx = toLowerHyphen(toClass.getSimpleName()); + } + + if (propNamePfx.endsWith(BUILDER)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() - BUILDER.length()); + } + + if (propNamePfx.endsWith("-impl")) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() - "-impl".length()); + } + } + + // Iterate through getter methods to figure out values we need to + // set + + for (Method m : toClass.getMethods()) { + if (isGetter(m)) { + Class returnClass = m.getReturnType(); + + String fieldName = toLowerHyphen(m.getName().substring(3)); + if (fieldName != null) { + fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); + } else { + fieldName = ""; + } + String propName = propNamePfx + "." + fieldName; + + // Is the return type a yang generated class? + if (isYangGenerated(returnClass)) { + // Is it an enum? + if (returnClass.isEnum()) { + pstr.print("\n\n * " + propName); + } else { + + String simpleName = returnClass.getSimpleName(); + + if (IPV4_ADDRESS.equals(simpleName) || IPV6_ADDRESS.equals(simpleName) + || IP_ADDRESS.equals(simpleName) || IP_PREFIX.equals(simpleName) + || "PortNumber".equals(simpleName) || "Dscp".equals(simpleName)) { + pstr.print("\n\n * " + propName); + } else { + printPropertyList(pstr, propNamePfx, returnClass); + } + + } + } else { + + // Setter's argument is not a yang-generated class. See + // if it is a List. + + if (List.class.isAssignableFrom(returnClass)) { + // Figure out what type of args are in List and pass + // that to toList(). + + Type returnType = m.getGenericReturnType(); + Type elementType = ((ParameterizedType) returnType).getActualTypeArguments()[0]; + Class elementClass = (Class) elementType; + printPropertyList(pstr, + propNamePfx + "." + toLowerHyphen(elementClass.getSimpleName()) + "[]", + elementClass); + + } else if (!returnClass.equals(Class.class)) { + + // Setter expects something that is not a List and + // not yang-generated. Just pass the parameter value + pstr.print("\n\n * " + propName); + } + } + } // End of section handling "setter" method + } // End of loop through Methods + } // End of section handling yang-generated class + + } + + public static boolean isYangGenerated(Class c) { + if (c != null) { + return (c.getName().startsWith("org.opendaylight.yang.gen.")); + } + return false; + } + + public static boolean isIpPrefix(Class c) { + + if (c == null) { + return (false); + } + if (!isIetfInet(c)) { + return (false); + } + String simpleName = c.getSimpleName(); + return (IP_PREFIX.equals(simpleName)); + } + + public static boolean isIpv4Address(Class c) { + + if (c == null) { + return (false); + } + if (!isIetfInet(c)) { + return (false); + } + String simpleName = c.getSimpleName(); + return (IPV4_ADDRESS.equals(simpleName)); + } + + public static boolean isIpv6Address(Class c) { + + if (c == null) { + return (false); + } + if (!isIetfInet(c)) { + return (false); + } + String simpleName = c.getSimpleName(); + return (IPV6_ADDRESS.equals(simpleName)); + } + + public static boolean isIpAddress(Class c) { + + if (c == null) { + return (false); + } + if (!isIetfInet(c)) { + return (false); + } + String simpleName = c.getSimpleName(); + return (IP_ADDRESS.equals(simpleName)); + } + + public static boolean isPortNumber(Class c) { + + if (c == null) { + return (false); + } + if (!isIetfInet(c)) { + return (false); + } + + String simpleName = c.getSimpleName(); + return ("PortNumber".equals(simpleName)); + } + + public static boolean isDscp(Class c) { + + if (c == null) { + return (false); + } + if (!isIetfInet(c)) { + return (false); + } + String simpleName = c.getSimpleName(); + return ("Dscp".equals(simpleName)); + } + + public static boolean isIetfInet(Class c) { + + Package p = c.getPackage(); + if (p != null) { + String pkgName = p.getName(); + + if ((pkgName != null) && (pkgName.indexOf("yang.ietf.inet.types") > -1)) { + return (true); + } + } + + return (false); + } + + public static String toLowerHyphen(String inStr) { + if (inStr == null) { + return (null); + } + + String str = inStr.substring(0, 1).toLowerCase(); + if (inStr.length() > 1) { + str = str + inStr.substring(1); + } + + String regex = "([a-z0-9A-Z])(?=[A-Z])"; + String replacement = "$1-"; + + String retval = str.replaceAll(regex, replacement).toLowerCase(); + + return (retval); + } + + // This is called when mapping the yang value back to a valid java enumeration + public static String toJavaEnum(String inStr) { + if (inStr == null) { + return (null); + } else if (inStr.length() == 0) { + return (inStr); + } + + // This is needed for enums containing under scores + inStr = inStr.replaceAll("_", ""); + + // This will strip out all periods, which cannot be in a java enum + inStr = inStr.replaceAll("\\.", ""); + + // This is needed for enums containing spaces + inStr = inStr.replaceAll(" ", ""); + + String[] terms = inStr.split("-"); + StringBuffer sbuff = new StringBuffer(); + + // appends an _ if the string starts with a digit to make it a valid java enum + if (Character.isDigit(inStr.charAt(0))) { + sbuff.append('_'); + } + // If the string contains hyphens it will convert the string to upperCamelCase without hyphens + for (String term : terms) { + sbuff.append(term.substring(0, 1).toUpperCase()); + if (term.length() > 1) { + sbuff.append(term.substring(1)); + } + } + return (sbuff.toString()); + + } + + public static boolean isGetter(Method m) { + if (m == null) { + return (false); + } + + if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 0)) { + if (m.getName().matches("^get[A-Z].*") && !m.getReturnType().equals(void.class)) { + if (!"getClass".equals(m.getName())) { + return (true); + } + } + + if (m.getName().matches("^get[A-Z].*") && m.getReturnType().equals(boolean.class)) { + return (true); + } + + if (m.getName().matches("^is[A-Z].*") && m.getReturnType().equals(Boolean.class)) { + return (true); + } + } + + return (false); + } + + public static boolean isSetter(Method m) { + if (m == null) { + return (false); + } + + if (Modifier.isPublic(m.getModifiers()) && (m.getParameterTypes().length == 1)) { + if (m.getName().matches("^set[A-Z].*")) { + Class[] paramTypes = m.getParameterTypes(); + if (paramTypes[0].isAssignableFrom(Identifier.class) + || Identifier.class.isAssignableFrom(paramTypes[0])) { + return (false); + } else { + return (true); + } + } + + } + + return (false); + } + + @Deprecated + public static String getFullPropertiesPath(String propertiesFileName) { + String karafHome = System.getProperty("karaf.home","/opt/lsc/controller"); + return karafHome + "/configuration/" + propertiesFileName; + } + + // This is called when mapping a valid java enumeration back to the yang model value + @Deprecated + public static String mapEnumeratedValue(String propertyName, String propertyValue) { + LOG.info("mapEnumeratedValue called with propertyName=" + propertyName + " and value=" + propertyValue); + String mappingKey = "yang." + propertyName + "." + propertyValue; + if (yangMappingProperties.containsKey(mappingKey)) { + return (yangMappingProperties.getProperty(mappingKey)); + } else { + LOG.info("yangMappingProperties did not contain the key " + mappingKey + " returning the original value."); + return propertyValue; + } + } + +} diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java new file mode 100644 index 000000000..992ed64d4 --- /dev/null +++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToProp.java @@ -0,0 +1,1355 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import java.io.PrintStream; +import java.io.FileDescriptor; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.Arrays; +import java.util.ArrayList; +import java.io.*; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.base.Strings; + + +public class PrintYangToProp { + + private static final Logger LOG = LoggerFactory.getLogger(PrintYangToProp.class); + public static final String PROPERTIES_FILE=""; + private static Properties properties; + private static final String BUILDER="-builder"; + private static final String IMPL="-impl"; + private static final String TO_PROPERTIES_STRING="() to Properties entry"; + private static final String CAUGHT_EXCEPTION_MSG="Caught exception trying to convert value returned by "; + public static Properties prop = new Properties(); + public static ArrayList<String> propList = new ArrayList<>(); + + + public static Properties toProperties(Properties props, Object fromObj) { + Class fromClass = null; + + if (fromObj != null) + { + fromClass = fromObj.getClass(); + } + return (toProperties(props, "", fromObj, fromClass)); + } + + public static Properties toProperties(Properties props, String pfx, Object fromObj) + { + Class fromClass = null; + + if (fromObj != null) + { + fromClass = fromObj.getClass(); + } + + return(toProperties(props, pfx, fromObj, fromClass)); + } + + public static Properties toProperties(Properties props, String pfx, + Object fromObj, Class fromClass) { + + if (fromObj == null) { + return (props); + } + + + String simpleName = fromClass.getSimpleName(); + + if (fromObj instanceof List) { + + + List fromList = (List) fromObj; + + for (int i = 0; i < fromList.size(); i++) { + toProperties(props, pfx + "[" + i + "]", fromList.get(i), fromClass); + } + props.setProperty(pfx + "_length", "" + fromList.size()); + + } else if (isYangGenerated(fromClass)) { + + String propNamePfx = null; + + // If called from a list (so prefix ends in ']'), don't + // add class name again + if (pfx.endsWith("]")) { + propNamePfx = pfx; + } else { + if ((pfx != null) && (pfx.length() > 0)) { + propNamePfx = pfx ; + } else { + propNamePfx = toLowerHyphen(fromClass.getSimpleName()); + } + + if (propNamePfx.endsWith(BUILDER)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() + - BUILDER.length()); + } + + if (propNamePfx.endsWith(IMPL)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() + - IMPL.length()); + } + } + + // Iterate through getter methods to figure out values we need to + // save from + + for (Method m : fromClass.getMethods()) { + + if (isGetter(m)) { + + Class returnType = m.getReturnType(); + String fieldName = toLowerHyphen(m.getName().substring(3)); + if(m != null && m.getName().matches("^is[A-Z].*")){ + fieldName = toLowerHyphen(m.getName().substring(2)); + } + + if(Strings.isNullOrEmpty(fieldName)) fieldName = fieldName.substring(0, 1).toLowerCase()+ fieldName.substring(1); + + + // Is the return type a yang generated class? + if (isYangGenerated(returnType)) { + + // Is it an enum? + if (returnType.isEnum()) { + // Return type is a typedef. Save its value. + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + Object retValue = m.invoke(fromObj); + + if (!isAccessible) { + m.setAccessible(isAccessible); + } + if (retValue != null) { + String propName = propNamePfx + "." + + fieldName; + String propVal = retValue.toString(); + String yangProp = "yang." + fieldName + "." + propVal; + if ( properties.containsKey(yangProp)) { + propVal = properties.getProperty(yangProp); + } + props.setProperty(propName, propVal); + } + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert Yang-generated enum returned by " + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } else if (isIpv4Address(returnType)) { + // Save its value + try { + String propName = propNamePfx + "." + fieldName; + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Ipv4Address retValue = (Ipv4Address) m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + + if (retValue != null) { + String propVal = retValue.getValue(); + + props.setProperty(propName, propVal); + + } + } catch (Exception e) { + LOG.error( + CAUGHT_EXCEPTION_MSG + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } else if (isIpv6Address(returnType)) { + // Save its value + try { + String propName = propNamePfx + "." + fieldName; + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Ipv6Address retValue = (Ipv6Address) m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + + if (retValue != null) { + String propVal = retValue.getValue(); + + props.setProperty(propName, propVal); + + } + } catch (Exception e) { + LOG.error( + CAUGHT_EXCEPTION_MSG + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } else if (isIpv4Prefix(returnType)) { + + // Save its value + try { + String propName = propNamePfx + "." + fieldName; + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Ipv4Prefix retValue = (Ipv4Prefix) m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + + if (retValue != null) { + String propVal = retValue.getValue(); + + props.setProperty(propName, propVal); + + } + } catch (Exception e) { + LOG.error( + CAUGHT_EXCEPTION_MSG + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } else if (isIpv6Prefix(returnType)) { + //System.out.println("isIpv6Prefix"); + // Save its value + try { + String propName = propNamePfx + "." + fieldName; + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Ipv6Prefix retValue = (Ipv6Prefix) m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + + if (retValue != null) { + String propVal = retValue.getValue().toString(); + //LOG.debug("Setting property " + propName + // + " to " + propVal); + props.setProperty(propName, propVal); + + } + } catch (Exception e) { + LOG.error( + CAUGHT_EXCEPTION_MSG + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } else { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object retValue = m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + if (retValue != null) { + toProperties(props, propNamePfx + "." + fieldName, retValue, returnType); + } + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert Yang-generated class returned by" + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } + } else if (returnType.equals(Class.class)) { + + //LOG.debug(m.getName() + // + " returns a Class object - not interested"); + + } else if (List.class.isAssignableFrom(returnType)) { + + // This getter method returns a list. + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object retList = m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + // Figure out what type of elements are stored in this array. + Type paramType = m.getGenericReturnType(); + Type elementType = ((ParameterizedType) paramType) + .getActualTypeArguments()[0]; + toProperties(props, propNamePfx + "." + fieldName, + retList, (Class)elementType); + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert List returned by " + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + + } else { + + // Method returns something that is not a List and not + // yang-generated. + // Save its value + try { + String propName = propNamePfx + "." + fieldName; + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + Object propValObj = m.invoke(fromObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + + if (propValObj != null) { + String propVal = propValObj.toString(); + //LOG.debug("Setting property " + propName + // + " to " + propVal); + props.setProperty(propName, propVal); + + } + } catch (Exception e) { + LOG.error( + CAUGHT_EXCEPTION_MSG + + fromClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, e); + } + } + + } + } + + } else { + // Class is not yang generated and not a list + // Do nothing. + + } + + return (props); + } + + public static Object toBuilder(Properties props, Object toObj) { + + return (toBuilder(props, "", toObj)); + } + + public static List toList(Properties props, String pfx, List toObj, + Class elemType) { + + int maxIdx = -1; + boolean foundValue = false; + + //LOG.debug("Saving properties to List<" + elemType.getName() + // + "> from " + pfx); + + // Figure out array size + for (Object pNameObj : props.keySet()) { + String key = (String) pNameObj; + + if (key.startsWith(pfx + "[")) { + String idxStr = key.substring(pfx.length() + 1); + int endloc = idxStr.indexOf("]"); + if (endloc != -1) { + idxStr = idxStr.substring(0, endloc); + } + + try { + int curIdx = Integer.parseInt(idxStr); + if (curIdx > maxIdx) { + maxIdx = curIdx; + } + } catch (Exception e) { + LOG.error("Illegal subscript in property " + key); + } + + } + } + + //LOG.debug(pfx + " has max index of " + maxIdx); + for (int i = 0; i <= maxIdx; i++) { + + String curBase = pfx + "[" + i + "]"; + + if (isYangGenerated(elemType)) { + String builderName = elemType.getName() + "Builder"; + try { + Class builderClass = Class.forName(builderName); + Object builderObj = builderClass.newInstance(); + Method buildMethod = builderClass.getMethod("build"); + builderObj = toBuilder(props, curBase, builderObj, true); + if (builderObj != null) { + //LOG.debug("Calling " + builderObj.getClass().getName() + // + "." + buildMethod.getName() + "()"); + Object builtObj = buildMethod.invoke(builderObj); + toObj.add(builtObj); + foundValue = true; + } + + } catch (ClassNotFoundException e) { + LOG.warn("Could not find builder class " + builderName, e); + } catch (Exception e) { + LOG.error("Caught exception trying to populate list from " + + pfx); + } + } + + } + + if (foundValue) { + return (toObj); + } else { + return (null); + } + + } + + public static Object toBuilder(Properties props, String pfx, Object toObj) { + return(toBuilder(props, pfx, toObj, false)); + } + + public static Object toBuilder(Properties props, String pfx, Object toObj, boolean preservePfx) { + Class toClass = toObj.getClass(); + boolean foundValue = false; + + //LOG.debug("Saving properties to " + toClass.getName() + " class from " + // + pfx); + + Ipv4Address addr; + + if (isYangGenerated(toClass)) { + // Class is yang generated. + //LOG.debug(toClass.getName() + " is a Yang-generated class"); + + String propNamePfx = null; + if (preservePfx) { + propNamePfx = pfx; + } else { + + if ((pfx != null) && (pfx.length() > 0)) { + propNamePfx = pfx + "." + + toLowerHyphen(toClass.getSimpleName()); + } else { + propNamePfx = toLowerHyphen(toClass.getSimpleName()); + } + + if (propNamePfx.endsWith(BUILDER)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() + - BUILDER.length()); + } + + if (propNamePfx.endsWith(IMPL)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() + - IMPL.length()); + } + } + + if (toObj instanceof Identifier) { + //LOG.debug(toClass.getName() + " is a Key - skipping"); + return (toObj); + } + + // Iterate through getter methods to figure out values we need to + // set + + for (Method m : toClass.getMethods()) { + // LOG.debug("Is " + m.getName() + " method a setter?"); + if (isSetter(m)) { + // LOG.debug(m.getName() + " is a setter"); + Class paramTypes[] = m.getParameterTypes(); + Class paramClass = paramTypes[0]; + + String fieldName = toLowerHyphen(m.getName().substring(3)); + fieldName = fieldName.substring(0, 1).toLowerCase() + + fieldName.substring(1); + + String propName = propNamePfx + "." + fieldName; + + String paramValue = props.getProperty(propName); + if (paramValue == null) { + //LOG.debug(propName + " is unset"); + } else { + //LOG.debug(propName + " = " + paramValue); + } + + // Is the return type a yang generated class? + if (isYangGenerated(paramClass)) { + // Is it an enum? + if (paramClass.isEnum()) { + + //LOG.debug(m.getName() + " expects an Enum"); + // Param type is a typedef. + if (paramValue != null) { + Object paramObj = null; + + try { + paramObj = Enum.valueOf(paramClass, + toUpperCamelCase(paramValue)); + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert field " + + propName + " to enum " + + paramClass.getName(), e); + } + + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + //LOG.debug("Calling " + // + toObj.getClass().getName() + "." + // + m.getName() + "(" + paramValue + // + ")"); + m.invoke(toObj, paramObj); + + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error( + "Caught exception trying to create Yang-generated enum expected by" + + toClass.getName() + + "." + + m.getName() + + "() from Properties entry", + e); + } + } + } else { + + String simpleName = paramClass.getSimpleName(); + LOG.info("simpleName:" + simpleName); + + if ("Ipv4Address".equals(simpleName) + || "Ipv6Address".equals(simpleName) || "Ipv4Prefix".equals(simpleName) || "Ipv6Prefix".equals(simpleName)) { + + if (paramValue != null) { + if("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName)){ + try { + IpAddress ipAddr = IpAddressBuilder + .getDefaultInstance(paramValue); + + + if ("Ipv4Address".equals(simpleName)) + { + m.invoke(toObj, ipAddr.getIpv4Address()); + } + else + { + m.invoke(toObj, ipAddr.getIpv6Address()); + + } + foundValue = true; + } catch (Exception e) { + LOG.error( + "Caught exception calling " + + toClass.getName() + "." + + m.getName() + "(" + + paramValue + ")", e); + + } + }else if("Ipv4Prefix".equals(simpleName)|| "Ipv6Prefix".equals(simpleName)){ + try { + IpPrefix ipPrefix = IpPrefixBuilder + .getDefaultInstance(paramValue); + + + if ("Ipv4Prefix".equals(simpleName)) + { + m.invoke(toObj, ipPrefix.getIpv4Prefix()); + } + else + { + m.invoke(toObj, ipPrefix.getIpv6Prefix()); + + } + foundValue = true; + } catch (Exception e) { + LOG.error( + "Caught exception calling " + + toClass.getName() + "." + + m.getName() + "(" + + paramValue + ")", e); + + } + } + } + + } else { + // setter expects a yang-generated class. Need + // to + // create a builder to set it. + + String builderName = paramClass.getName() + + "Builder"; + Class builderClass = null; + Object builderObj = null; + Object paramObj = null; + + //LOG.debug(m.getName() + // + " expects a yang-generated class - looking for builder " + // + builderName); + try { + builderClass = Class.forName(builderName); + builderObj = builderClass.newInstance(); + paramObj = toBuilder(props, propNamePfx, + builderObj); + } catch (ClassNotFoundException e) { + Object constObj = null; + try { + // See if I can find a constructor I can + // use + Constructor[] constructors = paramClass + .getConstructors(); + // Is there a String constructor? + for (Constructor c : constructors) { + Class[] cParms = c + .getParameterTypes(); + if ((cParms != null) + && (cParms.length == 1)) { + if (String.class + .isAssignableFrom(cParms[0])) { + constObj = c + .newInstance(paramValue); + } + } + } + + if (constObj == null) { + // Is there a Long constructor? + for (Constructor c : constructors) { + Class[] cParms = c + .getParameterTypes(); + if ((cParms != null) + && (cParms.length == 1)) { + if (Long.class + .isAssignableFrom(cParms[0])) { + constObj = c + .newInstance(Long + .parseLong(paramValue)); + } + } + } + + } + + if (constObj != null) { + try { + m.invoke(toObj, constObj); + foundValue = true; + } catch (Exception e2) { + LOG.error( + "Caught exception trying to call " + + m.getName(), + e2); + } + } + } catch (Exception e1) { + LOG.warn( + "Could not find a suitable constructor for " + + paramClass.getName(), + e1); + } + + if (paramObj == null) { + LOG.warn("Could not find builder class " + + builderName + + " and could not find a String or Long constructor - trying just to set passing paramValue"); + + } + + } catch (Exception e) { + LOG.error( + "Caught exception trying to create builder " + + builderName, e); + } + + if (paramObj != null) { + + try { + + Method buildMethod = builderClass + .getMethod("build"); + //LOG.debug("Calling " + // + paramObj.getClass().getName() + // + "." + buildMethod.getName() + // + "()"); + Object builtObj = buildMethod + .invoke(paramObj); + + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + + //LOG.debug("Calling " + // + toObj.getClass().getName() + // + "." + m.getName() + "()"); + m.invoke(toObj, builtObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error( + "Caught exception trying to set Yang-generated class expected by" + + toClass.getName() + + "." + + m.getName() + + "() from Properties entry", + e); + } + } else { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + //LOG.debug("Calling " + // + toObj.getClass().getName() + // + "." + m.getName() + "(" + // + paramValue + ")"); + m.invoke(toObj, paramValue); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert value returned by" + + toClass.getName() + + "." + + m.getName() + + TO_PROPERTIES_STRING, + e); + } + } + } + } + }else { + + // Setter's argument is not a yang-generated class. See + // if it is a List. + + if (List.class.isAssignableFrom(paramClass)) { + + //LOG.debug("Parameter class " + paramClass.getName() + // + " is a List"); + + // Figure out what type of args are in List and pass + // that to toList(). + + Type paramType = m.getGenericParameterTypes()[0]; + Type elementType = ((ParameterizedType) paramType) + .getActualTypeArguments()[0]; + Object paramObj = new LinkedList(); + try { + paramObj = toList(props, propName, + (List) paramObj, (Class) elementType); + } catch (Exception e) { + LOG.error("Caught exception trying to create list expected as argument to " + + toClass.getName() + "." + m.getName()); + } + + if (paramObj != null) { + try { + boolean isAccessible = m.isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + //LOG.debug("Calling " + // + toObj.getClass().getName() + "." + // + m.getName() + "(" + paramValue + // + ")"); + m.invoke(toObj, paramObj); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert List returned by" + + toClass.getName() + "." + + m.getName() + + TO_PROPERTIES_STRING, + e); + } + } + } else { + + // Setter expects something that is not a List and + // not yang-generated. Just pass the parameter value + + //LOG.debug("Parameter class " + // + paramClass.getName() + // + " is not a yang-generated class or a List"); + + if (paramValue != null) { + + Object constObj = null; + + try { + // See if I can find a constructor I can use + Constructor[] constructors = paramClass + .getConstructors(); + // Is there a String constructor? + for (Constructor c : constructors) { + Class[] cParms = c.getParameterTypes(); + if ((cParms != null) + && (cParms.length == 1)) { + if (String.class + .isAssignableFrom(cParms[0])) { + constObj = c + .newInstance(paramValue); + } + } + } + + if (constObj == null) { + // Is there a Long constructor? + for (Constructor c : constructors) { + Class[] cParms = c + .getParameterTypes(); + if ((cParms != null) + && (cParms.length == 1)) { + if (Long.class + .isAssignableFrom(cParms[0])) { + constObj = c + .newInstance(Long + .parseLong(paramValue)); + } + } + } + + } + + if (constObj != null) { + try { + //LOG.debug("Calling " + // + toObj.getClass() + // .getName() + "." + // + m.getName() + "(" + // + constObj + ")"); + m.invoke(toObj, constObj); + foundValue = true; + } catch (Exception e2) { + LOG.error( + "Caught exception trying to call " + + m.getName(), e2); + } + } else { + try { + boolean isAccessible = m + .isAccessible(); + if (!isAccessible) { + m.setAccessible(true); + } + //LOG.debug("Calling " + // + toObj.getClass() + // .getName() + "." + // + m.getName() + "(" + // + paramValue + ")"); + m.invoke(toObj, paramValue); + if (!isAccessible) { + m.setAccessible(isAccessible); + } + foundValue = true; + + } catch (Exception e) { + LOG.error( + "Caught exception trying to convert value returned by" + + toClass.getName() + + "." + + m.getName() + + TO_PROPERTIES_STRING, + e); + } + } + } catch (Exception e1) { + LOG.warn( + "Could not find a suitable constructor for " + + paramClass.getName(), e1); + } + + /* + * try { boolean isAccessible = + * m.isAccessible(); if (!isAccessible) { + * m.setAccessible(true); } LOG.debug("Calling " + * + toObj.getClass().getName() + "." + + * m.getName() + "(" + paramValue + ")"); + * m.invoke(toObj, paramValue); if + * (!isAccessible) { + * m.setAccessible(isAccessible); } foundValue = + * true; + * + * } catch (Exception e) { LOG.error( + * "Caught exception trying to convert value returned by" + * + toClass.getName() + "." + m.getName() + + * "() to Properties entry", e); } + */ + } + } + } + } // End of section handling "setter" method + } // End of loop through Methods + } // End of section handling yang-generated class + + if (foundValue) { + return (toObj); + } else { + return (null); + } + } + + public static Properties getProperties(PrintStream pstr, String pfx, + Class toClass) { + boolean foundValue = false; + + //LOG.debug("Analyzing " + toClass.getName() + " class : pfx " + pfx); + + if (isYangGenerated(toClass) + && (!Identifier.class.isAssignableFrom(toClass))) { + // Class is yang generated. + //LOG.debug(toClass.getName() + " is a Yang-generated class"); + + if (toClass.getName().endsWith("Key")) { + if (Identifier.class.isAssignableFrom(toClass)) { + //LOG.debug(Identifier.class.getName() + // + " is assignable from " + toClass.getName()); + } else { + + //LOG.debug(Identifier.class.getName() + // + " is NOT assignable from " + toClass.getName()); + } + } + + String propNamePfx = null; + if (pfx.endsWith("]")) { + propNamePfx = pfx; + }else if(pfx.indexOf(".CLASS_FOUND") != -1){ + pfx = pfx.replace(".CLASS_FOUND",""); + propNamePfx = pfx + "." + + toLowerHyphen(toClass.getSimpleName()); + } else { + + if ((pfx != null) && (pfx.length() > 0)) { + propNamePfx = pfx + "." + + toLowerHyphen(toClass.getSimpleName()); + } else { + propNamePfx = toLowerHyphen(toClass.getSimpleName()); + } + + if (propNamePfx.endsWith(BUILDER)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() + - BUILDER.length()); + } + + if (propNamePfx.endsWith(IMPL)) { + propNamePfx = propNamePfx.substring(0, propNamePfx.length() + - IMPL.length()); + } + } + + // Iterate through getter methods to figure out values we need to + // set + + for (Method m : toClass.getMethods()) { + //LOG.debug("Is " + m.getName() + " method a getter?"); + if (isGetter(m)) { + // LOG.debug(m.getName() + " is a getter"); + Class returnClass = m.getReturnType(); + + String fieldName = toLowerHyphen(m.getName().substring(3)); + if(m != null && m.getName().matches("^is[A-Z].*")){ + fieldName = toLowerHyphen(m.getName().substring(2)); + } + fieldName = fieldName.substring(0, 1).toLowerCase() + + fieldName.substring(1); + + String propName = propNamePfx + "." + fieldName; + //System.out.println("****" + propName); + + // Is the return type a yang generated class? + if (isYangGenerated(returnClass)) { + // Is it an enum? + if (returnClass.isEnum()) { + + //LOG.debug(m.getName() + " is an Enum"); + //pstr.print("\n" + propName); + //pstr.print("\n" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\n"); + pstr.print("\"" + propName + ":Enum:" + Arrays.asList(returnClass.getEnumConstants()) + "\","); + prop.setProperty(propName,""); + propList.add(propName); + + } else { + + String simpleName = returnClass.getSimpleName(); + //System.out.println("simpleName:" + simpleName); + + if ("Ipv4Address".equals(simpleName) || "Ipv6Address".equals(simpleName) || "IpAddress".equals(simpleName) || "Ipv4Prefix".equals(simpleName) || "Ipv6Prefix".equals(simpleName) || "IpPrefix".equals(simpleName)) { + //LOG.debug(m.getName()+" is an "+simpleName); + //pstr.print("\n" + propName); + //pstr.print("\n" + propName + ":" + simpleName + "\n"); + pstr.print("\"" + propName + ":" + simpleName + "\","); + prop.setProperty(propName,""); + propList.add(propName); + } else { + boolean isString = false; + boolean isNumber = false; + boolean isBoolean = false; + boolean isIdentifier = false; + //System.out.println("simpleName:" + simpleName); + //System.out.println("propName:" + propName); + for(Method mthd : returnClass.getMethods()){ + String methodName = mthd.getName(); + //System.out.println("methodName:" + methodName); + if(methodName.equals("getValue")){ + Class retType = mthd.getReturnType(); + //System.out.println("retType:" + retType); + isString = String.class.isAssignableFrom(retType); + isNumber = Number.class.isAssignableFrom(retType); + isBoolean = Boolean.class.isAssignableFrom(retType); + isIdentifier = Identifier.class.isAssignableFrom(retType); + //System.out.println("isString:" + isString); + //System.out.println("isNumber:" + isNumber); + //System.out.println("isNumber:" + isNumber); + break; + } + } + + if(isString){ + pstr.print("\"" + propName + ":String\","); + prop.setProperty(propName,""); + propList.add(propName); + }else if(isNumber){ + pstr.print("\"" + propName + ":Number\","); + prop.setProperty(propName,""); + propList.add(propName); + }else if(isBoolean){ + pstr.print("\"" + propName + ":Boolean\","); + prop.setProperty(propName,""); + propList.add(propName); + }else if(isIdentifier){ + //System.out.println("isIdentifier"); + //isIdentifer so skipping + continue; + }else{ + /* + System.out.println("fieldName:" + fieldName); + System.out.println("simpleName:" + simpleName); + System.out.println("returnClass:" + returnClass); + System.out.println("pstr:" + pstr); + System.out.println("propNamePfx:" + propNamePfx); + */ + getProperties(pstr, propNamePfx + ".CLASS_FOUND", returnClass); + } + } + + } + } else { + + // Setter's argument is not a yang-generated class. See + // if it is a List. + + if (List.class.isAssignableFrom(returnClass)) { + + //LOG.debug("Parameter class " + // + returnClass.getName() + " is a List"); + + // Figure out what type of args are in List and pass + // that to toList(). + + Type returnType = m.getGenericReturnType(); + Type elementType = ((ParameterizedType) returnType) + .getActualTypeArguments()[0]; + Class elementClass = (Class) elementType; + //LOG.debug("Calling printPropertyList on list type (" + //+ elementClass.getName() + // + "), pfx is (" + // + pfx + // + "), toClass is (" + // + toClass.getName() + ")"); + //System.out.println("List propNamePfx:" + propNamePfx+ "." + toLowerHyphen(elementClass.getSimpleName()) + "[]"); + if(String.class.isAssignableFrom(elementClass)){ + pstr.print("\"" + propName + ":[String,String,...]\","); + prop.setProperty(propName,""); + propList.add(propName); + }else if(Number.class.isAssignableFrom(elementClass)){ + pstr.print("\"" + propName + ":[Number,Number,...]\","); + prop.setProperty(propName,""); + propList.add(propName); + }else if(Boolean.class.isAssignableFrom(elementClass)){ + pstr.print("\"" + propName + ":[Boolean,Boolean,...]\","); + prop.setProperty(propName,""); + propList.add(propName); + }else if(Identifier.class.isAssignableFrom(elementClass)){ + continue; + }else{ + getProperties( + pstr, + propNamePfx + + "." + + toLowerHyphen(elementClass + .getSimpleName()) + "[]", + elementClass); + } + + } else if (!returnClass.equals(Class.class)) { + + // Setter expects something that is not a List and + // not yang-generated. Just pass the parameter value + + //LOG.debug("Parameter class " + // + returnClass.getName() + // + " is not a yang-generated class or a List"); + + //pstr.print("\n" + propName); + String className=returnClass.getName(); + int nClassNameIndex = className.lastIndexOf('.'); + String nClassName = className; + if(nClassNameIndex != -1){ + nClassName=className.substring(nClassNameIndex+1); + } + boolean isString = String.class.isAssignableFrom(returnClass); + boolean isNumber = Number.class.isAssignableFrom(returnClass); + boolean isBoolean = Boolean.class.isAssignableFrom(returnClass); + //pstr.print("\n" + propName +":" + nClassName +"\n"); + boolean isIdentifier = Identifier.class.isAssignableFrom(returnClass); + if(!isIdentifier && !nClassName.equals("[C")){ + if(isNumber){ + pstr.print("\"" + propName +":Number\","); + }else if(isBoolean){ + pstr.print("\"" + propName +":Boolean\","); + }else{ + if(nClassName.equals("[B")){ + pstr.print("\"" + propName +":Binary\","); + }else{ + pstr.print("\"" + propName +":" + nClassName +"\","); + } + } + prop.setProperty(propName,""); + propList.add(propName); + } + + } + } + } // End of section handling "setter" method + } // End of loop through Methods + } // End of section handling yang-generated class + + return prop; + } + + public static boolean isYangGenerated(Class c) { + if (c == null) { + return (false); + } else { + //System.out.println(c.getName()); + return (c.getName().startsWith("org.opendaylight.yang.gen.")); + } + } + + public static boolean isIpv4Address(Class c) { + + if (c == null ) { + return (false); + } + String simpleName = c.getSimpleName(); + return ("Ipv4Address".equals(simpleName)) ; + } + + public static boolean isIpv6Address(Class c) { + + if (c == null ) { + return (false); + } + String simpleName = c.getSimpleName(); + return ("Ipv6Address".equals(simpleName)) ; + } + public static boolean isIpv4Prefix(Class c) { + + if (c == null ) { + return (false); + } + String simpleName = c.getSimpleName(); + //System.out.println("simpleName:" + simpleName); + return ("Ipv4Prefix".equals(simpleName)) ; + } + + public static boolean isIpv6Prefix(Class c) { + + if (c == null ) { + return (false); + } + String simpleName = c.getSimpleName(); + //System.out.println("simpleName:" + simpleName); + return ("Ipv6Prefix".equals(simpleName)) ; + } + + public static String toLowerHyphen(String inStr) { + if (inStr == null) { + return (null); + } + + String str = inStr.substring(0, 1).toLowerCase(); + if (inStr.length() > 1) { + str = str + inStr.substring(1); + } + + String regex = "([a-z0-9A-Z])(?=[A-Z])"; + String replacement = "$1-"; + + String retval = str.replaceAll(regex, replacement).toLowerCase(); + + //LOG.debug("Converting " + inStr + " => " + str + " => " + retval); + return (retval); + } + + public static String toUpperCamelCase(String inStr) { + if (inStr == null) { + return (null); + } + + String[] terms = inStr.split("-"); + StringBuffer sbuff = new StringBuffer(); + // Check if string begins with a digit + if (Character.isDigit(inStr.charAt(0))) { + sbuff.append('_'); + } + for (String term : terms) { + sbuff.append(term.substring(0, 1).toUpperCase()); + if (term.length() > 1) { + sbuff.append(term.substring(1)); + } + } + return (sbuff.toString()); + + } + + public static boolean isGetter(Method m) { + //System.out.println(m); + if (m == null) { + return (false); + } + + if (Modifier.isPublic(m.getModifiers()) + && (m.getParameterTypes().length == 0)) { + if ((m.getName().matches("^is[A-Z].*") || m.getName().matches("^get[A-Z].*")) + && m.getReturnType().equals(Boolean.class)) { + return (true); + } + if (m.getName().matches("^get[A-Z].*") + && !m.getReturnType().equals(void.class)) { + return (true); + } + + } + + return (false); + } + + public static boolean isSetter(Method m) { + if (m == null) { + return (false); + } + + if (Modifier.isPublic(m.getModifiers()) + && (m.getParameterTypes().length == 1)) { + if (m.getName().matches("^set[A-Z].*")) { + Class[] paramTypes = m.getParameterTypes(); + if (paramTypes[0].isAssignableFrom(Identifier.class) + || Identifier.class.isAssignableFrom(paramTypes[0])) { + return (false); + } else { + return (true); + } + } + + } + + return (false); + } + + public static void main(String[] args){ + + try(PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out))){ + PrintYangToProp printYangToProp = new PrintYangToProp(); + String className = args[0]; + //ClassLoader classLoader = PrintYangToProp.class.getClassLoader(); + //Class aClass = classLoader.loadClass(className); + Class cl = Class.forName(className); + //printPropertyList(ps,"",cl); + //JsonObject jsonObj = Json.createObjectBuilder().build(); + Properties p = getProperties(ps,"",cl); + //System.out.println(p); + + }catch(Exception e){ + e.printStackTrace(); + } + } + + +} diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java new file mode 100644 index 000000000..08e957f1d --- /dev/null +++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicClassResolver.java @@ -0,0 +1,98 @@ +package org.onap.ccsdk.sli.core.sli.provider; + +import java.util.HashMap; +import org.onap.ccsdk.sli.core.sli.SvcLogicAdaptor; +import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; +import org.onap.ccsdk.sli.core.sli.SvcLogicRecorder; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicResolver; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicClassResolver implements SvcLogicResolver { + + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicClassResolver.class); + private static HashMap<String, SvcLogicAdaptor> adaptorMap = new HashMap<>(); + + public void registerAdaptor(SvcLogicAdaptor adaptor) { + String name = adaptor.getClass().getName(); + LOG.info("Registering adaptor " + name); + adaptorMap.put(name, adaptor); + + } + + public void unregisterAdaptor(String name) { + if (adaptorMap.containsKey(name)) { + LOG.info("Unregistering " + name); + adaptorMap.remove(name); + } + } + + private SvcLogicAdaptor getAdaptorInstance(String name) { + if (adaptorMap.containsKey(name)) { + return adaptorMap.get(name); + } else { + + SvcLogicAdaptor adaptor = (SvcLogicAdaptor) resolve(name); + + if (adaptor != null) { + registerAdaptor(adaptor); + } + + return adaptor; + } + } + + private Object resolve(String className) { + + Bundle bundle = FrameworkUtil.getBundle(SvcLogicClassResolver.class); + + if (bundle == null) { + // Running outside OSGi container (e.g. jUnit). Use Reflection + // to resolve class + try { + return (Class.forName(className).newInstance()); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + + LOG.error("Could not resolve class " + className, e); + return null; + } + + } else { + BundleContext bctx = bundle.getBundleContext(); + ServiceReference sref = bctx.getServiceReference(className); + if (sref != null) { + return bctx.getService(sref); + } else { + + LOG.warn("Could not find service reference object for class " + className); + return null; + } + } + } + + @Override + public SvcLogicResource getSvcLogicResource(String resourceName) { + return (SvcLogicResource) resolve(resourceName); + } + + @Override + public SvcLogicRecorder getSvcLogicRecorder(String recorderName) { + return (SvcLogicRecorder) resolve(recorderName); + } + + @Override + public SvcLogicJavaPlugin getSvcLogicJavaPlugin(String pluginName) { + return (SvcLogicJavaPlugin) resolve(pluginName); + } + + @Override + public SvcLogicAdaptor getSvcLogicAdaptor(String adaptorName) { + return getAdaptorInstance(adaptorName); + } + +} diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java new file mode 100644 index 000000000..aad7a5a6d --- /dev/null +++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicPropertiesProviderImpl.java @@ -0,0 +1,189 @@ +/*- + * ============LICENSE_START======================================================= + * onap + * ================================================================================ + * Copyright (C) 2016 - 2017 ONAP + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import java.util.Properties; +import java.util.Vector; + +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider; +import org.onap.ccsdk.sli.core.utils.JREFileResolver; +import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver; +import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver; +import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver; +import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Responsible for determining the properties file to use and instantiating the + * <code>DBResourceManager</code> Service. The priority for properties file + * resolution is as follows: + * + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>dblib.properties</code></li> + * <li>A <code>dblib.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ +public class SvcLogicPropertiesProviderImpl implements SvcLogicPropertiesProvider { + + private static final Logger log = LoggerFactory.getLogger(SvcLogicPropertiesProviderImpl.class); + + /** + * The name of the properties file for database configuration + */ + private static final String SVCLOGIC_PROP_FILE_NAME = "svclogic.properties"; + + /** + * A prioritized list of strategies for resolving dblib properties files. + */ + private Vector<PropertiesFileResolver> sliPropertiesFileResolvers = new Vector<>(); + + /** + * The configuration properties for the db connection. + */ + private Properties properties; + + /** + * Set up the prioritized list of strategies for resolving dblib properties + * files. + */ + public SvcLogicPropertiesProviderImpl() { + sliPropertiesFileResolvers + .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable")); + sliPropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory")); + + sliPropertiesFileResolvers.add( + new JREFileResolver("Using property file (3) from JRE argument", SvcLogicPropertiesProviderImpl.class)); + sliPropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this)); + + // determines properties file as according to the priority described in the + // class header comment + final File propertiesFile = determinePropertiesFile(this); + if (propertiesFile != null) { + try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { + properties = new Properties(); + properties.load(fileInputStream); + } catch (final IOException e) { + log.error("Failed to load properties for file: {}", propertiesFile.toString(), + new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(), + e)); + } + } else { + // Try to read properties as resource + + InputStream propStr = getClass().getResourceAsStream("/" + SVCLOGIC_PROP_FILE_NAME); + if (propStr != null) { + properties = new Properties(); + try { + properties.load(propStr); + propStr.close(); + } catch (IOException e) { + log.error("IO Exception",e); + properties = null; + } + } + + } + + if (properties == null) { + reportFailure("Missing configuration properties resource(3)", new ConfigurationException( + "Missing configuration properties resource(3): " + SVCLOGIC_PROP_FILE_NAME)); + } + } + + /** + * Extract svclogic config properties. + * + * @return the svclogic config properties + */ + public Properties getProperties() { + return properties; + } + + /** + * Reports the method chosen for properties resolution to the + * <code>Logger</code>. + * + * @param message + * Some user friendly message + * @param fileOptional + * The file location of the chosen properties file + * @return the file location of the chosen properties file + */ + private static File reportSuccess(final String message, final Optional<File> fileOptional) { + if (fileOptional.isPresent()) { + final File file = fileOptional.get(); + log.info("{} {}", message, file.getPath()); + return file; + } + return null; + } + + /** + * Reports fatal errors. This is the case in which no properties file could be + * found. + * + * @param message + * An appropriate fatal error message + * @param configurationException + * An exception describing what went wrong during resolution + */ + private static void reportFailure(final String message, final ConfigurationException configurationException) { + + log.error("{}", message, configurationException); + } + + /** + * Determines the dblib properties file to use based on the following priority: + * <ol> + * <li>A directory identified by the system environment variable + * <code>SDNC_CONFIG_DIR</code></li> + * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li> + * <li>A directory identified by the JRE argument + * <code>dblib.properties</code></li> + * <li>A <code>dblib.properties</code> file located in the karaf root + * directory</li> + * </ol> + */ + File determinePropertiesFile(final SvcLogicPropertiesProviderImpl resourceProvider) { + + for (final PropertiesFileResolver sliPropertiesFileResolver : sliPropertiesFileResolvers) { + final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(SVCLOGIC_PROP_FILE_NAME); + if (fileOptional.isPresent()) { + return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional); + } + } + + return null; + } +} diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java new file mode 100644 index 000000000..a23594ee3 --- /dev/null +++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicService.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import java.util.Properties; + +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; + +public interface SvcLogicService extends SvcLogicServiceBase { + + String NAME = "org.onap.ccsdk.sli.core.sli.provider.SvcLogicService"; + + @Deprecated + Properties execute(String module, String rpc, String version, String mode, Properties parms) throws SvcLogicException; + + /** + * Execute a directed graph + * + * @param module - module name + * @param rpc - rpc name + * @param version - version. If null, use active version + * @param mode - mode (sync/async) + * @param parms - parameters, used to set SvcLogicContext attributes + * @param domDataBroker - DOMDataBroker object + * @return final values of attributes from SvcLogicContext, as Properties + * @throws SvcLogicException + */ + Properties execute(String module, String rpc, String version, String mode, Properties parms, DOMDataBroker domDataBroker) throws SvcLogicException; + + +} diff --git a/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java new file mode 100755 index 000000000..92c2aa49a --- /dev/null +++ b/core/sli/provider/src/main/java/org/onap/ccsdk/sli/core/sli/provider/SvcLogicServiceImpl.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Modifications Copyright (C) 2018 IBM. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import java.util.Properties; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.onap.ccsdk.sli.core.sli.ConfigurationException; +import org.onap.ccsdk.sli.core.sli.SvcLogicDblibStore; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicStore; +import org.onap.ccsdk.sli.core.sli.SvcLogicStoreFactory; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicResolver; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceImplBase; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SvcLogicServiceImpl extends SvcLogicServiceImplBase implements SvcLogicService { + + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicServiceImpl.class); + + public SvcLogicServiceImpl(SvcLogicPropertiesProvider resourceProvider, SvcLogicResolver resolver) + throws SvcLogicException { + super(null, resolver); + properties = resourceProvider.getProperties(); + this.store = getStore(); + } + + public SvcLogicServiceImpl(SvcLogicPropertiesProvider resourceProvider, DbLibService dbSvc, + SvcLogicResolver resolver) throws SvcLogicException { + super(null, resolver); + properties = resourceProvider.getProperties(); + this.store = new SvcLogicDblibStore(dbSvc); + } + + @Override + @Deprecated + // DomDataBroker is not being used, this should be removed eventually + public Properties execute(String module, String rpc, String version, String mode, Properties props, + DOMDataBroker domDataBroker) throws SvcLogicException { + return (execute(module, rpc, version, mode, props)); + } + + @Override + public SvcLogicStore getStore() throws SvcLogicException { + // Create and initialize SvcLogicStore object - used to access + // saved service logic. + if (store != null) { + return store; + } + + try { + store = SvcLogicStoreFactory.getSvcLogicStore(properties); + } catch (Exception e) { + throw new ConfigurationException("Could not get service logic store", e); + + } + + try { + store.init(properties); + } catch (SvcLogicException e) { + throw new ConfigurationException("Could not get service logic store", e); + } + + return store; + } + +} diff --git a/core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml b/core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml new file mode 100644 index 000000000..fb3ab9a03 --- /dev/null +++ b/core/sli/provider/src/main/resources/OSGI-INF/blueprint/sli-blueprint.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicPropertiesProviderImpl" /> + <reference id="dblibService" interface="org.onap.ccsdk.sli.core.dblib.DbLibService" /> + <bean id="svcLogicClassResolver" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicClassResolver" /> + + <bean id="svcLogicService" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicServiceImpl"> + <argument ref="propProvider" /> + <argument ref="dblibService" /> + <argument ref="svcLogicClassResolver" /> + </bean> + + <service ref="svcLogicService"> + <interfaces> + <value>org.onap.ccsdk.sli.core.sli.provider.SvcLogicService</value> + </interfaces> + </service> + + <bean id="fileRecorder" class="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" /> + <!-- Implementation name was chosen over interface name due to the fact that this Service + was previously registered using the implementation name rather than the interface name. + To ensure backwards compatibility with abstractions polling the Service Registry for the + fileRecorder, the implementation name was chosen here. --> + <service ref="fileRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" /> + + <bean id="slf4jRecorder" class="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" /> + <!-- Implementation name was chosen over interface name due to the fact that this Service + was previously registered using the implementation name rather than the interface name. + To ensure backwards compatibility with abstractions polling the Service Registry for the + slf4jRecorder, the implementation name was chosen here. --> + <service ref="slf4jRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" /> + +</blueprint> diff --git a/core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml b/core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml new file mode 100644 index 000000000..fb3ab9a03 --- /dev/null +++ b/core/sli/provider/src/main/resources/org/opendaylight/blueprint/sli-blueprint.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" + odl:use-default-for-reference-types="true"> + + <bean id="propProvider" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicPropertiesProviderImpl" /> + <reference id="dblibService" interface="org.onap.ccsdk.sli.core.dblib.DbLibService" /> + <bean id="svcLogicClassResolver" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicClassResolver" /> + + <bean id="svcLogicService" class="org.onap.ccsdk.sli.core.sli.provider.SvcLogicServiceImpl"> + <argument ref="propProvider" /> + <argument ref="dblibService" /> + <argument ref="svcLogicClassResolver" /> + </bean> + + <service ref="svcLogicService"> + <interfaces> + <value>org.onap.ccsdk.sli.core.sli.provider.SvcLogicService</value> + </interfaces> + </service> + + <bean id="fileRecorder" class="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" /> + <!-- Implementation name was chosen over interface name due to the fact that this Service + was previously registered using the implementation name rather than the interface name. + To ensure backwards compatibility with abstractions polling the Service Registry for the + fileRecorder, the implementation name was chosen here. --> + <service ref="fileRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.FileRecorder" /> + + <bean id="slf4jRecorder" class="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" /> + <!-- Implementation name was chosen over interface name due to the fact that this Service + was previously registered using the implementation name rather than the interface name. + To ensure backwards compatibility with abstractions polling the Service Registry for the + slf4jRecorder, the implementation name was chosen here. --> + <service ref="slf4jRecorder" interface="org.onap.ccsdk.sli.core.sli.recording.Slf4jRecorder" /> + +</blueprint> diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java new file mode 100644 index 000000000..ad439cdb4 --- /dev/null +++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/ITCaseSvcLogicGraphExecutor.java @@ -0,0 +1,265 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Properties; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicGraph; +import org.onap.ccsdk.sli.core.sli.SvcLogicParser; +import org.onap.ccsdk.sli.core.sli.SvcLogicStore; +import org.onap.ccsdk.sli.core.sli.SvcLogicStoreFactory; +import org.onap.ccsdk.sli.core.sli.provider.base.AbstractSvcLogicNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.BlockNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.BreakNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.CallNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ConfigureNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.DeleteNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ExecuteNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ExistsNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ForNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.GetResourceNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.IsAvailableNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.NotifyNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.RecordNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ReleaseNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ReserveNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.ReturnNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.SaveNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.SetNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider; +import org.onap.ccsdk.sli.core.sli.provider.base.SwitchNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.UpdateNodeExecutor; +import org.onap.ccsdk.sli.core.sli.provider.base.WhileNodeExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ITCaseSvcLogicGraphExecutor { + + private static final Logger LOG = LoggerFactory.getLogger(SvcLogicGraph.class); + private static final Map<String, AbstractSvcLogicNodeExecutor> BUILTIN_NODES = new HashMap<String, AbstractSvcLogicNodeExecutor>() { + { + put("block", new BlockNodeExecutor()); + put("break", new BreakNodeExecutor()); + put("call", new CallNodeExecutor()); + put("configure", new ConfigureNodeExecutor()); + put("delete", new DeleteNodeExecutor()); + put("execute", new ExecuteNodeExecutor()); + put("exists", new ExistsNodeExecutor()); + put("for", new ForNodeExecutor()); + put("get-resource", new GetResourceNodeExecutor()); + put("is-available", new IsAvailableNodeExecutor()); + put("notify", new NotifyNodeExecutor()); + put("record", new RecordNodeExecutor()); + put("release", new ReleaseNodeExecutor()); + put("reserve", new ReserveNodeExecutor()); + put("return", new ReturnNodeExecutor()); + put("save", new SaveNodeExecutor()); + put("set", new SetNodeExecutor()); + put("switch", new SwitchNodeExecutor()); + put("update", new UpdateNodeExecutor()); + put("while", new WhileNodeExecutor()); + + } + }; + + private static SvcLogicClassResolver svcLogicClassResolver; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + + LOG.info("before class"); + + InputStream propStr = ITCaseSvcLogicGraphExecutor.class.getResourceAsStream("/svclogic.properties"); + + Properties svcprops = new Properties(); + svcprops.load(propStr); + + SvcLogicStore store = SvcLogicStoreFactory.getSvcLogicStore(svcprops); + + assertNotNull(store); + + SvcLogicParser parser = new SvcLogicParser(); + + SvcLogicPropertiesProvider resourceProvider = new SvcLogicPropertiesProviderImpl(); + svcLogicClassResolver = new SvcLogicClassResolver(); + SvcLogicServiceImpl svc = new SvcLogicServiceImpl(resourceProvider, svcLogicClassResolver); + + for (String nodeType : BUILTIN_NODES.keySet()) { + svc.registerExecutor(nodeType, BUILTIN_NODES.get(nodeType)); + } + + + + + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + LOG.info("after class"); + } + + @Before + public void setUp() throws Exception { + LOG.info("before"); + } + + @After + public void tearDown() throws Exception { + LOG.info("after"); + } + + @Test + public void testExecute() { + + try { + InputStream testStr = getClass().getResourceAsStream("/executor.tests"); + BufferedReader testsReader = new BufferedReader(new InputStreamReader(testStr)); + + InputStream propStr = getClass().getResourceAsStream("/svclogic.properties"); + + Properties svcprops = new Properties(); + svcprops.load(propStr); + + + + + SvcLogicParser parser = new SvcLogicParser(); + + // Loop through executor tests + SvcLogicPropertiesProvider resourceProvider = new SvcLogicPropertiesProvider() { + @Override + public Properties getProperties() { + return svcprops; + } + }; + SvcLogicServiceImpl svc = new SvcLogicServiceImpl(resourceProvider, svcLogicClassResolver); + SvcLogicStore store = svc.getStore(); + assertNotNull(store); + for (String nodeType : BUILTIN_NODES.keySet()) { + + + svc.registerExecutor(nodeType, BUILTIN_NODES.get(nodeType)); + + } + String testCaseLine = null; + while ((testCaseLine = testsReader.readLine()) != null) { + + String[] testCaseFields = testCaseLine.split(":"); + String testCaseFile = testCaseFields[0]; + String testCaseMethod = testCaseFields[1]; + String testCaseParameters = null; + + if (testCaseFields.length > 2) { + testCaseParameters = testCaseFields[2]; + } + + SvcLogicContext ctx = new SvcLogicContext(); + if (testCaseParameters != null) { + String[] testCaseParameterSettings = testCaseParameters.split(","); + + for (int i = 0; i < testCaseParameterSettings.length; i++) { + String[] nameValue = testCaseParameterSettings[i].split("="); + if (nameValue != null) { + String name = nameValue[0]; + String value = ""; + if (nameValue.length > 1) { + value = nameValue[1]; + } + + ctx.setAttribute(name, value); + } + } + } + + testCaseFile = testCaseFile.trim(); + + if (testCaseFile.length() > 0) { + if (!testCaseFile.startsWith("/")) { + testCaseFile = "/" + testCaseFile; + } + URL testCaseUrl = getClass().getResource(testCaseFile); + if (testCaseUrl == null) { + fail("Could not resolve test case file " + testCaseFile); + } + + + LinkedList<SvcLogicGraph> graphs = parser.parse(testCaseUrl.getPath()); + + assertNotNull(graphs); + + // Load grqphs into db to support call node + SvcLogicParser.load(testCaseUrl.getPath(), store); + SvcLogicParser.activate("neutron", "canCreateNetwork", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "switchTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "forRecordTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "whileNodeTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "resourceTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "configureTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "javaPluginTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "allNodesTester", "1.0.0", "sync", store); + SvcLogicParser.activate("neutron", "networkCreated", "1.0.0", "sync", store); + + for (SvcLogicGraph graph : graphs) { + if (graph.getRpc().equals(testCaseMethod)) { + Properties props = ctx.toProperties(); + LOG.info("SvcLogicContext before executing {}:", testCaseMethod); + for (Enumeration e1 = props.propertyNames(); e1.hasMoreElements(); ) { + String propName = (String) e1.nextElement(); + LOG.info(propName + " = " + props.getProperty(propName)); + } + + svc.execute(graph, ctx); + + props = ctx.toProperties(); + LOG.info("SvcLogicContext after executing {}:", testCaseMethod); + for (Enumeration e2 = props.propertyNames(); e2.hasMoreElements(); ) { + String propName = (String) e2.nextElement(); + LOG.info(propName + " = " + props.getProperty(propName)); + } + } + } + + } + } + + } catch (Exception e) { + LOG.error("Caught exception executing directed graphs", e); + fail("Exception executing graphs"); + } + } +} diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java new file mode 100755 index 000000000..93d9931d0 --- /dev/null +++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTest.java @@ -0,0 +1,763 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.Inet6Address; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInput.Mode; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameter; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameterBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Builtin.SampleBits; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Builtin.SampleEnumeration; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Builtin.SampleUnion; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.Percentage; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.SampleContainer; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.SampleContainerBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.sample.container.LoginBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.sample.container.login.CustomerAddresses; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.testmodel.rev190723.sample.container.login.CustomerAddressesBuilder; +import org.opendaylight.yang.gen.v1.test.TestObjectBuilder; +import org.opendaylight.yang.gen.v1.test.WrapperObj; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.DomainName; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.HostBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZoneBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpVersion; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; +import org.opendaylight.yangtools.yang.common.Empty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import junit.framework.TestCase; + +public class MdsalHelperTest extends TestCase { + private static final Logger LOG = LoggerFactory.getLogger(MdsalHelperTest.class); + public static final String pathToSdnPropertiesFile = "src/test/resources/l3sdn.properties"; + + public void testSdnProperties() { + + MdsalHelperTesterUtil.loadProperties(pathToSdnPropertiesFile); + assertEquals("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "synccomplete")); + assertEquals("asynccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "asynccomplete")); + assertEquals("notifycomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "notifycomplete")); + assertEquals("service-configuration-operation", + MdsalHelperTesterUtil.mapEnumeratedValue("rpc-name", "service-configuration-operation")); + } + + public void testNegativeSdnProperties() { + assertNotSame("synccomplete", MdsalHelperTesterUtil.mapEnumeratedValue("request-status", "Synccomplete")); + } + + public void testToProperties() { + + ExecuteGraphInputBuilder execBuilder = new ExecuteGraphInputBuilder(); + SliParameterBuilder parmBuilder = new SliParameterBuilder(); + List<SliParameter> params = new LinkedList<SliParameter>(); + + parmBuilder.setParameterName("boolean-parm"); + parmBuilder.setBooleanValue(Boolean.TRUE); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("int-parm"); + parmBuilder.setBooleanValue(null); + parmBuilder.setIntValue(1); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("str-parm"); + parmBuilder.setIntValue(null); + parmBuilder.setStringValue("hello"); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("ipaddress4-parm"); + parmBuilder.setStringValue(null); + parmBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("127.0.0.1")); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("ipaddress6-parm"); + parmBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("ef::1")); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("ipprefix-parm"); + parmBuilder.setIpaddressValue(null); + parmBuilder.setIpprefixValue(IpPrefixBuilder.getDefaultInstance("10.0.0.0/24")); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("portnumber-parm"); + parmBuilder.setIpprefixValue(null); + parmBuilder.setPortNumber(PortNumber.getDefaultInstance("8080")); + params.add(parmBuilder.build()); + + parmBuilder.setParameterName("dcsp-parm"); + parmBuilder.setPortNumber(null); + parmBuilder.setDscp(Dscp.getDefaultInstance("57")); + params.add(parmBuilder.build()); + + execBuilder.setMode(Mode.Sync); + execBuilder.setModuleName("my-module"); + execBuilder.setRpcName("do-it-now"); + execBuilder.setSliParameter(params); + + Properties props = new Properties(); + + MdsalHelperTesterUtil.toProperties(props, execBuilder); + + LOG.info("Converted to properties"); + for (Map.Entry<Object, Object> e : props.entrySet()) { + LOG.info(e.getKey().toString() + " = " + e.getValue().toString()); + + } + + } + + public void testToBuilder() { + + Properties props = new Properties(); + + props.setProperty("execute-graph-input.mode", "Sync"); + props.setProperty("execute-graph-input.module", "my-module"); + props.setProperty("execute-graph-input.rpc", "do-it-now"); + props.setProperty("execute-graph-input.sli-parameter[0].parameter-name", "bool-parm"); + props.setProperty("execute-graph-input.sli-parameter[0].boolean-value", "true"); + props.setProperty("execute-graph-input,sli-parameter[1].parameter-name", "int-param"); + props.setProperty("execute-graph-input.sli-parameter[1].int-value", "1"); + props.setProperty("execute-graph-input.sli-parameter[2].parameter-name", "str-param"); + props.setProperty("execute-graph-input.sli-parameter[2].str-value", "hello"); + props.setProperty("execute-graph-input.sli-parameter[3].parameter-name", "ipv4address-param"); + props.setProperty("execute-graph-input.sli-parameter[3].ipaddress-value", "127.0.0.1"); + props.setProperty("execute-graph-input.sli-parameter[4].parameter-name", "ipv6address-param"); + props.setProperty("execute-graph-input.sli-parameter[4].ipaddress-value", "ef::1"); + ExecuteGraphInputBuilder execBuilder = new ExecuteGraphInputBuilder(); + + MdsalHelperTesterUtil.toBuilder(props, execBuilder); + + } + + public void testToJavaEnum() throws Exception { + assertEquals("VENDOR6500MODEL", MdsalHelper.toJavaEnum("VENDOR_6500_MODEL")); + assertEquals("_2018HelloWorld", MdsalHelper.toJavaEnum("2018Hello World")); + assertEquals("SomethingElse", MdsalHelper.toJavaEnum("Something.Else")); + assertEquals("MyTestString", MdsalHelper.toJavaEnum("my-test-string")); + } + + // During the default enumeration mapping no properties file is needed, the yang + // value is returned + // by the java object + public void testDefaultEnumerationMapping() throws Exception { + Properties props = new Properties(); + MdsalHelper.toProperties(props, new WrapperObj()); + assertEquals("4COS", props.getProperty("wrapper-obj.cos-model-type")); + } + + // When no properties file exists the default java value will be returned if + // legacy enumeration + // mapping is enabled + public void testLegacyEnumerationMappingNoProperties() throws Exception { + Properties props = new Properties(); + MdsalHelper.toProperties(props, new WrapperObj(), true); + assertEquals("_4COS", props.getProperty("wrapper-obj.cos-model-type")); + } + + // When a properties file exists & legacy enumeration mapping is enabled the + // value from the + // properties file should be returned + public void testLegacyEnumerationMappingWithProperties() throws Exception { + MdsalHelper.loadProperties("src/test/resources/EnumerationMapping.properties"); + Properties props = new Properties(); + MdsalHelper.toProperties(props, new WrapperObj(), true); + assertEquals("HelloWorld", props.getProperty("wrapper-obj.cos-model-type")); + } + + public void testSingleIpAddressToProperties() throws Exception { + Properties props = new Properties(); + String ipAddress = "11.11.11.11"; + MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(ipAddress)); + assertEquals(ipAddress, props.getProperty("")); + ipAddress = "cafe::8888"; + MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(ipAddress)); + assertEquals(ipAddress, props.getProperty("")); + } + + public void testSingleIpAddressToBuilder() throws Exception { + Properties props = new Properties(); + String ipAddress = "11.11.11.11"; + props.setProperty("test-object.single-ip", ipAddress); + TestObjectBuilder b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + + assertEquals(ipAddress, String.valueOf(b.getSingleIp().stringValue())); + + ipAddress = "cafe::8888"; + props.setProperty("test-object.single-ip", ipAddress); + b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(ipAddress, String.valueOf(b.getSingleIp().stringValue())); + } + + public void testIpAddressListToProperties() throws Exception { + Properties props = new Properties(); + String ipAddress = "11.11.11.11"; + TestObjectBuilder b = new TestObjectBuilder(); + List<IpAddress> ipAddressList = new ArrayList<IpAddress>(); + ipAddressList.add(IpAddressBuilder.getDefaultInstance(ipAddress)); + b.setFloatingIp(ipAddressList); + MdsalHelper.toProperties(props, b.build()); + assertEquals(ipAddress, props.getProperty("test-object.floating-ip[0]")); + assertEquals("1", props.getProperty("test-object.floating-ip_length")); + } + + public void testIpAddressListToBuilder() throws Exception { + Properties props = new Properties(); + String ipaddress = "11.11.11.12"; + props.setProperty("test-object.floating-ip_length", "1"); + props.setProperty("test-object.floating-ip[0]", ipaddress); + TestObjectBuilder b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(ipaddress, String.valueOf(b.getFloatingIp().get(0).stringValue())); + + props = new Properties(); + ipaddress = "cafe::8888"; + props.setProperty("test-object.floating-ip_length", "1"); + props.setProperty("test-object.floating-ip[0]", ipaddress); + b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(ipaddress, String.valueOf(b.getFloatingIp().get(0).stringValue())); + } + + public void testSingleIpv4AddressToProperties() throws Exception { + Properties props = new Properties(); + String v4address = "11.11.11.11"; + MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(v4address).getIpv4Address()); + assertEquals(v4address, props.getProperty("")); + } + + public void testSingleIpv4AddressToBuilder() throws Exception { + Properties props = new Properties(); + String v4address = "11.11.11.11"; + props.setProperty("test-object.single-ip-v4", v4address); + TestObjectBuilder b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(v4address, b.getSingleIpV4().getValue()); + } + + public void testIpv4AddressListToProperties() throws Exception { + Properties props = new Properties(); + String v4address = "11.11.11.11"; + + TestObjectBuilder b = new TestObjectBuilder(); + List<Ipv4Address> v4list = new ArrayList<Ipv4Address>(); + v4list.add(IpAddressBuilder.getDefaultInstance(v4address).getIpv4Address()); + b.setFloatingIpV4(v4list); + MdsalHelper.toProperties(props, b.build()); + assertEquals(v4address, props.getProperty("test-object.floating-ip-v4[0]")); + assertEquals("1", props.getProperty("test-object.floating-ip-v4_length")); + } + + public void testIpv4AddressListToBuilder() throws Exception { + Properties props = new Properties(); + String v4address = "11.11.11.12"; + props.setProperty("test-object.floating-ip-v4_length", "1"); + props.setProperty("test-object.floating-ip-v4[0]", v4address); + TestObjectBuilder b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(v4address, b.getFloatingIpV4().get(0).getValue()); + } + + public void testSingleIpv6AddressToProperties() throws Exception { + Properties props = new Properties(); + String v6address = "cafe::8888"; + MdsalHelper.toProperties(props, IpAddressBuilder.getDefaultInstance(v6address).getIpv6Address()); + MdsalHelper.toBuilder(props, IpAddressBuilder.getDefaultInstance("cafe::8887")); + assertEquals(v6address, props.getProperty("")); + } + + public void testSingleIpv6AddressToBuilder() throws Exception { + Properties props = new Properties(); + String v6address = "cafe::8888"; + props.setProperty("test-object.single-ip-v6", v6address); + TestObjectBuilder b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(v6address, b.getSingleIpV6().getValue()); + } + + public void testIpv6AddressListToProperties() throws Exception { + Properties props = new Properties(); + String v6address = "cafe::8888"; + + TestObjectBuilder b = new TestObjectBuilder(); + List<Ipv6Address> v6list = new ArrayList<Ipv6Address>(); + v6list.add(IpAddressBuilder.getDefaultInstance(v6address).getIpv6Address()); + b.setFloatingIpV6(v6list); + MdsalHelper.toProperties(props, b.build()); + assertEquals(v6address, props.getProperty("test-object.floating-ip-v6[0]")); + assertEquals("1", props.getProperty("test-object.floating-ip-v6_length")); + } + + public void testIpv6AddressListToBuilder() throws Exception { + Properties props = new Properties(); + String v6address = "cafe::8888"; + props.setProperty("test-object.floating-ip-v6_length", "1"); + props.setProperty("test-object.floating-ip-v6[0]", v6address); + TestObjectBuilder b = new TestObjectBuilder(); + MdsalHelper.toBuilder(props, b); + assertEquals(v6address, b.getFloatingIpV6().get(0).getValue()); + } + + public void testIpPrefix() throws Exception { + String ipPrefix = "10.0.0.0/24"; + Properties props = new Properties(); + MdsalHelper.toProperties(props, IpPrefixBuilder.getDefaultInstance(ipPrefix)); + assertEquals(ipPrefix, props.getProperty("")); + } + + public void testPortNumber() throws Exception { + Properties props = new Properties(); + String portNumber = "5"; + MdsalHelper.toProperties(props, PortNumber.getDefaultInstance(portNumber)); + assertEquals(portNumber, props.getProperty("")); + } + + public void testDscp() throws Exception { + Properties props = new Properties(); + String dscp = "1"; + MdsalHelper.toProperties(props, Dscp.getDefaultInstance(dscp)); + assertEquals(dscp, props.getProperty("")); + } + + public void testIetfInet() throws Exception { + Properties props = new Properties(); + Inet6Address address = + IetfInetUtil.INSTANCE.inet6AddressFor(IpAddressBuilder.getDefaultInstance("cafe::8888").getIpv6Address()); + MdsalHelper.toProperties(props, address); + assertEquals("/cafe:0:0:0:0:0:0:8888", props.getProperty("")); + } + + public void testAsNumber() throws Exception { + String value = "1"; + Properties props = new Properties(); + AsNumber num = AsNumber.getDefaultInstance(value); + MdsalHelper.toProperties(props, num); + assertEquals(value, props.getProperty("as-number")); + assertEquals(value, props.getProperty("as-number.value")); + + } + + public void testGetFullPropertiesPath() { + String propertiesName = "l3ucpe.properties"; + String path = MdsalHelper.getFullPropertiesPath(propertiesName); + // verify the default works + assertEquals("/opt/lsc/controller/configuration/l3ucpe.properties", path); + System.setProperty("karaf.home", "/opt/opendaylight/current"); + path = MdsalHelper.getFullPropertiesPath(propertiesName); + // verify the system property is read + assertEquals("/opt/opendaylight/current/configuration/l3ucpe.properties", path); + } + + public void testToPropertiesWithBinary() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Properties props = new Properties(); + byte arr[] = new byte[] {1, 6, 3}; + sampleBuilder.setSampleBinary(arr); + MdsalHelper.toProperties(props, sampleBuilder); + assertNotNull(props.get("sample-container.sample-binary")); + } + + public void testToPropertiesWithBits() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Boolean fanRunning = true; + Boolean hdLed = false; + Boolean powerLed = false; + SampleBits sampleBits = new SampleBits(fanRunning, hdLed, powerLed); + sampleBuilder.setSampleBits(sampleBits); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(fanRunning.toString(), props.get("sample-container.sample-bits.fan-running")); + assertEquals(hdLed.toString(), props.get("sample-container.sample-bits.hd-led")); + assertEquals(powerLed.toString(), props.get("sample-container.sample-bits.power-led")); + } + + public void testToPropertiesWithBoolean() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Boolean myBoolean = true; + sampleBuilder.setSampleBoolean(myBoolean); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myBoolean.toString(), props.get("sample-container.sample-boolean")); + } + + public void testToPropertiesWithDecimal64() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + BigDecimal myBigDecimal = new BigDecimal(".0000000000000000000000000000001"); + sampleBuilder.setSampleDecimal64(myBigDecimal); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + // note toString() value is 1E-31 + assertEquals(myBigDecimal.toString(), props.get("sample-container.sample-decimal64")); + } + + public void testToPropertiesWithEmpty() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Empty isEmpty = Empty.getInstance(); + sampleBuilder.setSampleEmpty(isEmpty); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(isEmpty.toString(), props.get("sample-container.sample-empty")); + } + + public void testToPropertiesWithEnumeration() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Properties props = new Properties(); + SampleEnumeration currentEnum = SampleEnumeration.ShelfSlotPort; + sampleBuilder.setSampleEnumeration(currentEnum); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals("shelf.slot.port", props.get("sample-container.sample-enumeration")); + + currentEnum = SampleEnumeration.NotAvailable; + sampleBuilder.setSampleEnumeration(currentEnum); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals("not available", props.get("sample-container.sample-enumeration")); + + currentEnum = SampleEnumeration.CURRENTLYAVAILABLE; + sampleBuilder.setSampleEnumeration(currentEnum); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals("CURRENTLY_AVAILABLE", props.get("sample-container.sample-enumeration")); + + currentEnum = SampleEnumeration._200OK; + sampleBuilder.setSampleEnumeration(currentEnum); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals("200OK", props.get("sample-container.sample-enumeration")); + + currentEnum = SampleEnumeration.HyphenSeparatedValue; + sampleBuilder.setSampleEnumeration(currentEnum); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals("hyphen-separated-value", props.get("sample-container.sample-enumeration")); + } + + // TODO test sampleBuilder.setSampleIdentityref(value); + + public void testToPropertiesWithInt8() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Byte myByte = new Byte("-128"); + sampleBuilder.setSampleInt8(myByte); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myByte.toString(), props.get("sample-container.sample-int8")); + } + + public void testToPropertiesWithInt16() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Short myShort = new Short("-32768"); + sampleBuilder.setSampleInt16(myShort); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myShort.toString(), props.get("sample-container.sample-int16")); + } + + public void testToPropertiesWithInt32() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Integer myInt = new Integer("-32768"); + sampleBuilder.setSampleInt32(myInt); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myInt.toString(), props.get("sample-container.sample-int32")); + } + + public void testToPropertiesWithInt64() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Long myLong = new Long("-9223372036854775808"); + sampleBuilder.setSampleInt64(myLong); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myLong.toString(), props.get("sample-container.sample-int64")); + } + + public void testToPropertiesWithLeafRef() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Boolean myBool = false; + sampleBuilder.setSampleLeafref(myBool); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myBool.toString(), props.get("sample-container.sample-leafref")); + } + + public void testToPropertiesWithString() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + String myString = "Hello World!"; + sampleBuilder.setSampleString(myString); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myString.toString(), props.get("sample-container.sample-string")); + } + + public void testToPropertiesWithuInt8() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Short myShort = new Short("255"); + sampleBuilder.setSampleUint8(myShort); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myShort.toString(), props.get("sample-container.sample-uint8")); + } + + public void testToPropertiesWithuInt16() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Integer myInt = new Integer("65535"); + sampleBuilder.setSampleUint16(myInt); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myInt.toString(), props.get("sample-container.sample-uint16")); + } + + public void testToPropertiesWithuInt32() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Long myLong = new Long("4294967295"); + sampleBuilder.setSampleUint32(myLong); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myLong.toString(), props.get("sample-container.sample-uint32")); + } + + public void testToPropertiesWithuInt64() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + BigInteger myBigInt = new BigInteger("2432902008176640000"); + sampleBuilder.setSampleUint64(myBigInt); + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myBigInt.toString(), props.get("sample-container.sample-uint64")); + } + + public void testToPropertiesFromBuilderUnion() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Properties props = new Properties(); + + Integer myInt = new Integer("1"); + SampleUnion test = new SampleUnion(myInt); + sampleBuilder.setSampleUnion(test); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(test.getInt32().toString(), props.get("sample-container.sample-union.int32")); + + test = new SampleUnion(SampleUnion.Enumeration.Unbounded); + sampleBuilder.setSampleUnion(test); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals("unbounded", props.get("sample-container.sample-union.enumeration")); + } + + public void testToPropertiesWithCustomType() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + Properties props = new Properties(); + + Short myShort = new Short("99"); + Percentage myPercent = new Percentage(myShort); + sampleBuilder.setPercentCompleted(myPercent); + MdsalHelper.toProperties(props, sampleBuilder); + assertEquals(myShort.toString(), props.get("sample-container.percent-completed")); + assertEquals(myShort.toString(), props.get("sample-container.percent-completed.value")); + } + + public void testToPropertiesWithLeaftList() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + List<String> nickNames = new ArrayList<String>(); + sampleBuilder.setCustomerNicknames(nickNames); + String nameOne = "coffee"; + String nameTwo = "java"; + String nameThree = "mud"; + + nickNames.add(nameOne); + nickNames.add(nameTwo); + nickNames.add(nameThree); + + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + + assertEquals(nameOne, props.get("sample-container.customer-nicknames[0]")); + assertEquals(nameTwo, props.get("sample-container.customer-nicknames[1]")); + assertEquals(nameThree, props.get("sample-container.customer-nicknames[2]")); + assertEquals(String.valueOf(nickNames.size()), props.get("sample-container.customer-nicknames_length")); + } + + public void testToPropertiesWithComplexContainer() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + LoginBuilder lb = new LoginBuilder(); + lb.setMessage("WELCOME!"); + List<CustomerAddresses> addresses = new ArrayList<CustomerAddresses>(); + CustomerAddressesBuilder cab = new CustomerAddressesBuilder(); + cab.setAddressName("home"); + cab.setState("NJ"); + cab.setStreetAddress("yellowbrick road"); + + CustomerAddresses addressOne = cab.build(); + addresses.add(addressOne); + + cab.setAddressName("vacation house"); + cab.setState("FL"); + cab.setStreetAddress("ocean ave"); + + CustomerAddresses addressTwo = cab.build(); + addresses.add(addressTwo); + + lb.setCustomerAddresses(addresses); + sampleBuilder.setLogin(lb.build()); + + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + + assertEquals("WELCOME!", props.get("sample-container.login.message")); + assertEquals("NJ", props.get("sample-container.login.customer-addresses[0].state")); + assertEquals("home", props.get("sample-container.login.customer-addresses[0].address-name")); + assertEquals("yellowbrick road", props.get("sample-container.login.customer-addresses[0].street-address")); + assertEquals("FL", props.get("sample-container.login.customer-addresses[1].state")); + assertEquals("vacation house", props.get("sample-container.login.customer-addresses[1].address-name")); + assertEquals("ocean ave", props.get("sample-container.login.customer-addresses[1].street-address")); + assertEquals("2", props.get("sample-container.login.customer-addresses_length")); + } + + public void testToPropertiesIetf() throws Exception { + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + sampleBuilder.setIpVersion(IpVersion.Ipv4); + sampleBuilder.setDscp(Dscp.getDefaultInstance("1")); + sampleBuilder.setPortNumber(PortNumber.getDefaultInstance("2")); + sampleBuilder.setIpv6FlowLabel(Ipv6FlowLabel.getDefaultInstance("3")); + sampleBuilder.setAsNumber(AsNumber.getDefaultInstance("4")); + sampleBuilder.setIpv6Address(Ipv6Address.getDefaultInstance("fdda:5cc1:23:4::1f")); + sampleBuilder.setIpAddressNoZone(IpAddressNoZoneBuilder.getDefaultInstance("fdda:5cc1:23:4::1f")); + sampleBuilder.setIpv4Address(Ipv4Address.getDefaultInstance("192.168.1.2")); + sampleBuilder.setIpv4AddressNoZone(Ipv4AddressNoZone.getDefaultInstance("192.168.1.3")); + sampleBuilder.setIpv6AddressNoZone(Ipv6AddressNoZone.getDefaultInstance("fdda:5cc1:23:4::1f")); + sampleBuilder.setIpv4Prefix(Ipv4Prefix.getDefaultInstance("198.51.100.0/24")); + sampleBuilder.setIpv6Prefix(Ipv6Prefix.getDefaultInstance("2001:db8:aaaa:1111::100/64")); + sampleBuilder.setDomainName(DomainName.getDefaultInstance("onap.org")); + sampleBuilder.setHost(HostBuilder.getDefaultInstance("machine.onap.org")); + sampleBuilder.setUri(Uri.getDefaultInstance("http://wiki.onap.org:8080")); + + Properties props = new Properties(); + MdsalHelper.toProperties(props, sampleBuilder); + + assertEquals("4", props.get("sample-container.as-number")); + assertEquals("4", props.get("sample-container.as-number.value")); + assertEquals("onap.org", props.get("sample-container.domain-name")); + assertEquals("onap.org", props.get("sample-container.domain-name.value")); + assertEquals("1", props.get("sample-container.dscp")); + assertEquals("machine.onap.org", props.get("sample-container.host.domain-name")); + assertEquals("machine.onap.org", props.get("sample-container.host.domain-name.value")); + assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ip-address-no-zone.ipv6-address-no-zone")); + assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ip-address-no-zone.ipv6-address-no-zone.value")); + assertEquals("ipv4", props.get("sample-container.ip-version")); + assertEquals("192.168.1.2", props.get("sample-container.ipv4-address")); + assertEquals("192.168.1.3", props.get("sample-container.ipv4-address-no-zone")); + assertEquals("192.168.1.3", props.get("sample-container.ipv4-address-no-zone.value")); + assertEquals("198.51.100.0/24", props.get("sample-container.ipv4-prefix")); + assertEquals("198.51.100.0/24", props.get("sample-container.ipv4-prefix.value")); + assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ipv6-address")); + assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ipv6-address-no-zone")); + assertEquals("fdda:5cc1:23:4::1f", props.get("sample-container.ipv6-address-no-zone.value")); + assertEquals("3", props.get("sample-container.ipv6-flow-label")); + assertEquals("3", props.get("sample-container.ipv6-flow-label.value")); + assertEquals("2001:db8:aaaa:1111::100/64", props.get("sample-container.ipv6-prefix")); + assertEquals("2001:db8:aaaa:1111::100/64", props.get("sample-container.ipv6-prefix.value")); + assertEquals("2", props.get("sample-container.port-number")); + assertEquals("http://wiki.onap.org:8080", props.get("sample-container.uri")); + assertEquals("http://wiki.onap.org:8080", props.get("sample-container.uri.value")); + } + + public void testIetfToBuilder() throws Exception { + Properties props = new Properties(); + props.put("sample-container.as-number", "4"); + props.put("sample-container.as-number.value", "4"); + props.put("sample-container.domain-name", "onap.org"); + props.put("sample-container.domain-name.value", "onap.org"); + props.put("sample-container.dscp", "1"); + props.put("sample-container.host.domain-name", "machine.onap.org"); + props.put("sample-container.host.domain-name.value", "machine.onap.org"); + props.put("sample-container.ip-address-no-zone.ipv6-address-no-zone", "fdda:5cc1:23:4::1f"); + props.put("sample-container.ip-address-no-zone.ipv6-address-no-zone.value", "fdda:5cc1:23:4::1f"); + props.put("sample-container.ip-version", "ipv4"); + props.put("sample-container.ipv4-address", "192.168.1.2"); + props.put("sample-container.ipv4-address-no-zone", "192.168.1.3"); + props.put("sample-container.ipv4-address-no-zone.value", "192.168.1.3"); + props.put("sample-container.ipv4-prefix", "198.51.100.0/24"); + props.put("sample-container.ipv4-prefix.value", "198.51.100.0/24"); + props.put("sample-container.ipv6-address", "fdda:5cc1:23:4::1f"); + props.put("sample-container.ipv6-address-no-zone", "fdda:5cc1:23:4::1f"); + props.put("sample-container.ipv6-address-no-zone.value", "fdda:5cc1:23:4::1f"); + props.put("sample-container.ipv6-flow-label", "3"); + props.put("sample-container.ipv6-flow-label.value", "3"); + props.put("sample-container.ipv6-prefix", "2001:db8:aaaa:1111::100/64"); + props.put("sample-container.ipv6-prefix.value", "2001:db8:aaaa:1111::100/64"); + props.put("sample-container.port-number", "2"); + props.put("sample-container.uri", "http://wiki.onap.org:8080"); + props.put("sample-container.uri.value", "http://wiki.onap.org:8080"); + SampleContainerBuilder sampleBuilder = new SampleContainerBuilder(); + + MdsalHelper.toBuilder(props, sampleBuilder); + SampleContainer result = sampleBuilder.build(); + assertEquals(AsNumber.getDefaultInstance("4"), result.getAsNumber()); + assertEquals(DomainName.getDefaultInstance("onap.org"), result.getDomainName()); + assertEquals(Dscp.getDefaultInstance("1"), result.getDscp()); + // assertEquals(HostBuilder.getDefaultInstance("machine.onap.org").getDomainName(), + // result.getHost().getDomainName()); + assertEquals(Ipv6AddressNoZone.getDefaultInstance("fdda:5cc1:23:4::1f").getValue(), + result.getIpv6AddressNoZone().getValue()); + assertEquals(IpVersion.Ipv4, result.getIpVersion()); + assertEquals(Ipv4Address.getDefaultInstance("192.168.1.2"), result.getIpv4Address()); + assertEquals(Ipv4AddressNoZone.getDefaultInstance("192.168.1.3"), result.getIpv4AddressNoZone()); + assertEquals(Ipv4Prefix.getDefaultInstance("198.51.100.0/24"), result.getIpv4Prefix()); + assertEquals(Ipv6Address.getDefaultInstance("fdda:5cc1:23:4::1f"), result.getIpv6Address()); + assertEquals(IpAddressNoZoneBuilder.getDefaultInstance("fdda:5cc1:23:4::1f").getIpv6AddressNoZone().getValue(), + result.getIpv6AddressNoZone().getValue()); + assertEquals(Ipv6FlowLabel.getDefaultInstance("3"), result.getIpv6FlowLabel()); + assertEquals(Ipv6Prefix.getDefaultInstance("2001:db8:aaaa:1111::100/64"), result.getIpv6Prefix()); + assertEquals(PortNumber.getDefaultInstance("2"), result.getPortNumber()); + assertEquals(Uri.getDefaultInstance("http://wiki.onap.org:8080"), result.getUri()); + } + + public void testToLowerHyphen() throws Exception { + String camelCase = "HelloWorld"; + String hypenCase = MdsalHelper.toLowerHyphen(camelCase); + assertEquals("hello-world", hypenCase); + + camelCase = "L2SwitchInterfaces"; + hypenCase = MdsalHelper.toLowerHyphen(camelCase); + assertEquals("l2-switch-interfaces", hypenCase); + + camelCase = "ABC"; + hypenCase = MdsalHelper.toLowerHyphen(camelCase); + assertEquals("a-b-c", hypenCase); + } + +} diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java new file mode 100644 index 000000000..2167b8101 --- /dev/null +++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/MdsalHelperTesterUtil.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP : CCSDK + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.ccsdk.sli.core.sli.provider; + +import org.onap.ccsdk.sli.core.sli.provider.MdsalHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MdsalHelperTesterUtil extends MdsalHelper { + + private static final Logger LOG = LoggerFactory.getLogger(MdsalHelperTesterUtil.class); + + //Normally static init of classes goes here for some weird classloader thing + static { + String str = "Hello World!"; + } + +} diff --git a/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java new file mode 100644 index 000000000..50b7926a0 --- /dev/null +++ b/core/sli/provider/src/test/java/org/onap/ccsdk/sli/core/sli/provider/PrintYangToPropTest.java @@ -0,0 +1,142 @@ +/*- + 2 * ============LICENSE_START======================================================= + 3 * ONAP CCSDK + 4 * ================================================================================ + 5 * Copyright (C) 2019 AT&T Intellectual Property. All rights + 6 * reserved. + 7 * ================================================================================ + 8 * Licensed under the Apache License, Version 2.0 (the "License"); + 9 * you may not use this file except in compliance with the License. + 10 * You may obtain a copy of the License at + 11 * + 12 * http://www.apache.org/licenses/LICENSE-2.0 + 13 * + 14 * Unless required by applicable law or agreed to in writing, software + 15 * distributed under the License is distributed on an "AS IS" BASIS, + 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + 17 * See the License for the specific language governing permissions and + 18 * limitations under the License. + 19 * ============LICENSE_END============================================ + 20 * =================================================================== + 21 * + 22 */ +package org.onap.ccsdk.sli.core.sli.provider; + +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + +import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.provider.PrintYangToProp; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInput.Mode; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.ExecuteGraphInputBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.TestResultsBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameter; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.execute.graph.input.SliParameterBuilder; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.test.results.TestResult; +import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.core.sliapi.rev161110.test.results.TestResultBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author dt5972 + * + */ +public class PrintYangToPropTest { + + private static final Logger LOG = LoggerFactory.getLogger(PrintYangToPropTest.class); + @Test + public void test() { + + Properties props = new Properties(); + + // Set up a builder with data + ExecuteGraphInputBuilder egBuilder = new ExecuteGraphInputBuilder(); + egBuilder.setMode(Mode.Sync); + egBuilder.setModuleName("my-module"); + egBuilder.setRpcName("my-rpc"); + + List<SliParameter> pList = new LinkedList<>(); + + SliParameterBuilder pBuilder = new SliParameterBuilder(); + pBuilder.setParameterName("string-param"); + pBuilder.setStringValue("hi"); + pList.add(pBuilder.build()); + pBuilder.setParameterName("int-param"); + pBuilder.setIntValue(1); + pBuilder.setStringValue(null); + pList.add(pBuilder.build()); + pBuilder.setParameterName("bool-param"); + pBuilder.setIntValue(null); + pBuilder.setBooleanValue(true); + pList.add(pBuilder.build()); + pBuilder.setParameterName("ipaddress-value1"); + pBuilder.setBooleanValue(null); + pBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("127.0.0.1")); + pList.add(pBuilder.build()); + pBuilder.setParameterName("ipaddress-value1"); + pBuilder.setIpaddressValue(IpAddressBuilder.getDefaultInstance("::1")); + pList.add(pBuilder.build()); + pBuilder.setParameterName("ipprefix-value1"); + pBuilder.setIpaddressValue(null); + pBuilder.setIpprefixValue(IpPrefixBuilder.getDefaultInstance("192.168.0.0/16")); + pList.add(pBuilder.build()); + pBuilder.setParameterName("ipprefix-value2"); + pBuilder.setIpprefixValue(IpPrefixBuilder.getDefaultInstance("2001:db8:3c4d::/48")); + pList.add(pBuilder.build()); + + + + egBuilder.setSliParameter(pList); + + + // Generate properties + props = PrintYangToProp.toProperties(props, egBuilder); + + Enumeration propNames = props.propertyNames(); + + while (propNames.hasMoreElements()) { + String propName = (String) propNames.nextElement(); + LOG.info("Property {} = {}", propName, props.getProperty(propName)); + } + + // Generate builder from properties just generated + PrintYangToProp.toBuilder(props, pBuilder); + + + } + + @Test + public void testWithList() { + TestResultsBuilder resultsBuilder = new TestResultsBuilder(); + TestResultBuilder resultBuilder = new TestResultBuilder(); + + // Set builder with values + List<TestResult> resultList = new LinkedList<>(); + resultBuilder.setTestIdentifier("test1"); + List<String> results = new LinkedList<>(); + results.add("pass"); + resultBuilder.setResults(results); + resultList.add(resultBuilder.build()); + resultsBuilder.setTestResult(resultList); + + // Generate properties + Properties props = new Properties(); + props = PrintYangToProp.toProperties(props, resultsBuilder); + + Enumeration propNames = props.propertyNames(); + + while (propNames.hasMoreElements()) { + String propName = (String) propNames.nextElement(); + LOG.info("Property {} = {}", propName, props.getProperty(propName)); + } + + // Generate builder from properties just generated + PrintYangToProp.toBuilder(props, resultsBuilder); + + } + +} diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java new file mode 100644 index 000000000..2aaaf8aa3 --- /dev/null +++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/CosModelType.java @@ -0,0 +1,51 @@ +package org.opendaylight.yang.gen.v1.test; + +public enum CosModelType { + _4COS(0, "4COS"), + + _6COS(1, "6COS") + ; + + private static final java.util.Map<java.lang.Integer, CosModelType> VALUE_MAP; + + static { + final com.google.common.collect.ImmutableMap.Builder<java.lang.Integer, CosModelType> b = com.google.common.collect.ImmutableMap.builder(); + for (CosModelType enumItem : CosModelType.values()) { + b.put(enumItem.value, enumItem); + } + + VALUE_MAP = b.build(); + } + + private final java.lang.String name; + private final int value; + + private CosModelType(int value, java.lang.String name) { + this.value = value; + this.name = name; + } + + /** + * Returns the name of the enumeration item as it is specified in the input yang. + * + * @return the name of the enumeration item as it is specified in the input yang + */ + public java.lang.String getName() { + return name; + } + + /** + * @return integer value + */ + public int getIntValue() { + return value; + } + + /** + * @param valueArg integer value + * @return corresponding CosModelType item + */ + public static CosModelType forValue(int valueArg) { + return VALUE_MAP.get(valueArg); + } +}
\ No newline at end of file diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java new file mode 100755 index 000000000..eacfc9f63 --- /dev/null +++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObject.java @@ -0,0 +1,17 @@ +package org.opendaylight.yang.gen.v1.test;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+
+public interface TestObject {
+ List<IpAddress> getFloatingIp();
+ List<Ipv4Address> getFloatingIpV4();
+ List<Ipv6Address> getFloatingIpV6();
+ Ipv4Address getSingleIpV4();
+ Ipv6Address getSingleIpV6();
+ IpAddress getSingleIp();
+
+}
diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java new file mode 100755 index 000000000..8301a0f05 --- /dev/null +++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/TestObjectBuilder.java @@ -0,0 +1,134 @@ +package org.opendaylight.yang.gen.v1.test;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yangtools.concepts.Builder;
+
+public class TestObjectBuilder implements Builder<TestObject> {
+ private List<IpAddress> _floatingIp;
+ private List<Ipv4Address> _floatingIpV4;
+ private List<Ipv6Address> _floatingIpV6;
+ private IpAddress _singleIp;
+ private Ipv4Address _singleIpV4;
+ private Ipv6Address _singleIpV6;
+
+ public List<IpAddress> getFloatingIp() {
+ return _floatingIp;
+ }
+
+ public List<Ipv4Address> getFloatingIpV4() {
+ return _floatingIpV4;
+ }
+
+ public List<Ipv6Address> getFloatingIpV6() {
+ return _floatingIpV6;
+ }
+
+ public Ipv4Address getSingleIpV4() {
+ return _singleIpV4;
+ }
+
+ public Ipv6Address getSingleIpV6() {
+ return _singleIpV6;
+ }
+
+ public IpAddress getSingleIp() {
+ return _singleIp;
+ }
+
+ public TestObjectBuilder setFloatingIp(final List<IpAddress> value) {
+ this._floatingIp = value;
+ return this;
+ }
+
+ public TestObjectBuilder setFloatingIpV4(final List<Ipv4Address> value) {
+ this._floatingIpV4 = value;
+ return this;
+ }
+
+ public TestObjectBuilder setFloatingIpV6(final List<Ipv6Address> value) {
+ this._floatingIpV6 = value;
+ return this;
+ }
+
+ public TestObjectBuilder setSingleIp(final IpAddress value) {
+ this._singleIp = value;
+ return this;
+ }
+
+ public TestObjectBuilder setSingleIpV4(final Ipv4Address value) {
+ this._singleIpV4 = value;
+ return this;
+ }
+
+ public TestObjectBuilder setSingleIpV6(final Ipv6Address value) {
+ this._singleIpV6 = value;
+ return this;
+ }
+
+ public TestObjectBuilder() {
+
+ }
+
+ public TestObject build() {
+ return new TestObjectImpl(this);
+ }
+
+ @Override
+ public String toString() {
+ return "TestObjectBuilder [_floatingIp=" + _floatingIp + ", _floatingIpV4=" + _floatingIpV4 + ", _floatingIpV6="
+ + _floatingIpV6 + ", _singleIp=" + _singleIp + ", _singleIpV4=" + _singleIpV4 + ", _singleIpV6="
+ + _singleIpV6 + "]";
+ }
+
+ private static final class TestObjectImpl implements TestObject {
+ private List<IpAddress> _floatingIp;
+ private List<Ipv4Address> _floatingIpV4;
+ private List<Ipv6Address> _floatingIpV6;
+ private IpAddress _singleIp;
+ private Ipv4Address _singleIpV4;
+ private Ipv6Address _singleIpV6;
+
+ @Override
+ public List<IpAddress> getFloatingIp() {
+ return _floatingIp;
+ }
+
+ @Override
+ public List<Ipv4Address> getFloatingIpV4() {
+ return _floatingIpV4;
+ }
+
+ @Override
+ public List<Ipv6Address> getFloatingIpV6() {
+ return _floatingIpV6;
+ }
+
+ @Override
+ public Ipv4Address getSingleIpV4() {
+ return _singleIpV4;
+ }
+
+ @Override
+ public Ipv6Address getSingleIpV6() {
+ return _singleIpV6;
+ }
+
+ @Override
+ public IpAddress getSingleIp() {
+ return _singleIp;
+ }
+
+ private TestObjectImpl(TestObjectBuilder base) {
+ this._floatingIp = base.getFloatingIp();
+ this._floatingIpV4 = base.getFloatingIpV4();
+ this._floatingIpV6 = base.getFloatingIpV6();
+ this._singleIp = base.getSingleIp();
+ this._singleIpV4 = base.getSingleIpV4();
+ this._singleIpV6 = base.getSingleIpV6();
+ }
+ }
+}
diff --git a/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java new file mode 100644 index 000000000..bae0bdb1c --- /dev/null +++ b/core/sli/provider/src/test/java/org/opendaylight/yang/gen/v1/test/WrapperObj.java @@ -0,0 +1,10 @@ +package org.opendaylight.yang.gen.v1.test; + +public class WrapperObj { + + CosModelType cosModel = CosModelType._4COS; + + public CosModelType getCosModelType() { + return cosModel; + } +} diff --git a/core/sli/provider/src/test/resources/EnumerationMapping.properties b/core/sli/provider/src/test/resources/EnumerationMapping.properties new file mode 100644 index 000000000..d0fb29710 --- /dev/null +++ b/core/sli/provider/src/test/resources/EnumerationMapping.properties @@ -0,0 +1 @@ +yang.cos-model-type._4COS=HelloWorld
\ No newline at end of file diff --git a/core/sli/provider/src/test/resources/executor.tests b/core/sli/provider/src/test/resources/executor.tests new file mode 100755 index 000000000..5468c8d60 --- /dev/null +++ b/core/sli/provider/src/test/resources/executor.tests @@ -0,0 +1,8 @@ +l3sdn_logic_v10.xml:switchTester:test-value="" +l3sdn_logic_v10.xml:switchTester:test-value="hi" +l3sdn_logic_v10.xml:forRecordTester +l3sdn_logic_v10.xml:whileNodeTester +l3sdn_logic_v10.xml:resourceTester +l3sdn_logic_v10.xml:configureTester +l3sdn_logic_v10.xml:javaPluginTester +l3sdn_logic_v10.xml:allNodesTester
\ No newline at end of file diff --git a/core/sli/provider/src/test/resources/l3sdn.properties b/core/sli/provider/src/test/resources/l3sdn.properties new file mode 100644 index 000000000..6f40ebca0 --- /dev/null +++ b/core/sli/provider/src/test/resources/l3sdn.properties @@ -0,0 +1,66 @@ +# yang conversion properties +# used to convert Enum back to the original yang value +yang.request-status.Synccomplete=synccomplete +yang.request-status.Asynccomplete=asynccomplete +yang.request-status.Notifycomplete=notifycomplete +yang.rpc-name.ServiceConfigurationOperation=service-configuration-operation +yang.rpc-name.SvcTopologyOperation=svc-topology-operation +yang.rpc-name.ServiceConfigurationNotification=service-configuration-notification +yang.rpc-action.Reserve=reserve +yang.rpc-action.Activate=activate +yang.rpc-action.Assign=assign +yang.rpc-action.Turnup=turnup +yang.rpc-action.Delete=delete +yang.rpc-action.Changereserve=changereserve +yang.rpc-action.Changeactivate=changeactivate +yang.rpc-action.Changedelete=changedelete +yang.rpc-action.Changeassign=changeassign +yang.svc-vnf-type.Vce=vce +yang.vnf-type.Vce=vce +yang.vnf-status.PendingCreate=pending-create +yang.vnf-status.Created=created +yang.vnf-status.Active=active +yang.vnf-status.PendingDelete=pending-delete +yang.connection-type.Customer=customer +yang.connection-type.Internet=internet +yang.net-status.PendingCreate=pending-create +yang.net-status.Created=created +yang.net-status.Active=active +yang.net-status.PendingDelete=pending-delete +yang.svc-action.Reserve=reserve +yang.svc-action.Activate=activate +yang.svc-action.Assign=assign +yang.svc-action.Turnup=turnup +yang.svc-action.Delete=delete +yang.svc-action.Changereserve=changereserve +yang.svc-action.Changeactivate=changeactivate +yang.svc-action.Changedelete=changedelete +yang.svc-action.Changeassign=changeassign +yang.service-type.SDNETHERNETINTERNET=SDN-ETHERNET-INTERNET +yang.internet-evc-speed-value._2=2 +yang.internet-evc-speed-value._4=4 +yang.internet-evc-speed-value._5=5 +yang.internet-evc-speed-value._8=8 +yang.internet-evc-speed-value._10=10 +yang.internet-evc-speed-value._20=20 +yang.internet-evc-speed-value._50=50 +yang.internet-evc-speed-value._100=100 +yang.internet-evc-speed-value._150=150 +yang.internet-evc-speed-value._250=250 +yang.internet-evc-speed-value._400=400 +yang.internet-evc-speed-value._500=500 +yang.internet-evc-speed-value._600=600 +yang.internet-evc-speed-value._1000=1000 +yang.ip-version.Ds=ds +yang.ip-version.V6=v6 +yang.routing-protocol.None=none +yang.routing-protocol.Bgp=bgp +yang.routing-protocol.Ospf=ospf +yang.routing-protocol.Igrp=igrp +yang.routing-protocol.Eigrp=eigrp +yang.routing-protocol.Rip=rip +yang.routing-protocol.IsIs=is-is +yang.vr-designation.Primary=primary +yang.feature-type.FIREWALLLITE=FIREWALL-LITE +yang.equipment-role.VPLSPE=VPLS-PE +yang.interface-role.CUSTOMERUPLINK=CUSTOMER-UPLINK diff --git a/core/sli/provider/src/test/resources/l3sdn_logic_v10.xml b/core/sli/provider/src/test/resources/l3sdn_logic_v10.xml new file mode 100644 index 000000000..64397236b --- /dev/null +++ b/core/sli/provider/src/test/resources/l3sdn_logic_v10.xml @@ -0,0 +1,227 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============LICENSE_START======================================================= + ONAP : CCSDK ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); you may not + use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required + by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. ============LICENSE_END========================================================= --> + + +<service-logic xmlns="http://www.onap.org/sdnc/svclogic" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" + module="neutron" version="1.0.0"> + + <method rpc="canCreateNetwork" mode="sync"> + <return status="success"> + <parameter name="error-code" value="200" /> + </return> + </method> + + <method rpc="switchTester" mode="sync"> + + <switch test="`$test-value`"> + <outcome value=""> + <return status="success"> + <parameter name="visited-outcome" value="empty string" /> + </return> + </outcome> + <outcome value="Other"> + <return status="success"> + <parameter name="visited-outcome" value="Other" /> + </return> + </outcome> + </switch> + + + </method> + + <method rpc="forRecordTester" mode="sync"> + <for index="i" start="0" end="1"> + <record plugin="org.onap.ccsdk.sli.core.sli.provider.DummyRecorder"> + <parameter name="level" value="INFO"/> + <parameter name="field1" value="`forRecordTester message $i`"/> + </record> + </for> + </method> + + <method rpc="whileNodeTester" mode="sync"> + <block> + <set> + <parameter name="counter" value="0" /> + + </set> + <while test="`$counter < 10`"> + <set> + <parameter name="counter" value="`$counter + 1`" /> + </set> + + <switch test="`$counter > 6`"> + <outcome value="true"> + <break /> + </outcome> + </switch> + </while> + </block> + + </method> + + <method rpc="resourceTester" mode="sync"> + <block> + <set> + <parameter name='resource-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' /> + </set> + + <save plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"> + <parameter name="sample-key" value="resourceTester.status"/> + <parameter name="sample-value" value="FAILED"/> + </save> + + <update plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"> + <parameter name="sample-key" value="resourceTester.status"/> + <parameter name="sample-value" value="PASSED"/> + </update> + + <get-resource plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'" pfx="sample"/> + + <exists plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <is-available plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <release plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + + <reserve plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + <notify plugin="`$resource-plugin`" resource="sample" action="RESERVE"/> + + <delete plugin="`$resource-plugin`" resource="sample" key="sample-key == 'resourceTester.status'"/> + + + + </block> + </method> + + <method rpc="configureTester" mode="sync"> + <block> + <set> + <parameter name='configure-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' /> + </set> + <configure adaptor="`$configure-plugin`" key="dummy" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="FAILURE" activate="true"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="dummy" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="SUCCESS" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="ALREADY_ACTIVE" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_FOUND" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="NOT_READY" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="FAILURE" activate="false"> + <parameter name="field1" value="1"/> + </configure> + <configure adaptor="`$configure-plugin`" key="dummy" activate="true"> + <parameter name="" value=""/> + </configure> + <configure adaptor="`$configure-plugin`" key="dummy" activate="false"> + <parameter name="" value=""/> + </configure> + </block> + </method> + + + <method rpc="javaPluginTester" mode="sync"> + <block> + <set> + <parameter name='java-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' /> + </set> + <execute plugin="`$java-plugin`" method="dummy"/> + </block> + </method> + + <method rpc="allNodesTester" mode="sync"> + <block> + <set> + <parameter name='resource-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyResource' /> + <parameter name='configure-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.DummyAdaptor' /> + <parameter name='java-plugin' + value='org.onap.ccsdk.sli.core.sli.provider.VoidDummyPlugin' /> + + </set> + + <call rpc="switchTester" mode="sync" /> + + <call rpc="forRecordTester" mode="sync"/> + + <call rpc="resourceTester" mode="sync"/> + + <call rpc="configureTester" mode="sync"/> + + <call rpc="javaPluginTester" mode="sync"/> + + <call rpc="whileNodeTester" mode="sync"/> + + </block> + </method> + + <method rpc="networkCreated" mode="sync"> + <switch + test="length($network.segment[0].provider-physical-network) >= 5 and substr($network.segment[0].provider-physical-network,0,5) == 'dvspg'"> + <outcome value="true"> + <block> + <set> + <parameter name="$vlanlist" + value="$network.segment[0].provider-segmentation-id" /> + </set> + <for index="i" start="1" end="$network.num-segments"> + <set> + <parameter name="$vlanlist" + value="eval($vlanlist+','+$network.segment[i].provider-segmentation-id)" /> + </set> + </for> + + </block> + </outcome> + <outcome value="Other"> + <return status="success"> + <parameter name="error-code" value="200" /> + </return> + </outcome> + </switch> + </method> + +</service-logic> diff --git a/core/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang b/core/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang new file mode 100755 index 000000000..4af080608 --- /dev/null +++ b/core/sli/provider/src/test/resources/l3vpnyang/ietf-l3vpn-svc-part@2017-09-21.yang @@ -0,0 +1,68 @@ +module ietf-l3vpn-svc-part {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-l3vpn-svc-part";
+
+ prefix l3vpn-svc;
+
+ organization
+ "IETF L3SM Working Group";
+
+ contact
+ "WG List: <mailto:l3sm@ietf.org>
+
+ Editor:
+
+ ";
+
+ description
+ "The YANG module defines a generic service configuration
+ model for Layer 3 VPN common across all of the vendor
+ implementations.";
+
+ revision 2017-09-21 {
+ description
+ "Part of draft-ietf-l3sm-l3vpn-service-yang-11";
+ reference
+ "draft-ietf-l3sm-l3vpn-service-yang-11";
+ }
+
+ /* Typedefs */
+
+ typedef svc-id {
+ type string;
+ description
+ "Defining a type of service component
+ identificators.";
+ }
+
+ /* Main blocks */
+
+ container l3vpn-svc {
+ container vpn-services {
+ list vpn-svc {
+ key vpn-id;
+
+ uses vpn-svc-cfg; /*Not used*/
+
+ description "
+ List of VPN services.";
+ }
+ description
+ "top level container
+ for the VPN services.";
+ }
+ }
+
+ grouping vpn-svc-cfg {
+ leaf vpn-id {
+ type svc-id;
+ description
+ "VPN identifier. Local administration meaning.";
+ }
+ leaf customer-name {
+ type string;
+ description
+ "Name of the customer.";
+ }
+ }
+}
diff --git a/core/sli/provider/src/test/resources/simplelogger.properties b/core/sli/provider/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..07ab67f70 --- /dev/null +++ b/core/sli/provider/src/test/resources/simplelogger.properties @@ -0,0 +1,22 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +org.slf4j.simpleLogger.defaultLogLevel=info diff --git a/core/sli/provider/src/test/resources/svclogic.properties b/core/sli/provider/src/test/resources/svclogic.properties new file mode 100644 index 000000000..426960f76 --- /dev/null +++ b/core/sli/provider/src/test/resources/svclogic.properties @@ -0,0 +1,27 @@ +### +# ============LICENSE_START======================================================= +# ONAP : CCSDK +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= +### + +org.onap.ccsdk.sli.dbtype = jdbc +org.onap.ccsdk.sli.jdbc.url=jdbc:derby:memory:sdnctl;create=true +org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver +org.onap.ccsdk.sli.jdbc.database = sdnctl +org.onap.ccsdk.sli.jdbc.user = test +org.onap.ccsdk.sli.jdbc.password = test |