AEM 5.6.1 im Clusterbetrieb – Notwendige Sourcecodeanpassungen

Ausgangslage

In einem unserer Kundenprojekte, das mit AEM 5.6.1 umgesetzt wurde, kam ein Cluster von AEM-Autoreninstanzen zum Einsatz. Dadurch sollte vor allen Dingen eine hohe Ausfallsicherheit erreicht werden.

Wir haben geprüft, welche Anpassungen wir an unseren Sourcecode vornehmen mussten, um ein fehlerfreies Funktionieren im Cluster zu garantieren. Wir wollten auf jeden Fall vermeiden, dass zur selben Zeit die gleichen Schreibzugriffe auf die Contentrepositories der einzelnen Clusterknoten erfolgen, z.B. durch einen zeitgesteuerten Service. Durch die anschliessende Replikation der Änderungen käme es zu redundanten Schreiboperationen und somit zu einem unnötigen Resourcenverbrauch.
(mehr …)

Umgang mit Vanity URLs

Allgemeines

In CQ/AEM gibt es eine Funktionalität für Kurz-URLs genannt Vanity URLs. Diese werden genutzt, um z.B. marketing-freundliche URLs zu erzeugen. Z.B. www.domain.de/jobs, um eine URL für eine Job-Kampagne zu haben. Im Normalfall wird beim Aufruf dieser URL eine automatische Weiterleitung auf die eigentliche Seite im CQ/AEM erfolgen. Z.B. auf www.domain.de/de/home/company/jobs.html.

Die Verwendung von Vanity URLs im Autoren-Interface ist in der Adobe Dokumentation kurz beschrieben.

Redirect / SEO

Eine Weiterleitung in AEM erfolgt standardmäßig mit dem HTTP-Status 302 „Found“.  Aus SEO-Sicht stellt die Verwendung einer Vanity-URL allerdings keine vorübergehende Weiterleitung dar, sondern eine permanente. Daher sollte CQ/AEM so konfiguriert werden, dass der Redirect mit dem Status Code 301 „Moved Permanently“ erfolgt.

Die Einstellung des Default HTTP-Status erfolgt im Apache Felix im „Apache Sling Resource Resolver Factory“ in der Einstellung „Default Vanity Path Redirect Status“.

Technische Hürden

1.) In der Dispatcher-Konfiguration wird standardmäßig mit einem Whitelisting-Ansatz das System gehärtet.

D.h. nur bestimmte Pfade sind erlaubt. Vanity URLs stehen immer direkt hinter der Domain und daher ist der Aufruf redaktionell gepflegter Vanity URLs meistens nicht so einfach möglich.

Lösungsidee

Für dieses Probleme gibt es einen Lösungsansatz, der wie folgt aussieht:

  • Vanity URLs werden vom Redakteur mit einem vanity/ als Prefix gepflegt. Z.B. vanity/jobs
  • Im Webserver gibt es eine Rewrite Rule, welche Vanity URLs erkennt und entsprechend umschreibt („/jobs“ wird umgeschrieben, „/jobs/zwei“ nicht)
    RewriteRule ^/([-0-9a-z]+)$ /vanity/$1 [PT]
  • In der Dispatcher-Konfiguration gibt es einen Whitelist-Eintrag für Pfade, die mit „vanity/“ beginnen
    /0123 { /type "allow" /glob "GET /vanity/*" }
  • Damit ist die Verwendung von Vanity URLs mit dem Prefix „vanity/“ ohne weitere Konfigurationen redaktionell nutzbar.

Ab einer Dispatcher-Version 4.1.9 wird es für dieses Problem seitens Adobe eine neue Möglichkeit für Vanity-URL-Konfigurationen im Dispatcher geben. Dieses Feature wurde in einem Screencast vorgestellt, ist allerdings anscheinend noch nicht dokumentiert.

2.) Vanity URLs müssen im Gesamtsystem eindeutig sein, was zu Problemen bei Multimandanten-Systemen führt. So kann ein Mandant B nicht nochmal eine selbe Vanity URL vergeben, wenn sie schon Mandant A vergeben hat

Lösungsidee

Wenn mehrere Mandanten existieren, benötigt es noch einen weiteren Bezeichner in dem konfigurierten Vanity-URL-Prefix. Das durch den Redakteur zu pflegende Prefix müsste um den Mandantenbezeichner erweitert werden und wie folgt lauten: „vanity/<mandant>/„. Jeder Mandant hätte vermutlich eine eigene Webserverkonfiguration, so dass die o.g. Rewrite Rule pro Mandant entsprechend um den Namen des Mandanten erweitert werden müsste.

3.) Es gibt keine Auflistung der Vanity URLs im CQ/AEM.

Lösungsidee

Entweder ein Servlet schreiben, welches sich dieser Query bedient und eine Ausgabe z.B. in Form einer csv-Datei generiert. Denkbar wäre auch eine Ausgabe auf einem technischen Template. Standardmäßig gibt es nur eine Auflistung aller Mappings inkl. Vanity-URLs in der Felix Konsole unter „Status“ -> „Sling Resource Resolver

4.) Vanity-URLs ohne Extension und ohne Redirect werden nicht gecached

Lösungsidee

Es ist ebenfalls eine Lösung über Apache mod_rewrite möglich / denkbar. Zum Beispiel, wenn man davon ausgeht, dass alle URLs ohne Extensions Vanity-URLs sind. Weitere Problematik kommt mit verschiedenen Mandanten.

AEM in der Google Cloud

logo

Seit etwas über einem Jahr enthält die Cloud Plattform von Google auch eine IaaS Komponente mit dem Namen Google Compute Engine. In diesem Blogpost möchte ich kurz aufzeigen, was die Plattform bietet und anhand eines kleinen Beispieles aufzeigen, wie man mit wenigen … Weiterlesen

Apache Sling Models – Teil 2 – Hands-On

Mit der neuen Erweiterung Apache Sling Models bietet Apache Sling unter anderem die Möglichkeit über Annotations Objekte mit Inhalten des Repositories zu befüllen. In diesem Hands-On wird erklärt, wie Apache Sling Models anhand konkreter Beispiele in der aktuellen Version Adobe AEM 5.6.1 eingesetzt werden kann und was dabei zu beachten ist. Eine Einführung in das Thema gibt es im ersten Teil dieser Blog-Serie.

Apache Sling Models ist neu
Apache Sling Models ist ganz frisch und daher noch nicht praxiserprobt. Dieses Hands-On ist eine Aufforderung diese Erweiterung zu testen. Wie gut sich diese in der Praxis bewährt, wird sich noch zeigen.

Benötigte OSGI-Bundles
AEM 5.6.1 bringt die OSGI-Bundles für Apache Sling Models nicht mit. Die entsprechenden Bundles müssen daher installiert werden. Apache Sling Models selbst besteht aus den folgenden beiden Bundles:

org.apache.sling:org.apache.sling.models.impl:1.0.0
org.apache.sling:org.apache.sling.models.api:1.0.0

Damit die Models direkt in JSPs verwendet werden können, gibt es eine Erweiterung der Sling JSP Scripting Taglib um den Tag sling:adaptTo. Damit dieser Tag verwendet werden kann, muss das entsprechende Bundle in AEM 5.6.1 mit der aktuellsten Version aktualisiert werden:

org.apache.sling:org.apache.sling.scripting.jsp.taglib:2.2.0

Die URI der neuen Version der Taglib unterscheidet sich von der älteren und enthält neu keine Versionsnummer mehr. Die neue Taglib muss wie folgt registriert werden kann (beispielsweise über ein global.jsp).

<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling" %>

Eigenes OSGI Bundle anpassen
Damit die Models durch die neue Erweiterung in einem eigenen OSGI-Bundle verarbeitet werden können, müssen im Manifest des Bundles die Models respektive Packages angegeben werden:

<Sling-Model-Packages>
 com.namics.example.sling.models
</Sling-Model-Packages>

Code-Beispiel
Im OSGI-Bundle kann nun ein POJO erzeugt werden, welches mit den entsprechenden Annotations zum Sling Model wird.

@Model(adaptables = Resource.class)
public class Example {

    @Inject
    private String title;

    public String getTitle() {
        return title;
    }

}

Dieses Beispiel lässt sich nochmals vereinfachen. Es wird keine konkrete Implementierung des Models benötigt, ein Interface genügt:

@Model(adaptables = Resource.class)
public interface Example {

    @Inject
    public String getTitle();

}

In einem entsprechenden JSP kann dann auf dieses Objekt zugegriffen werden:

<%@include file="/apps/sling-models-example/global.jsp" %>
<sling:adaptTo adaptable="${resource}" adaptTo="com.namics.example.sling.models.Example" var="model"/>

<h2>${model.title}</h2>

In einer entsprechenden AEM-Komponente mit einem Dialog, welcher eine Property title schreiben kann, kann Apache Sling Models dann konkret getestet werden. Der Titel wird automatisch anhand des Namens der Methode oder Attributes geladen, soweit dieser über @Inject annotiert ist.

Dokumentation
Der folgende Link zu Apache Sling bietet weitere Details zu Apache Sling Models.

Erstes Fazit
Apache Sling Models ist eine interessante Erweiterung von Apache Sling. Sie bietet gute Möglichkeiten, um Adobe AEM/CQ Code besser zu strukturieren und die Qualität in Projekten zu erhöhen. Zudem lässt sich Apache Sling Models über ein Service Provider Interface (SPI) auch für projektspezifische Belange erweitern.

Apache Sling Models – Teil 1 – Vorstellung

Apache Sling ist ein Web-Framework und Basis von Adobe CQ/AEM. Es bietet eine nahtlose Integration zum JCR-Repository Apache Jackrabbit über die eigene Resource-API. Mit der neuen Erweiterung Apache Sling Models bietet Apache Sling nun die Möglichkeit über Annotations Objekte mit Inhalten eines Repositories zu befüllen oder auch OSGI-Services zu injizieren. Über einen JSP-Tag lässt sich ein solches Objekt erzeugen und in einem JSP-Template darauf zugreifen.

Welche Probleme löst Apache Sling Models?
Apache Sling Models basiert auf dem Adapter-Interface von Sling. Damit lassen sich beliebige Objekte in andere transformieren (adaptTo), soweit die entsprechende Transformation unterstützt wird. Dies wird auch durch Apache Sling Models verwendet. Ein Sling Resource-Objekt, welches beispielsweise Properties eines Blog-Eintrages enthält, kann mit resource.adaptTo(Example.class) über Sling Models direkt in ein entsprechendes POJO transformiert werden. Das POJO selbst hat abgesehen von Annotations keine Abhängigkeiten zum Sling Framework. Es lässt sich so beispielsweise besser mit JUnit testen und wird insgesamt einfacher.

Aktuelle Praxis
In unseren aktuellen Adobe AEM/CQ-Projekten werden ähnliche Ansätze, wie Apache Sling Models bietet, bereits verwendet. So verwendet Namics seit einigen Jahren eine eigene, auf Annotations basierendes Bibliothek. Ein wichtiger Vorteil für uns ist da die Trennung von Code und Templating. Die JSPs können ausschliesslich als Templates verwendet werden und die Logik ist in Java-Code enthalten. Dies erhöht die Code-Qualität einerseits durch das Design, andererseits auch durch bessere Testing-Möglichkeiten.

Beispiel
Das folgende Beispiel zeigt, wie ein einfaches Sling Model aussehen und verwendet werden kann.

@Model(adaptables=Resource.class)
public class Example {

@Inject
private String title;
}

Example example = resource.adaptTo(Example.class);

Im zweiten Teil dieser Blog-Serie wird das Beispiel näher erklärt und gezeigt, wie die ersten Schritte mit Apache Sling Models in AEM 5.6.1 durchgeführt werden können.

Schnelles Deployment in CQ mit den Sling IDE Tools

An der AdaptTo() 2013 wurde das erste Mal über die neuen Sling IDE Tools berichtet. Der Vortrag von Robert Munteanu gab einen guten Einblick über den aktuellen Stand und die Vision dahinter. In diesen Blogbeitrag berichte ich von den ersten Erfahrungen bei der CQ Entwicklung mit den Sling IDE Tools.

Die Sling IDE Tools sollen die Entwicklungsprozesse verbessern und im ersten Schritt das inkrementelle Deployment während der Entwicklung beschleunigen. Die Sling IDE Tools sind im Moment nur für Eclipse verfügbar, aber weitere Entwicklungsumgebungen sind später denkbar.

(mehr …)

Varnish Präsentation an adaptTo() 2013

An der adaptTo() 2013 habe ich für Namics einen Vortrag über das Thema Caching mit Varnish im Umfeld von CQ5 gehalten.

Die Inhalte:

  • Einleitung zu Varnish
  • Anwendungsfälle und mögliche Architekturen
  • Einschränkungen und Stolperfallen

Bei den Anwendungsfällen wurden drei Beispiele beschrieben, welche nachfolgend kurz erläutert werden.

(mehr …)

Pathmarks – Kleines Helferlein für AEM/CQ mit Google Chrome

Der Adobe Experience Manager (AEM) respektive CQ ist ein mächtiges System. Entsprechend vielfältig sind die Funktionen und alle sind irgendwie über URL-Pfade erreichbar. Wer mit AEM respektive CQ entwickelt oder mehrere Instanzen und Umgebungen (Produktion, Test, Integration, Entwicklung etc.) betreut, ruft daher auf den jeweiligen Systeme immer mal wieder dieselben Pfade auf. Die Hostnames (und/oder Ports) ändern sich natürlich, die Pfade bleiben aber dieselben. Einige Pfade sind irgendwann im Gedächtnis präsent, von einigen ist bekannt, wo im System ein Link darauf vorhanden ist und bei anderen, wo in der Dokumentation der gewünschte Pfad zu finden sein könnte. Es gibt aber immer auch mal die Situation, wo auf einem System das Ziel bekannt ist, der Weg allerdings neu gesucht werden muss.

Mit der Google Chrome Extension Pathmarks gibt es ein praktisches Helferlein, welches diese Suche nach dem gewünschten Pfad stark erleichtert. Anstelle eines klassischen Bookmarks speichert die Erweiterung nur die Pfade. Egal in welcher AEM oder CQ Umgebung – mit einem Klick auf den gespeicherten Pfad wird die Zielseite in der aktuellen Umgebung geöffnet.

Der aktuelle Pfad einer geöffneten Seite lässt sich mit der Erweiterung direkt speichern und zuvor auch editieren. Die einzelnen Einträge lassen sich per Drag-and-Drop umsortieren. Über die Options-Seite der Erweiterung stehen die gespeicherten Pfade ausserdem im JSON-Format zur Verfügung. Die Einstellungen können so einfach zwischen Entwicklern ausgetauscht werden. Über die Tastatur lässt sich schnell zwischen den Pfaden navigieren und den gewünschten auswählen.

Natürlich eignet sich diese Extension für Google Chrome auch für beliebige andere, web-basierte Systeme.

Pathmarks im Chrome Web Store

Suchtiefe der AEM CQ Volltext-Suche bei Seiten-Inhalten

Die integrierte Volltextsuche von AEM CQ nach Seiten (cq:Page respektive cq:PageContent) besitzt eine wenig bekannte Einschränkung. Die Suche findet nur auf vier Node-Ebenen innerhalb des PageContent-Nodes (jcr:content) statt.

Diese Einschränkung fällt oft nicht auf, da eher selten eine tiefere Node-Struktur anzutreffen ist. Es gibt aber Fälle, wo komplexe Komponenten tiefere Strukturen aufweisen und die Inhalte dann mit der Volltextsuche nicht mehr gefunden werden. Beim Testen ist die Wahrscheinlichkeit eher klein diesen Fall zu erkennen. Daher ist es wichtig diese Einschränkung zu kennen und in der Entwicklung bei der Verwendung tieferer Node-Strukturen zu beachten. (mehr …)

Performance Verbesserung von JCR Queries

Die Optimierung von Suchen gegen das JCR kann erhebliche Geschwindigkeitsvorteile bringen. Ein Hilfsmittel ist hier das QueryStat MBean, welches in der Standard JMX Console zu finden ist.  Dort sind langsame und populäre Queries schnell ersichtlich. Beispiel-Link: http://localhost:8081/system/console/jmx/com.adobe.granite%3Atype%3DQueryStat

(mehr …)