Giro... vedo nodi... faccio cose...
Do things with nodes.
A modern, threaded and easily customizable Spring Boot Application that - given a means for collecting nodes - do something with them.
Think about this as a template for your application.
Pull requests are welcome!
QueryNodeCollectorcollect nodes with Alfresco FTS queriesNodeListCollectorreads node IDs from a fileNodeTreeCollectorwalks the repository treeDeleteNodeProcessordeletes or trashes nodesMoveNodeProcessorrelocates nodes under a new parentAddAspectsAndSetPropertiesProcessoradds aspects and propertiesSetPermissionsProcessorapplies permissions and inheritanceDownloadNodeProcessorsaves node content and metadata to the filesystemChainingNodeProcessorexecutes multiple processors sequentially- Queue based architecture with configurable consumer threads
- Easily extensible by implementing
AbstractNodeCollectorandAbstractNodeProcessor
If none of the predefined Collectors/Processors meet your needs, simply write your own by extending the abstract ones. Just inject the required handlers (e.g., NodesApi) and override the relevant methods.
The QueryNodeCollector takes an Alfresco FTS query, execute it on a separate thread and feed the queue:
"collector": {
"name": "QueryNodeCollector",
"args": {
"query": "PATH:'/app:company_home/*' AND TYPE:'cm:folder'"
}
}the default page size for search is 100 and can be modified by passing an additional argument to the collector:
"batch-size": 1000The NodeListCollector takes an input file containing a list of node-id with each id on a separate line, e.g.:
e72b6596-ec2e-4279-b490-3a03b119d8de
d78c0036-15c0-43cf-89e4-cd198d14b626
1a7ecc34-de06-45ed-85c0-76f8355f3724
and the path of the file need to be specified in the config:
"collector": {
"name": "NodeListCollector",
"args": {
"node-list-file": "/tmp/node-ids.txt"
}
}Iteratively walk the tree starting from a folder node given either its id or its repository path:
"collector": {
"name": "NodeTreeCollector",
"args": {
"path": "/"
}
}The collector automatically descends into folders.
The default page size for listNodeChildren is 100 and can be modified by passing an additional argument to the collector:
"batch-size": 200Delete the collected nodes, set the permanent flag to true if you want to delete the nodes directly rather than move them into the trashcan:
"processor": {
"name": "DeleteNodeProcessor",
"args": {
"permanent": true
}
}Add a list of aspects and apply a map of properties to the collected nodes:
"processor": {
"name": "AddAspectsAndSetPropertiesProcessor",
"args": {
"properties": {
"cm:publisher": "saidone",
"cm:contributor": "saidone"
},
"aspects": [
"cm:dublincore"
]
}
}Apply a list of permissions and set inheritance flag to the collected nodes:
"processor": {
"name": "SetPermissionsProcessor",
"args": {
"permissions": {
"isInheritanceEnabled": false,
"locallySet": [
{
"authorityId": "GROUP_EVERYONE",
"name": "Collaborator",
"accessStatus": "ALLOWED"
}
]
}
}
}Move collected nodes to a new folder identified either by its node-id or by the repository path:
"processor": {
"name": "MoveNodeProcessor",
"args": {
"target-parent-id": "e72b6596-ec2e-4279-b490-3a03b119d8de"
}
}Download node content and metadata to a local directory in a format compatible with bulk import:
"processor": {
"name": "DownloadNodeProcessor",
"args": {
"output-dir": "/tmp/export"
}
}Execute a list of processors sequentially on each node:
"processor": {
"name": "ChainingNodeProcessor",
"args": {
"processors": [
{ "name": "LogNodeNameProcessor" },
{ "name": "VoidProcessor" }
]
}
}Custom processors can be easily created by extending the AbstractNodeProcessor and overriding the processNode method:
@Component
@Slf4j
public class LogNodeNameProcessor extends AbstractNodeProcessor {
@Autowired
private NodesApi nodesApi;
@Override
public void processNode(String nodeId, Config config) {
var node = Objects.requireNonNull(nodesApi.getNode(nodeId, null, null, null).getBody()).getEntry();
log.debug("node name --> {}", node.getName());
}
}Java and Maven required
mvn package -DskipTests -Dlicense.skip=true
look at the build.sh or build.bat scripts for creating a convenient distribution package.
Global configuration is stored in config/application.yml file, the relevant parameters are:
| Parameter/env variable | Key in application.yml |
Default value | Purpose |
|---|---|---|---|
| ALFRESCO_BASE_PATH | content.service.url |
http://localhost:8080 | scheme, host and port of the Alfresco server |
| ALFRESCO_USERNAME | content.service.security.basicAuth.username |
admin | Alfresco user |
| ALFRESCO_PASSWORD | content.service.security.basicAuth.password |
admin | password for the Alfresco user |
| QUEUE_SIZE | application.queue-size |
1000 | size of the node-uuid queue |
| CONSUMER_THREADS | application.consumer-threads |
4 | number of consumers that are executed simultaneously |
| CONSUMER_TIMEOUT | application.consumer-timeout |
5000 | milliseconds after which a consumer gives up waiting for data in the queue |
| READ_ONLY | application.read-only |
true | when true, mutating operations on nodes are skipped |
For integration tests just change configuration and point it to an existing Alfresco installation, or use alfresco.(sh|bat) script to start it with docker.
$ java -jar anp.jar -c example-log-node-name.json
See Javadoc
Copyright (c) 2023-2025 Saidone
Distributed under the GNU General Public License v3.0