Showing posts with label mds. Show all posts
Showing posts with label mds. Show all posts

Thursday, December 31, 2015

Dramatically reduce SOA Suite 11g startup time by cleaning the MDS

SOA Suite can sometimes be a bit slow to start. This is especially the case when there are a lot of composites to load. Customers using different versions of composites can benefit from undeploying non-default revisions of processes which do not have any running instances (see for example here). Undeployment in most cases is an asynchronous process which does not give feedback. It can partially fail without you noticing (apparently not an atomic transaction). This sometimes leaves composite remains; parts of the composite which are still loaded at startup but are not visible from the Enterprise Manager. Removing these can dramatically reduce server startup time. Especially in an environment which has been used for some time and environments with many versions of composites. Reducing the time required to get the soa-infra application fully up and running is of course mostly relevant for 11g SOA installations and less for 12.1.3 (which does some lazy loading) and 12.2.1 (which supports parallel deployments, also during server start-up).

In this article I'll demonstrate how these left-over composite parts can be identified and removed on an 11.1.1.7 SOA environment. First try this procedure on a development or test environment before executing it in production! This method is not supported by Oracle (or me) in any way and using it is entirely at your own risk. If something breaks, tell me so I can update this article. Thanks!

Please mind that these actions, although they help with the start time and memory usage of your SOA environment, have less impact on run-time performance than for example purging of instances and reducing the amount of deployed composites (or tweaking datasources, soa-infra database, JVM, etc).

SOA Suite can be up quickly!

Tuesday, July 8, 2014

SOA Suite 12c: Obtaining composite resources such as WSDLs, XSDs and WADLs

In SOA Suite 12c and 11g there are several options to obtain composite resources such as WSDL's and WADL's. In this blog post I will demonstrate some of them and provide some background information. First I'll describe how URL's can be used to access composite resources. Next I'll describe how and when the EM test console and the Webservice test client can be used to gain information about composite WSDL's and XSD's.

Thursday, July 25, 2013

Oracle SOA Blackbelt training June 2013 Berlin

The Oracle SOA Blackbelt training in Berlin in June of 2013 has provided me with some valuable new insights into various topics related to Oracle SOA Suite. Below are some examples of things which I found interesting to share. These are mostly not literally from the slides but written down in my own words. Some examples have been expanded a bit by additional resources I've found. This not a complete list as the training covers quite a lot of material. I've focused on topics which can relatively easily be implemented or considered. The training also covered a lot of background which is harder to summarize and make concrete in practices/suggestions. The topics are various and not written down in a particular order.

SOA Best practices

The presentation on SOA best practices contained a lot of good suggestions. These are a few of them.

Problem; Over usage of dehydration causes much overhead. Examples; synchronous non-idempotent services, multiple mid-process receives, dehydrate/wait activities in processes.
Recommendations; Avoid chattiness, design services to be idempotent, if possible avoid asynchronous services (callbacks cause thread/transaction overhead)

Problem; Usage of FlowN where N is unconstrained can cause resource problems and lack of control.
Recommendation; Do not base N in FlowN on the data. Design the process using the driver / worker pattern (driver hands small chunks to the worker and the worker processes this). This can for example be implemented by using queues for decoupling/performance.

Problem; Asynchronous services cause overhead. This can become a problem if there are large numbers of asynchronous processes waiting for a response since for every callback, a new thread/transaction is needed and a callback needs to be matched to a correlation table which takes longer if there are a lot of open processes.
Recommendation; Design processes to be synchronous as much as possible. avoid nesting of asynchronous processes. also avoid synchronous processes calling asynchronous processes

Problem; A single BPEL process does batch processing of a large amount of messages. This takes a lot of memory and causes a lot overhead for storing audit information.
Recommendations; Put the work to be done in a separate BPEL process and optimize this process.  design for worst case scenario's. implement retry mechanisms in fault-policies. implement your own scheduling mechanism to spread the load. if no message level processing is needed, ODI might be an option.

Problem; Scope variables are dehydrated and when the variables become large, this causes overhead.
Recommendations; Use local variables whenever possible. assign portions of the message to scope variables.

BPEL is meant for service orchestration. It's not a procedural programming language.
Recommendations; use declarative constructs instead of elaborate custom constructions. use the skip condition instead of if statements. use assertions before and after invokes. use pick activities to time responses

Problem; Identifying BPEL processes can be difficult due to lack of business content in the EM views.
Recommendation; Set the composite title to a business value. it is possible to search for this name. business transaction keys and sensors (both have to be custom implemented) can be used to identify a flow instead of only the ECID since the ECID can not always be traced back to business context.

Diagnostics

I usually tend to look in the log files and in the Enterprise Manager if something goes wrong. There are however several other options;
- creating dumps. the following provides a nice overview; http://docs.oracle.com/cd/E25178_01/admin.1111/e10226/soacompapp_diag.htm#BABJFIFG
- collect info from the MBean browser; oracle.as.soainfra.bpm; Server/bpel:CubeDispatcher ReadXMLDispatcherTrace and oracle.as.soainfra.bpel; Server/BPELEngine:SyncProcessStats and AsyncProcessStats

Database growth (BPEL/BPM)

A concern for managing SOA Suite installations is the growth in database size. It is essential to think about a cleaning strategy. What I learned during the training is that with some programming practices the amount of information saved can also be reduced.

What causes growth;
- creating process instances
- updates to a message payload (workflow)
- asynchronous operations
- process scopes, task assignments. looping back to tasks
- audit (entry and exit of scope and model elements)

Thus it can be more efficient to build larger processes instead of multiple smaller ones. Also scoping and the use of a lot of model elements causes the database size to increase. For example, it could be (untested) more efficient (database space wise) to create a single assign activity with a lot of actions in it instead of several smaller assign activities.

Authorization, authentication and policies

Oracle Platform Security Services provides an abstraction layer to authorization/authentication/role/group providers. In Oracle BPM, users/groups are used but also application roles. The users/groups can be stored by LDAP providers. If there are multiple LDAP providers, these providers can be virtualized by Oracle Virtual Directory (OVD). When OVD is not available at a customer, libOVD can be used to provide a limited lightweight alternative. See for example http://fusionsecurity.blogspot.nl/2012/06/libovd-when-and-how.html. Application roles are stored in a policy store which can also be LDAP based. See for example; http://docs.oracle.com/cd/E12839_01/core.1111/e10043/cfgauthr.htm. Another option is to have it database based. See for example; http://redstack.wordpress.com/2011/10/29/soa11g-database-as-a-policy-store/. Identities can be queried via the browser, for example at; http://localhost:7001/integration/services/IdentityService/identity.

Transactions

The Blackbelt training contained a presentation on the BPEL Engine internals. This provided some additional points to pay attention to when developing. There are 4 'types' of BPEL processes. These 4 types can be categorized by 2 properties; synchronous or asynchronous and durable or transient. The different types behave differently in respect to transactions and threads. This has consequences for exception handling/propagation. The following should be avoided; a transient asynchronous process and a durable synchronous process. Transaction semantics can also have consequences for performance. See for example; http://javaoraclesoa.blogspot.nl/2013/06/oracle-soa-11g-bpel-transaction.html

The Event Delivery Network

Events can be published with different settings; guaranteed delivery and once-and-only-once (OAOO). With the guaranteed delivery setting, local transactions are used (non-XA), the EDN_EVENT_QUEUE is used and there is the possibility of duplicate messages (in case of catastrophic failures). Also, the dequeue transaction is committed when all subscribers have received the message. Retries are not possible in case one subscriber fails to pickup the message. Once and only once setting works differently. A second queue is used; EDN_OAOO_QUEUE. Each subscriber picks up the message in it's own transaction. An XA connection is used with global transactions and the dequeue action can be retried. The EDN can be debugged in the following ways; by using the EDN servlet; http://<host_name>:<port_number>/soa-infra/events/edn-db-log (when EDN is AQ based (which is the default)). This servlet uses the EDN_LOG_MESSAGES table in the SOAINFRA schema. The following loggers are related oracle.integration.platform.blocks.event, oracle.integration.platform.blocks.event.saq, oracle.integration.platform.blocks.event.jms. In the Enterprise Manager, the log level can be tuned. The delivery of messages can be paused by setting the 'Paused' property of oracle.as.soainfra.config/EDNConfig:edn in the System MBean browser.

Local Invocation Optimization

If certain criteria are met, the SOAP/HTTP layer can be skipped when calling a service. The criteria are; the processes have to be on the same server, client/server policies must allow it (this is a property in the policy file). The same server requirement has implications for the use of loadbalancers in cluster configurations. Check the following part of the documentation for more details on how the 'same server check' is performed; http://docs.oracle.com/cd/E28271_01/admin.1111/e10226/soainfra_config.htm. You should also check out https://forums.oracle.com/thread/2302988 for some more information on how to make sure local optimization is used in case of clustering/load balancing setup's. A recommendation is to avoid too many small processes since this increases complexity (in order to achieve local optimization) and overhead.

BPEL fault handling best practices

The following best practices were mentioned in the training (I've rephrased them for brevity);
- always have a catch-all block (selectionFailure for example cannot be caught by using a fault policy)
- use named exceptions for business faults
- when using fault policies, always have a default action
- rethrow faults from fault policies in order to catch them in a BPEL process (when no fault handling action has been defined in the policy)
- notify the source system something has gone wrong
- think about how enable automatic recovery can have impact on transactions and business functionality. this can also be disabled; http://www.albinsblog.com/2011/10/oracle-soa-suite-11g-disabling-auto.html#.Ue_sxm3JWVA
- for asynchronous processes, after a mid-process receive, check the response (which can contain business faults) and terminate the process on error after sending a message to a notification service

MDS

An efficient way to use the MDS is to use a local filebased repository during development and use the database based MDS during runtime. MDS configuration is stored in adf-config.xml files. MDS files can be referred to by a path ; <Store_Root>/<Partition>/<Namespace>/<Resource>. When an MDS object changes, all dependant resources need to be recompiled. The MDS can be used to avoid server startup issues due to dependencies. See; https://blogs.oracle.com/aia/entry/aia_11g_best_practices_for_dec.

Mediator

The Mediator is the only product which has an out of the box resequencer to provide ordening of messages. See for example; http://docs.oracle.com/cd/E17904_01/integration.1111/e10224/med_resequencer.htm for details. Also it currently is the only component supporting Schematron based validations (see for example; http://beatechnologies.wordpress.com/2011/04/06/using-schematron-in-oracle-soa-suite-11g-for-validating-xml/). The Mediator has an Hearbeat infrastructure; if in a clustered environment one instance of a Mediator fails (for whatever reason) this is detected and the other node in the cluster will process the message. Information on message 'lease' is stored in the table; MEDIATOR_CONTAINERID_LEASE. A message is locked when processing starts and released afterwards. The Heartbeat framework can be configured. See; http://docs.oracle.com/cd/E14571_01/integration.1111/e10226/med_config.htm#BABEDHBJ. Sequential routing rules are executed in a single transaction and thread. Parallel routing rules use 3 threads; inbound threads, locker threads and worker threads. Each worker thread uses it's own transaction. Parallel routing rules can be debugged by looking at the MEDIATOR_DEFERRED_MESSAGE. One row is one message in a parallel routing rule.

Oracle Service Bus

Local transport can be used for internal service chaining (for example when calling reusable components). Local transport services can not be invoked from outside the service bus and are not published to a UDDI. See for example http://docs.oracle.com/cd/E23943_01/dev.1111/e15866/local.htm. The split/join pattern which can be implemented in the OSB uses a BEA BPEL implementation and works in-memory (not persistent). The service bus is minimalistic; by default, most features are turned off and the focus is on performance/high throughput. Oracle BPEL for example is more maximalistic and if you want high performance there you should turn things off.

Cube engine internals

Work items for the same instance are not allowed to execute concurrently. This implicates that the parallel execution in for example for-each/while loops is 'simulated' and not truly parallel. This knowledge helps understanding the behaviour of the nonBlockingInvoke setting. See; http://docs.oracle.com/cd/E23943_01/core.1111/e10108/bpel.htm#ASPER99890. The nonBlockingInvoke setting creates new threads for invocations but the invocations are still executed in sequence. In practice, this leads to performance degradation.

Thursday, April 11, 2013

SOA Suite PS6 (11.1.1.7); Service loose coupling and tokens

Oracle SOA Suite Patchset 6 (11.1.1.7) has been released (https://blogs.oracle.com/SOA/entry/new_release_of_oracle_soa). Several new features are available such as the implementation of configuration tokens. This could be an interesting new feature, since it could potentially allow configuration plans to become obsolete, so I decided to try it out in order to determine it's usefulness.

Using tokens

Edwin Biemond has described in his post on http://biemond.blogspot.nl/2013/04/token-configurations-in-oracle-soa.html how tokens can be used in configurations. He describes the following limitation; "Important to know this only works on the location attribute of the binding.ws element of the composite.xml file.". So if you use references in other locations to for example concrete WSDL's , you can't replace them by using tokens.

Service Loose Coupling

One of the general principles of Service Orientation is Service Loose Coupling (http://serviceorientation.com/serviceorientation/service_loose_coupling); "This principle advocates the creation of a specific type of relationship within and outside of service boundaries, with a constant emphasis on reducing ("loosening") dependencies between the service contract, its implementation, and its service consumers.". On the following blog, a method is described to reduce the dependency between Oracle SOA composite services by placing abstract WSDL's in the MDS; https://blogs.oracle.com/aia/entry/aia_11g_best_practices_for_dec. You can find a clear description of what an abstract WSDL is and how you can create one at; http://sathyam-soa.blogspot.nl/2012/10/abstract-wsdl-vs-concrete-wsdl.html. In the AIA 11g best practice blog post it is mentioned that in the composite.xml file there is a reference to an abstract and a concrete WSDL. The concrete WSDL is referenced in the binding.ws location attribute, which is exactly the attribute which can be replaced with tokens!

An example of a reference to an abstract WSDL is;
http://localhost:8001/soa-infra/services/default/HelloWorld/HelloWorld.wsdl

An example of a reference to a concrete WSDL is;
http://localhost:8001/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL

Implementation

I created a HelloWorld process and a CallHelloWorld process. The CallHelloWorld process is a proxy to the HelloWorld process.

When creating the process, the following composite.xml was generated for the CallHelloWorld process (indicated in bold the references to the HelloWorld process);

<?xml version="1.0" encoding="UTF-8" ?>
<!-- Generated by Oracle SOA Modeler version 11.1.1.7.0 at [4/11/13 12:22 PM]. -->
<composite name="CallHelloWorld"
           revision="1.0"
           label="2013-04-11_12-22-56_153"
           mode="active"
           state="on"
           xmlns="http://xmlns.oracle.com/sca/1.0"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
           xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
           xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <import namespace="http://xmlns.oracle.com/HelloWorld/CallHelloWorld/CallHelloWorld"
          location="CallHelloWorld.wsdl" importType="wsdl"/>
  <import namespace="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld"
          location="
http://localhost:8001/soa-infra/services/default/HelloWorld/HelloWorld.wsdl"
          importType="wsdl"/>

  <service name="callhelloworld_client_ep"
           ui:wsdlLocation="CallHelloWorld.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/CallHelloWorld/CallHelloWorld#wsdl.interface(CallHelloWorld)"/>
    <binding.ws port="http://xmlns.oracle.com/HelloWorld/CallHelloWorld/CallHelloWorld#wsdl.endpoint(callhelloworld_client_ep/CallHelloWorld_pt)"/>
  </service>
  <property name="productVersion" type="xs:string" many="false">11.1.1.7.0</property>
  <component name="CallHelloWorld" version="2.0">
    <implementation.bpel src="CallHelloWorld.bpel"/>
    <property name="bpel.config.transaction" type="xs:string" many="false">required</property>
    <property name="bpel.config.oneWayDeliveryPolicy" type="xs:string"
              many="false">async.persist</property>
  </component>
  <reference name="HelloWorld"
             ui:wsdlLocation="
http://localhost:8001/soa-infra/services/default/HelloWorld/HelloWorld.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.interface(HelloWorld)"/>
    <binding.ws port="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.endpoint(helloworld_client_ep/HelloWorld_pt)"
                location="http://localhost:8001/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL"
                supports="" soapVersion="1.1">

      <property name="weblogic.wsee.wsat.transaction.flowOption"
                type="xs:string" many="false">WSDLDriven</property>
    </binding.ws>
  </reference>
  <wire>
    <source.uri>callhelloworld_client_ep</source.uri>
    <target.uri>CallHelloWorld/callhelloworld_client</target.uri>
  </wire>
  <wire>
    <source.uri>CallHelloWorld/HelloWorld</source.uri>
    <target.uri>HelloWorld</target.uri>
  </wire>
</composite>


This composite.xml refers to a concrete WSDL; http://localhost:8001/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL. It also refers to the abstract WSDL at http://localhost:8001/soa-infra/services/default/HelloWorld/HelloWorld.wsdl.These WSDL's however cannot be accessed if the HelloWorld process has not been deployed. For compilation and loading of the process in the SOA runtime, only the abstract WSDL's are required. Therefore, putting the abstract WSDL in the MDS resolves some dependency issues which are for example observed during server start (since there is no guarantee to the order in which services are started).

Putting the abstract WSDL in the MDS

MDS usage in Oracle SOA Suite 11g could in my opinion be improved. You can deploy to the MDS by using scripts; http://biemond.blogspot.nl/2009/11/soa-suite-11g-mds-deploy-and-removal.html or you can create a ZIP-file and upload it. See http://www.oracle.com/technetwork/articles/soa/fonnegra-storing-sca-metadata-1715004.html for an overview of what Oracle provides to interact with the MDS. When developing from JDeveloper though I recommend using a local file based MDS from a version controlled workarea. There are several arguments in support of this but since it is not the focus of this post, I'll not go into details here. For simplicity, I've created a ZIPfile with the following structure;

/apps/hello/wsdl/HelloWorld.wsdl
/apps/hello/xsd/HelloWorld.xsd

And uploaded it using the MDS Configuration page (Import)


Updating the composite.xml from CallHelloWorld
 
In order to use the files put in the MDS, the composite.xml from the CallHelloWorld process needs to be updated. Indicated in bold are the parts I've changed.

<?xml version="1.0" encoding="UTF-8" ?>
<!-- Generated by Oracle SOA Modeler version 11.1.1.7.0 at [4/11/13 12:22 PM]. -->
<composite name="CallHelloWorld"
           revision="1.0"
           label="2013-04-11_12-22-56_153"
           mode="active"
           state="on"
           xmlns="http://xmlns.oracle.com/sca/1.0"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
           xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
           xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <import namespace="http://xmlns.oracle.com/HelloWorld/CallHelloWorld/CallHelloWorld"
          location="CallHelloWorld.wsdl" importType="wsdl"/>
  <import namespace="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld"
          location="oramds:/apps/hello/wsdl/HelloWorld.wsdl"
          importType="wsdl"/>

  <service name="callhelloworld_client_ep"
           ui:wsdlLocation="CallHelloWorld.wsdl">
    <interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/CallHelloWorld/CallHelloWorld#wsdl.interface(CallHelloWorld)"/>
    <binding.ws port="http://xmlns.oracle.com/HelloWorld/CallHelloWorld/CallHelloWorld#wsdl.endpoint(callhelloworld_client_ep/CallHelloWorld_pt)"/>
  </service>
  <property name="productVersion" type="xs:string" many="false">11.1.1.7.0</property>
  <component name="CallHelloWorld" version="2.0">
    <implementation.bpel src="CallHelloWorld.bpel"/>
    <property name="bpel.config.transaction" type="xs:string" many="false">required</property>
    <property name="bpel.config.oneWayDeliveryPolicy" type="xs:string"
              many="false">async.persist</property>
  </component>
  <reference name="HelloWorld"
             ui:wsdlLocation="oramds:/apps/hello/wsdl/HelloWorld.wsdl">

    <interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.interface(HelloWorld)"/>
    <binding.ws port="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.endpoint(helloworld_client_ep/HelloWorld_pt)"
                location="http://localhost:8001/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL"
                supports="" soapVersion="1.1">
      <property name="weblogic.wsee.wsat.transaction.flowOption"
                type="xs:string" many="false">WSDLDriven</property>
    </binding.ws>
  </reference>
  <wire>
    <source.uri>callhelloworld_client_ep</source.uri>
    <target.uri>CallHelloWorld/callhelloworld_client</target.uri>
  </wire>
  <wire>
    <source.uri>CallHelloWorld/HelloWorld</source.uri>
    <target.uri>HelloWorld</target.uri>
  </wire>
</composite>



Configuring the MDS connection (JDeveloper)

For the compilation of the process, make sure you have a local file based MDS configured; In the Application Resources tab under Applications there is a Connections folder. Here you can create the MDS connection.


Make sure the connection is correctly present in the adf-config.xml of your application. My MDS was in /dev/HelloWorld/mds. My adf-config.xml was as followed (in bold what I needed to add to make the oramds references work correctly);

<?xml version="1.0" encoding="windows-1252" ?>
<adf-config xmlns="http://xmlns.oracle.com/adf/config"
            xmlns:config="http://xmlns.oracle.com/bc4j/configuration"
            xmlns:adf="http://xmlns.oracle.com/adf/config/properties"
            xmlns:sec="http://xmlns.oracle.com/adf/security/config">
  <adf-adfm-config xmlns="http://xmlns.oracle.com/adfm/config">
    <defaults useBindVarsForViewCriteriaLiterals="true"/>
    <startup>
      <amconfig-overrides>
        <config:Database jbo.locking.mode="optimistic"/>
      </amconfig-overrides>
    </startup>
  </adf-adfm-config>
  <adf:adf-properties-child xmlns="http://xmlns.oracle.com/adf/config/properties">
    <adf-property name="adfAppUID" value="HelloWorld.ms.testapp.soa.utils"/>
  </adf:adf-properties-child>
  <sec:adf-security-child xmlns="http://xmlns.oracle.com/adf/security/config">
    <CredentialStoreContext credentialStoreClass="oracle.adf.share.security.providers.jps.CSFCredentialStore"
                            credentialStoreLocation="../../src/META-INF/jps-config.xml"/>
  </sec:adf-security-child>
  <adf-mds-config xmlns="http://xmlns.oracle.com/adf/mds/config">
    <mds-config xmlns="http://xmlns.oracle.com/mds/config">
      <persistence-config>
        <metadata-namespaces>
          <namespace path="/soa/shared" metadata-store-usage="mstore-usage_1"/>
          <namespace path="/apps" metadata-store-usage="mstore-usage_3"/>
        </metadata-namespaces>
        <metadata-store-usages>
          <metadata-store-usage id="mstore-usage_1">
            <metadata-store class-name="oracle.mds.persistence.stores.file.FileMetadataStore">
              <property name="metadata-path"
                        value="${oracle.home}/integration"/>
              <property name="partition-name" value="seed"/>
            </metadata-store>
          </metadata-store-usage>
          <metadata-store-usage id="mstore-usage_3">
                  <metadata-store class-name="oracle.mds.persistence.stores.file.FileMetadataStore">
                     <property value="D:\dev\HelloWorld"
                      name="metadata-path"/>
                     <property value="mds" name="partition-name"/>
                  </metadata-store>
               </metadata-store-usage>

        </metadata-store-usages>
      </persistence-config>
    </mds-config>
  </adf-mds-config>
</adf-config>


Next I undeployed HelloWorld and compiled/deployed CallHelloWorld to confirm they were loosely coupled. I got the following warning; Warning(28,72): Failed to Find Binding "Service1":"{http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld}HelloWorld_pt" in WSDL Manager

This is correct since the binding is still;
    <binding.ws port="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.endpoint(helloworld_client_ep/HelloWorld_pt)"
                location="http://localhost:8001/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL"
                soapVersion="1.1">


I could create the JAR file and deploy it. Even without the HelloWorld process.

Tokens

As you might have noticed, the binding is the only concrete coupling between the endpoint of HelloWorld and the CallHelloWorld. Here tokens come in. We can use a token to specify the endpoint and thus become completely independant of configuration plans for the specification of the endpoint to use!

    <binding.ws port="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.endpoint(helloworld_client_ep/HelloWorld_pt)"
                location="http://localhost:8001/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL"
                soapVersion="1.1">


How to use tokens has been described on http://docs.oracle.com/cd/E28280_01/dev.1111/e10224/sca_bindingcomps.htm#CIHFJFJC. I will not go into detail here. The steps are as followed;

Use from the Composite Editor the Binding URL tokenizer

The binding.ws entry is replaced in my example by;

<binding.ws port="http://xmlns.oracle.com/HelloWorld/HelloWorld/HelloWorld#wsdl.endpoint(helloworld_client_ep/HelloWorld_pt)"
                location="${helloworld_protocol}://${helloworld_host}:${helloworld_port}/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL"
                supports="" soapVersion="1.1">


Update the tokens on the server


On the server, there is now a file mdm-url-resolver.xml present. In my example this file could be found in; /u01/app/Middleware/user_projects/domains/base_domain/config/fmwconfig/mdm-url-resolver.xml. This file is an example token file;

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="helloworld_host">localhost</entry>
<entry key="helloworld_protocol">http</entry>
<entry key="helloworld_port">8001</entry>
</properties>


You can place the token file in the MDS so it is easily available to other developers. I deployed the HelloWorld process and called the CallHelloWorld service with the following result;


After restarting the (Admin)Server, it worked.

Predefined token ${serverURL} 

There is one predefined token; the ${serverURL} token. This token uses the soa-infra server URL as it's value. When I changed my binding.ws location entry to ${serverURL}/soa-infra/services/default/HelloWorld/helloworld_client_ep?WSDL and tested the service, it worked.This means no token configuration on the server is required if you want to call processes on the same server.

You can download the sample code here; https://dl.dropboxusercontent.com/u/6693935/blog/HelloWorldTokens.zip. It does not require server configuration since the serverURL token is used. Keep in mind though that you will need an 11.1.1.7 (PS6) SOA Suite installation for this to work.

Conclusion

Tight coupling between services by using references to WSDL's and/or XSD's which are part of another process, should be avoided. This can be done by putting abstract WSDL's in the MDS.

When the above has been implemented, the loose coupling between processes can be extended by using tokens in the composite.xml file to set the correct binding.ws location attribute. When changing tokens/token values, the server needs to be restarted though. Since only one property can be replaced, it's use is limited to the concrete WSDL used to obtain the binding in the composite.xml file. When calling processes on the same server, the serverURL token can be used which is always available and does not require specific definition of tokens on the server.

With the above in place; loose coupling to WSDL's/services and tokens, one can argue that configuration plans become obsolete. When however variables/properties in the composite.xml are used, you still might need a mechanism to make these values differ per environment and configuration plans provide a (deploy time) solution to that. By using the MBean browser, these properties can be updated on runtime (see http://beatechnologies.wordpress.com/2011/11/04/persisting-component-preferences-in-oracle-soa-suite-11g/). This would not be needed if global variables could be used. I'm however not aware of an out of the box (GUI supported, little coding) implementation for deploytime and runtime global variables in Oracle SOA Suite 11g. Of course a database can be used, Server MBeans or plain old property files, but you have to build your own implementation.

Monday, August 27, 2012

Building BPEL / MDS applications using Jenkins and Ant

This post describes a tryout (not production ready) of a manually triggered Ant build of Oracle SOA applications using Jenkins and custom Ant scripts. I've used and expanded on the scripts mentioned in; http://javaoraclesoa.blogspot.nl/2012/08/standalone-buildtool-for-deployment-of.html

Introduction

'builds' globally consist of several steps (details can differ among different customers)

- selecting what to build. this can be based for example on a tag or status/property of a source in a version control system or a selection of tasks with a specific status (if issue management and version control are linked).
- preparing a workarea / workspace based on the above
- triggering a build (manually or automated by monitoring a version control system)
- archiving the build ('releasing')

This post will have a limited scope since putting the above into place is customer specific and requires some time (a project) to achieve a production ready setup. I will manually trigger a build for a prepared workarea. This can of course be expanded. I've chosen to call Ant from Jenkins. The following post describes how Maven can be used to wrap Ant; http://redstack.wordpress.com/2011/03/15/getting-started-with-continuous-integration-for-soa-projects/. Ant wraps Java classes to achieve deployment. Jenkins has plug-ins to directly call Ant tasks and has easy integration in the GUI (Ant output parsing). I do not see the added benefit of wrapping Ant in Maven.

I've installed Jenkins as described on; https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu

I've chosen for Jenkins instead of Hudson based on http://stackoverflow.com/questions/4973981/how-to-choose-between-hudson-and-jenkins.

The Buildserver installed is an Ubuntu 12.04 server 64 bit installation.
 
Implementation

I've adapted the scripts used in my previous buildtool post slightly for this purpose. I've used a JDeveloper installation instead of 'manually' copying JAR files. This has the benefit that JDeveloper can easily be upgraded and plugins can more easily be installed using the GUI. This provides a more steady and flexible base for the buildtool then manually copying JAR files.

MDS and adf-config.xml

Also for the purpose of MDS dependencies I've expanded the build.xml file to write an application specific adf-config.xml and copy it to the relevant application directory. The adf-config is copied to the application directory and it contains placeholders; MDS_REPOSITORY and MDS_APPLICATION. These are replaced in the build.xml using;

Copy to application

                <mkdir dir="${proj.compositeDir}/${proj.compositeName}/SCA-INF/classes/META-INF"/>
                <copy file="${base.dir}/adf-config.xml" tofile="${proj.compositeDir}/${proj.compositeName}/SCA-INF/classes/META-INF/adf-config.xml"/>
    
Replace placeholders
               
                <replace file="${proj.compositeDir}/${proj.compositeName}/SCA-INF/classes/META-INF/adf-config.xml" token="MDS_REPOSITORY" value="${mds.repository}"/>
                <replace file="${proj.compositeDir}/${proj.compositeName}/SCA-INF/classes/META-INF/adf-config.xml" token="MDS_APPLICATION" value="${mds.application}"/>

Buildtool setup

I've installed JDeveloper in /home/oracle/Middleware11116. I've used the standard installer. I did however encounter the following problem when I tried to call the 32 bit JDeveloper installer on a 64 bit OS; http://stackoverflow.com/questions/2716702/no-such-file-or-directory-error-when-executing-a-binary

I've created a buildtool directory /home/oracle/Middleware11116buildtool. In this directory I've created a symlink Middleware to /home/oracle/Middleware11116. The directory structure is as followed;

-rw-rw-r--  1 oracle oracle  1911 Aug 21 09:40 adf-config.xml
drwxrwxr-x  3 oracle oracle  4096 Aug 23 16:40 build-area
-rw-rw-r--  1 oracle oracle    83 Aug 25 13:06 build.num
-rw-rw-r--  1 oracle oracle   925 Aug 25 12:59 build.properties
drwxrwxr-x 16 oracle oracle  4096 Aug 25 13:06 builds
-rw-rw-r--  1 oracle oracle 21961 Aug 25 10:54 build.xml
-rwxrwxr-x  1 oracle oracle   449 Aug 23 13:32 deployAll
-rw-rw-r--  1 oracle oracle   407 Aug 14 09:05 deployAll.bat
-rw-rw-r--  1 oracle oracle   261 Aug  5 18:07 dev.jndi.properties
drwxrwxr-x  2 oracle oracle  4096 Aug 23 13:33 junit
drwxrwxr-x  2 oracle oracle  4096 Aug 23 13:16 lib
drwxrwxr-x  2 oracle oracle  4096 Aug 25 13:06 logs
lrwxrwxrwx  1 oracle oracle    28 Aug 23 13:19 Middleware -> /home/oracle/Middleware11116

You can download the scripts here; http://dl.dropbox.com/u/6693935/blog/buildtoolscriptsincmds.zip

Jenkins setup

After the Jenkins installation I've added the Jenkins user to the oracle group (/etc/group) in order to access the buildtool, Ant, JDK, etc. After having started Jenkins, first I've configured the JDK and Ant;

I've set these to the JDeveloper JDK and Ant

Then I've created a multiconfiguration project


I've done this in order to be able to allow different configurations to be deployed at a later stage. I've not tried this yet though.


Then I've selected the JDK ant Ant version to be used. Important here is;

- specify the base dir in which Ant is executed; base.dir=/home/oracle/Middleware11116buildtool. this makes sure Ant can find the required scripts and of course the build.properties!
- specify the build.xml file; /home/oracle/Middleware11116buildtool/build.xml.

Running

After the task is configured, it can be run. This results in the below
The different Ant tasks which are executed can be navigated to by clicking at the left side of the Console output on the specific task. Also the result is analyzed; in this case of course BUILD SUCCESFUL.

Sunday, August 5, 2012

Standalone Buildtool for deployment of Oracle SOA Suite 11.1.1.6 composites

Introduction

SOA Suite 11g allows deployment to environments from JDeveloper. The people installing software often don't have JDeveloper available or configured correctly. Often there is the requirement to provide a standalone package for installation which can be executed without too much configuration by someone with relatively little knowledge about what he/she is installing.

There have already been numerous posts about build automation for Oracle SOA 11g applications, such as the excellent post from Edwin Biemond; http://biemond.blogspot.nl/2009/09/deploy-soa-suite-11g-composite.html and http://redstack.wordpress.com/2011/03/15/getting-started-with-continuous-integration-for-soa-projects/

In this post I've created a standalone Buildtool for SOA Suite 11.1.1.6. This Buildtool allows compilation and deployment of various SOA artifacts. It is heavily based on http://biemond.blogspot.nl/2009/09/deploy-soa-suite-11g-composite.html however provides some added value such as;

- it's fully based on 11.1.1.6 libraries
- can be used standalone without the need to install JDeveloper or Weblogic Server
- allows applications to be packaged/configured separately and independently
- provides a script to recreate most of the Buildtool from scratch (hopefully making upgrades to the buildtool more easy)
- this buildtool compiles and installs composites. compilation is thus not dependent on the client providing a jar file; the sources can be used as source for the build.

Implementation

Install JDeveloper

Download and install JDeveloper 11.1.1.6. Install the following plugins from http://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/156082.xml

-          Oracle BPM Studio 11g
-          Oracle SOA Composite Editor

This will be used as the start-point for the Buildtool.

Copy sources

The below DOS batch script copies the required libraries to the TARGETDIR (build tool base directory). The SOURCEDIR is a locally installed JDeveloper 11.1.1.6.

set SOURCEDIR=D:\dev\Middleware11116
set TARGETDIR=D:\dev\buildtool11116


rem buildtool generator 11.1.1.6
rem Maarten Smeets, 2012-08-05


mkdir %TARGETDIR%\logs
mkdir %TARGETDIR%\junit
mkdir %TARGETDIR%\builds

rem wlserver_10.3/server/lib
mkdir %TARGETDIR%\Middleware\wlserver_10.3\server\lib
xcopy /i %SOURCEDIR%\wlserver_10.3\server\lib\*.jar %TARGETDIR%\Middleware\wlserver_10.3\server\lib


rem jdeveloper\ant
mkdir %TARGETDIR%\Middleware\jdeveloper\ant
xcopy /s %SOURCEDIR%\jdeveloper\ant %TARGETDIR%\Middleware\jdeveloper\ant


rem jdeveloper\bin
mkdir %TARGETDIR%\Middleware\jdeveloper\bin
xcopy /s %SOURCEDIR%\jdeveloper\bin %TARGETDIR%\Middleware\jdeveloper\bin


rem jdeveloper\soa\modules
mkdir %TARGETDIR%\Middleware\jdeveloper\soa\modules
xcopy /s %SOURCEDIR%\jdeveloper\soa\modules %TARGETDIR%\Middleware\jdeveloper\soa\modules


rem jdeveloper\uddi
mkdir %TARGETDIR%\Middleware\jdeveloper\uddi
xcopy /s %SOURCEDIR%\jdeveloper\uddi %TARGETDIR%\Middleware\jdeveloper\uddi


rem jdk160_24
rem 11.1.1.4: jdk160_21
mkdir %TARGETDIR%\Middleware\jdk160_24
xcopy /s %SOURCEDIR%\jdk160_24 %TARGETDIR%\Middleware\jdk160_24


rem ant-contrib.jar
mkdir %TARGETDIR%\lib
xcopy %SOURCEDIR%\modules\net.sf.antcontrib_1.1.0.0_1-0b2\lib\* %TARGETDIR%\lib


rem oracle_common\webservices
mkdir %TARGETDIR%\Middleware\oracle_common\webservices
xcopy /s %SOURCEDIR%\oracle_common\webservices %TARGETDIR%\Middleware\oracle_common\webservices


rem oracle_common/modules
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.adf.model_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.adf.share.ca_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.adf.share_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.bali.share_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.dms_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.fabriccommon_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.javacache_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.jmx_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.jps_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.jrf_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.mds_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.nlsrtl_11.1.0
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.odl_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.webservices_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.wsm.common_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.xdk_11.1.0
mkdir %TARGETDIR%\Middleware\oracle_common\modules\oracle.xmlef_11.1.1
mkdir %TARGETDIR%\Middleware\oracle_common\modules\datadirect_4.1


xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.adf.model_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.adf.model_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.adf.share.ca_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.adf.share.ca_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.adf.share_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.adf.share_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.bali.share_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.bali.share_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.dms_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.dms_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.fabriccommon_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.fabriccommon_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.javacache_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.javacache_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.jmx_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.jmx_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.jps_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.jps_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.jrf_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.jrf_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.mds_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.mds_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.nlsrtl_11.1.0 %TARGETDIR%\Middleware\oracle_common\modules\oracle.nlsrtl_11.1.0
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.odl_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.odl_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.webservices_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.webservices_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.wsm.common_11.1.1 %TARGETDIR%\Middleware\oracle_common\modules\oracle.wsm.common_11.1.1
xcopy /s %SOURCEDIR%\oracle_common\modules\oracle.xdk_11.1.0 %TARGETDIR%\Middleware\oracle_common\modules\oracle.xdk_11.1.0
xcopy /s %SOURCEDIR%\oracle_common\modules\datadirect_4.1 %TARGETDIR%\Middleware\oracle_common\modules\datadirect_4.1


xcopy /i %SOURCEDIR%\oracle_common\modules\oracle.ucp_11.1.0.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\org.apache.commons.beanutils_1.6.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\org.apache.commons.digester_1.8.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\org.apache.commons.logging_1.0.4.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\org.springframework_2.5.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\oracle.classloader_11.1.1.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\oracle.http_client_11.1.1.jar %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\oracle.logging-utils_11.1.1.jar  %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\commonj.sdo_2.1.0.jar  %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\com.bea.core.xml.xmlbeans_2.1.0.0_2-5-1.jar  %TARGETDIR%\Middleware\oracle_common\modules
xcopy /i %SOURCEDIR%\oracle_common\modules\com.bea.core.weblogic.security.identity_1.1.2.1.jar  %TARGETDIR%\Middleware\oracle_common\modules

rem modules


mkdir %TARGETDIR%\Middleware\modules


xcopy /i %SOURCEDIR%\modules\com.bea.core.apache.commons.collections_3.2.0.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\com.bea.core.apache.commons.lang_2.1.0.jar %TARGETDIR%\Middleware\modules
rem 11.1.1.4
rem xcopy /i %SOURCEDIR%\modules\com.bea.core.weblogic.workmanager_1.9.0.0.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\com.bea.core.weblogic.workmanager_1.10.0.0.jar %TARGETDIR%\Middleware\modules
rem 11.1.1.4
rem xcopy /i %SOURCEDIR%\modules\com.bea.core.xml.beaxmlbeans_2.2.0.0_2-5-1.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\com.bea.core.xml.beaxmlbeans_2.3.0.0_2-5-1.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\commonj.sdo_1.0.0.0_1-0.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\glassfish.jaxb_1.0.0.0_2-1-12.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\javax.management.j2ee_1.0.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\javax.xml.rpc_1.2.1.jar %TARGETDIR%\Middleware\modules
rem 11.1.1.4
rem xcopy /i %SOURCEDIR%\modules\org.eclipse.persistence_1.0.0.0_2-1.jar %TARGETDIR%\Middleware\modules
xcopy /i %SOURCEDIR%\modules\org.eclipse.persistence_1.1.0.0_2-1.jar %TARGETDIR%\Middleware\modules

Some script files were taken from https://github.com/biemond/soa_tools/tree/master/ant and updated. The updated scriptfiles can be downloaded here; https://dl.dropbox.com/u/6693935/blog/buildtool11116scriptfiles.zip

Usage

In my case, the buildtool base dir is; D:\dev\buildtool11116. Here you can create a directory build-area (as specified in the build.properties file). In this directory you can create a structure like for example; https://dl.dropbox.com/u/6693935/blog/build-area.zip

The structure contains an example project, a deployment profile and configuration files. This is what the developer has to provide. The person installing the software has to update the following files;
- update deployAll.bat to reflect the correct locations (once)
- update build.properties to reflect the environment which is used (it is recommended the installer keeps per environment a separate build.properties file)

When deployAll.bat is executed, log files are generated in the logs directory and the deployed applications are put in the builds directory.

The build.xml is capable of calling unit tests, but since I got the following error which I couldn't fix quickly enough;

  [scatest] java.lang.NoClassDefFoundError: weblogic/security/subject/AbstractSubject

and

D:\dev\buildtool11116\Middleware\jdeveloper\bin\ant-sca-test.xml:111: Problem executing test cases
weblogic/security/subject/AbstractSubject

I've decided to put this functionality in comments and maybe look at it later. wlclient.jar contains this class and it should be in the classpath.

The example build-area provides a simple deployment of a SCA composite. The supplied build.xml provides functionality for MDS deployments and partitions (Edwin Biemond has described this functionality on his blog site). Some minor changes to the script might be needed to make sure deployment of the MDS is from the build-area folder so developers can more easily provide the required files. You can download the entire 11.1.1.6 buildtool here; https://dl.dropbox.com/u/6693935/blog/buildtool11116.zip.

Thursday, February 23, 2012

Using the MDS

One of the nice new features of Oracle SOA Suite 11g is the MDS (Metadata Services). The MDS is a unified store for metadata. When for example a BPEL process is deployed, it's put in the MDS. This store can also be used among other things to share common artifacts such as XSD's, EDL (Event Definition Language) and WSDL files. The MDS provides a more secure, better maintainable alternative to putting these artifacts on (for example) a webserver. JDeveloper also supports browsing the MDS directly and the MDS can be imported and exported from the Enterprise Manager. 





Updating the MDS however on a per application basis, can not be done directly from JDeveloper without some additional scripts.

Because Ant scripts to make working with the MDS easier, are already available, I will not repeat those sources and just point out what I needed to do to make those examples work with my installation of  JDeveloper 11.1.1.5. Edwin Biemond has provided a base script on http://biemond.blogspot.com/2009/11/soa-suite-11g-mds-deploy-and-removal.html. A tutorial describing an implementation of scripts similar to the base example, can be found on; http://technology.amis.nl/blog/15295/using-the-metadata-services-in-a-soa-environment-part-1

To make the script from the tutorial work from JDeveloper I had to do two things;
- download ant-contrib-1.0b3.jar from http://sourceforge.net/projects/ant-contrib/files/
- create a libs directory and add the folowing lines to the build.xml file;

<taskdef resource="net/sf/antcontrib/antcontrib.properties">
  <classpath>
   <pathelement location="../libs/ant-contrib-1.0b3.jar" />
   </classpath>
</taskdef>

For reference you can download my test project. I've removed the servername, user, password in the env.dev.properties. http://dl.dropbox.com/u/6693935/mds-store.zip