Skip to main content

Getting Started

net.democritus:data-operations-bundle::1.0.0

The easiest way to get started is to add the addon-stack to your application:

<expansionResources>
<expansionResource name="net.democritus:data-operations-bundle" version="1.0.0"/>
</expansionResources>

This will include all the necessary dependencies depending on your setup. It currently supports integration with the following beams:

  • minimal-jee-beam: base of the application. Note: backend only, no struts and knockout support.
  • standard-api-beam: control layer integration for standard-api.
  • service-api-beam: control layer integration for jaxrs-service-api (rest-expanders).
  • angular-beam: view layer integration for angular.
  • process-automation-beam: workflow integration (triggers and events) for process-automation.

Model

After adding the addon-stack you will be able to edit the model through the MicroRadiant. Make sure the data-operations-mr-plugin is installed.

The majority of the model is an extension of DataElement except for the Angular View integration which has its own model to represent Actions and Forms.

A DataOperation essentially models functionality of a DataElement using a type and a parameter object. For the type you can think of a CreateOperation or BatchDeleteOperation. See the Type Reference for all available types. You may even define your own types!

Each DataOperation contains at least one ParameterGroup without name called the root. This group describes the parameter object or input of the operation. The extra layer of ParameterGroup may look redundant at first, but serves a purpose when defining nested structures.

A DataOperation may additionally define a returnType (ValueType) and errorCodes. The return type may provide some extra info when the operation is successful, for example a count on a BatchDeleteOperation. Some error codes are provided by default and additional codes can be defined in the application. See error handling for more info.

Naming Convention

All elements of a dataOperation should use camelCase naming. This means both a dataOperation and any parameters or groups have a camelCase name. The dataOperation itself is suffixed by the DataElement name. For example with an operation named register on DataElement City, the working name will be registerCity. The root group will always inherit the name of the dataOpeartion it is defined on. Any additional groups require a name which will be added as a suffix. For example registerCityAddress for a group named address on the dataOperation above.

Code Structure

One of the goals is to provide a strong interface and avoid coupling. This means there are very few places you have to look for customizations, which will be listed here.

  • «DataOperation»Performer (logic/common): main implementation of a DataOperation. Any required services will be injected through class fields. It will also handle any exceptions defined for error codes.
  • «DataOperation»Mapper (logic/common): mapper from parameter object to element details. Not available for all operations.
  • «DataOperation»Validator (logic/common): data validations of a DataOperation.
  • «ParameterGroup»SharedValidator (shared/common): datatype validations of a ParameterGroup.
  • «DataElement»QueryOperations (data/ejb3): query definitions for QueryOperations.

The entrypoint for all operations is «DataElement»OperationsBean, which makes it a useful place to visit to see what is happening. All operations are also exposed through the «DataElement»Agent to make them easy to access. This does impose some limitations on which names can be chosen, which is also enforced by a model-validation.

Another difference with previous implementations is that you will get a dedicated «DataOperation»Result class for each DataOperation. These follow a predefined interface and can be extended to provide type-specific additions. For example the CreateOperation adds a DataRef value accessible through .getCreatedReference(). All available error-codes can be handled separately if needed through the .hasError(ErrorCode) api. For validations a ValidationReport can be added and retrieved using .getValidationReport().

// interface of a DataOperation called 'publish' on DataElement 'Article'.
PublishArticleResult publish(ParameterContext<PublishArticle> parameterContext);
// Manual error handling of data-operations (not needed in expanded contexts)
PublishArticleResult result = agent.publish(context.withParameter(paramegers));
if (result.hasValidationErrors()) {
ValidationReport validationReport = result.getValidationReport();
// Do something with the validation errors
} else if (result.hasError(MY_SPECIFIC_ERROR)) {
// Check very specific error
} else if (result.isError()) {
ErrorDescription description = result.getError(); // General error
} else {
return result.getCreatedReference(); // specific value accessor.
}

Layers

DataOperations are "off" by default, which means they only span the minimal number of layers unless explicitly exposed further. The default scope depends on the DataOperation type, but most operations only need the Logic and Shared layers. An exception to this is the QueryOperation which also needs access to the Data layer.

To expose an operation through additional layers, specific options need to be used. These options are cascading meaning you can apply them to DataElement, Component or Application as well.

Option
control.operation.stdapi DataOperationDataElementComponentApplicationCascading

Enable JAX-RS Service API CONTROL layer on a DataOperation.

<options>
<control.operation.stdapi/>
</options>
Option
control.operation.restapi DataOperationDataElementComponentApplicationCascading

Enable JAX-RS Service API CONTROL layer on a DataOperation.

<options>
<control.operation.restapi/>
</options>
Option
operation.exposeProxy DataOperationDataElementComponentApplicationCascading

Enable PROXY layer on a DataOperation. Enables proxy-expander integration as well.

<options>
<operation.exposeProxy/>
</options>