Search code examples
siebel

Can I merge integration components using Siebel data mapping?


I have an integration object with this XML representation:

<root>
  <request code="123" title="Test">
    <user name="Chuck Bartowski" email="-" />
    <data d1="aaa" d2="bbb" d3="ccc" />
    <attachments>
      <attachment name="text.txt" size="50" />
      <attachment name="image.png" size="385" />
    </attachments>
  </request>
</root>

And I need to merge some of the nodes (integration components) into one, to convert the XML into something like this:

<root>
  <request code="123" title="Test" userName="Chuck Bartowski" userEmail="-"
           data1="aaa" data2="bbb" data3="ccc" />
    <attachments>
      <attachment name="text.txt" size="50" />
      <attachment name="image.png" size="385" />
    </attachments>
  </request>
</root>

I'm trying to achieve this using Siebel 7.8 data mappings (EAI Data Transformation Engine). So, I have created an integration object map, with the following integration component maps:

NAME  SOURCE IC     TARGET IC
r1    request    -> request
r2    user       -> request
r3    data       -> request
att   attachment -> attachment

Unfortunately, it's not doing what I was expecting. Instead, it outputs this:

<root>
  <request code="123" title="Test">
    <attachments>...</attachments>
  </request>
  <request userName="Chuck Bartowski" userEmail="-">
    <attachments>...</attachments>
  </request>
  <request data1="aaa" data2="bbb" data3="ccc">
    <attachments>...</attachments>
  </request>
</root>

I know it's possible to map a single source component into multiple targets, but, can the opposite be done? Can I merge many sources into a single target?

So far, I've tried setting the Parent Component Map Name field to r1, in both r2 and r3, but it only earned me a nice SBL-EAI-04008 error: Integration component type 'request' is not a valid child type for component type 'request'.

Am I missing some configuration step, or is this just impossible to do using only the data mapping engine? I'm calling it from a server script, so if nothing else works, I could just adapt the property set there after the mapping finishes.


Solution

  • I found the answer in the Siebel bookshelf. Yes, it can be done, but not how I was trying to do it:

    You may want to address fields in components other than the source component. This is because your target component may depend on more than one component in the source object. In such cases, you cannot use different component maps with different source components, and the same target component, because each component map creates a different instance of the target component. Data Mapping Engine expressions allow you to use the dot notation to address fields, other than the source component, in source integration object components —for example, [Component Name.Field Name].

    Addressing fields in other components is legal only if the cardinality of the component is less than or equal to one relative to the source component —that is, only if the component can be uniquely identified from the context of the source component without using any qualifiers other than the component name.

    So, the key is to create only one component mapping for each target, and then include field mappings from the other sources. In my example, I would have:

    NAME  SOURCE IC     TARGET IC
    req   request    -> request
    att   attachment -> attachment
    

    And inside req, the following field mappings:

    SOURCE            TARGET
    [code]        ->  code
    [title]       ->  title
    [user.name]   ->  userName
    [user.email]  ->  userEmail
    [data.d1]     ->  data1
    ...