Maintain Operations Step by Step
TL;DR
Configure your
hashCodegenerator template.Decide if it's a
DataorStructureoperation.Implement all 4 operations (
add,change,addOrChange,remove). Do not forget sub properties and implementChangeOperationinterface.Include the operations at the properly
ChangeSetDTO.Generate
xsdto commit.Register the execution of your operations at
ChangeSetStructureExecutororChangeSetDataExecutor.Implement the executors, do not forget
getEntity()and provide aEntityResolverto your Object.Create tests to each executor.
Implement download mapping.
DTO
HashCode
Since there is a MD5 hash validation over the changeSet by Liquibase, it's necessary to have a different approach when implement hashCode, basically computes value only if the property is not null.
This prevent false positive hash validation when adding new properties to the ChangeSetDTO object. Bellow there are two examples:
Default Template
@Override
public final int hashCode() {
int result = dataObject != null ? dataObject.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (criteriaList != null ? criteriaList.hashCode() : 0);
return result;
}
Custom Template
@Override
public int hashCode() {
int result = dataObject != null ? dataObject.hashCode() : 0;
result = (name != null ? 31 * result : result) + (name != null ? name.hashCode() : 0);
result = (CollectionUtils.isNotEmpty(criteriaList) ? 31 * result : result) + (CollectionUtils.isNotEmpty(criteriaList) ? criteriaList.hashCode() : 0);
return result;
}
Observe the difference, at the Custom Template the result variable only receives value if the property is not null.
Configuration
1) Open the file you want to create the hashCode and equals code and press ALT + INSERT

2) Check the first option and click at ... button

3) Click at Copy button and define a name of your preference and click OK


4) Paste the code of the custom template located at meceap\extra\templates\changelog-hashCode.template at the HasCode Template input and click OK

Done, to use simple select the created template. You may need restart your IDE to work.
Operations
Structure vs Data
First of all, you need to decide if your operation is considered Structure or Data, this is easy to know, if your object depends on data from xlsx files, you are dealing with a Data operation, if not, Structure. This is important, since the JarProcessor has the following order to process files:
Structure- Import
xlsxfiles Data
A good example of data operation is every object that contains criteria.
Operations
There are 4 types of operations:
add: Used to create a object, by default generate a exception when the object already exists.change: Used to change a object, by default generate a exception when the object doesn't exists.addOrChange: Created specially to provide compatibility toappscreated byAppBuilder. This operation verify if the object exists or not and redirect to the correct executor,addif not exists andchangeif exists.remove: Used to remove a object, normally do not generate a exception if the object doesn't exists.
This all four operations have to be implemented, the exception is change, there are objects that has no need to change, for example: DocumentType Notification. But the addOrChange must be implemented and in the case of the object already exists simple do nothing.
Remember:
ChangeSet operation needs to be as granular as possible. The goal is always to provide a way to change a specific part or property without having to process the whole object.
Taking
DataObjectas a example, there are operations over theDataObject, but also operations related tofields,indexesanddataSources.Another tip, you must pay attention on
changeoperations,changeoperations may have many fields and you only should change fields that were informed.Your class must implement
ChangeOperationinterface, this is need because all operations are stored at database, more about this later.
After create all operations list them at the properly ChangeSetDTO class, do not forget to change equals and hashCode methods to include the new properties.
XSD
After implement your DTOs and list at ChangeSetDTO execute the test testGeneratingSchema(). You'll notice some xsd files changed, do not forget to commit them.
Register the Execution
You need to register your operation at ChangeSetStructureExecutor or ChangeSetDataExecutor. Pay attention in the order you place the operation. For example, DataObject must be created before DocumentType, you'll see a bunch of examples at these classes.
Implement the Executor
After register your operation at ChangeSetExecutor create a class that implements ChangeExecutor<T> where T is your ChangeOperation / DTO. After this the ChangeSetExecutor is responsible to execute the correct ChangeExecutor for each DTO that need to be processed.
You'll need to implement two methods:
-
execute(): Execute change operation. -
getEntity(): Return the targetEntityof operation. (Only high level:DataObject,DocumentType. Neverfieldfor example.)
First, it's important to understand what is this Entity object, short description: It's a generic implementation to store information about any object that exist at CEAP.
Was created because every operation executed by the ChangeLog is persisted in a collection at MongoDB named customRootName._Change.
Fortunately there is a simple way to obtain this Entity for every BaseObject and BaseMongoObject, two steps:
1) Create your EntityResolver: Implement a EntityBaseObjectResolver or EntityBaseMongoObjectResolver, examples: EntityDataObjectResolver and EntityMacroResolver. The resolver is needed to define which properties compose the unique key of the object.
2) Use the EntityService at your ChangeExecutor simple executing the method getEntity().
This is useful to navigate from the Change to the affect Object and from the Object to Changes. Even if the object is removed and recreated we'll be able to reproduce these steps because we don't store the id, but the properties that make the object unique.
Tests
Implement tests for each executor, remember the quality gate and try to obtain at least 80% of coverage. You also can use CoffeeDispenser to write xml files and verify if your operation is executing properly.
Download
Verify if it's necessary to export and import information across CEAP instances, if yes:
- Implement the
UIandDownloadConfigurationclass. - Create a class that implement
ChangeSetMapperinterface. - Change
ChangeLog*MappingManagerincluding yourMapper.