SlideShare a Scribd company logo
1 of 39
Moving from Actions & Behaviors to Microservices
Jeff Potts, Metaversant
@jeffpotts01
How do we make it easier to
integrate Alfresco with other
systems?
Learn. Connect. Collaborate.
“We want to be able to report against metadata in real-time.”
“When this custom property changes we need to notify this other system.”
“We want to improve how Alfresco transforms Word documents into HTML.”
“When content changes we want to run it through an NLP model.”
“Our company has an enterprise search solution that needs to index Alfresco content.”
“We want to replicate content between multiple Alfresco servers.”
Recurring customer requirements
Learn. Connect. Collaborate.
Traditional approaches run in-process
• Custom Alfresco Actions
– Java, deployed to Alfresco WAR
– Triggered by rule on a folder, a UI action, or by a schedule
• Custom Alfresco Behaviors
– Java, deployed to Alfresco WAR
– Bound to a policy on a class of nodes (e.g., specific type or aspect)
• Custom Web Scripts
– Java or JavaScript, deployed to Alfresco WAR
– Triggered by a REST call
• All of these run in Alfresco’s process
Learn. Connect. Collaborate.
Tradeoffs of the traditional approach
• Advantages
– Full access to the Alfresco API
– Runs as the authenticated user or as the system user
– Code is managed with the content model and other customizations
• Disadvantages
– Performance risk
– Requires server restart to deploy
– Requires an Alfresco developer familiar with Alfresco API
• Java & JavaScript are the only practical language options
– Long-running tasks may block user interface
– Scales as Alfresco scales
An event-based approach
Learn. Connect. Collaborate.
Event-based integration approach
• Alfresco can be extended to generate generic events when something
happens to a node
• Interested systems
– Listen for Alfresco events
– Filter out what they don’t care about
– Fetch additional data from Alfresco and perform custom logic as needed
• Additional systems can be added without touching Alfresco
• Systems can use different frameworks & languages
• Independently scalable
• Can use Alfresco Kafka as a starting point
Learn. Connect. Collaborate.
Apache Kafka
Alfresco
Microservice
Event
Event
Microservice
Event
Microservice
Event
Move logic out of Alfresco into microservices
alfresco-
kafka
Kafka
Client JAR
Learn. Connect. Collaborate.
Example event JSON
{
"nodeRef": "3f375925-fa87-4e34-9734-b98bed2d483f",
"eventType": "CREATE",
"path":
"/{http://www.alfresco.org/model/application/1.0}company_home/…/{http://www.alfresco
.org/model/content/1.0}test2.txt",
"created": 1497282061322,
"modified": 1497282061322,
"creator": "admin",
"modifier": "admin",
"mimetype": "text/plain",
"contentType": "content",
"siteId": "test-site-1",
"size": 128,
"parent": "06a154e3-4014-4a55-adfa-5e55040fae2d”
}
Simple Example
Learn. Connect. Collaborate.
Alfresco Kafka Listener Example
• Alfresco Kafka
– https://github.com/jpotts/alfresco-kafka
• Alfresco Kafka Listener Example
– https://github.com/jpotts/alfresco-kafka-listener-example
• Demo: https://youtu.be/K40M2gJA7vM
Learn. Connect. Collaborate.
Alfresco Kafka Listener
• Small Spring Boot app
• Runs in a servlet container
• Logs Alfresco Kafka events
• Example/starter code
Apache Kafka
Alfresco
alfresco-kafka-listener
alfresco-
kafka
Kafka
Client JAR
Event
Event
Demo: Alfresco Kafka Listener
Learn. Connect. Collaborate.
GenerateNodeEvent behavior calls MessageService
@Override
public void onCreateNode(ChildAssociationRef childAssocRef) {
NodeRef nodeRef = childAssocRef.getChildRef();
if (nodeService.exists(nodeRef)) {
messageService.publish(nodeRef, NodeEvent.EventType.CREATE);
}
}
Learn. Connect. Collaborate.
MessageService sends JSON to the Kafka queue
public void init() {
producer = new KafkaProducer<>(createProducerConfig());
}
public void publish(NodeRef nodeRef, NodeEvent.EventType eventType) {
NodeEvent e = nodeTransformer.transform(nodeRef);
e.setEventType(eventType);
publish(e);
}
private void publish(NodeEvent event) {
try {
final String message = mapper.writeValueAsString(event);
if (message != null && message.length() != 0) {
producer.send(new ProducerRecord<String, String>(topic, message));
}
} catch (JsonProcessingException jpe) {
logger.error(jpe);
}
}
Learn. Connect. Collaborate.
Example listener logs event type and node ref
@KafkaListener(topics="${kafka.topic}", group = "${kafka.group}", containerFactory =
"nodeEventKafkaListenerFactory")
public void consumeJson(NodeEvent nodeEvent) {
try {
if (nodeEvent.getContentType().equals("F:cm:systemfolder") ||
nodeEvent.getContentType().equals("F:bpm:package") ||
nodeEvent.getContentType().equals("I:act:actionparameter") ||
nodeEvent.getContentType().equals("I:act:action") ||
nodeEvent.getContentType().equals("D:cm:thumbnail")) {
return;
}
logger.debug("Event: " + nodeEvent.getEventType() + " on " +
nodeEvent.getNodeRef());
} catch (Exception e) {
logger.error(e.getMessage());
}
}
Real World Example: Reporting
Learn. Connect. Collaborate.
Example: Alfresco reporting
• Customer: “We want to be able to report against metadata in real-time.”
• Solution:
– Spring Boot microservice consumes Alfresco Kafka events
– When a node changes that is interesting, it fetches the metadata using CMIS
– Indexes metadata into Elasticsearch
– Kibana dashboard used to visualize data
• Demo: https://youtu.be/jGZVfP5L8yU
Learn. Connect. Collaborate.
Indexer Service
• Small Spring Boot app
• Runs in a servlet container
• Listens for Alfresco Kafka events
• Fetches the Alfresco Node as
JSON
• Indexes the Node JSON into
Elasticsearch
• Deletes objects from
Elasticsearch when DELETE
events occur
Apache Kafka
Alfresco
Elasticsearch Cluster
alf-es-indexer
alfresco-
kafka
Kafka
Client JAR
Event
Event
CMIS GET
Node JSON
Node JSON
Demo: alf-es-indexer
Learn. Connect. Collaborate.
KafkaConsumer fetches the node, calls indexer
if (nodeEvent.getEventType().equals(NodeEvent.EventType.CREATE) ||
nodeEvent.getEventType().equals(NodeEvent.EventType.UPDATE) ||
nodeEvent.getEventType().equals(NodeEvent.EventType.PING)) {
Node node = alfrescoService.getNode(nodeEvent.getNodeRef());
// Copy some of the properties from the event onto the node object
if (nodeEvent.getParent() != null) {
node.setParent(nodeEvent.getParent());
}
if (nodeEvent.getSiteId() != null) {
node.setSiteId(nodeEvent.getSiteId());
}
nodeIndexer.index(node);
} else if (nodeEvent.getEventType().equals(NodeEvent.EventType.DELETE)) {
nodeRemover.delete(nodeEvent.getNodeRef());
}
Learn. Connect. Collaborate.
Real World Example: Metadata
Enrichment with NLP
Learn. Connect. Collaborate.
Example: Natural Language Processing
• Customer: “I want to be able to enrich Alfresco metadata by extracting
people, places, and names from content using an NLP model”
• Solution:
– Spring Boot microservice consumes Alfresco Kafka events
– When a node with a “marker” aspect changes, the microservice fetches the
content
– Fingerprints are used to avoid repeatedly processing the same content
– Text is extracted using Apache Tika
– Extracted text is run through Apache OpenNLP to extract people and places
– People and places are written to Alfresco content metadata via CMIS
• Demo: https://youtu.be/H-2TgoUijzY
Learn. Connect. Collaborate.
NLP Enricher Service
• Small Spring Boot app
• Runs in a servlet container
• Listens for Alfresco Kafka events
• Fetches Alfresco content
• Extracts people, places, and orgs
• Writes metadata back to Alfresco Apache Kafka
Alfresco
alf-nlp-enricher
alfresco-
kafka
Kafka
Client JAR
Event
Event
CMIS GET
Node JSON
CMIS POST
Demo: alf-nlp-enricher
Learn. Connect. Collaborate.
NodeProcessor uses hash to avoid re-processing file
String hash = null;
try {
hash = HashSumGenerator.getHash(new FileInputStream(new
File(downloadFilePath)));
logger.debug("Hash: " + hash);
} catch (FileNotFoundException fnfe) {
logger.error("Download file not found");
}
// If we have seen this exact content before for this node, stop
String pastHash = pastHashesById.get(id);
if (pastHash != null) {
logger.debug("Past hash: " + pastHash);
if (pastHash.equals(hash)) {
logger.debug("Have already processed this exact file for this id,
skipping");
deleteFile(downloadFilePath);
return;
}
}
Learn. Connect. Collaborate.
Detect sentences, call OpenNLP, update metadata
String sentences[] = sentenceDetector.detect(text);
for (String sentence : sentences) {
locations = addToSet(locationExtractor.extract(sentence), locations);
orgs = addToSet(orgExtractor.extract(sentence), orgs);
names = addToSet(nameExtractor.extract(sentence), names);
}
HashMap<String, Serializable> properties = new HashMap<>();
properties.put(PROP_LOCATIONS, toArrayList(locations));
properties.put(PROP_ORGS, toArrayList(orgs));
properties.put(PROP_NAMES, toArrayList(names));
try {
alfrescoService.updateNode(id, properties);
} catch (AlfrescoServiceException ase) {
logger.error(ase.getMessage());
}
Learn. Connect. Collaborate.
Considerations
Learn. Connect. Collaborate.
Apache Kafka
Alfresco
Microservice
Event
Event
Microservice
Event
Microservice
Event
Move logic out of Alfresco into microservices
alfresco-
kafka
Kafka
Client JAR
Learn. Connect. Collaborate.
Other potential uses
• Full-text search indexing into standalone search engine
• Synchronizing content with other servers
• Improved HTML transformations
• Notification/subscription service
• Chat integration
Learn. Connect. Collaborate.
Event-based approach disadvantages
• More code/complexity than traditional approach
• User feedback/notification is not straightforward
• Potentially increases the number of “containers” in the IT shop
Learn. Connect. Collaborate.
Event-based approach advantages
• In-line with Alfresco’s stated architectural direction
• Reduces the amount of code running in Alfresco’s process
– Reduces the number of deployments required to support integrations
– Off-loads long-running and/or process-intensive integrations from Alfresco
– Scales independently of Alfresco
• Integrations are more loosely-coupled from Alfresco
– Requires less Alfresco knowledge
– Frees up architectural choices for integrations (not just Java)
• Integration apps are relatively easy to containerize
• Can work alongside traditional approach
Learn. Connect. Collaborate.
Demo Dependency Versions
• Alfresco 5.2.g CE & 5.2.3 Enterprise with
– Metaversant Alfresco Kafka open source add-on 0.0.2
• Apache Kafka 2.12-0.10.2.1
• Elasticsearch 6.3.2
• Kibana 6.3.2
• Custom Spring Boot applications
– Spring Boot 1.5.8
– Elasticsearch High-level Rest Client 6.3.2
– Tika 1.18
– OpenNLP 1.8.4
– Apache Chemistry 1.0.0
Learn. Connect. Collaborate.
Links
• Apache Kafka: http://kafka.apache.org/
• Apache OpenNLP: http://opennlp.apache.org/
• Apache Tika: https://tika.apache.org/
• Elasticsearch: https://www.elastic.co/products/elasticsearch
• Kibana: https://www.elastic.co/products/kibana
• Spring Boot: https://spring.io/projects/spring-boot
Learn. Connect. Collaborate.
See Also
• Apache ManifoldCF
– http://manifoldcf.apache.org/
– Crawler that indexes from repositories like Alfresco into Solr & Elasticsearch
• Apache Stanbol
– http://stanbol.apache.org/
– Semantic engine that can do metadata enhancement and other things
• Apache Camel
– http://camel.apache.org/
– Enterprise integration platform
Learn. Connect. Collaborate.
• Consulting firm focused on solving business problems with open source
Content Management, Workflow, & Search technology
• Founded in 2010
• Clients all over the world in a variety of industries, including:
– Airlines & Aerospace
– Manufacturing
– Construction
– Financial Services
– Higher Education
– Life Sciences
– Professional Services
https://www.metaversant.com
Moving from Actions &
Behaviors to Microservices
Jeff Potts, Metaversant
@jeffpotts01

More Related Content

What's hot

Using MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - Berlin
Using MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - BerlinUsing MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - Berlin
Using MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - Berlin
Sébastien Le Marchand
 

What's hot (20)

Exciting New Alfresco REST APIs
Exciting New Alfresco REST APIsExciting New Alfresco REST APIs
Exciting New Alfresco REST APIs
 
Alfresco node lifecyle, services and zones
Alfresco node lifecyle, services and zonesAlfresco node lifecyle, services and zones
Alfresco node lifecyle, services and zones
 
Sizing your alfresco platform
Sizing your alfresco platformSizing your alfresco platform
Sizing your alfresco platform
 
Alfresco Backup and Disaster Recovery White Paper
Alfresco Backup and Disaster Recovery White PaperAlfresco Backup and Disaster Recovery White Paper
Alfresco Backup and Disaster Recovery White Paper
 
(Re)Indexing Large Repositories in Alfresco
(Re)Indexing Large Repositories in Alfresco(Re)Indexing Large Repositories in Alfresco
(Re)Indexing Large Repositories in Alfresco
 
Guide to alfresco monitoring
Guide to alfresco monitoringGuide to alfresco monitoring
Guide to alfresco monitoring
 
From zero to hero Backing up alfresco
From zero to hero Backing up alfrescoFrom zero to hero Backing up alfresco
From zero to hero Backing up alfresco
 
Alfresco tuning part1
Alfresco tuning part1Alfresco tuning part1
Alfresco tuning part1
 
Alfresco DevCon 2019 Performance Tools of the Trade
Alfresco DevCon 2019   Performance Tools of the TradeAlfresco DevCon 2019   Performance Tools of the Trade
Alfresco DevCon 2019 Performance Tools of the Trade
 
Using MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - Berlin
Using MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - BerlinUsing MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - Berlin
Using MyBatis in Alfresco custom extensions - Alfresco Devcon 2012 - Berlin
 
Alfresco Transform Service DevCon 2019
Alfresco Transform Service DevCon 2019Alfresco Transform Service DevCon 2019
Alfresco Transform Service DevCon 2019
 
Alfresco Security Best Practices 2014
Alfresco Security Best Practices 2014Alfresco Security Best Practices 2014
Alfresco Security Best Practices 2014
 
Important work-arounds for making ASS multi-lingual
Important work-arounds for making ASS multi-lingualImportant work-arounds for making ASS multi-lingual
Important work-arounds for making ASS multi-lingual
 
Bulk Export Tool for Alfresco
Bulk Export Tool for AlfrescoBulk Export Tool for Alfresco
Bulk Export Tool for Alfresco
 
Alfresco Security Best Practices Guide
Alfresco Security Best Practices GuideAlfresco Security Best Practices Guide
Alfresco Security Best Practices Guide
 
CUST-10 Customizing the Upload File(s) dialog in Alfresco Share
CUST-10 Customizing the Upload File(s) dialog in Alfresco ShareCUST-10 Customizing the Upload File(s) dialog in Alfresco Share
CUST-10 Customizing the Upload File(s) dialog in Alfresco Share
 
Alfresco tuning part1
Alfresco tuning part1Alfresco tuning part1
Alfresco tuning part1
 
Storage and Alfresco
Storage and AlfrescoStorage and Alfresco
Storage and Alfresco
 
CMIS: An Open API for Managing Content
CMIS: An Open API for Managing ContentCMIS: An Open API for Managing Content
CMIS: An Open API for Managing Content
 
Oracle Real Application Clusters 19c- Best Practices and Internals- EMEA Tour...
Oracle Real Application Clusters 19c- Best Practices and Internals- EMEA Tour...Oracle Real Application Clusters 19c- Best Practices and Internals- EMEA Tour...
Oracle Real Application Clusters 19c- Best Practices and Internals- EMEA Tour...
 

Similar to Moving From Actions & Behaviors to Microservices

Structured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim Dowling
Structured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim DowlingStructured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim Dowling
Structured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim Dowling
Databricks
 
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Timothy Spann
 
Kafka Connect & Kafka Streams/KSQL - the ecosystem around Kafka
Kafka Connect & Kafka Streams/KSQL - the ecosystem around KafkaKafka Connect & Kafka Streams/KSQL - the ecosystem around Kafka
Kafka Connect & Kafka Streams/KSQL - the ecosystem around Kafka
Guido Schmutz
 

Similar to Moving From Actions & Behaviors to Microservices (20)

Data / Streaming / Microservices Platform with Devops
Data / Streaming / Microservices Platform with DevopsData / Streaming / Microservices Platform with Devops
Data / Streaming / Microservices Platform with Devops
 
From Zero to Stream Processing
From Zero to Stream ProcessingFrom Zero to Stream Processing
From Zero to Stream Processing
 
Jug - ecosystem
Jug -  ecosystemJug -  ecosystem
Jug - ecosystem
 
Integrating Apache Kafka and Elastic Using the Connect Framework
Integrating Apache Kafka and Elastic Using the Connect FrameworkIntegrating Apache Kafka and Elastic Using the Connect Framework
Integrating Apache Kafka and Elastic Using the Connect Framework
 
Structured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim Dowling
Structured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim DowlingStructured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim Dowling
Structured-Streaming-as-a-Service with Kafka, YARN, and Tooling with Jim Dowling
 
Chti jug - 2018-06-26
Chti jug - 2018-06-26Chti jug - 2018-06-26
Chti jug - 2018-06-26
 
Analitica de datos en tiempo real con Apache Flink y Apache BEAM
Analitica de datos en tiempo real con Apache Flink y Apache BEAMAnalitica de datos en tiempo real con Apache Flink y Apache BEAM
Analitica de datos en tiempo real con Apache Flink y Apache BEAM
 
Deploying Apache Flume to enable low-latency analytics
Deploying Apache Flume to enable low-latency analyticsDeploying Apache Flume to enable low-latency analytics
Deploying Apache Flume to enable low-latency analytics
 
No Docker? No Problem: Automating installation and config with Ansible
No Docker? No Problem: Automating installation and config with AnsibleNo Docker? No Problem: Automating installation and config with Ansible
No Docker? No Problem: Automating installation and config with Ansible
 
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
Designing Event-Driven Applications with Apache NiFi, Apache Flink, Apache Sp...
 
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
 
Multi-tenant Flink as-a-service with Kafka on Hopsworks
Multi-tenant Flink as-a-service with Kafka on HopsworksMulti-tenant Flink as-a-service with Kafka on Hopsworks
Multi-tenant Flink as-a-service with Kafka on Hopsworks
 
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
Jim Dowling - Multi-tenant Flink-as-a-Service on YARN
 
Apache Kafka - Scalable Message-Processing and more !
Apache Kafka - Scalable Message-Processing and more !Apache Kafka - Scalable Message-Processing and more !
Apache Kafka - Scalable Message-Processing and more !
 
Real time Analytics with Apache Kafka and Apache Spark
Real time Analytics with Apache Kafka and Apache SparkReal time Analytics with Apache Kafka and Apache Spark
Real time Analytics with Apache Kafka and Apache Spark
 
BBL KAPPA Lesfurets.com
BBL KAPPA Lesfurets.comBBL KAPPA Lesfurets.com
BBL KAPPA Lesfurets.com
 
Kafka Connect & Kafka Streams/KSQL - the ecosystem around Kafka
Kafka Connect & Kafka Streams/KSQL - the ecosystem around KafkaKafka Connect & Kafka Streams/KSQL - the ecosystem around Kafka
Kafka Connect & Kafka Streams/KSQL - the ecosystem around Kafka
 
Apache Kafka - A Distributed Streaming Platform
Apache Kafka - A Distributed Streaming PlatformApache Kafka - A Distributed Streaming Platform
Apache Kafka - A Distributed Streaming Platform
 
Apache kafka-a distributed streaming platform
Apache kafka-a distributed streaming platformApache kafka-a distributed streaming platform
Apache kafka-a distributed streaming platform
 
Extending Kubernetes
Extending KubernetesExtending Kubernetes
Extending Kubernetes
 

More from Jeff Potts

Alfresco Community Survey 2012 Results
Alfresco Community Survey 2012 ResultsAlfresco Community Survey 2012 Results
Alfresco Community Survey 2012 Results
Jeff Potts
 
Alfresco SAUG: CMIS & Integrations
Alfresco SAUG: CMIS & IntegrationsAlfresco SAUG: CMIS & Integrations
Alfresco SAUG: CMIS & Integrations
Jeff Potts
 

More from Jeff Potts (20)

Flexible Permissions Management with ACL Templates
Flexible Permissions Management with ACL TemplatesFlexible Permissions Management with ACL Templates
Flexible Permissions Management with ACL Templates
 
Could Alfresco Survive a Zombie Attack?
Could Alfresco Survive a Zombie Attack?Could Alfresco Survive a Zombie Attack?
Could Alfresco Survive a Zombie Attack?
 
Connecting Content Management Apps with CMIS
Connecting Content Management Apps with CMISConnecting Content Management Apps with CMIS
Connecting Content Management Apps with CMIS
 
The Challenges of Keeping Bees
The Challenges of Keeping BeesThe Challenges of Keeping Bees
The Challenges of Keeping Bees
 
Getting Started With CMIS
Getting Started With CMISGetting Started With CMIS
Getting Started With CMIS
 
Alfresco: What every developer should know
Alfresco: What every developer should knowAlfresco: What every developer should know
Alfresco: What every developer should know
 
Apache Chemistry in Action: Using CMIS and your favorite language to unlock c...
Apache Chemistry in Action: Using CMIS and your favorite language to unlock c...Apache Chemistry in Action: Using CMIS and your favorite language to unlock c...
Apache Chemistry in Action: Using CMIS and your favorite language to unlock c...
 
Alfresco: The Story of How Open Source Disrupted the ECM Market
Alfresco: The Story of How Open Source Disrupted the ECM MarketAlfresco: The Story of How Open Source Disrupted the ECM Market
Alfresco: The Story of How Open Source Disrupted the ECM Market
 
Join the Alfresco community
Join the Alfresco communityJoin the Alfresco community
Join the Alfresco community
 
Intro to the Alfresco Public API
Intro to the Alfresco Public APIIntro to the Alfresco Public API
Intro to the Alfresco Public API
 
Apache Chemistry in Action
Apache Chemistry in ActionApache Chemistry in Action
Apache Chemistry in Action
 
Building Content-Rich Java Apps in the Cloud with the Alfresco API
Building Content-Rich Java Apps in the Cloud with the Alfresco APIBuilding Content-Rich Java Apps in the Cloud with the Alfresco API
Building Content-Rich Java Apps in the Cloud with the Alfresco API
 
Alfresco Community Survey 2012 Results
Alfresco Community Survey 2012 ResultsAlfresco Community Survey 2012 Results
Alfresco Community Survey 2012 Results
 
Getting Started with CMIS
Getting Started with CMISGetting Started with CMIS
Getting Started with CMIS
 
Relational Won't Cut It: Architecting Content Centric Apps
Relational Won't Cut It: Architecting Content Centric AppsRelational Won't Cut It: Architecting Content Centric Apps
Relational Won't Cut It: Architecting Content Centric Apps
 
Alfresco SAUG: State of ECM
Alfresco SAUG: State of ECMAlfresco SAUG: State of ECM
Alfresco SAUG: State of ECM
 
Alfresco SAUG: CMIS & Integrations
Alfresco SAUG: CMIS & IntegrationsAlfresco SAUG: CMIS & Integrations
Alfresco SAUG: CMIS & Integrations
 
Should You Attend Alfresco Devcon 2011
Should You Attend Alfresco Devcon 2011Should You Attend Alfresco Devcon 2011
Should You Attend Alfresco Devcon 2011
 
2011 Alfresco Community Survey Results
2011 Alfresco Community Survey Results2011 Alfresco Community Survey Results
2011 Alfresco Community Survey Results
 
Intro to Alfresco for Developers
Intro to Alfresco for DevelopersIntro to Alfresco for Developers
Intro to Alfresco for Developers
 

Recently uploaded

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Recently uploaded (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 

Moving From Actions & Behaviors to Microservices

  • 1. Moving from Actions & Behaviors to Microservices Jeff Potts, Metaversant @jeffpotts01
  • 2. How do we make it easier to integrate Alfresco with other systems?
  • 3. Learn. Connect. Collaborate. “We want to be able to report against metadata in real-time.” “When this custom property changes we need to notify this other system.” “We want to improve how Alfresco transforms Word documents into HTML.” “When content changes we want to run it through an NLP model.” “Our company has an enterprise search solution that needs to index Alfresco content.” “We want to replicate content between multiple Alfresco servers.” Recurring customer requirements
  • 4. Learn. Connect. Collaborate. Traditional approaches run in-process • Custom Alfresco Actions – Java, deployed to Alfresco WAR – Triggered by rule on a folder, a UI action, or by a schedule • Custom Alfresco Behaviors – Java, deployed to Alfresco WAR – Bound to a policy on a class of nodes (e.g., specific type or aspect) • Custom Web Scripts – Java or JavaScript, deployed to Alfresco WAR – Triggered by a REST call • All of these run in Alfresco’s process
  • 5. Learn. Connect. Collaborate. Tradeoffs of the traditional approach • Advantages – Full access to the Alfresco API – Runs as the authenticated user or as the system user – Code is managed with the content model and other customizations • Disadvantages – Performance risk – Requires server restart to deploy – Requires an Alfresco developer familiar with Alfresco API • Java & JavaScript are the only practical language options – Long-running tasks may block user interface – Scales as Alfresco scales
  • 7. Learn. Connect. Collaborate. Event-based integration approach • Alfresco can be extended to generate generic events when something happens to a node • Interested systems – Listen for Alfresco events – Filter out what they don’t care about – Fetch additional data from Alfresco and perform custom logic as needed • Additional systems can be added without touching Alfresco • Systems can use different frameworks & languages • Independently scalable • Can use Alfresco Kafka as a starting point
  • 8. Learn. Connect. Collaborate. Apache Kafka Alfresco Microservice Event Event Microservice Event Microservice Event Move logic out of Alfresco into microservices alfresco- kafka Kafka Client JAR
  • 9. Learn. Connect. Collaborate. Example event JSON { "nodeRef": "3f375925-fa87-4e34-9734-b98bed2d483f", "eventType": "CREATE", "path": "/{http://www.alfresco.org/model/application/1.0}company_home/…/{http://www.alfresco .org/model/content/1.0}test2.txt", "created": 1497282061322, "modified": 1497282061322, "creator": "admin", "modifier": "admin", "mimetype": "text/plain", "contentType": "content", "siteId": "test-site-1", "size": 128, "parent": "06a154e3-4014-4a55-adfa-5e55040fae2d” }
  • 11. Learn. Connect. Collaborate. Alfresco Kafka Listener Example • Alfresco Kafka – https://github.com/jpotts/alfresco-kafka • Alfresco Kafka Listener Example – https://github.com/jpotts/alfresco-kafka-listener-example • Demo: https://youtu.be/K40M2gJA7vM
  • 12. Learn. Connect. Collaborate. Alfresco Kafka Listener • Small Spring Boot app • Runs in a servlet container • Logs Alfresco Kafka events • Example/starter code Apache Kafka Alfresco alfresco-kafka-listener alfresco- kafka Kafka Client JAR Event Event
  • 14. Learn. Connect. Collaborate. GenerateNodeEvent behavior calls MessageService @Override public void onCreateNode(ChildAssociationRef childAssocRef) { NodeRef nodeRef = childAssocRef.getChildRef(); if (nodeService.exists(nodeRef)) { messageService.publish(nodeRef, NodeEvent.EventType.CREATE); } }
  • 15. Learn. Connect. Collaborate. MessageService sends JSON to the Kafka queue public void init() { producer = new KafkaProducer<>(createProducerConfig()); } public void publish(NodeRef nodeRef, NodeEvent.EventType eventType) { NodeEvent e = nodeTransformer.transform(nodeRef); e.setEventType(eventType); publish(e); } private void publish(NodeEvent event) { try { final String message = mapper.writeValueAsString(event); if (message != null && message.length() != 0) { producer.send(new ProducerRecord<String, String>(topic, message)); } } catch (JsonProcessingException jpe) { logger.error(jpe); } }
  • 16. Learn. Connect. Collaborate. Example listener logs event type and node ref @KafkaListener(topics="${kafka.topic}", group = "${kafka.group}", containerFactory = "nodeEventKafkaListenerFactory") public void consumeJson(NodeEvent nodeEvent) { try { if (nodeEvent.getContentType().equals("F:cm:systemfolder") || nodeEvent.getContentType().equals("F:bpm:package") || nodeEvent.getContentType().equals("I:act:actionparameter") || nodeEvent.getContentType().equals("I:act:action") || nodeEvent.getContentType().equals("D:cm:thumbnail")) { return; } logger.debug("Event: " + nodeEvent.getEventType() + " on " + nodeEvent.getNodeRef()); } catch (Exception e) { logger.error(e.getMessage()); } }
  • 17. Real World Example: Reporting
  • 18. Learn. Connect. Collaborate. Example: Alfresco reporting • Customer: “We want to be able to report against metadata in real-time.” • Solution: – Spring Boot microservice consumes Alfresco Kafka events – When a node changes that is interesting, it fetches the metadata using CMIS – Indexes metadata into Elasticsearch – Kibana dashboard used to visualize data • Demo: https://youtu.be/jGZVfP5L8yU
  • 19. Learn. Connect. Collaborate. Indexer Service • Small Spring Boot app • Runs in a servlet container • Listens for Alfresco Kafka events • Fetches the Alfresco Node as JSON • Indexes the Node JSON into Elasticsearch • Deletes objects from Elasticsearch when DELETE events occur Apache Kafka Alfresco Elasticsearch Cluster alf-es-indexer alfresco- kafka Kafka Client JAR Event Event CMIS GET Node JSON Node JSON
  • 21. Learn. Connect. Collaborate. KafkaConsumer fetches the node, calls indexer if (nodeEvent.getEventType().equals(NodeEvent.EventType.CREATE) || nodeEvent.getEventType().equals(NodeEvent.EventType.UPDATE) || nodeEvent.getEventType().equals(NodeEvent.EventType.PING)) { Node node = alfrescoService.getNode(nodeEvent.getNodeRef()); // Copy some of the properties from the event onto the node object if (nodeEvent.getParent() != null) { node.setParent(nodeEvent.getParent()); } if (nodeEvent.getSiteId() != null) { node.setSiteId(nodeEvent.getSiteId()); } nodeIndexer.index(node); } else if (nodeEvent.getEventType().equals(NodeEvent.EventType.DELETE)) { nodeRemover.delete(nodeEvent.getNodeRef()); }
  • 23. Real World Example: Metadata Enrichment with NLP
  • 24. Learn. Connect. Collaborate. Example: Natural Language Processing • Customer: “I want to be able to enrich Alfresco metadata by extracting people, places, and names from content using an NLP model” • Solution: – Spring Boot microservice consumes Alfresco Kafka events – When a node with a “marker” aspect changes, the microservice fetches the content – Fingerprints are used to avoid repeatedly processing the same content – Text is extracted using Apache Tika – Extracted text is run through Apache OpenNLP to extract people and places – People and places are written to Alfresco content metadata via CMIS • Demo: https://youtu.be/H-2TgoUijzY
  • 25. Learn. Connect. Collaborate. NLP Enricher Service • Small Spring Boot app • Runs in a servlet container • Listens for Alfresco Kafka events • Fetches Alfresco content • Extracts people, places, and orgs • Writes metadata back to Alfresco Apache Kafka Alfresco alf-nlp-enricher alfresco- kafka Kafka Client JAR Event Event CMIS GET Node JSON CMIS POST
  • 27. Learn. Connect. Collaborate. NodeProcessor uses hash to avoid re-processing file String hash = null; try { hash = HashSumGenerator.getHash(new FileInputStream(new File(downloadFilePath))); logger.debug("Hash: " + hash); } catch (FileNotFoundException fnfe) { logger.error("Download file not found"); } // If we have seen this exact content before for this node, stop String pastHash = pastHashesById.get(id); if (pastHash != null) { logger.debug("Past hash: " + pastHash); if (pastHash.equals(hash)) { logger.debug("Have already processed this exact file for this id, skipping"); deleteFile(downloadFilePath); return; } }
  • 28. Learn. Connect. Collaborate. Detect sentences, call OpenNLP, update metadata String sentences[] = sentenceDetector.detect(text); for (String sentence : sentences) { locations = addToSet(locationExtractor.extract(sentence), locations); orgs = addToSet(orgExtractor.extract(sentence), orgs); names = addToSet(nameExtractor.extract(sentence), names); } HashMap<String, Serializable> properties = new HashMap<>(); properties.put(PROP_LOCATIONS, toArrayList(locations)); properties.put(PROP_ORGS, toArrayList(orgs)); properties.put(PROP_NAMES, toArrayList(names)); try { alfrescoService.updateNode(id, properties); } catch (AlfrescoServiceException ase) { logger.error(ase.getMessage()); }
  • 31. Learn. Connect. Collaborate. Apache Kafka Alfresco Microservice Event Event Microservice Event Microservice Event Move logic out of Alfresco into microservices alfresco- kafka Kafka Client JAR
  • 32. Learn. Connect. Collaborate. Other potential uses • Full-text search indexing into standalone search engine • Synchronizing content with other servers • Improved HTML transformations • Notification/subscription service • Chat integration
  • 33. Learn. Connect. Collaborate. Event-based approach disadvantages • More code/complexity than traditional approach • User feedback/notification is not straightforward • Potentially increases the number of “containers” in the IT shop
  • 34. Learn. Connect. Collaborate. Event-based approach advantages • In-line with Alfresco’s stated architectural direction • Reduces the amount of code running in Alfresco’s process – Reduces the number of deployments required to support integrations – Off-loads long-running and/or process-intensive integrations from Alfresco – Scales independently of Alfresco • Integrations are more loosely-coupled from Alfresco – Requires less Alfresco knowledge – Frees up architectural choices for integrations (not just Java) • Integration apps are relatively easy to containerize • Can work alongside traditional approach
  • 35. Learn. Connect. Collaborate. Demo Dependency Versions • Alfresco 5.2.g CE & 5.2.3 Enterprise with – Metaversant Alfresco Kafka open source add-on 0.0.2 • Apache Kafka 2.12-0.10.2.1 • Elasticsearch 6.3.2 • Kibana 6.3.2 • Custom Spring Boot applications – Spring Boot 1.5.8 – Elasticsearch High-level Rest Client 6.3.2 – Tika 1.18 – OpenNLP 1.8.4 – Apache Chemistry 1.0.0
  • 36. Learn. Connect. Collaborate. Links • Apache Kafka: http://kafka.apache.org/ • Apache OpenNLP: http://opennlp.apache.org/ • Apache Tika: https://tika.apache.org/ • Elasticsearch: https://www.elastic.co/products/elasticsearch • Kibana: https://www.elastic.co/products/kibana • Spring Boot: https://spring.io/projects/spring-boot
  • 37. Learn. Connect. Collaborate. See Also • Apache ManifoldCF – http://manifoldcf.apache.org/ – Crawler that indexes from repositories like Alfresco into Solr & Elasticsearch • Apache Stanbol – http://stanbol.apache.org/ – Semantic engine that can do metadata enhancement and other things • Apache Camel – http://camel.apache.org/ – Enterprise integration platform
  • 38. Learn. Connect. Collaborate. • Consulting firm focused on solving business problems with open source Content Management, Workflow, & Search technology • Founded in 2010 • Clients all over the world in a variety of industries, including: – Airlines & Aerospace – Manufacturing – Construction – Financial Services – Higher Education – Life Sciences – Professional Services https://www.metaversant.com
  • 39. Moving from Actions & Behaviors to Microservices Jeff Potts, Metaversant @jeffpotts01

Editor's Notes

  1. …without writing one-off integrations that must be deployed to the Alfresco server …without adding unnecessary performance burden on Alfresco …without requiring other teams to learn Alfresco internals
  2. Triggers can be action-driven or change-driven or both. These requirements often met with actions and behaviors.
  3. Event is kept minimal to avoid disclosing sensitive information and to keep the solution as generic as possible.
  4. Alfresco Insight Engine is an interesting alternative, but it requires the latest Alfresco version.
  5. For a production implementation, the past hashes should probably be persisted somewhere instead of being kept in memory