SAP 3D Visual Enterprise Generator is a very customizable solution. However, unlike SAP ERP, there is no transport mechanism to automatically migrate content from one environment to another. The method for moving Processes through the different environments like Dev, QA, Prod, is a very manual one.

Along with this, there is not an easy way to deal with environment specific configuration properties. For instance, let’s say there’s another database that has some business data that needs to be merged into the 3D data as metadata. Also, that database has a Dev, QA, and Prod environment also. That means, your VEG process needs to know which database it needs to access based on which environment VEG is running in.

One option is to have a variable in the VEG process. However, when the process is migrated to QA, someone would need to update that variable to point at the QA database. This is ok the first time but if there is a change to the process in Dev and it gets migrated to QA, the variable needs to be modified again. This is the issue in a nutshell.

To resolve this, the SAP 3D Visual Enterprise Services team has come up with a best practice that allows for a configuration file that is outside the VEG Process but can easily be loaded in at runtime.

YAML

For this type of configuration file, YAML files tend to work the best. They’re much easier to read than XML and much, much easier to edit. JSON could be used but that one is still not as easy to edit but it is easier to read.

Here’s a good example of the difference between XML, JSON and YAML if you’re interested:

https://pynative.com/python-yaml/#h-what-is-yaml

A little Prep Work

Before getting the YAML module, you’ll need somewhere on the VEG server to put it. The best place for this is the VEG_SHAREWorkspacePythonLibraries folder.
NOTE: Replace VEG_SHARE with the actual path to the VEG Share directory.
NOTE: If the PythonLibraries folder doesn’t exist, please create it spelled that exact way so VEG can find it.

The next thing that needs to happen is VEG needs to know how to load YAML files by adding a Python library. PyYaml will be what is used here as it’s pretty well maintained.

https://github.com/yaml/pyyaml

Once there, click on the green Code button and select “Download ZIP”

PyYaml%20download

PyYaml download

Once PyYaml is downloaded, extract it and grab the pyyaml-masterlibyaml directory itself.

Place the yaml folder in the PythonLibraries folder created previously.

The yaml folder should look something like this:

yaml%20folder%20example

yaml folder example

Config File

The YAML module allows Python to load YAML files but there’s no YAML configuration file on our Dev environment. Creating the config file is easy as YAML is a nice text file to create.

The best location for configuration files like this is somewhere in the VEG_SHAREWorkspace directory as this is an easy path to determine in a VEG Process that you will see shortly.

Create a new text file in the VEG_SHAREWorkspace directory called blog.yaml and edit it in a text editor like Notepad or Notepad++.

Use the following values for testing (including the — as that’s a header for yaml files):

---
database: someServer
user: someUser
pass: somePa$$

Save the file and that part’s all done.

yaml%20file%20content

yaml file content

VEG Process

Now that the YAML module is set up and the configuration file has been created, a VEG Process needs to be created to load it.

Using the VEG Administrator application, log in, go to the Server Configuration area, and create a new Process.

New%20VEG%20Process

New VEG Process

For this example, we will use:
Name: TEST_Blog_Example
Display Name: _TEST – Blog Example

The first operation is a Trigger so drag Trigger / filetrigger onto the workspace and press OK:

New%20filetrigger

New filetrigger

Then add a General / serverproperties_getall and press OK

serverproperties_getall

serverproperties_getall

The next step is to connect those two together by dragging from the bottom of the filetrigger to the top of the serverproperties_getall:

connect%20filetrigger%20to%20serverproperties_getall

connect filetrigger to serverproperties_getall

Now we need a new Scriptable Operation so we can add some custom Python code to load the YAML file and convert it to an XML output.

To do this, select the menu Operations -> New Scriptable Operation…

New%20Scriptable%20Operation

New Scriptable Operation

Set the Operation Name to py_yaml_load and Display Name to py_yaml_load

Then drag a filename parameter from the list on the right and drop it on the Input panel on the left.
Double click on the filename parameter that’s in the Input panel and specify the Name and Display Name to be yamlFile

Then, drag an xml parameter (you’ll need to scroll down a little) from the parameter list and drop it into the Output panel in the middle.
Double click on the xml parameter that’s in the Output panel and specify the Name and Display Name to be config.

The window should look like this:

Scriptable%20Operation%20Settings

Scriptable Operation Settings

Once you have that done, press OK.

Then, drag the new py_yaml_load operation onto the workspace and connect it after the serverproperties_getall operation:

py_yaml_load

py_yaml_load

The black lines just show the flow of execution but to connect properties together, we need to use the properties windows.

Double click on the serverproperties_getall operation and the py_yaml_load operation to open their properties windows.

Since our blog.yaml configuration file is in the VEG_ShareWorkspace directory, we can use the GlobalWorkspace property for our yamlFiledirectoryname property. To link these, expand the yamlFile parameter by clicking on the + next to the name. Then, drag the GlobalWorkspace property from serverproperties_getall to the py_yaml_loadyamlFiledirectoryname parameter:

GlobalWorkspace%20to%20directoryname

GlobalWorkspace to directoryname

Then, put blog.yaml in the name parameter:

blog.yaml%20name

blog.yaml name

NOTE: Make sure the directoryname property is grey as that denotes that it’s an XPath statement that will be evaluated at runtime. However, the name property is black and editable because it’s a hard coded value.

Now, we need to set up the Python code to load the YAML file and put the output into the config parameter.

To do this, expand the script parameter and then select the code line and press the … button that appears.

Here’s the code we want to use to load the config file and put the output into the config output parameter:

def yaml2xml(yamlFile):
    import yaml
    from xml.sax.saxutils import escape
    data = yaml.safe_load(open(yamlFile))
   
    def _parseValues(rslt, item):
        if isinstance(item, dict):
            for key in item:
                if str(item[key]) == "None":
                    item[key] = ""
                rslt += "<" + key + ">"
                if isinstance(item[key], dict):
                    rslt = _parseValues(rslt, item[key])
                elif isinstance(item[key], list):
                    rslt = _parseValues(rslt, item[key])
                else:
                    rslt += escape(str(item[key]))
                rslt += "</" + key + ">"
        elif isinstance(item, list):
            for idx in range(len(item)):
                val = item[idx]
                rslt += "<val>"
                if isinstance(val, dict):
                    rslt = _parseValues(rslt, val)
                elif isinstance(val, list):
                    rslt = _parseValues(rslt, val)
                else:
                    rslt += escape(str(val))
                rslt += "</val>"
        return rslt
   
    rslt = "<data>"
    rslt = _parseValues(rslt, data)
    rslt += "</data>"
    return rslt

sap.output_parameters["config"] = yaml2xml(sap.input_parameters["yamlFile"])

Copy that and paste it into the Edit Script Code window and press OK.

To test the process, use the menu Debug -> Run. When the red box disappears from the py_yaml_load operation, you’ll know it’s done. Then use the menu Debug -> View Results Document.

Scroll down to the bottom and you should see the blog.yaml content converted into XML and inserted into VEG process log:

Result%20log%20showing%20config%20import

Result log showing config import

The final step would be to use one of these config properties in the Process. An example of this would be to use a General / log_message operation.

Drag one of them onto the workspace and connect it after the py_yaml_load operation.

Open the log_message properties by double-clicking on the log_message operation.

To create an XPath link, you’ll need to drag the py_yaml_load/config parameter to the log_message/message parameter.

config%20to%20log_message

config to log_message

However, that is not the correct XPath statement as we want to just log the database parameter. So, click the message property and select the … button that appears at the end of the line to open the XPath editor.

Then, edit the XPath Statement field so it specifies:
string(//py_yaml_load/config/data/database)

Edit%20XPath%20to%20specify%20database%20property%20location

Edit XPath to specify database property location

Then press OK.

Now, when you use the menu item Debug -> Run, you should see this in the Results window:

log_message%20result%20log

log_message result log

That means you can access the information from your configuration file easily from your VEG Process.

 

Now What?

Now that this is working, you can safely migrate your VEG Process to QA and Prod and set up the blog.yaml config files in each server’s Workspace directory. That way, the VEG Process is disconnected from the configuration file and will just load it at run time.

 

I hope this has been a helpful blog post for those trying to make it easier to migrate VEG Processes through the development landscape.

Sara Sampaio

Sara Sampaio

Author Since: March 10, 2022

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x