cancel
Showing results for 
Search instead for 
Did you mean: 

How to implement lists/multiple entries of one type within process context?

Former Member
0 Kudos

Hi all,

is it possible to save multiple data into the process context as a list?

I'm trying to create kind of a process log, that every activitiy can write a status message into a data object assign to the datatype defined by the following XSD:

...

<element name="ServiceRequestProcessLog" type="tns:ServiceRequestProcessLog"/>

<complexType name="ServiceRequestProcessLog">

<sequence>

<element name="Timestamp" type="dateTime"/>

<element name="ShortDescription" type="string"/>

<element name="LongDescription" type="string"/>

</sequence>

</complexType>

...

For sure, in that way i am able to fill these 3 fields from an activity.

But from the next the fields get overwritten of course.

How can i make an activity adding a new "Log Entry" into the context? Cardinality is not possible with complexType...

TIA

Michael

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Oliver,

interessting idea using sub-processes.

But at the moment i won't have any concurrency in my process so i guess i will prefer the mapping-activity-solution, even though thats not very nice aswell.

But i guess my plan to implement a process-status-tracking-functionality (which this issue is a part of) will fail anyway cause there is no proper way to access the process context from outside. See

Maybe both will be ready with the next EHP of CE?

Thank you profusely for your help!

Best regards

Michael

OliverGoetz
Employee
Employee
0 Kudos

Hi Michael,

I just got off the phone with a colleague from the mapping editor development, and he had a quite simple and elegant solution for the log append problem:

- Right-click on "Rules and Functions" in the Project Explorer tree and select "New Mapping Function..."

- Enter a name (e.g. 'CreateLogEntry')

- Select the LogEntry data type as return type.

- Add a parameter (with the add button) for each subelement you want to include in the log and select the appropriate type (like string for the descriptions or dateTime for the timestamp).

- Go to the "Mapping" pane and you will see a mapping editor that allows you to map the individual input parameters of the mapping function to the output fields of the LogEntry structure. (If you like you can assign the "current-dateTime()" function to the Timestamp in the output here and omit the timestamp input parameter altogether.)

- Click on the "Finish" button.

- Go to the Process model and in the output mapping of the activity assign the response of the activity to the logEntry subnode of the Log data object on the right-hand side. You will get an error marker complaining about incompatible types.

- Double-click on the logEntry node of the Log data object on the right-hand side to open the mapping editor and replace the entry in there with the call to the mapping function (e.g. 'CreateLogEntry("lala", "lalala")'); click "OK"

- Change the mapping assigment to "Append" by right-clicking on the mapping edge and selecting Assignment -> Append.

This should do the trick; if it doesn't work, please open a support ticket

Best regards,

Oliver

Answers (4)

Answers (4)

Former Member
0 Kudos

Marvelously!

That's a nice workaround! And it did work!

Except the fact, that the Function Editor is just available for nodes when something is mapped to them, even if it's not used. But that's negligible...(as long as it gets fixed in a upcoming release?)

Thank you Oliver!

Best regards

Michael

Former Member
0 Kudos

Hi Oliver,

i didn't really get what you mean. Or if i got it, what i tried does not work.

What did you mean by assigning the top level operations response node to itself on the right?

What i tried now, is assigning the logEntry node on the left to the one on the right. There i can choose between appending, merging or setting it. But then there is no possibility to enter functions for the new logEntry. I can't edit functions for the leaves on the right side then.

See [Screenshot|http://www.qpic.ws/images/Y2Q87843.jpg]

Regards

Michael

OliverGoetz
Employee
Employee
0 Kudos

Michael,

I just tried this again in the IDE and you're right: if you map a type that doesn't match you'll get an error (I could swear I did not get this when I first tried it) and if you use a matching type you cannot change the elements below to something else. I will try to contact an expert from the mapping editor to clarify how this can be accomplished. (But I don't think I will reach anyone before next Tuesday...)

In the mean time, I could offer you a workaround, which is a bit ugly and also more costly at runtime; but if it helps you to continue with your work you could try this until we have a better solution:

- Create a WSDL with the LogEntry for both request and response type.

- Create a process "Logger" that only consists of a start event, and end event and a data obect.

- Assign the new WSDL as service interface for this process.

- Assign the LogEntry type as type for the data object.

- In the output mapping of the start event, map the requests log entry to the data object.

- In the input mapping of the end event, map the data object log entry to the response.

- In your real process, add a sub-process right after the activity for which you want to log something.

- Assign the new "Logger" process to the sub-process.

- Map your functions to the input elements of the sub-process in the input mapping.

- Map the response from the sub-process to the Log data object with an append assignment in the output mapping of the sub-process.

An easier solution would of course be to introduce a new data object of type LogEntry in your main process and use an additional mapping activity, but if you have concurrency in your process a global data object like that would introduce the danger of race conditions and deadlocks...

I admit, this looks a bit ugly

Best regards,

Oliver

Former Member
0 Kudos

Hi Oliver,

thanks for your answer and the improved XSD file!

The LogEntry now occurs as unbound context within the mapping editor.

But actually my intention was to assign the values (Timestamp, ShortDescription, LongDescription) via the expression editor at each activity. So actually there is no real mapping, just functions. I don't have an datatype LogEntry on the left side (task output) that i could connect to the LogEntry node on the left side, which is unbound of course and allows multiple entries.

So i have now 3 functions assign to the leaves below LogEntry on the right side. But i can't declare them as "Append".

I guess i could assign a function the the node LogEntry and set it to "Append" if i only knew how to use either the datatype LogEntry within the expression editor or combine the 3 simple types within one expression to fill the leaves.

Any idea about that?

Another possibility would be to import the datatype LogEntry into my WDs and make them return the data for the LogEntry that i could use the real mapping instead of functions within the mapping editor...

TIA

OliverGoetz
Employee
Employee
0 Kudos

Hi Michael,

I haven't actually tried it at runtime yet, but one of our mapping experts told me it should work to connect the top level operations response node itself to the logEntry node on the right-hand side with the append assignment (provided that the activity has a response).

Then you can enter your function calls in the expression editor of the individual sub-elements of the log entry.

The append assignment on the log entry level will not try to copy any values from sub-elements of the response to the log entry elements at runtime, but just signals the mapping runtime that for each instance of such a source node a new instance of the target node element is appended. And since you have one response for each invokation of an activity this should trigger one log entry to be appended.

Please let me know if this works; as I said: I haven't tried it myself yet...

Best regards,

Oliver

OliverGoetz
Employee
Employee
0 Kudos

Hi Michael,

if you model your type so that it allows unbounded cardinality for the log entries, you can append the individual entries from the output of the automated activity to the log.

You should model this in two types, one for the entry and one for the log itself, like this for example:


<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/ServiceRequestProcessLog" xmlns:tns="http://www.example.org/ServiceRequestProcessLog" elementFormDefault="qualified">

    <complexType name="LogEntryList">
    	<sequence>
    		<element name="logEntry" type="tns:LogEntry" minOccurs="0" maxOccurs="unbounded"></element>
    	</sequence>
    </complexType>

    <complexType name="LogEntry">
    	<sequence>
    		<element name="Timestamp" type="dateTime" minOccurs="1" maxOccurs="1"></element>
    		<element name="ShortDescription" type="string" minOccurs="1" maxOccurs="1"></element>
    		<element name="LongDescription" type="string" minOccurs="0" maxOccurs="1"></element>
    	</sequence>
    </complexType>
    

</schema>

Add the LogEntry type to the output of your activities and assign the LogEntryList as data type for the data object.

In the mapping editor for the output mapping of the activity, drag the log entry from the activities response to the log entry of the log list data object. Then right-click on the mapping connection and select "Assignment" -> "Append". This will create the mapping such that the data is appended to the list rather than overwriting an existing entry.

Best regards,

Oliver