Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Attribute

Required?

Description

Default Value

name

Y

The unique name of the service.

 

engine

Y

The name of the engine (defined in serviceengine.xml).

 

location

N

The location or package of the service's class.

 

invoke

N

The method name of the service.

 

auth

N

Does this service require authorization? (true/false)

true

debug

N

Enable verbose debugging when calling this service?

true

default-entity-name

N

The default Entity to use for auto-attributes

 

export

N

Is this service allowed to be accessed via SOAP/HTTP/JMS? (true/false)

false

max-retry

N

Sets the max number of times this service will retry when failed (persisted async only)

-1 (unlimited)

require-new-transaction

N

Require a new transaction for this service

true

semaphore

N

Defines how concurrent calls to this service should be handled:
none: multiple calls to this service may run concurrently
wait: while this service is running, queue any subsequent calls
fail: while this service is running, fail any subsequent calls

none

semaphore-wait-seconds

N

When semaphore="wait" how many seconds to wait before failing the service call

300

sempahore-sleep

N

When semaphore="wait" how often (in milliseconds) to check if the waiting service call can be run

500

transaction-timeout

N

Override the default transaction timeout, only works if we start the transaction

0 (Use system default)

use-transaction

N

Create a transaction for this service (if one is not already in place)

true

validate

N

Do we validate the attributes found below for name and type matching? (true/false)

true

...

Internal Usage of the Services Framework is quite simple. In a Web Application the LocalDispatcher is stored in the ServletContext which can be accessed via the Session object in an Event. For non-web based applications you simply create a GenericDispatcher: GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
LocalDispatcher dispatcher = new GenericDispatcher("UniqueName",delegator);
Now we have a dispatcher which we can use to invoke services. To invoke the test service create a Map for the context which contains the IN parameter message *then invoke the service:*

Code Block
Map context = UtilMisc.toMap("message","This is a test.");
Map result = null;

try {
    result = dispatcher.runSync("testScv", context);
} catch (GenericServiceException e) {
    e.printStackTrace();
}

if (result != null) {
    System.out.println("Result from service: " + (String) result.get("resp"));
}

Now look at the console and see what the test service has echoed.
The test service is located in core/docs/examples/ServiceTest.java You must compile this and place it in the classpath.

To schedule a service to run at a later time or to repeat use this:

Code Block
// This example will schedule a job to run now.
Map context = UtilMisc.toMap("message","This is a test.");
try {
    long startTime = (new Date()).getTime();
    dispatcher.schedule("testScv", context, startTime);
} catch (GenericServiceException e) {     e.printStackTrace();



// This example will schedule a service to run now and repeat once every 5 seconds a total of 10 times.
Map context = UtilMisc.toMap("message","This is a test.");
try {
    long startTime = (new Date()).getTime();
    int frequency = RecurrenceRule.SECONDLY;
    int interval = 5;
    int count = 10;
    dispatcher.schedule("testScv", context, startTime, frequency, interval, count);
} catch (GenericServiceException e) {
    e.printStackTrace();
}

...

The interface service engine has been implemented to help with defining services which share a number of the same parameters. An interface service cannot be invoked, but rather is a defined service which other services inherit from. Each interface service will be defined using the interface engine, for example:

Code Block

<service name="testInterface" engine="interface" location="" invoke="">

...


    <description>A test interface service</description>

...


    <attribute name="partyId" type="String" mode="IN"/>

...


    <attribute name="partyTypeId" type="String" mode="IN"/>

...


    <attribute name="userLoginId" type="org.ofbiz.entity.GenericValue" mode="OUT" optional="true"/>

...


</service>

**Note that the location and the invokefields are required in the DTD, so we simply leave these as empty strings when used as an interface.

Now that we have an interface we need to define a service which implements this interface<service interface

Code Block

<service name="testExample1" engine="simple"

...

 location="org/ofbiz/commonapp/common/SomeTestFile.xml" invoke="testExample1">

...


    <description>A test service which implements testInterface</description>

...


    <implements service="testInterface"/>

...


</service>

The testExample1 service will have the exact same required and optional attributes as thetestInterface service. Any service which implements testInterfacewill also inherit the parameters/attributes. If needed, additional attributes can be added to a specific service by including the attribute tag along with the implementstag. You may also override an attribute by re-defining it after the implements tag.

...

ECA (Event Condition Action) is much like a trigger. When a service is called, a lookup is performed to see if any ECAs are defined for this event. Events include before authentication, before IN parameter validation, before actual service invocation, before OUT parameter validation, before transaction commit, or before the service returns. Next each conditionin the ECA definition is evaluated and if all come back as true, each actionis performed. An action is just a service which must be defined to work with the parameters already in the service's context. There are no limit to the number of conditions or actions each ECA may define.

Code Block

<service-eca>

...


    <eca service="testScv" event="commit">

...


        <condition field-name="message" operator="equals" value="12345"

...

/>
        <action service="testBsh" mode="sync"/>

...


    </eca>

...


</service-eca>

eca tag:

Attribute Name

Required?

Description

service

Y

The name of the service this ECA is attached to.

event

Y

The event on which this ECA will run can be (before): auth, in-validate, out-validate, invoke, commit, or return.

run-on-error

N

Should this ECA run if there is an error in the service (default false)

...

The group definition is very simple, it contains a group elements along with 1 or more service elements. The group element contains a name attribute and a modeattribute used to define how the group will function. The service element is much like the actionelement in an ECA, the difference being the default value for result-to-context.

Code Block

<service-group>

...


    <group name="testGroup" send-mode="all">

...


        <invoke name="testScv" mode="sync"/>

...


        <invoke name="testBsh" mode="sync"/>

...


    </group>

...


</service-group>

group tag

Attribute Name

Required?

Description

name

Y

The name of the service this action will invoke.

send-mode

N

The mode in which the service(s) should be invoked. The options are: none, all, first-available, random, or round-robin. The default is all.

service invoke tag

Attribute Name

Required?

Description

service name

N

The name of the service this action will invoke.

mode

Y

The mode in which this service should be invoked. Can be sync or async. Note that async actions will not update the context even when set to true.

result-to-context

N

Should the results of the action service update the main service's context. Default false.

...