APACHE SLING & FRIENDS TECH MEETUP
2 - 4 SEPTEMBER 2019
Swagger AEM - An OpenAPI Specification For AEM
Cliffano Subagio and Michael Bloch, Shine Solutions Australia
About
2
Cliffano Subagio and Michael Bloch!
Consultants at Shine Solutions, Australia!
AEM OpenCloud Core Contributors
3
Early challenges with AEM provisioning
Our first ‘AEM on the cloud’ project
4
AEM 5.6 on AWS circa 2013-2014
Infrastructure as code
Cloud: auto-provisioning, auto-recoverable
AEM tooling largely ‘Java-focused’
Sysops teams use of non-Java tools
We were advised to use cURL
5
Integrate this harmless shell script with cURL!
6
set -o errexit
result=$(curl )
if [[$result = *“error” ]]; then
exit 123
fi
Is it really harmless?
7
set -o errexit
result=$(curl )
if [[$result = *“error” ]]; then
exit 123
fi
<- Unreliable exit code
<- Fragile error checking
<- Uninformative error result
<- No success result
Problems with AEM Web ‘API’
8
cURL is not always available everywhere
Inconsistent response payload types!
JSON, XML, HTML
Unreliable status code!
Response 200 on change password error
Lack of integration with various tech stacks!
The world has been polyglot for a while
9
What did we do to solve this?
10
We built Swagger AEM
What is Swagger AEM?
11
API specification for AEM endpoints
OpenAPI version 3
OpenAPI Generator
API clients for 30+ languages
OpenAPI specification - metadata
12
OpenAPI specification - path
13
API Clients Generation
14
OpenAPI
Specification!
swagger_aem
Ruby API Client!
ruby_aem
Resource-oriented!
Ruby API Client
Other languages!
API Clients…
Python API Client
Go API Client
What is Ruby AEM?
15
Resource-oriented design Ruby API
Further abstraction from AEM endpoints
Error and response objects
Result handling
16
package = aem.package(‘mygroup’, ‘mypkg’, ‘1.2.3’)!
opts = { force: true }!
result = package.upload(‘/tmp’, opts)
!
puts result.message
puts result.response.status_code
puts result.response.body!
puts result.response.headers
Error handling
17
begin!
package = aem.package(‘mygroup’, ‘mypkg’, ‘1.2.3’)
opts = { force: true }!
result = package.upload(‘/tmp’, opts)
rescue RubyAem::Error => err!
puts err.message
puts err.result.response.status_code
puts err.result.response.body!
puts err.result.response.headers
end
What else can Swagger AEM and Ruby AEM do?
18
Replication, flush, reverse replication agents
Packages, users, groups, paths, nodes
Certificates, truststores, keystores
Resource readiness checks with retries
Many more to add in the future!
19
We also built Swagger AEM OSGI
SAML config with AEM package
20
!
AEM Developer!
!
System Engineer!
Please update SAML provider.
What’s the provider name?
It’s sso-provider-123.
Done. Please test.
Doesn’t work. Any typo?
How about cURL?
21
curl -v -u admin:admin -F 'jcr:primaryType=sling:OsgiConfig' -F
'keyStorePassword="password"' -F 'service.ranking=I"5002"' -F 'idpHttpRedirect=B"true"' -
F 'createUser=B"true"' -F 'defaultRedirectUrl="/sites.html"' -F 'userIDAttribute="NameID"'
-F 'defaultGroups=["content-authors"]' -F 'idpCertAlias="certalias___1471833774937"' -F
'addGroupMemberships=B"true"' -F 'path=["/"]' -F
'synchronizeAttributes=["givenName=profile/givenName,familyName=profile/
familyName,mail=profile/email"]' -F 'clockTolerance=I"60"' -F
'groupMembershipAttribute="http://temp/variable/aem-groups"' -F 'idpUrl="https://
accounts.google.com/o/saml2/idp?idpid=xyz"' -F 'logoutUrl="https://
accounts.google.com/logout"' -F ‘serviceProviderEntityId="AEMSSO"' -F
'handleLogout=B"true"' -F 'spPrivateKeyAlias=""' -F 'useEncryption=B"false"' -F
'nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"'
What is Swagger AEM OSGI?
22
API specification for AEM OSGI configurations
Converted from Configuration Admin Service
71k+ lines of generated OpenAPI v3 spec
12m+ lines of generated API clients
Regenerated for each AEM version
API Clients Generation
23
Configuration
Admin
Service
swagger_aem_osgi
OpenAPI Specification!
swagger_aem_osgi
API Clients
In 30+ Languages!
Apache Felix Web Console
24
Converted into OpenAPI specification
25
paths:
"/system/console/configMgr/Adaptive Form
post:
parameters:
- name: showPlaceholder
in: query
schema:
type: boolean
- name: maximumCacheEntries
in: query
schema:
type: integer
- name: af.scripting.compatversion
in: query
schema:
type: string
- name: makeFileNameUnique
in: query
schema:
type: boolean
- name: generatingCompliantData
in: query
schema:
type: boolean
operationId: adaptiveFormAndInteractiveCommunicationWebChannelConfiguration
tags:
- configmgr
responses:
'200':
description: Successfully retrieved configuration parameters
content:
application/json:
schema:
"$ref": "#/components/schemas/adaptiveFormAndInteractiveCommunicationWebChannelConfigurationInfo"
'302':
description: Default response
content:
text/plain:
schema:
type: string
default:
description: Default response
content:
application/json:
schema:
type: string
Converted into Ruby API client code
26
27
Demo: SAML provisioning
Demo
Code flow
28
puppet-aem-resources
ruby_aem
swagger_aem_osgi
OSGI configuration
Provisioning tool
API client
AEM
29
Demo: AEM package installation via voice
Demo
Data flow
30
Install package ABC”
{ “inputs”: [
{ “intent”: “actions.intent.TEXT”,
“rawInputs”: [ {
“inputType”: “VOICE”,
“queryType”: “Install package ABC”
}]}]}
{ "queryText": “Install package ABC",
"parameters": {
"packageName": "ABC"
},
"intent": {
"displayName": “install-package"
}}
/crx/packmgr/service/.json/{path}
200 OK
{
"fulfllmentText”: "Package ABC has been installed”,
"payload”: { "google”: { "richResponse”: { "items”: [
"simpleResponse”: {
"textToSpeech”: "Package ABC has been installed”,
"displayText”: "Package ABC has been installed”,
}]}}}}
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [ { "simpleResponse": {
"textToSpeech": "Package ABC has been installed”
}}]}}}]}
“Package ABC has been installed”
31
In conclusion
What have we learned?
32
API specifications enable API clients
API clients enable richer integration
AEM provisioning doesn’t have to be!
Java-focused
Think outside the box!!
Lots of DevOps tools to integrate
Most important of all
33
You are welcome to join this effort!
and contribute to benefit!
the wider AEM community!
34
Thank you and any questions ?
Links
35
- https://github.com/shinesolutions/swagger-aem
- https://github.com/shinesolutions/ruby_aem
- https://github.com/shinesolutions/swagger-aem-osgi
- https://github.com/shinesolutions/adaptto-2019-demo
- https://aemopencloud.io/
- https://www.openapis.org/
- https://openapi-generator.tech/