ArgoUML Enki Module

This page is a getting-started guide for the argouml-enki module, which gives ArgoUML the ability to use an RDBMS for model persistence.

= Introduction =

''Warning: argouml-enki is in a very early unstable development stage, and is not ready for real usage yet. However, if you are interested, you are encouraged to take a look and provide feedback to help get it into good shape for a real release.''

For an overview of argouml-enki, please read the project home page.

argouml-enki does not have any packaged module releases yet; if you want to try it, you'll need to pull the latest source from Subversion, then use the instructions below to build and run it.

= Build and Run =

These instructions are for a command line build. (See the next section for Eclipse instructions.)

Prerequisites:


 * The latest source build of ArgoUML in a directory named argouml.
 * An installation of MySQL. (Hibernate will work with most DBMS's, but the only one that has been heavily tested so far with Enki is MySQL.)

To get the argouml-enki source code from Subversion, execute this command in the parent directory of your argouml workspace (so argouml and argouml-enki will end up as sibling directories):

svn co http://argouml-enki.tigris.org/svn/argouml-enki/trunk argouml-enki --username guest

Next, in the argouml-enki directory, create a file named local.properties as follows, editing the path and version for your MySQL client JDBC driver:

argo.enki.jdbc.driver.file=/path/to/mysql-connector/mysql-connector-java-x.y.z-bin.jar

Create another file, named argouml-enki.properties, in the same directory:


 * 1) Hibernate configuration file.

org.eigenbase.enki.hibernate.allowImplicitSessions=true

org.eigenbase.enki.implementationType=ENKI_HIBERNATE
 * 1) Configure Hibernate usage

org.eigenbase.enki.hibernate.connection.driver_class=com.mysql.jdbc.Driver org.eigenbase.enki.hibernate.connection.url=jdbc:mysql://localhost:3306/ARGOUML org.eigenbase.enki.hibernate.connection.username= org.eigenbase.enki.hibernate.connection.password= org.eigenbase.enki.hibernate.connection.max_idle=1
 * 1) Configure mysql connection

org.eigenbase.enki.hibernate.createSchema=AUTO
 * 1) Create all-of-type/all-of-class views

hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
 * 1) Configure Hibernate's SQL dialect for mysql

hibernate.default_batch_fetch_size=25
 * 1) Use batch fetching

hibernate.jdbc.batch_size=25
 * 1) Use JDBC batches

You'll need to fill in the user name and password, and if your MySQL server is running on another machine and/or port, change localhost:3306 accordingly.

If the MySQL user account has the ability to create databases, execute this command via the mysql client utility:

CREATE DATABASE ARGOUML;

Otherwise, you'll need to ask your DBA to do it. (If you choose a different database name, change the URL in the properties file accordingly.)

Note: eventually we'd like to handle all of this via a DB connection wizard in ArgoUML, and avoid storing unencrypted passwords, but for now these steps are required.

Now, execute ant run to build and launch argouml-enki. Behind the scenes, this will also create the database schema automatically. As you start creating model elements, corresponding records will be inserted into the tables in this schema.

The build produces two jars:


 * argo-enki.jar: the Enki model subsystem implementation
 * enki-hibernate-uml-impl.jar: Enki-generated Hibernate data access classes for the UML metamodel; these implement the interfaces from argouml-mdr's java-interfaces.jar (since MDR and Enki both implement the same JMI spec, these are compatible even though the interfaces were generated by MDR and the implementations by Enki)

= Eclipse Setup =

After getting the command line build working, you can set up an Eclipse environment for argouml-enki.

First, set up Eclipse for a normal ArgoUML build following the Cookbook instructions. However, for the team projectset file, use the one for argouml-enki.

Next, there are some one-time setup steps required outside of Eclipse:


 * 1) In workspace/argouml-enki, create argouml-enki.properties and local.properties as described in the previous section on command-line builds.
 * 2) In workspace/argouml-enki/local.properties, add a line argo.base.dir=/path/to/your/command/line/build/for/argouml
 * 3) In MySQL, DROP DATABASE ARGOUML followed by CREATE DATABASE ARGOUML
 * 4) In workspace/argouml-enki, run ant generate

Finally, back in Eclipse, under the argouml-enki project, right-click ArgoUML with Enki.launch, then Run As and Open Run Dialog. In the Classpath tab, add an external jar references for your MySQL JDBC driver. Now you should be able to run, debug, etc.

(Yes, this is all a bit confusing and redundant. If you can figure out ways to streamline it, please let us know.)

= Model Persistence =

Usually, ArgoUML manipulates models in memory only, with well-defined load/save points to transfer them between memory and .uml/.zargo files.

When run with Enki, ArgoUML is instead manipulating models directly in the DBMS. This means for models, load and save are no longer meaningful. So if you close argouml-enki, and then run it again, the model you were working on is already available in the tree; no need to explicitly reload it.

Unfortunately, diagrams are not currently treated the same as models, so they are not persisted to the database. What this means is that when you run argouml-enki again, your model will still be there, but your diagrams will be gone. Ideally (for multi-user access), diagrams would be persisted along with models; short of that, the project file would need to be enhanced to keep the diagrams in the file system while accessing the models from the DB--if that route is chosen, load/save will become meaningful again.

How frequently does argouml-enki commits your edits to the database? This ought to be well-defined (either explicit transactions under user control, or autocommit); the current implementation is unpredictable and dependent on certain UI actions taking place (or ArgoUML finally being shut down).

Does argouml-enki support multi-user access yet? No, don't try accessing the same database from multiple ArgoUML instances at the same time yet, unless you want to see a lot of strange errors.

= Bugs =

There are a lot of known problems with very basic operations logged already; you can use this report to see them. Scan those, and then please go ahead and log new ones as you encounter them.

When the Hibernate session gets into a bad state, a lot of operations may start failing; in this case, close ArgoUML and reopen it to get it back to a good state.

You can also open up discussions about existing or proposed behavior on the developer mailing list.

= Schema =

If you'd like to see how your models are being mapped and stored in the database, you can take a look using the mysql client utility:

mysql> use ARGOUML; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A

Database changed mysql> show tables; ++ ++ ++
 * Tables_in_ARGOUML                         |
 * AU_ActivityGraphs_ActionState             |
 * AU_ActivityGraphs_ActivityGraph           |
 * AU_ActivityGraphs_CallState               |
 * AU_ActivityGraphs_ClassifierInState       |
 * AU_ActivityGraphs_ObjectFlowState         |
 * AU_ActivityGraphs_Partition               |
 * AU_ActivityGraphs_SubactivityState        |
 * AU_AssocManyToMany                        |
 * AU_AssocManyToManyOrdered                 |
 * AU_AssocManyToManyOrderedTarget           |
 * AU_AssocManyToManyTarget                  |
 * AU_AssocOneToMany                         |
 * AU_AssocOneToManyChildren                 |
 * AU_AssocOneToManyHC                       |
 * AU_AssocOneToManyHCChildren               |
 * AU_AssocOneToManyOrdered                  |
 * AU_AssocOneToManyOrderedChildren          |
 * AU_AssocOneToOne                          |
 * AU_Collaborations_AssociationEndRole      |
 * AU_Collaborations_AssociationRole         |
 * AU_Collaborations_ClassifierRole          |
 * AU_Collaborations_Collaboration           |
 * AU_CommonBehavior_UninterpretedAction     |
 * AU_Core_Abstraction                       |
 * AU_Core_Artifact                          |
 * AU_Core_Association                       |
 * AU_Core_AssociationClass                  |
 * AU_Core_AssociationEnd                    |
 * AU_Core_Attribute                         |
 * AU_Core_Binding                           |
 * AU_Core_Class                             |
 * AU_Core_Comment                           |
 * AU_Core_Component                         |
 * AU_Core_Constraint                        |
 * AU_Core_DataType                          |
 * AU_Core_Dependency                        |
 * AU_StateMachines_TimeEvent                |
 * AU_StateMachines_Transition               |
 * AU_UseCases_Actor                         |
 * AU_UseCases_Extend                        |
 * AU_UseCases_ExtensionPoint                |
 * AU_UseCases_Include                       |
 * AU_UseCases_UseCase                       |
 * AU_UseCases_UseCaseInstance               |
 * ENKI_EXTENT                               |
 * ENKI_MOF_ID_SEQUENCE                      |
 * ENKI_TYPE_LOOKUP                          |
 * ENKI_MOF_ID_SEQUENCE                      |
 * ENKI_TYPE_LOOKUP                          |

Most of the tables prefixed with "AU_" correspond to the classes in the metamodel for UML. There are a few exceptions: the "AU_Assoc..." tables, which are association tables used by Enki to link together model elements. The three "ENKI_" tables are special system tables present in every Enki database.

The table for a UML metamodel class has columns corresponding to that metaclass's attributes (including inherited ones), plus Enki-defined columns for bigint object identifiers and association links. For example, here are the columns for the table which stores package objects:

mysql> describe AU_ModelManagement_Package; ++--+--+-+-+---+ ++--+--+-+-+---+ ++--+--+-+-+---+
 * Field                                             | Type         | Null | Key | Default | Extra |
 * mofId                                             | bigint(20)   | NO   | PRI | NULL    |       |
 * name                                              | text         | YES  |     | NULL    |       |
 * visibility                                        | varchar(128) | YES  |     | NULL    |       |
 * isSpecification                                   | bit(1)       | YES  |     |         |       |
 * isRoot                                            | bit(1)       | YES  |     |         |       |
 * isLeaf                                            | bit(1)       | YES  |     |         |       |
 * isAbstract                                        | bit(1)       | YES  |     |         |       |
 * namespace                                         | bigint(20)   | YES  | MUL | NULL    |       |
 * clientDependency                                  | bigint(20)   | YES  | MUL | NULL    |       |
 * constraint                                        | bigint(20)   | YES  | MUL | NULL    |       |
 * targetFlow                                        | bigint(20)   | YES  | MUL | NULL    |       |
 * sourceFlow                                        | bigint(20)   | YES  | MUL | NULL    |       |
 * comment                                           | bigint(20)   | YES  | MUL | NULL    |       |
 * templateParameter                                 | bigint(20)   | YES  | MUL | NULL    |       |
 * stereotype                                        | bigint(20)   | YES  | MUL | NULL    |       |
 * taggedValue                                       | bigint(20)   | YES  | MUL | NULL    |       |
 * generalization                                    | bigint(20)   | YES  | MUL | NULL    |       |
 * ownedElement                                      | bigint(20)   | YES  | MUL | NULL    |       |
 * elementImport                                     | bigint(20)   | YES  | MUL | NULL    |       |
 * a_parent_specialization_Specialization            | bigint(20)   | YES  | MUL | NULL    |       |
 * a_supplier_supplierDependency_SupplierDependency  | bigint(20)   | YES  | MUL | NULL    |       |
 * a_presentation_subject_Presentation               | bigint(20)   | YES  | MUL | NULL    |       |
 * a_defaultElement_defaultedParameter_DefaultedParam | bigint(20)  | YES  | MUL | NULL    |       |
 * a_resident_elementResidence_ElementResidence      | bigint(20)   | YES  | MUL | NULL    |       |
 * a_parameter_parameterTemplate_ParameterTemplate   | bigint(20)   | YES  | MUL | NULL    |       |
 * a_referenceValue_referenceTag_ReferenceTag        | bigint(20)   | YES  | MUL | NULL    |       |
 * a_modelElement_templateArgument_TemplateArgument  | bigint(20)   | YES  | MUL | NULL    |       |
 * a_behavior_context_Behavior                       | bigint(20)   | YES  | MUL | NULL    |       |
 * a_classifierRole_availableContents_ClassifierRole | bigint(20)   | YES  | MUL | NULL    |       |
 * a_collaboration_constrainingElement_Collaboration | bigint(20)   | YES  | MUL | NULL    |       |
 * a_collaborationInstanceSet_constrainingElement_Col | bigint(20)  | YES  | MUL | NULL    |       |
 * a_contents_partition_Partition                    | bigint(20)   | YES  | MUL | NULL    |       |
 * a_importedElement_elementImport_ElementImport     | bigint(20)   | YES  | MUL | NULL    |       |

Hibernate-compatible data access classes are generated automatically as part of the build; for an example corresponding to the table above, see argouml-enki/build/java/org/omg/uml/modelmanagement/UmlPackage$Impl.java.

If you want to see the SQL generated by Enki/Hibernate for querying and saving objects, you can either turn on MySQL tracing, or add hibernate.show_sql=true to your argouml-enki.properties file to get the SQL statements dumped to the ArgoUML console output.

If your database somehow gets corrupted, or you just want to clean it out and start fresh, here are the steps:


 * 1) From MySQL, DROP DATABASE ARGOUML
 * 2) From MySQL, CREATE DATABASE ARGOUML
 * 3) From the argouml-enki directory, ant clean
 * 4) From the argouml-enki directory, ant run

You can also use MySQL's backup/restore utilities to save and restore persistent model copies.