Until now, we only discussed services that get no input parameters upon initiation. However, in most cases, you would probably want to provide your executable with some input parameters when executing it. Opereto has been designed to allow the developer maximum flexibility regarding how to pass input parameters to his code and process them.


Passing input parameters to service code

Input and output parameters are specified in the Service Specification YAML as item_properties and passed to the service code during runtime. Assuming that your service specification YAML is the following: 
...
...
item_properties:
- key: param1
  direction: input
  type: integer
  value: 50
- key: param2
  direction: input
  type: text
  value: client_123
- key: param3
  direction: input
  type: boolean
  value: true
- key: param4
  direction: input
  type: json
  value: 
      a: b
      c: d
...
... 

 Opereto provides three ways to read the input parameters in your service code:


Option 1: via property files

Opereto run services in an isolated environment on the remote agent host. It creates a temporary work directory for every new process and stores in it all service files and directories. Also, Opereto adds two files containing a json and YAML representations of the input parameters (arguments.json and arguments.yaml in correspondence).


arguments.json  

{
   "param1" : 50,
   "param2" : "client_123",
   "param3" : true,
   "param4" : {
                 "a" : "b",
                 "c" : "d"
              }
} 

  

arguments.yaml      

param1: 50
param2: client_123
param4: true
param4:
    a : b
    c : d 

    

The developer can easily process those argument files as shown in the following python example:

  

## my python service script..
import os
import simplejson

work_directory = os.environ['opereto_workspace'] ## the work directory where arguments files resides 
                                                   

with open(os.path.join(work_directory,'arguments.json'), 'r') as property_file:
    properties=simplejson.loads(f.readlines())

param1 = int(properties['param1'])
param2 = str(properties['param2'])
param3 = bool(properties['param3'])
param4 = properties['param4']
.....
.....

   

In the last example, opereto_workspace is a built-in input parameter that Opereto passes as environment variables or YAML/JSON arguments to the process at run time. We will discuss built-in input parameters in the next section.


bell-2x.png Handling input parameter using pyopereto is quite simple. If you write your code in Python, we recommend using it. Otherwise, you may want to build a simple wrapper function that reads the arguments.json file and store it in some data structure or class.   

from pyopereto import OperetoClient

client = OperetoClient()
input = client.input## input is a dictionary containing all key-value input properties 
...
...

   

Option 2: via environment variables

As mention above, Opereto creates an isolated process environment per new process. In addition to the argument files, it also passes all input parameters and built-in parameters as environment variables specific to that isolated environment. Thus, the developer can easily access these environment variables in his code. For example:

   

## run.py
import os
import simplejson

bool = lambda x: x=='true' and True or False

param1 = int(os.environ['param1'])
param2 = str(os.environ['param2'])
param3 = bool(os.environ['param3'])
param4 = simplejson.loads(os.environ['param4'])
.....
.....

   

While this option is less useful for higher level languages like python, ruby, java (that include libraries that can process the JSON or YAML argument files quite easily), reading the environment variables may be very useful if your service code is a simple batch file. For instance:   

#/bin/bash

if [ -z $param1 ] then;
    echo "param1 is missing.." 
fi

...
... 

   

Option 3: via command line


If you have a legacy or a third-party executable code that you cannot or don't want to change, you may use this option to wrap it as an Opereto service. Assuming that this executable gets input parameters via the command line, you can build your service.yaml as follows:   

cmd: my.exe ${param1} ${param2}
item_properties:
- key: param1
  value: 
  mandatory: true
  type: text
- key: param2
  value: 50
  mandatory: true
  type: integer
...
... 

     


Opereto build-in parameters


Opereto stores a few useful parameters as environment variables for every service process executed. Some are required for flow orchestration as you will see in later sections. Following is the list of opereto built-in parameters:


Parameter NameParameter Description
pid
current running Opereto process id
opereto_home
opereto home directory (it is ~/.opereto where ~ is the home directory of the user started the agent.
opereto_workspace
current process work directory (where all service files, as well as input property files) resides
opereto_agent
opereto_agentagent name
opereto_agent_pid
agent os process id
opereto_agent_home
agent home directory
opereto_host
operetobox host url (e.g. https://10.0.0.2)
opereto_user
the username that the current agent logged-in with
opereto_password
the password that the current agent logged-in with
opereto_source_flow_idThe Opereto process id of the ancestor in case that the process is a flow member, otherwise the id of the current process.
opereto_parent_flow_idThe Opereto process id of the direct parent if the process is a flow member, otherwise an empty string.
opereto_product_idProduct under test
opereto_service_versionThe service version if passed or empty string.
opereto_originator_usernameThe user initiated this process or the flow.
opereto_originator_emailThe email address of the user started this process or the flow, otherwise empty string.
opereto_originator_mobileThe mobile number of the user initiated this process or the flow that this process is a member of or otherwise empty string.
opereto_execution_mode
'production" or "development" (sandbox)


Handling service output

Opereto handles the output of a service execution in tree ways: process log, process output properties, and process status.


Process log: the standard output and error streams

Opereto collects anything written to the console (standard output and error). Thus the developer only needs to use the standard and error streams (print functions) to write data to log. Opereto indexes all log entries allowing a granular search of words and phrases in the process log.


Process output properties

Process properties may be used as well to store process output. It is especially convenient when passing the output of the previous process to the successive one within a flow. Only properties that are marked as “output” in the direction specification in the service YAML specification can be used to output data to. To update process properties, the developer may use the Modify Process Output REST call. For example:

  

## run.py
import os
import simplejson
import requests

s0 = requests.Session()
s0.auth = (os.environ['opereto_user'], os.environ['opereto_password'])
.....
.....

properties_to_update = {
    {
      "key": "param1",                  
      "value": 80
    },
    {
      "key": "new_param",                  
      "value": "this is a new property value"               
    }
}
r = s0.post(os.environ['opereto_host']+'/processes/'+os.environ['pid']+'/properties', data=simplejson.dumps(properties_to_update))
.....
.....

   


bell-2x.png Handling output parameters using pyopereto is quite simple. If you write your code in Python, we recommend using it. Otherwise, you may want to build a simple wrapper function that wraps the REST API call.    

from pyopereto.client import OperetoClient

client = OperetoClient()
...
...
client.modify_process_property('my_output_property', 100) 

     


Process status

Opereto supports the following process states: 

STATUSICONDESCRIPTION
success

Set by service code: In case that the process exited with 0, and no exceptions occurred.
failure

Set by service code: In case that the process exited with 2.
warning

Set by service code: In case that the process exited with 3.
error

Set by service code: In case that the process exited with 1 or exit code > 3 or exception raised.
timeout

Set automatically by Opereto if the process runs time is higher then the service timeout specification. In that case, the process will be terminated by the agent running it.
terminate_pending

Set automatically by Opereto when the user terminates a given process. Opereto will change it to “terminated” after the agent will complete the termination.
terminated

Set automatically by Opereto. Indicates that the user has terminated the process.
registered

Set automatically by Opereto for new processes. At this point, the process is registered but had not been collected by the relevant agent yet.
in_process

Set automatically by Opereto. Indicates that the process had been collected by the relevant agent and is now running.

 

bell-2x.png pyopereto provides a list of predefined process status code: SUCCESS, FAILURE, WARNING, ERROR   

from pyopereto.client import OperetoClient
client = OperetoClient()

def my_service():
    try:
...
        ...

        return client.SUCCESS  
    except Exception, e:
        return client.FAILURE

if __name__ == "__main__":
    exit(my_service())