integration patterns in aem 6
TRANSCRIPT
![Page 1: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/1.jpg)
INTEGRATION
PATTERNS IN AEMYuval Ararat
![Page 2: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/2.jpg)
• Basics
• Sling
• Integration
• Sample
• Other resources
• Sling Models
![Page 3: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/3.jpg)
• What do we integrate with?
– Backend API layer• SAP PI, Oracle Fusion or other middleware layer.
• Bespoke API
– DB
– File System
– Forms Engine
![Page 4: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/4.jpg)
• First questions when arriving to the scene.
– Is it exposed to WWW?
– What authentication does the layer require?
– What can I cache?
– Protocol and output formats.
![Page 5: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/5.jpg)
• Exposed to WWW?
– Client side integration
– Mixed integration
• Not exposed to the WWW
– Server Side
– Tunneled through
![Page 6: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/6.jpg)
![Page 7: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/7.jpg)
• SlingMainServlet
– Outermost Request Handler
– Starts Request Processing
• ResourceResolver
– Resolves the URL to a Resource
• ServletResolver
– Resolve the Resource Type to a Servlet/Script
![Page 8: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/8.jpg)
• Resolve the Resource
– Source: Request URI
• Resolve Servlet or Script
– Source: Resource Type
• sling:resourceType
• sling:resourceSuperType
• Call Servlet Filters
• Call Servlet or Script
protocol host path selector extension
http:// myhost/ .print.a4 .html /tools/spy
suffix
a/b ?
param(s)
x=12
![Page 9: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/9.jpg)
• ResourceProvider
• Sling Filter
• Custom SlingServlet
• OSGi HTTP Service
![Page 10: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/10.jpg)
![Page 11: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/11.jpg)
• Provides access to resources from different locations
through a single ResourceResolver
• Registered to a path in the virtual resource tree
• The last fallback is always the JCR repository
![Page 12: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/12.jpg)
• PlanetResourceProvider Sample
• Respond with a relevant planet resource when calling
“/planets/<planet>”
https://svn.apache.org/repos/asf/sling/trunk/launchpad/test-
services/src/main/java/org/apache/sling/launchpad/testservices/resourceprovider/
![Page 13: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/13.jpg)
@Component
@Service
@Properties({
@Property(name=ResourceProvider.ROOTS, value=PlanetsResourceProvider.ROOT)
})
public class PlanetsResourceProvider implements ResourceProvider {
private static final Map<String, ValueMap> PLANETS = new HashMap<String, ValueMap>();
/** This can be configurable of course */
public static final String ROOT = "planets";
public static final String ABS_ROOT = "/" + ROOT;
static {
definePlanet("Mercury", 57910);
definePlanet("Venus", 108200);
definePlanet("Earth", 149600).put("comment", "Resources can have different sets of properties");
definePlanet("Mars", 227940);
definePlanet("Jupiter", 4332);
definePlanet("Saturn", 10759);
definePlanet("Uranus", 30685);
definePlanet("Neptune", 60190);
// Add the moon to test a two-level hierarchy
final String moonPath = ABS_ROOT + "/earth/moon";
PLANETS.put(moonPath, new PlanetResource.PlanetValueMap("Moon", 384));
}
![Page 14: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/14.jpg)
public Resource getResource(ResourceResolver resolver, HttpServletRequest req, String path) {
// Synthetic resource for our root, so that /planets works
if((ABS_ROOT).equals(path)) {
return new SyntheticResource(resolver, path, PlanetResource.RESOURCE_TYPE);
}
// Not root, return a Planet if we have one
final ValueMap data = PLANETS.get(path);
return data == null ? null : new PlanetResource(resolver, path, data);
}
![Page 15: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/15.jpg)
public Iterator<Resource> listChildren(Resource parent) {
if(parent.getPath().startsWith(ABS_ROOT)) {
// Not the most efficient thing...good enough for this example
final List<Resource> kids = new ArrayList<Resource>();
for(Map.Entry<String, ValueMap> e : PLANETS.entrySet()) {
if(parent.getPath().equals(parentPath(e.getKey()))) {
kids.add(new PlanetResource(parent.getResourceResolver(), e.getKey(), e.getValue()));
}
}
return kids.iterator();
} else {
return null;
}
}
![Page 16: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/16.jpg)
@Adaptable(adaptableClass=Resource.class, adapters={
@Adapter({ValueMap.class})
})
public class PlanetResource extends AbstractResource implements Resource {
private final String path;
private final ResourceMetadata metadata;
private final ValueMap valueMap;
private final ResourceResolver resolver;
public static final String RESOURCE_TYPE = "sling/test-services/planet";
PlanetResource(ResourceResolver resolver, String path, ValueMap valueMap) {
this.path = path;
this.valueMap = valueMap;
this.resolver = resolver;
metadata = new ResourceMetadata();
metadata.setResolutionPath(path);
}
![Page 17: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/17.jpg)
– BundleResourceProvider provides access to files and directories
contained in an OSGi bundle
– The BundleResourceProvider is responsible for mapping the
directory tree into the resource tree
– It‘s most conveniently configured as instruction in the maven-
bundle-plugin:<configuration>
<instructions>
<Sling-Bundle-Resources>/resource/tree;path:=/bundle/tree</Sling-Bundle-Resources>
</instructions>
</configuration>
![Page 18: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/18.jpg)
– FsResourceProvider, which is part of org.apache.sling.fsresource,
maps file system paths as resources.
– Requires installation.
– Configuration through fsresource.xml:
• provider.roots
• Provider.files
– http://sling.apache.org/documentation/bundles/accessing-filesystem-resources-
extensions-fsresource.html
![Page 19: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/19.jpg)
• Sling Models
– Creating an adaptable class from a POJO by annotations
• Blueprints
– Dependency injection framework for OSGi
– Implementations include SpringDM (Historical) and Neba.io
• Cognifide Slice framework
– God’s speed…
![Page 20: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/20.jpg)
• Creating an adaptable class from a POJO by annotations
– Resource resource = getResource();– Return resource.adaptTo(YourCustom.class);
– @Model(adaptables = Resource.class)– public class YourCustom {
– ...– }
• Use Sling Models for Controller or Business Logic that is “context-aware”• Use Value Map to read resource data
• http://sling.apache.org/documentation/bundles/models.html
![Page 21: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/21.jpg)
• Use Sling Models for Dependency
Injection
– Inject Sling Context Objects via @SlingObject
– Inject AEM Context Objects via @AemObject
– Inject Business Classes via @Self
– Inject Resource Data or Parameters
• Dependencies can be mocked with tools like
Mockito@InjectMocks
![Page 22: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/22.jpg)
• Injecting
@Model(adaptables= Resource.class) public class YourCustom{
@Inject // we expected always an email-property
private String email;
@Inject @Optional // first name can be empty
private String firstName;
// read property “surname” if empty use “empty”
@Inject @Named(“surname“) @Default(values=“empty“)
private String lastName;
}
![Page 23: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/23.jpg)
@Model(adaptables= Resource.class)Public class YourCustom{
@Inject// OSGiServiceprivate Externalizer externalizer;
@PostConstructProtected void init() {
// gets executed after the class is created// set to protected, so it can be unit-tested
}}
![Page 24: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/24.jpg)
@Model(adaptables= Resource.class)Public class YourCustom{
//option1@Selfprivate Resource resource;
//option2public YourCustom(Resource resource) {
// to get access to the adaptorthis.resource= resource;
}}
![Page 25: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/25.jpg)
• Available for AEM6
– Can be installed in CQ5.6.1
– Sling Models Content Packages
– https://github.com/Adobe-Consulting-
Services/com.adobe.acs.bundles.sling-
models/releases
• What’s new in Sling Models 1.1
– http://adapt.to/2014/en/schedule/whats-new-in-sling-
models-11.html
![Page 26: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/26.jpg)
• Recommended pattern: Controller per concern,
not per component!
• Controllers are Sling Models
• Component/View can re-use multiple controllers
![Page 27: Integration patterns in AEM 6](https://reader030.vdocuments.us/reader030/viewer/2022013105/55a2e2a71a28ab35358b45e6/html5/thumbnails/27.jpg)
• Sling Models Documentation
– http://sling.apache.org/documentation/bundles/model
s.html
• Sling Models 1.0.x Introduction by Justin Edelson
– http://slideshare.net/justinedelson/sling-models-
overview
• AEM Object Injector Implementations
– http://wcm.io/sling/models/
– http://adobe-consulting-services.github.io/acs-aem-
commons/features/aem-sling-models-injectors.html