<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>The Fulib solution to the T TC 2020 migration case</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Sebastian Copei</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Albert Zuendorf</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Kassel University</institution>
          ,
          <country country="DE">Germany</country>
        </aff>
      </contrib-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>
        At Kassel University we are working on a solution for
bidirectional transformations based on event sourcing
for about a year, now. It turned out, that the TTC 2020
migration case [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] is a special case of a bidirectional
transformation and that our approach provides a reasonable
solution for it.
      </p>
    </sec>
    <sec id="sec-2">
      <title>2. Design</title>
      <p>M1
objects
- c1
- c2
- ...</p>
      <p>- c1
- c2
- ...</p>
      <p>M2
objects
The idea and design for our solution stems from Domain M1Editor M2Editor
Driven Design [2] and Event Sourcing [3]. Basically, we p1: M1Person h3: HavePerson h5: HavePerson p7: M2Person
umsoedtewl oofetdhietocrasseMs1tEuddiy,tcof.rFaignudrMe21.EEdaicthoerd,iotonrehfoolrdesathche iandga=em“e=o=b2j50“A”lice” iandga=em“e=o=b“2j0“5A””lice” inadag=em“e=o=“b2j0“5A””lice” iyndba=imrth“eo==b1j0“9A”9li5ce”
current object model (based on the corresponding ecore
model). In addition, each editor provides editing com- d2: M1Dog h4: HaveDog h6: HaveDog d8: M2Dog
ompaenrdastifoonlsloowninthgethoebjceocmtmmoandedldaerseigenncpaaptsteurlnatoedf[w4]i.thAinll iandga=em“e=o=b2j1“B”ob” iaondgaw=emne“e=orI=b“d2j1“”=B” o“obb”j0” ioandgaw=emne“e=orI=“bd2j1“”=B” o“obb”j0” inda=m“eo=bj1“B”ob”
editor commands. Each editor keeps track of all executed
commands (and the used command parameters) within
its event store, cf. Figure 1. To enable collaboration Figure 2: Objects
of M1Editor and M2Editor, both editors provide the same
set of commands: a HavePerson command with
parameters id, name, and age and a HaveDog command with
parameters id, ownerId, name, and age, cf. Figure 3 In [5] we have developed theoretical foundations for
and Figure 2. this command (or event) sharing between multiple
edieach editor implements the command execution difer- tors: basically, we require that multiple commands that
ently according to its specific ecore model. As an example, address the same object (have the same id) overwrite
Listing 1 shows the implementation of the HavePerson each other, i.e.: if c1 and c2 are commands with the same
command within M2Editor. Line 22 of Listing 1 shows id than applying c1 and then c2 is similar to applying
how the age parameter of the HavePerson command is only c2. In addition, commands that work on diferent
turned into a ybirth value for model M2. objects may be executed in any order (are commutative),</p>
      <p>Generally, we consider M1Editor and M2Editor as inde- i.e. if c3 and c4 are commands with diferent ids, applying
pendent programs that may run on diferent computers, ifrst c3 and then c4 must result in the same object model
concurrently. Therefore each editor is able to serialize its as applying c4 first and c3 second. While these are pretty
event store (in yaml format) and to send its commands strong conditions, it turned out to be easy to implement
to the other editor. Correspondingly, the receiving editor the commands according to these rules. For the TTC2020
is able to deserialize and execute the commands, too. migration case we will discuss this in Section 3.</p>
      <p>Provided with overwriting and commutative
commands, our editors are able to merge commands executed
TTC’20: Transformation Tool Contest, Part of the Software by themselves or received from another editor: if a new
Technologies: Applications and Foundations (STAF) federated command arrives that uses an id that is already used by
conferences, Eds. A. Boronat, A. García-Domínguez, G. Hinkel, and F. some old command, the new command is executed and
eKmřiakialv:as,c1o7@Juunlyi-2k0a2s0s,eBl.dereg(eSn., CNooprweia);yz(uoennlidnoer)f.@uni-kassel.de then the old command is replaced by the new command
(A. Zuendorf) in the event store. If a new command arrives that uses a
CPWrEooUrckReshdoinpgs IhStpN:/c1e6u1r3-w-0s.o7r3g ©CCo2Em02mU1oRCnospLWyicreigonhsrtekfAostrthrtihboiusptpioanpPe4rr.0obIynctieetsrenaaduttiihononragsl.s(CUC(seCBpYEer4Um.0i)Rt.te-d WundSe.roCrrega)tive new id, the new command is executed and added to the
id: String
run ()
HavePerson
name: String
age: String
run ()</p>
      <p>HaveDog
name: String
age: String
ownerId: String
run ()
object but we shall lookup the already existing object
and just adjust its attributes. In Line 5 of Listing 1 our
HavePerson command achieves this behavior by using
Figure 3: Command Classes the getOrCreatePerson method of its editor. Our
editors have hash tables for each model class (i.e. for Person
and Dog) and the getOrCreatePerson method looks
event store. The event store is treated as a set, i.e. the up this hash table. If the hash table already has a
Perorder of the commands (and the order of the command son with the given id, this Person is returned. Otherwise,
execution) does not matter due to our commutativity getOrCreatePerson creates a Person object, initializes
condition. its id, adds it to the hash table, and then returns the new</p>
      <p>Overall this editor design enables us to implement the Person. Thus, you may call getOrCreatePerson with
TTC2020 migration case as outlined in Figure 4. The mi- a certain id as often as you like, it will always return the
grate step is invoked by the test or benchmark Tasks. The same Person object.
loading of objects is done by loading the corresponding This getOrCreate mechanism also helps us to
xml files via EMF mechanisms. The parsing steps are achieve commutativity for our commands.
Commudiscussed in Section 4. The sending is done via our yaml tativity for commands requires e.g. that you can
exserialization and deserialization. The execution of com- ecute a HaveDog command before you execute the
mands is discussed in Section 3. The modification step HavePerson command for the dog owner. To allow this,
is again done by the test or benchmark tasks. Similarly, our HaveDog commands uses getOrCreatePerson
the test and benchmark tasks invoke the migrate back with the ownerId to retrieve the corresponding Person
step. The migrate back step uses parsing and sending object. If the owner already exists, we just use it,
otherand execution similar to the migrate forward step. How- wise, the owner object is created on the fly. In the latter
ever, some details dealing with missing information are case, a subsequent execution of the HavePerson
comdiscussed in Section 4. mand with the same id will retrieve the already existing
Person object and then fill the Person’s name and age (or
ybirth).
3. Commands Once the targeted Person object has been retrieved,
Line 6 to Line 22 of Listing 1 fill the attributes of that
Our approach relies on commands that are shared be- Person. In this solution, we use EMF dynamic editing
tween the two editors. In the simple TTC20 Migration features to set the name and age or ybirth attributes.
rcuearqseeu2iw.reTeotnhfeaaetcdiclooitmnaltmyeattwhnedosmcaoermregmionvagenrodwfs,rcicotfni.ncFguigrarunerdnetc3eoadmnitmds,uFwtigae-- wTmhiotehddedilfeiwrfeerinethntmitnpigtrhroaepteieordntiitetoasr.sskWsaunesdsettdohirufeersethtnhteeccuoermrceomnrtaenmdescoodjureslest
tive. Thus, if we e.g. execute a HavePerson command query the current ecore model e.g. whether the current
with a certain id on an empty model, the first time we Person has either an age attribute or an ybirth attribute.
shall create a Person object and fill its attributes. How- Thus one implementation of our M2.HavePerson
comever the second time, we shall not create a second Person
mand sufices to address all diferent migration tasks of
the TTC2020 migration case. Note, the M1.HavePerson command. Thereby, the editor adds the new command
command also has only one implementation for all tasks, to the event store.
however this implementation is slightly simpler as the One crucial step during parsing is the retrieval of ids
one of M2.HavePerson as no variant of model M1 deals for the model objects, cf. Line 15 of Listing 2. Usually,
with ybirth attributes. we require that the model objects have an id attribute. In
the TTC2020 migration case this is not true. We solve
this by storing the ids for model objects within the hash
4. Parsing tables that are used by our getOrCreate methods. To
look up the id of a model object that is already stored
The implementation of the diferent migration tasks pro- in such a hash table, we search e.g. the hash table for
vided by the TTC2020 migration case resources [6] load Persons for the given instance. If an entry exists, we
the diferent start models from XML files. After the first return the corresponding id. If there is no entry yet (i.e.
migration the task implementation may retrieve the mi- after loading the initial object model) we just create a
grated model and it may modify the migrated model new id and add the instance to the hash table under this
directly via dynamic EMF means. This means, the task new id and then return the new id. Within the backward
implementation does not use our editor commands to migration step the hash table will already contain the
load or to modify the models. Thus, our first task is instance and the old id is retrieved.
to parse the provided model and to derive the editing There is one special case when merging the commands
commands that correspond to it. created by the parse methods into the editor’s event store:</p>
      <p>
        For this purpose, our editors provide a parse method In migration Task4 of the TTC2020 migration case [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ],
that basically uses a visitor to travel through the current in model M2 the Dog has no age attribute. Thus, when
model. For each model object our visitor then calls special we parse the Dog object during the backward migration
parsePerson or parseDog methods, respectively. step, the parseDog method will not find any age
infor
      </p>
      <p>Listing 2 shows the parsePerson method of our mation. However, this age information is still contained
M2Editor. Basically, Line 5 to Line 20 of Listing 2 use within the original HaveDog command that has been
redynamic EMF features to retrieve the parameters needed ceived from M1Editor and that has been executed and
for the corresponding HavePerson command. Line 20 to added to the event store of M2Editor during forward
Line 25 then create the desired HavePerson command transformation. To keep the age information alive, if
and provide its parameters. Finally, Line 26 executes the the parseDog method cannot find the age attribute in
the parsed model object, it tries to retrieve the old com- [2] E. Evans, Domain-driven design: tackling
complexmand from the M2Editor event store and copies the age ity in the heart of software, Addison-Wesley
Profesinformation from there into the new command. sional, 2004.</p>
      <p>Altogether, our parsing approach utilizes that our com- [3] V. Vernon, Implementing domain-driven design,
mand execution is overriding and commutative. Due to Addison-Wesley, 2013.
the commutativity, the parsing visitor may visit the ob- [4] E. Gamma, R. Helm, R. Johnson, J. Vlissides, Design
jects of the current input model in any order and thus patterns: Abstraction and reuse of object-oriented
create the editor commands in any order. Due to the design, in: European Conference on Object-Oriented
overriding property, the backward migration may just Programming, Springer, 1993, pp. 406–431.
(re)execute the detected commands and this will over- [5] S. Copei, A. Zündorf, Mx for microservices, in: Proc.
write the old commands and blend into the event store, Dagstuhl Seminar, volume 18491, 2019.
easily.1 [6] ttc2020resources, Ttc2020 case: Round-trip
migration of object-oriented data model instances, github
resources, https://github.com/lbeurerkellner/ttc2020,
5. Results 2020. Last viewed 13.06.2020.
Overall, our editor and command approach was very well
suited for the TTC2020 migration case. We were able to
address all migration task with the same implementation.</p>
      <p>While our design might appear a little bit over engineered
we took benefit from the FulibServiceGenerator, a
tool we are just building and that generates a lot of boiler
plate code for editors and commands. After all we just
had to implement the run methods of the 2 commands
for the two editors and the parsing methods for the two
editors as described above.</p>
      <p>We believe that the use of overwriting and
commutative commands provides a great leverage for the parsing
and merging of command sets. Overall, our design is able
to handle much more complicated migration cases which
we address in our current work.</p>
      <p>Unfortunately, our performance is very poor, on a test
run the Fulib solution took 9.6 seconds for 10000
iterations while the original solution used only 0.3 seconds.</p>
      <p>We had no time to go into the details of this.</p>
      <p>You find our solution on:
Github:
https://github.com/fujaba/
ttc2020MigrationCaseByFulib</p>
      <p>Docker: zuendorf/fulib-solution-ttc2019</p>
      <p>1Fortunately, the TTC2020 migration case does not include any
delete operations during model modification. To handle deletion of
model objects one has to remove the corresponding old commands
from the event store and one has to propagate this command
removal to the other editor and the other editor needs to remove the
command, too, and it needs to undo the command in order to roll
back the corresponding model changes. This rollback needs some
careful dealing with our getOrCreate operations.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          <article-title>[1] ttc2020migration, Ttc2020 case: Round-trip migration of object-oriented data model instances</article-title>
          , https://www.transformation-toolcontest.eu/2020_roundtrip.pdf,
          <year>2020</year>
          .
          <source>Last viewed 13.06</source>
          .
          <year>2020</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>