summaryrefslogtreecommitdiffstats
path: root/src/site-docs/adoc/fragments/howto-write-logic/logic-cheatsheet.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/site-docs/adoc/fragments/howto-write-logic/logic-cheatsheet.adoc')
-rw-r--r--src/site-docs/adoc/fragments/howto-write-logic/logic-cheatsheet.adoc269
1 files changed, 269 insertions, 0 deletions
diff --git a/src/site-docs/adoc/fragments/howto-write-logic/logic-cheatsheet.adoc b/src/site-docs/adoc/fragments/howto-write-logic/logic-cheatsheet.adoc
new file mode 100644
index 000000000..fe3cd0d0d
--- /dev/null
+++ b/src/site-docs/adoc/fragments/howto-write-logic/logic-cheatsheet.adoc
@@ -0,0 +1,269 @@
+//
+// ============LICENSE_START=======================================================
+// Copyright (C) 2016-2018 Ericsson. All rights reserved.
+// ================================================================================
+// This file is licensed under the CREATIVE COMMONS ATTRIBUTION 4.0 INTERNATIONAL LICENSE
+// Full license text at https://creativecommons.org/licenses/by/4.0/legalcode
+//
+// SPDX-License-Identifier: CC-BY-4.0
+// ============LICENSE_END=========================================================
+//
+// @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+//
+
+== Logic Cheatsheet
+
+Examples given here use Javascript (if not stated otherwise), other execution environments will be similar.
+
+
+=== Add Nashorn
+
+First line in the logic use this import.
+
+.JS Nashorn
+[source,javascript,options="nowrap"]
+----
+load("nashorn:mozilla_compat.js");
+----
+
+
+=== Finish Logic with Success or Error
+
+To finish logic, i.e. return to APEX, with success use the following lines close to the end of the logic.
+
+.JS Success
+[source,javascript,options="nowrap"]
+----
+var returnValueType = Java.type("java.lang.Boolean");
+var returnValue = new returnValueType(true);
+----
+
+To notify a problem, finish with an error.
+
+.JS Fail
+[source,javascript,options="nowrap"]
+----
+var returnValueType = Java.type("java.lang.Boolean");
+var returnValue = new returnValueType(false);
+----
+
+
+=== Logic Logging
+
+Logging can be made easy using a local variable for the logger.
+Line 1 below does that.
+Then we start with a trace log with the task (or task logic) identifier followed by the infields.
+
+.JS Logging
+[source,javascript,options="nowrap"]
+----
+var logger = executor.logger;
+logger.trace("start: " + executor.subject.id);
+logger.trace("-- infields: " + executor.inFields);
+----
+
+For larger logging blocks you can use the standard logging API to detect log levels, for instance:
+
+.JS Logging Blocks
+[source,javascript,options="nowrap"]
+----
+if(logger.isTraceEnabled()){
+ // trace logging block here
+}
+----
+
+Note: the shown logger here logs to `org.onap.policy.apex.executionlogging`.
+The behavior of the actual logging can be specified in the `$APEX_HOME/etc/logback.xml`.
+
+If you want to log into the APEX root logger (which is sometimes necessary to report serious logic errors to the top),
+then import the required class and use this logger.
+
+.JS Root Logger
+[source,javascript,options="nowrap"]
+----
+importClass(org.slf4j.LoggerFactory);
+var rootLogger = LoggerFactory.getLogger(logger.ROOT_LOGGER_NAME);
+
+rootLogger.error("Serious error in logic detected: " + executor.subject.id);
+----
+
+=== Local Variable for Infields
+
+It is a good idea to use local variables for `infields`.
+This avoids long code lines and policy evolution.
+The following example assumes infields named `nodeName` and `nodeAlias`.
+
+.JS Infields Local Var
+[source,javascript,options="nowrap"]
+----
+var ifNodeName = executor.inFields["nodeName"];
+var ifNodeAlias = executor.inFields["nodeAlias"];
+----
+
+
+=== Local Variable for Context Albums
+
+Similar to the `infields` it is good practice to use local variables for context albums as well.
+The following example assumes that a task can access a context album `albumTopoNodes`.
+The second line gets a particular node from this context album.
+
+.JS Infields Local Var
+[source,javascript,options="nowrap"]
+----
+var albumTopoNodes = executor.getContextAlbum("albumTopoNodes");
+var ctxtNode = albumTopoNodes.get(ifNodeName);
+----
+
+
+=== Set Outfields in Logic
+
+The task logic needs to set outfields with content generated.
+The exception are outfields that are a direct copy from an infield of the same name, APEX does that autmatically.
+
+.JS Set Outfields
+[source,javascript,options="nowrap"]
+----
+executor.outFields["report"] = "node ctxt :: added node " + ifNodeName;
+----
+
+
+=== Create a instance of an Outfield using Schemas
+
+If an outfield is not an atomic type (string, integer, etc.) but uses a complex schema (with a Java or Avro backend), APEX can help to create new instances.
+The `executor` provides a field called `subject`, which provides a schem helper with an API for this.
+The complete API of the schema helper is documented here: link:https://ericsson.github.io/apex-docs/javadocs/index.html[API Doc: SchemaHelper].
+
+If the backend is Avro, then an import of the Avro schema library is required:
+
+.JS Import Avro
+[source,javascript,options="nowrap"]
+----
+importClass(org.apache.avro.generic.GenericData.Array);
+importClass(org.apache.avro.generic.GenericRecord);
+importClass(org.apache.avro.Schema);
+----
+
+If the backend is Java, then the Java class implementing the schema needs to be imported.
+
+The following example assumes an outfield `situation`.
+The `subject` method `getOutFieldSchemaHelper()` is used to create a new instance.
+
+.JS Outfield Instance with Schema
+[source,javascript,options="nowrap"]
+----
+var situation = executor.subject.getOutFieldSchemaHelper("situation").createNewInstance();
+----
+
+If the schema backend is Java, the new instance will be as implemented in the Java class.
+If the schema backend is Avro, the new instance will have all fields from the Avro schema specification, but set to `null`.
+So any entry here needs to be done separately.
+For instance, the `situation` schema has a field `problemID` which we set.
+
+.JS Outfield Instance with Schema, set
+[source,javascript,options="nowrap"]
+----
+situation.put("problemID", "my-problem");
+----
+
+
+=== Create a instance of an Context Album entry using Schemas
+
+Context album instances can be created using very similar to the outfields.
+Here, the schema helper comes from the context album directly.
+The API of the schema helper is the same as for outfields, see link:https://ericsson.github.io/apex-docs/javadocs/index.html[API Doc: SchemaHelper].
+
+If the backend is Avro, then an import of the Avro schema library is required:
+
+.JS Import Avro
+[source,javascript,options="nowrap"]
+----
+importClass(org.apache.avro.generic.GenericData.Array);
+importClass(org.apache.avro.generic.GenericRecord);
+importClass(org.apache.avro.Schema);
+----
+
+If the backend is Java, then the Java class implementing the schema needs to be imported.
+
+The following example creates a new instance of a context album instance named `albumProblemMap`.
+
+.JS Outfield Instance with Schema
+[source,javascript,options="nowrap"]
+----
+var albumProblemMap = executor.getContextAlbum("albumProblemMap");
+var linkProblem = albumProblemMap.getSchemaHelper().createNewInstance();
+----
+
+This can of course be also done in a single call without the local variable for the context album.
+
+.JS Outfield Instance with Schema, one line
+[source,javascript,options="nowrap"]
+----
+var linkProblem = executor.getContextAlbum("albumProblemMap").getSchemaHelper().createNewInstance();
+----
+
+If the schema backend is Java, the new instance will be as implemented in the Java class.
+If the schema backend is Avro, the new instance will have all fields from the Avro schema specification, but set to `null`.
+So any entry here needs to be done separately (see above in outfields for an example).
+
+
+=== Enumerates
+
+When dealing with enumerates (Avro or Java defined), it is sometimes and in some execution environments necessary to convert them to a string.
+For example, assume an Avro enumerate schema as:
+
+.Avro Enumerate Schema
+[source,json,options="nowrap"]
+----
+{
+ "type": "enum",
+ "name": "Status",
+ "symbols" : [
+ "UP",
+ "DOWN"
+ ]
+}
+
+----
+
+Using a switch over a field initialized with this enumerate in Javascript will fail.
+Instead, use the `toString` method, for example:
+
+.JS Outfield Instance with Schema, one line
+[source,javascript,options="nowrap"]
+----
+var switchTest = executor.inFields["status"];
+switch(switchTest.toString()){
+ case "UP": ...; break;
+ case "DOWN": ...; break;
+ default: ...;
+}
+----
+
+
+=== MVEL Initialize Outfields First!
+
+In MVEL, we observed a problem when accessing (setting) outfields without a prior access to them.
+So in any MVEL task logic, before setting any outfield, simply do a get (with any string), to load the outfields into the MVEL cache.
+
+.MVEL Outfield Initialization
+[source,java,options="nowrap"]
+----
+outFields.get("initialize outfields");
+----
+
+
+=== Using Java in Scripting Logic
+
+Since APEX executes the logic inside a JVM, most scripting languages provide access to all standard Java classes.
+Simply add an import for the required class and then use it as in actual Java.
+
+The following example imports `java.util.arraylist` into a Javascript logic, and then creates a new list.
+
+.JS Import ArrayList
+[source,javascript,options="nowrap"]
+----
+importClass(java.util.ArrayList);
+var myList = new ArrayList();
+----
+
+