Saturday, April 16, 2011

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 ADF 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 and metadata-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 with mo.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.



10 comments:

  1. Nice post! thanks for sharing.
    i got one question.
    how can i get MDSInstance without passing MDSConfig config = new MDSConfig(new File(path to adf-config.xml));
    because adf-config.xml is packaged in ear. and it's not easy to access it. i'm thinking if there is a way to get it via some context?
    do you have any ideas?

    ReplyDelete
  2. There are 2 ways:

    - if your application is an ADF application, you can do ADFContext.getCurrent().getMDSInstanceAsObject();
    - if your application is not an ADF application, then the only way is to know the instance name and get it with MDSInstance.getInstance(String name)
    - there could be another way by questioning the MBean server. I will look into this and let u know.

    ReplyDelete
  3. Thanks Flavius,

    I was trying to understand the role of MDS in Oracle and your post is really helpful. I dint find this information on net anywhere else. Thanks for sharing.

    ReplyDelete
  4. how to maintain versioning with dictionary in OBR. please help me.

    ReplyDelete
  5. Metadata Manager is Metadata Repository a web-based repository that offers enhanced capabilities in the areas of data governance, regulatory compliance and metadata management.

    ReplyDelete
    Replies
    1. hi rupali ,
      can u please tell me how to resolve this error :::

      when ever i start my weblogic server i got this warning ::

      "(Warning) (oracle.mds) (BEA-000000) (A call to flushChanges on the current MDSSession does not specify the correct transaction key)"

      i checked on oracle it shows below :

      MDS-00047: Use the flushChanges method on the MDSSession to commit the changes.
      Cause: Commit was disabled in the PTransaction that was being used.
      Action: Use the flushChanges method on the MDSSession to commit the changes.

      Level: 1

      Type: ERROR

      Impact: Programmatic


      can u help me how to resolve this

      Delete
  6. hello and thanks Flavius,

    I'm actually a new player at this oracle FMW stuff and I got something that make me stuck. It's called FlushChanges. I was trying to start up the SOA Server from Oracle FMW Enterprise Manager, but I got an error that said

    " <,a call to flushChanges on the current MDSSession does not specify the correct transaction key>"

    could you please tell me what to do with this kind of error.
    Thanks before and after

    ReplyDelete
    Replies
    1. hi friend, i have same error can you please tell me how u resolve it ?

      Delete
  7. HI and thanks , Flavius,

    when ever i start my weblogic server i got this warning ::

    "(Warning) (oracle.mds) (BEA-000000) (A call to flushChanges on the current MDSSession does not specify the correct transaction key)"


    can you please help me on this ... how to resolve it.


    i check it on oracle docs it says :::

    MDS-00047: Use the flushChanges method on the MDSSession to commit the changes.
    Cause: Commit was disabled in the PTransaction that was being used.
    Action: Use the flushChanges method on the MDSSession to commit the changes.

    Level: 1

    Type: ERROR

    Impact: Programmatic


    but i don't have any idea how to apply flushchange please help.

    ReplyDelete