This document describes the steps needed to upgrade the edoras one application to 2.0.0.
Please stop the edoras one server, perform all upgrade steps described below and then restart the server again at the end.
General migration
Always create a database backup before upgrading. |
In addition to the specific changes described in these upgrade notes, the 2.0 release contains major changes to the internals of the edoras one application.
On the server side, this means that any classes that have been overwritten are likely to have undergone significant updates or may have been removed completely. All overwritten classes should be reviewed to see whether the changes are still required in the new codebase or if they need to be adjusted / re-implemented.
If you run edoras one in a cluster, then please clear all Redis caches and user sessions after you complete this upgrade and before you deploy it to production. |
Upgrades
Java 8
Please compile and run using Java 8.
Spring 4.3.7
Spring integration package
As Spring Integration 4.3.8
moved the import org.springframework.integration.Message
class (and related classes)
into the org.springframework.messaging
package, you need to adapt the imports on your classes if you extend/implement one
of the following classes/interfaces:
-
com.edorasware.cloud.core.transfer.IncomingAppService
-
com.edorasware.cloud.core.transfer.internal.AbstractOutgoingAppChannelAdapter
-
com.edorasware.cloud.core.transfer.integration.FileToResourceTransformer
Spring security
We now use the built-in CSRF support from the Spring framework. The following list shows what we changed
in the product and what you also need to change if you have adapted/overwritten any .html
or .jsp
file
or have a custom security configuration.
The following endpoints changed in Spring security:
-
/j_spring_security_logout
changed to/logout
-
/j_spring_security_check
changed to/login
-
j_spring_security_switch_user?j_username=
changed tologin/impersonate?username=
-
j_spring_security_exit_user
changed tologout/impersonate
The parameters for the username and password also changed:
-
j_username
is nowusername
-
j_password
is nowpassword
Please search for all occurences of the affected values and replace them with the new values.
Flowable 6.1.2
Redeploy all Apps
You should redeploy all Apps in all tenants after the system has been migrated. The redeploy ensures that all process definitions are redeployed with the Flowable 6 deployer and newly created process instances will be executed by the Flowable 6 engine.
Process termination
With the process engine upgrade, new features are available. One of them is the ability to extend the terminate end event.
Previously, the default behaviour was equivalent to the terminateAll
flag being set to true.
This flag specifies whether all executions are terminated or not.
If you use terminate end event functionality, consider migrating currently running process instances to a new process
definition with the terminateAll
flag set correctly for your use case using a custom sql script.
Supporting Flowable 5 process execution
Check whether there are currently running Flowable 5 process instances by running the following query before migration:
SELECT Count(exe.id_) FROM act_ru_execution;
If there are no running process instances then no action is required, otherwise you should activate the Flowable 5 compatibility until all Flowable 5 executions have been completed. This can be done by setting the following configuration property:
backwardcompatibility.enable-flowable5-compatibility=true
After the migration has been completed you can check for remaining Flowable 5 executions by running the following query:
SELECT Count(exe.id_)
FROM act_ru_execution as exe, act_re_procdef as def
WHERE def.engine_version_='v5' AND exe.proc_def_id_ = def.id_;
When no Flowable 5 executions are left then the backwards compatibility setting can be removed again.
Dependencies
The following sections describe the migrations needed to upgrade to the latest versions of the dependencies.
- IMPORTANT
-
If you fixed some versions of the upgraded dependencies (Spring and other 3rd party libraries) in your Gradle/Maven build, then please remove these such that the new libraries are used and not the ones you fixed. Please update your list accordingly.
Upgraded Spring libraries
We have upgraded our Spring dependencies to the following versions:
Dependency | Version |
---|---|
Spring Core |
|
Spring Security |
|
Spring Integration |
|
Spring Batch |
|
Spring Data Redis |
|
Spring Session Data Redis |
|
These changes apply to the product and may affect multiple Spring libraries, but if you use other parts of the Spring framework please visit the Spring migration page and check what needs to be changed to use this Spring version.
Upgraded third-party libraries
In the following tables you see the dependencies which we upgraded in the 2.0.0 release:
Dependency | Version |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dependency | Version |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
We have also upgraded the Jackson libraries to version 2.8.8
. Please adapt your code and customizations to the
new library and follow the Jackson upgrade notes. Be aware that the package names changed from
org.codehaus.jackson
to com.fasterxml.jackson
.
Dependency | Version |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Frontend dependencies
The edoras-one-client
dependency should be replaced by the new edoras-frontend
dependency. If an add-on
has a transitive dependency on edoras-one-client
from an older edoras one release then this dependency should
be excluded.
The edoras one frontend is now using the following library versions:
Dependency |
Version |
|
|
|
|
Test dependencies
Only one test dependency is now required: edoras-test
. Other test dependencies from particular modules
can be removed, as they will be included automatically.
Deprecations and removals
GenericWorkObjectService
The new WorkObjectService
API provides the same functionality as the GenericWorkObjectService
and so the latter
has been removed.
Beats and Audit interfaces
In this release we removed the beats from the edoras gear module. In addition we also removed the audit interfaces which were needed for the beats implementation. Due to the fact that it was not a fully complete feature and not public API either, there are no migrations to do.
Transaction proxies
In this release we removed the deprecated transaction proxies. As of now, you need to properly handle the transactions when you use the edoras one services. See release notes of 1.5.0.S106 for further information.
Default hierarchy value support
In version 1.5.0.S120
we introduced the hierarchy-values
profile which enabled default loading of parent
variables/properties on work objects/work object definitions. This has now been removed during the refactorings
in the new work object API. You are still able to retrieve the parent variables with the
Query.Hint.INCLUDE_PARENT_VARIABLES
hint and the parent properties with the
WorkObjectDefinitionQuery.Hint.INCLUDE_PARENT_PROPERTIES
hint.
Therefore the Query.Hint.OMIT_PARENT_VARIABLES
and Query.Hint.OMIT_PARENT_VARIABLES
hints have been removed and you
can just remove these usages in your code, as to omit the hierarchy values is now the default.
Registry and Service interfaces
The idea behind the com.edorasware.commons.core.registry.Registry
was to be able to retrieve a specified collection
of beans which implemented the com.edorasware.commons.core.util.service.Service
interface.
The Registry
class has now been removed as it can be replaced by just using one of the the
org.springframework.context.ApplicationContext#getBean(…)
methods of Springs ApplicationContext
where you can
get all beans without any restrictions. This also changes the following two events where you are not able to retrieve
the Registry
anymore:
-
com.edorasware.commons.core.any.support.AnyWorkObjectDefinitionActionEvent
-
com.edorasware.commons.core.any.support.AnyWorkObjectActionEvent
To adapt to this change, you need to define the listener as a bean and inject the ApplicationContext
by
implementing the org.springframework.context.ApplicationContextAware
interface and then retrieve the bean you need
via the ApplicationContext
as mentioned above.
If you used the Service
interface and had logic inside the com.edorasware.commons.core.util.service.Service#init()
method, then please implement the org.springframework.beans.factory.InitializingBean
interface and use
the afterPropertiesSet()
method for that purpose.
Removal of the JUL logging bridge
As Flowable now uses SLF4J consistently, the com.edorasware.commons.core.util.logging.JulToSlf4jBridgeHandlerInstaller
class has now been removed. Please remove this bean from your Spring configuration.
Java API
Data type support
The supported work object variable types have been restricted in both the legacy edoras gear work object API and the new public API. The reduced variable types ensure that the values written to a work object are preserved throughout the work object lifecycle. In previous edoras one versions, some types would not be correctly preserved if the work object was edited in the user interface.
The following types are now supported:
-
Boolean
-
String
-
Long
-
Double
-
Date
-
Map
-
List
-
null
The following types were previously supported and now have different behaviour:
Type |
New behaviour |
|
Existing Character values are migrated to String. New Character values can still be written but will be persisted and read as Strings. |
|
Existing Byte values are migrated to Long. New Byte values can still be written but will be persisted and read as Longs. |
|
Existing Short values are migrated to Long. New Short values can still be written but will be persisted and read as Longs. |
|
Existing Integer values are migrated to Long. New Integer values can still be written but will be persisted and read as Longs. |
|
Existing Float values are migrated to Double. New Float values can still be written but will be persisted and read as Doubles. |
|
Existing Set values are migrated to List. New Set values cannot be written. |
|
Existing Expression values are migrated to plain String values. The |
|
Existing XmlString values are migrated to plain String values. The |
|
Existing JsonString values are migrated to plain String values. The |
|
Existing Serializable values will result in an exception if they are read. If you have Serializable variables in your installation then you will either have to delete them or migrate them to one of the supported types outside of edoras one. |
|
Existing Id values are migrated to the underlying String value. New Id values can still be written but only the underlying String value will be persisted and read. |
Note that the field accessors are not affected by this change, so field accessors return the same types as before.
If you want to access variable values using the original types, this can be achieved by using a VariableName
definition with a suitable value conversion from the persisted to the required type.
Note that the type-specific query variable operands for the deleted types have also been removed
(e.g. VARIABLE.intValue().lessThan(42)
). These operand references should be replaced by the corresponding
supported type operand as shown in the table above.
Work object and work object definition types
The constants for all work object types used in the edoras one product have been moved to the WorkObjectTypes
class in the public API. The work object definition types have also been moved to the WorkObjectDefinitionTypes
class so the same pattern is used in both cases, even though definition handling is not yet part of the
public API.
Date and time values
The complete server code has been migrated to use the new Java time classes, making date handling much easier. In most
cases this means that java.util.Date
references are replaced by java.time.Instant
. In particular, the 'raw' work object
timestamp values (e.g. as returned by workObject.getValues()
) are now java.time.Instant
values.
The various time and date parsing and formatting utility methods have now been renamed and unified in the
com.edorasware.api.time.TimeUtils
class. Similar functionality elsewhere (e.g. in the OneUtils
class)
has been removed.
Conversion to / from the new time classes for interaction with libraries that still use the java.util
date
representations is straightforward and documented in the standard Java documentation.
Date expressions
The following date expressions now either accept Instant
values or return Instant
values.
-
now()
-
formatDate(date, pattern)
-
formatDateNullSafe(date, pattern)
In most cases no changes will be required, but where the date values are passed into or read from a custom expression
bean then this bean must also be adapted to use Instant
. Any expressions that invoke specific methods from the
java.util.Date
class are no longer supported.
Optional values
All Optional
references in the edoras one core now use the Java 8 implementation (java.util.Optional
) instead
of the Google Guava implementation (com.google.common.base.Optional
).
Optional return values in WorkObjectService
WorkObjectService
find()
methods that would previously return null if no return value is found now return an
Optional
value. In the case of findWorkObject()
methods there are also equivalent getWorkObject()
methods that either return a correct value or throw an exception. The getWorkObject()
alternatives can be used
when the work object is expected to be present, and a missing work object would be an error.
Work object API
Building work objects
Building a new WorkObject
instance can now be done directly using static methods on the WorkObject interface:
WorkObject workObject = WorkObject.builder().type(CASE_TYPE).build();
WorkObject fromTemplate = WorkObject.builder(workObject).name("test").build();
The corresponding builder()
methods in the WorkObjectService
have been removed, and it is no longer necessary to specify
the work object type when creating a new builder. Type information must now be provided when creating a new work object,
even for the legacy gear work object builders. If no type information is provided then the build()
call will fail.
Conversion between the legacy edoras gear classes and the new work object API implementations is now implemented
by static methods in the WorkObjectUtils
class. The corresponding convert()
methods in the WorkObjectService
have been removed. The WorkObjectFactory
class and its implementation have been removed completely.
Creating new work objects
The legacy edoras gear
API provided multiple methods for creating new work objects,
typically either variants of startWorkObject()
or addWorkObject()
. The difference between these
two sets of methods was not obvious, and it was only possible to set initial variables. Initial
values for fields were not supported, leading to various workarounds such as passing a template work object
as an initial variable.
These legacy methods have now been removed and replaced with a single create()
method in the following variants:
String create(WorkObject templateWorkObject);
String create(WorkObject templateWorkObject, String parentId);
String create(String definitionId);
String create(String definitionId, String parentId);
If a definition ID or provider ID is set on the template work object then the corresponding provider will be notified and can perform any related actions (such as starting the corresponding process in the case of a process definition).
In no definition ID or provider ID is set then the work object template will simply be persisted. No provider will be notified.
Updating work objects
Work object update builders now support the forceUpdate()
method. This forces the modification timestamp to be
updated on the work object. If there are no other changes then only the modification timestamp will be changed,
the modification updater ID and modification version will not be changed. The provider will be notified of the
change (if there is one), but no listeners will be invoked. If additional changes are made to the work object then
the forceUpdate()
call has no effect and the change will be processed as in previous releases.
findParent support
The legacy edoras gear API supported the following methods on a work object for finding parent work objects by type:
<T extends WorkObjectId> T getParentId(Class<T> expectedParentType)
<T extends WorkObjectId> T getTopMostParentId(Class<T> expectedParentType)
These methods relied on the work object class to locate the parent work object, which is no longer possible
as there is now just one work object class. Equivalent methods can now be found in the WorkObjectService
and
accept any work object type (not the class):
/**
* Returns the optional ID of the closest parent work object of the given type for a given work object.
*
* @param workObject the starting work object
* @param requiredType the required work object type
* @return the optional parent work object ID
*/
Optional<String> findParentIdByType(WorkObject workObject, String requiredType);
/**
* Returns the optional ID of the top-most parent work object of the given type for a given work object.
*
* @param workObject the starting work object
* @param requiredType the required work object type
* @param includeSelf `true` if the starting work object should also be considered
* @return the optional parent work object ID
*/
Optional<String> findTopMostParentIdByType(WorkObject workObject, String requiredType, boolean includeSelf);
Although not part of the public API, the corresponding methods are also provided by the AnyWorkObjectDefinitionService
,
allowing definition hierarchies to be traversed in the same way.
Query API
The work object query and predicate implementations have been extensively refactored and moved into the public API. The main changes to the old implementation are as follows:
Single query implementation
The query class hierarchy has been simplified. In place of the AnyWorkObjectQuery
and AnyWorkObjectDefinitionQuery
classes there is now a single Query
implementation. Otherwise the behaviour of a query is unchanged, so instead of
AnyWorkObjectQuery.builder()
you can now use just Query.builder()
.
Renamed Query work object class
To avoid a naming conflict with the new Query
implementation, the query work object class has been renamed to
StoredQuery
. The entity type is unchanged, so no migration is needed.
Query hints
The query hint constants have been moved to the new classes WorkObjectQueryHints
and WorkObjectDefinitionQueryHints
.
The RESTRICT_VARIABLES
hint now has additional methods that accept string name or value accessor parameters, avoiding
the need for explicit creation of a variable name matching predicate:
WorkObjectQueryHints.RESTRICT_VARIABLES.matching("A", "B")
Variable definitions and predicate creation
The legacy VariableName
and VariableMap
classes have been removed. The ValueAccessor
interface
has been combined with the predicate operands (providing factory methods for creating predicates) to create
new {type}Value
classes. These can be used in conjunction with ValueMap
to replace the legacy classes. The updated
variable and field constants can be used both to access values in a work object and to generate predicates.
All variable definitions using the ValueAccessor
or VariableName
interfaces should be replaced by the new value
definition classes in the package com.edorasware.api.value
:
-
BooleanValue
for values that will be persisted as booleans -
NumberValue
for values that will be persisted as longs or doubles -
StringValue
for values that will be persisted as strings -
TimestampValue
for values that will be persisted as date timestamps -
ComplexValue
for values that will be persisted as complex values (lists or maps)
Predefined accessors for common work object values are provided as constants in the WorkObjectValues
class.
Accessors for values specific to a given work object type are generally provided as constants in a type-specific
class (e.g. TimerValues
, DocumentValues
).
To create a custom value accessor, you should use the static factory methods in the WorkObjectValues
class, e.g.:
public static final StringValue<String> EMAIL_ADDRESS = newStringValue("email");
Note that the new value types each have a generic parameter representing the type that will be used on the application side.
In the simple case shown above, the application type is the same as the persisted type (StringValue<String>
). To
use an alternative representation in the application, you should specify a suitable ValueConverter
instance, e.g.
for an application-specific ManagerId type:
public static final StringValue<ManagerId> MANAGER_ID = newStringValue("manager", new ManagerIdConverter());
In this case we have a converter that converts the persisted string into a ManagerId
, so the signature of our variable
declaration changes to StringValue<ManagerId>
.
The ValueConverters
class provides a number of preconfigured value converters, or you can create your own converter
implementing the ValueConverter
interface if required.
As well as implementing the ValueAccessor
interface to support type-safe reading and writing of work object values,
the new value classes also provide methods to create predicates for the variable concerned. Previously, a variable
predicate was created at a fairly low level:
Set<ManagerId> managers = ...;
Predicate ownedByManager = Predicates.and(
WorkObjectValues.VARIABLE.name().eq(MANAGER_ID.getName()),
WorkObjectValues.VARIABLE.stringValue().in(convertToStringValues(managers)));
The new value classes take care of a lot of the boiler-plate code and the value conversion, allowing variable predicates to be created much more simply:
Set<ManagerId> managers = ...;
Predicate ownedByManager = MANAGER_ID.in(managers);
Variable predicate combinations are also simpler when using the new value declarations to generate the predicates.
The generated predicates can be combined without additional use of the MultipleNamedValuePredicate
decoration,
so instead of:
WorkObject result = this.workObjectService.getWorkObject(
MultipleNamedValuePredicate.matchAll(
WorkObjectValues.VARIABLE.nameAndValueEq(TEST1, "foo"),
WorkObjectValues.VARIABLE.nameAndValueEq(TEST2, "bar")));
you can now simply combine the predicates:
WorkObject result = this.workObjectService.getWorkObject(
Predicates.and(
TEST1.eq("foo"),
TEST2.eq("bar")));
If low-level variable predicates are still required for particular use cases, they can be created as before
using using the WorkObjectValues.VARIABLE
operand constant.
New predicate creation methods are also provided by the new value declarations to allow simple creation of name-and-not-value predicates:
TEST1.notEq("foo");
TEST1.notIn("foo", "bar");
TEST1.notLike("foo*");
STATE.isNotActive();
- Note
-
The resulting predicates are not the same as simply surrounding the normal predicate with a
not()
predicate (e.g.not(TEST1.eq("foo"))
). The latter form matches when there is no variable with nameTEST1.getName()
and value"foo"
. TheTEST1.notEq("foo")
form matches when there is a variable with nameTEST1.getName()
whose value is not"foo"
(this is normally what is intended).
If required, predicates can also still be created in the equivalent expanded form:
Predicate nameAndNotValuePredicate = MultipleNamedValuePredicate.match(
Predicates.and(
WorkObjectValues.VARIABLE.name().eq(TEST1.getName()),
Predicates.not(WorkObjectValues.VARIABLE.stringValue().eq("foo"))));
Field operand constants
As described above, the work object value constants can now also be used to generate predicates directly (both for
fields and for variables). The operand constants from AnyWorkObject
have been removed and the corresponding
WorkObjectValues
constant should be used instead, e.g. WorkObjectValues.ID
instead of AnyWorkObject.ID
.
Note that the functionality provided by the AnyWorkObject.HIERARCHY
operand is now provided by the
WorkObjectValues.PATH
constant.
exists() predicate
The new value interfaces also support the exists()
predicate generator to check whether the given value exists.
For field values this will always match, for variables it will simply check that a variable with the correct name
is present. For complex variables (with List
or Map
values) this is the only predicate that is supported.
Process variable action listener behaviour
A small change has been made to the behaviour of variables on process creation. When a new process is created, no variable update events will be sent for the initial variable values. The variables are now present on the initial work object creation event, as for other work object types.
Content management API
The handling of Optional
values in the content management interfaces has been updated. Optional
method parameters
have been replaced by nullable plain values, and the source ID accessors in the ContentInfo
and ContentReference
interfaces now also return an Optional<String>
.
Elasticsearch integration API
The following changes were made to the elasticsearch integration API in this release:
-
IndexConfiguration
beans now have to implement arequiredExplicitSynchronization()
method. If this returnstrue
then the index will only be synchronized when explicitly requested by name, not as part of a 'synchronize all' request. -
the
IndexConfiguration
accept()
methods have been removed. This can be implemented in the index configuration indexing methods directly. -
a new
IndexConfigurationProvider
interface allows beans to provide index configurations without having to explicitly configure them. Beans implementing this interface are autowired in the same way asIndexConfiguration
beans. -
the functionality from
com.edorasware.api.elastic.util.ContentUtil
has been moved to theContentManager
interface (getContentAsBytes(…)
) -
the unused interface
com.edorasware.api.elastic.index.IndexValidator
has been removed
Elasticsearch configuration
The Elasticsearch integration has been upgraded to support version 5.6.3. In the 5.x version, several features haven been deprecated. The following 'modes' of integrating with Elasticsearch have been removed:
-
local (running an embedded Elasticsearch instance)
-
node
The way of connecting to an Elasticsearch cluster is always done now using the transport client.
As the 'embedded' way of running Elasticsearch has been removed, following properties are now not used anymore:
-
elasticsearch.type
-
elasticsearch.configuration
-
elasticsearch.root.dir
Miscellaneous changes
The following changes have also been made that may affect application code:
-
The
ProcessServiceUtils
helper class has been renamed toProcessUtils
Migrating code from the legacy gear APIs
This release contains a new public work object API defined in the com.edorasware.api.workobject
package and
documented in the public API Javadoc. Wherever possible this new API should be used in application code.
In most cases, the new public work object API provides the similar functionality to the legacy edoras gear interfaces, and a straightforward mapping from one to the other will be possible.
Although not part of the public API, the legacy gear interface is still provided, and for code that cannot yet be migrated to the new API, the following information may be useful:
-
the work object type hierarchy has been simplified. All work objects are now of one type (
AnyWorkObject
) and there is only one service (AnyWorkObjectService
) and one set of corresponding support classes (providers, listeners etc.) -
as in the public API, all IDs, State and Type values are now plain strings and are no longer typed
-
type-specific fields on document and timer work objects are now persisted as variables
-
the abstract
com.edorasware.commons.core.entity.WorkObject
class has been renamed tocom.edorasware.commons.core.entity.GearWorkObject
-
the abstract
com.edorasware.commons.core.service.entity.WorkObjectService
class has been renamed tocom.edorasware.commons.core.service.entity.GearWorkObjectService
-
WorkObjectIdLookupService
has been renamed toIdLookupService
and moved to the packagecom.edorasware.gear.core.workobject
-
the bean name for
AnyWorkObjectService
has been changed fromworkObjectService
toanyWorkObjectService
-
the bean name for
AnyWorkObjectDefinitionService
has been changed fromworkObjectDefinitionService
toanyWorkObjectDefinitionService
-
some
findParent
methods have been moved from the work object itself to the work object service and now accept a type rather than a work object class -
the
AnyWorkObjectService
methodscreateUpdateBuilder()
andcreateReadableUpdateBuilder()
now take a work object ID instead of a global ID
The changes needed to migrate existing application code are described in the following sections.
Modified edoras gear generics signatures
Many generic signatures for internal edoras gear base classes have been updated as part of the general refactoring. Any references to these generic base classes can either be:
-
replaced by concrete class references (as there is now only an
AnyWorkObject
implementation) -
replaced by the public work object API
-
updated to match the new signature
Reorganise predefined customer action listeners
The type-specific customer action listener placeholders have been removed:
-
customerFirstXXXDefinitionActionListener
-
customerLastXXXDefinitionActionListener
-
customerFirstXXXActionListener
-
customerLastXXXActionListener
You can migrate existing customer action listeners in one of the following ways:
-
drop the listener completely if it is just a duplicate of a corresponding
AnyWorkObject
listener -
create a new
AnyWorkObject
listener with a type check if the listener implements type-specific functionality -
if the listener implements related, but not identical functionality to an existing
AnyWorkObject
listener then create a single merged listener suppoerting both use cases
Note that in the new Spring Java configuration, the predefined names for customer-specific listeners are no longer required.
Arbitrary listener beans can be created in the custom configuration with an ordering defined using the standard
@Order
bean annotation. The ordering information for the standard listeners can be found in the ProviderConfiguration
class.
Check for event type in migrated action listeners
After listeners are moved to the AnyWorkObject
configuration, they will receive events for
more work objects than before. As an example, when migrating ProcessActionListener
implementations to
AnyWorkObjectActionListener
, you may need to add an extra check for the work object type
using the new isEventForType()
method on the event, returning immediately if the type doesn’t match:
public void actionWillBePerformed(AnyWorkObjectActionEvent event) {
if (!event.isEventForType(PROCESS_TYPE)) {
return;
}
...
}
In some cases you may also have to check the work object provider ID to restrict the events being processed even further.
- NOTE
-
There may be duplicated functionality between listeners of different types, in which case you may just be able to drop listener implementations completely.
Use AnyWorkObject APIs instead of type-specific APIs
If you are not migrating directly to the new public API, all typed gear interfaces should be replaced with the
equivalent AnyWorkObject
interface, e.g.:
-
Process
⇒AnyWorkObject
-
ProcessActionEvent
⇒AnyWorkObjectActionEvent
-
…
Add the type to work object builders
In legacy code, the type-specific work object builders (e.g. Process.builder()
) automatically set the type on the
work object being created. When using the AnyWorkObject
builder or the new public API you have to explicitly add the
type information, e.g.:
-
Process.builder()
⇒AnyWorkObject.builder().type(PROCESS_TYPE)
-
ProcessDefinition.builder()
⇒AnyWorkObjectDefinition.builder().type(PROCESS_DEFINITION_TYPE)
Add a type predicate to queries
The type-specific work object APIs (e.g. processService.findProcess(predicate)
) automatically extend the
provided predicate or query with a term that constrains the work object type. When you migrate the
lookup to use AnyWorkObjectService
or the new public API, this additional term will not be added automatically
so you will have to add it explicitly:
workObjectService.findWorkObject(Predicates.and(
WorkObjectValues.TYPE.eq(PROCESS_TYPE),
predicate));
Remove Spring configurations
The type-specific Spring service configurations are no longer supported and should be removed during the migration to the new Java Spring configuration.
Sending messages to a process
The legacy gear process service provided methods for sending messages to a process. This functionality is not supported
by either the AnyWorkObjectService
or the new public WorkObjectService
and is now provided by a new ProcessService
bean.
This new bean provides only the process-specific messaging functionality. It doesn’t support any work object operations.
If you use the default edoras one configurations then this bean will already be available.
Clear all caches
The type-specific caches are no longer required, and the contents of the remaining caches may no longer be valid as they contain serialized values that may no longer be readable. The existing caches should therefore be cleared.
Loading XML process definitions
The process engine configuration support for automatic loading of process definitions from BPMN2.0 XML resources has been dropped. If you need to load process definitions (e.g. in unit tests) then this must be done explicitly in the test code. The following example shows how this can be done:
protected void deployProcessDefinitionsFromResources(String... classPathResources) {
try {
PathMatchingResourcePatternResolver loader = new PathMatchingResourcePatternResolver();
List<Resource> resourceList = new ArrayList<>();
for (String classPathResource : classPathResources) {
Resource[] resources = loader.getResources("classpath*:" + classPathResource);
resourceList.addAll(Arrays.asList(resources));
}
FlowableUtils.deployProcessDefinitions(
resourceList,
"DEFAULT",
true,
this.processEngine.getRepositoryService(),
this.currentTenantService.getCurrentTenantId());
} catch (IOException exception) {
throw new RuntimeException("Cannot deploy process definitions", exception);
}
}
Tenant handling
The following methods have been removed from the CurrentTenantService
interface:
-
getSharedTenantId()
-
isMultiTenant()
For most code that uses these methods, the non-multi-tenant path can simply be removed as the system will always be running in multi-tenant mode. This simplifies both the implementation of the tenant service and application code that has to be tenant-aware.
Configuration
Migrate to Spring Java configuration
Please have a look at the developer documentation and check the Javadoc of the com.edorasware.api.config.ConfigurationConfigurer
/com.edorasware.api.config.ConfigurationBuilder
and its subclasses. There you will find all the information needed how to use
the new Spring Java configuration.
Caches
The following cache-related classes have been renamed:
Old class name |
New class name |
|
|
|
|
The following caches have also been renamed:
Old cache name |
New cache name |
|
|
|
|
Corresponding changes to the project cache configurations will be required, and the existing caches should be flushed.
Spring profiles
The following Spring profiles have been removed:
-
security-basic
,security-low
,security-embedded
→ See the new security configuration. -
database-jndi
,database-jndi-xa
→ See the new persistence configuration. -
integration-development
,integration-production
→ See the new mail configuration.
Configuration properties
As part of the move to Spring Java configuration, the application configuration properties have been revised and made consistent. Please adapt the property names in all environments where you override the defaults. The following table shows the changed property names in alphabetical order:
Old property name | New Property name |
---|---|
application.endpoint |
system.application-endpoint |
apps.preinstalled.location |
apps.import.custom-location |
backwardcompatibility.allowVariableReferencesInInitVariableTask |
backwardcompatibility.enable-variable-reference-for-init-task |
backwardcompatibility.flowable5.compatibility.enabled |
backwardcompatibility.enable-flowable5-compatibility |
cmmn.expose.planItemModelTypes |
cmmn.planitem.exposed-model-types |
cmmn.expose.planItemStates |
cmmn.planitem.exposed-states |
cmmn.expose.planItemTypes |
cmmn.planitem.exposed-types |
content.conversionCacheDir |
content.cache.folder |
content.enableVersioning |
content.versioning.enable |
cors.* |
security.cors.* |
databaseJndiName |
datasource.jndi.name |
schemaDatabaseJndiName |
No property anymore, use custom Configurer |
databaseSchema |
datasource.schema-name |
defaultLanguages |
i18n.default-language-order |
edoras.modeler.palette.location |
modeler.custom-palette-location |
edoras.persistence.dataSource.connectionTimeout |
datasource.connection-pool.timeout |
edoras.persistence.dataSource.driverClassName |
datasource.driver-class-name |
edoras.persistence.dataSource.idleTimeout |
datasource.connection-pool.idle-timeout |
edoras.persistence.dataSource.jdbcUrl |
datasource.url |
edoras.persistence.dataSource.password |
datasource.password |
edoras.persistence.dataSource.maximumLifeTime |
datasource.connection-pool.max-life-time |
edoras.persistence.dataSource.maximumPoolSize |
datasource.connection-pool.max-size |
edoras.persistence.dataSource.minimumIdle |
datasource.connection-pool.min-idle |
edoras.persistence.dataSource.poolName |
datasource.connection-pool.name |
edoras.persistence.dataSource.username |
datasource.username |
edorasware.license |
system.license-location |
edorasware.upgrade.description.workobject.usefield |
upgrade.description.force-workobject-field |
edorasware.upgrade.description.workobject.usevariable |
upgrade.description.force-workobject-variable |
edorasware.upgrade.description.definition.usefield |
upgrade.description.force-definition-field |
edorasware.upgrade.description.definition.useproperty |
upgrade.description.force-definition-property |
elasticsearch.addresses |
search.elasticsearch.node-addresses |
elasticsearch.cluser.name |
search.elasticsearch.cluster-name |
experimental.app.graph.enabled |
experimental.enable-app-graph |
experimental.cmmn.caseMigration |
experimental.enable-cmmn-case-migration |
experimental.form.live.preview |
experimental.enable-form-live-preview |
expression.propagate.unresolved.object.error |
expression.propagate-unresolved-object-error |
expression.user.variable.whitelist |
expression.whitelisted-user-fields |
fix.duplicate.definitions |
upgrade.definition-key.fix-duplicates |
frontendProxyVariables |
ui.frontend-proxy-variables |
globalMessage.autoHide |
ui.hide-global-message-delay |
helpUrl |
ui.help-url |
i18n.message.source.basenames |
i18n.custom-message-source-location |
mail.model.assignee.model.id |
mail.model.assignee-changed |
mail.model.candidate.groups.model.id |
mail.model.candidate.groups |
mail.model.edited.model.id |
mail.model.edited |
mail.validation.pattern |
validation.email-address |
maxChunkUploadSize |
content.upload.max-chunk-size |
maxUploadFileSize |
content.upload.max-file-size |
password.validation.pattern |
validation.user-password |
redis.* |
cluster.redis.* |
rest.defaultLimit |
rest-api.paging-default-limit |
session.timeout |
cluster.cache.session.timeout |
supportCaseModel |
ui.support-case-model |
supportMail |
ui.support-mail |
supportedBrowserEditorRegExp |
modeler.supported-browsers |
app.startup.ignore.import.failures |
apps.import.ignore-failure |
system.forceAppImport |
apps.import.force-system-app |
system.isEditable |
apps.import.force-system-app |
tenant.data.location |
system.tenant-cfg-location |
xsrf.cookie.name |
security.xsrf.cookie-name |
xsrf.header.name |
security.xsrf.header-name |
REST API
To access the API documentation from within your project you need to include the following dependency:
`com.edorasware.one:edoras-one-documentation:{version}`.
This JAR file includes the whole documentation plus the REST API documentation which is available at the
{your-base-url-and-context}/documentation/api/ui
endpoint.
Removed REST endpoints
The following REST endpoints were deprecated in 1.5.0S103 and have now been removed:
-
/PRC/{processId}/next
-
/TSK/{taskId}/next
Front end API
URL encoding in select / autocomplete components
The previous autocomplete components encoded only the search term written by the user before doing remote requests. The new components encode the whole URL.
It’s recommended to review and update the definition of autocomplete / select components. If you need to restore the old behavior you can use the following code in the custom.js:
angular.module('edoras-components.select').decorator('ecSelectUrlInterpolatorEncoder', function ($delegate) {
$delegate.getQueryUrl = function(metadataService, context, searchTerm){
return metadataService.getInterpolatedProperty('queryUrl', _.assign({}, context,
{$searchTerm: encodeURIComponent(searchTerm)}
));
}
return $delegate;
});
Support for backward compatibility URL encoding removed
Support for the backwardcompatibility.urlencoding
flag has been removed.
We expect (and recommend) all customers not to have manually encoded URLs in their models,
but if you still have some encoded URLs around (e.g. in long running cases) then
you can add the following code to your custom.js
file to avoid problems with URL encoding:
angular.module('oneModule').decorator('ecUrlEncoder', function ($delegate) {
$delegate.encode = function (url) {
return url;
};
return $delegate;
});
Date encoding
Previously all serialized date values (ISO strings) that went from the server to the browser were converted to date objects using an HTTP interceptor. Date strings are now left as they are, and can be interpreted as dates by a form component as required. If you have custom code that directly manipulates date values then you may need to convert the ISO string to a date first.
APP_CONTEXT variable removed
The APP_CONTEXT
variable has been removed from the front end. Please have a look at the
external HTML configuration
section in the documentation on how to put the HTML in a different place than the back-end resources.
Model migration
Form models
Select and autocomplete components
The new component definitions are slightly different to the old component definitions. To ease the migration we implemented a runtime translation of the old component definition into the new one, so old forms should still work, but the new components will be shown instead of the old ones. When a form containing old component definitions is loaded in the modeller the components will be migrated too and the user will get a notification to review them.
CMMN models
Applying allowed actions from definitions
We’ve fixed a bug that the "allowed actions" as defined on the CMMN tasks were not taken into account. Please ensure you have properly specified "allowed actions" in all your CMMN models and redeploy applications when needed. The first application start-up tries to apply a data upgrade to patch existing instances. In the case of warnings/errors during the upgrade, please fix the failed cases manually.
Data migration
Description storage
In edoras one, work object descriptions were normally stored as variables, but it was also possible to store
text in the description
field of the work object. This could lead to confusion and unexpected behaviour, and so
the descriptions for work objects and work object definitions are now stored exclusively as variables (for work objects)
or properties (for work object definitions).
In the case where a description is set on the field, but the description variable/property is empty, the migration
will copy the description from the field into the variable. If you want to discard all text in the description
field
for either work objects or work object definitions then you can set one of the following startup properties:
-
upgrade.description.force-workobject-variable = true
-
upgrade.description.foce-definition-property = true
In cases where both the description
field and the corresponding variable / property contain valid text, the
migration will normally terminate with an error as it cannot know which text should be kept. In this case the
database content should be reviewed. If the variable / property text should be kept, you can set the properties
as shown above. If the field text should be kept then the following properties can be used:
-
upgrade.description.force-workobject-field = true
-
upgrade.description.force-definition-field = true
Legacy serialized classes
The Flowable database tables may contain serialized versions of certain legacy classes from Release 1.6, especially
ID values. It is unlikely that these will present a problem in most cases as most data access takes place through the
edoras gear persistence, but should such a problem occur, the edoras-one-legacy
dependency can be added to the
project, allowing these serialized classes to be read.
Elasticsearch Upgrade
Please have a look at the official upgrade notes https://www.elastic.co/guide/en/elasticsearch/reference/current/restart-upgrade.html