Saturday, October 18, 2014

Working with Oracle MDS Repository (MetaData Services)


With the release of FMW 11g, the Oracle MDS Repository is now the central place for storing configuration files, personalization elements, page customizations, pages etc. for WebCenter, IDM and SOA Suite. Understanding and working with this repository is essential for custom application developers and implementers.

Oracle provides some basic tools for managing the repository, such as import/export and a JDeveloper browser plugin. Unfortunately, there is no tool currently for managing the files within the repository, so there really is no possibility to change the files at run-time without exporting and then reimporting the repository.

I will explain in this blog post how you can connect to a MDS repository and how you can work with the files stored there.

The MDS is basically an XML store with transaction capabilities, versioning, merging and a persistence framework optimized to work with XML nodes and attributes. It is somehow similar to an ORM, but for XML entities. The persistence framework has two adapters that can persist the store to a database or to a folder on disk. The database store has more advanced features is the recommended way of working with MDS. The file store is useful for at development time, because one can change the files manually.

The same as an ORM needs a configuration file to know the environment (e.g. hibernate.cfg.xml), the MDS uses its own config file named adf-config.xml. You can find this file automatically generated by JDeveloper in any SOA FMW project, with a default configuration.

The file has several configuration sections, but one is of particular interest, and it's called
adf-mds-config:
<adf-mds-config>
  <mds-config>
    <type-config>
      <type-definitions>
        <classpath>/com/tutorial/model/schema/beanType.xsd</classpath>
        ......
      </type-definitions>
    </type-config>
  </mds-config>
  <persistence-config>
    <metadata-namespaces>
      <namespace metadata-store-usage="MetadataStore" path="/custom/" />
      ......
    </metadata-namespaces>
    <metadata-store-usages>
      <metadata-store-usage default-cust-store="true" deploy-target="true" id="MetadataStore">
         <metadata-store class-name="oracle.mds.persistence.stores.db.DBMetadataStore">
           <property name="jdbc-userid" value="DEV_MDS"/>
           <property name="jdbc-password" value="dev"/>
           <property name="jdbc-url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
           <property name="partition-name" value="p1"/>
           <property name="repository-name" value="mds-SpacesDS"/>
         </metadata-store>
      </metadata-store-usage>
    </metadata-store-usages>
  </persistence-config>
</adf-mds-config>

In the above configuration, the most interesting elements are: type-definitions, namespace andmetadata-store:
·                      type-definitions: here you can define custom XSD nodes that describe custom entities. The easiest way to generate XSD definitions is with the help of JAXB: you can define you data model as serializable POJOs  (same as JPA entities) and then use Oracle's MDSBeanGenTool (located in the mdstools.jar file) java utility to generate the schema definition.
·                      namespace: here you must define the virtual paths within the MDS repository, so the persistence framework will know where to store and find the files
·                      metadata-store: this node configures the persistence adaper. It can be either DBMetadataStore, ClassPathMetadataStore, FileMetadataStore or ServletContextMetadataStore.
Once you have these in place, you are ready to connect to the metadata store:
MDSConfig config = new MDSConfig(new File(path to adf-config.xml));
MDSInstance mdsInstance = MDSInstance.getOrCreateInstance("test-instance", config);
MDSSession mdsSession = mdsInstance.createSession(new SessionOptions(null, null, new CustConfig(new CustClassListMapping[0])), null);
The mdsSession variable holds the session instance for the MDS repository. A MDSSession is similar to the Hibernate Session object. It will handle all persistence operations and holds a transactional context.
You can now query the repository to find the desired items. For example, to find all files in repository you would write:
NameQueryImpl query = new NameQueryImpl(mdsSession, ConditionFactory.createNameCondition("/", "%", true));
Iterator<QueryResult> result = query.execute();
while(result.hasNext()) {
    QueryResult qr = result.next();
    // ...do your magic here...
}
Using the above query, you would only retrieve the names of the items inside the repository. To get the actual instance of an MDS object ( MetadataObject ), you have to write:
MOReference ref = mdsSession.getMOReference(path inside the repository);
MetadataObject mo = mdsSession.getMetadataObject(ref);
Once you have the MetadataObject instance, you can retrieve the XML document behind withmo.getDocument(); Having the DOM XML Document instance, you can alter the XML file and save it hack to the repository by issuing mdsSession.flushChanges();

Using the information briefly described here and with a little bit of SWING knowledge, you can easily write an MDS browser and XML editor to change what you want inside the repository.

No comments:

Post a Comment