Show Menu
TEMAS×

Estructura del proyecto AEM

Familiarícese con el uso básico AEM del arquetipo del proyecto, y con el complemento Maven de contenido de FileVault, ya que este artículo se basa en estos conocimientos y conceptos.
Este artículo describe los cambios necesarios para que los proyectos de Adobe Experience Manager Maven se AEM como Cloud Service compatibles, asegurándose de que respetan la división del contenido mutable e inmutable, las dependencias se establecen para crear implementaciones determinísticas y no conflictivas y que se empaquetan en una estructura implementable.
AEM implementaciones de aplicaciones deben estar compuestas por un único paquete AEM. A su vez, este paquete debe contener subpaquetes que comprenden todo lo que la aplicación necesita para funcionar, incluyendo código, configuración y cualquier contenido de línea de base compatible.
AEM requiere una separación de contenido y código , lo que significa que un paquete de contenido único no puede implementarse en ambas instancias /apps y en áreas de tiempo de ejecución (p. ej. /content , /conf , /home o cualquier cosa que no sea /apps ) del repositorio. En su lugar, la aplicación debe separar el código y el contenido en paquetes discretos para su implementación en AEM.
La estructura del paquete descrita en este documento es compatible tanto con las implementaciones de desarrollo local, como con las implementaciones de AEM Cloud Service.
Las configuraciones descritas en este documento son proporcionadas por AEM Project Maven Archetype 24 o posterior .

Áreas mutables vs. inmutables del repositorio

/apps y /libs se consideran áreas inmutables de AEM, ya que no se pueden cambiar (crear, actualizar, eliminar) después de iniciarse AEM (es decir, durante la ejecución). Cualquier intento de cambiar un área inmutable durante la ejecución fallará.
Everything else in the repository, /content , /conf , /var , /etc , /oak:index , /system , /tmp , etc. are all mutable areas, meaning they can be changed at runtime.
Como en versiones anteriores de AEM, no /libs debe modificarse. Sólo se puede implementar AEM código de producto en /libs .

Índices de roble

Los índices Oak ( /oak:index ) son administrados específicamente por el AEM como un proceso de implementación de Cloud Service. Esto se debe a que el Administrador de nube debe esperar hasta que se implemente cualquier nuevo índice y se vuelva a indexar completamente antes de cambiar a la nueva imagen de código.
Por este motivo, aunque los índices Oak son mutables en tiempo de ejecución, deben implementarse como código para que se puedan instalar antes de instalar cualquier paquete mutable. Por lo tanto, /oak:index las configuraciones forman parte del paquete de código y no del paquete de contenido como se describe a continuación .
Para obtener más información acerca de la indexación en AEM como Cloud Service, consulte Búsqueda de contenido de documento e Indexación .

Tipos de paquetes

Los paquetes se marcarán con su tipo de paquete declarado.
  • Los paquetes de contenedor deben configurar su packageType en container .
  • Los paquetes de código (inmutables) deben configurar su packageType en application .
  • Los paquetes de contenido (mutable) deben configurarse packageType en content .
Para obtener más información, consulte la documentación del plugin Apache Jackrabbit FileVault - Package Maven y el fragmento Marcado de paquetes para implementación por Adobe Cloud Manager de configuración FileVault Maven más abajo.
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.

Marcado de paquetes para implementación por Adobe Cloud Manager

De forma predeterminada, Adobe Cloud Manager obtiene todos los paquetes producidos por la compilación de Maven; sin embargo, dado que el paquete de contenedor ( all ) es el único artefacto de implementación que contiene todos los paquetes de contenido y código, debemos asegurarnos de que solo se implementa el paquete de contenedor ( all ). Para garantizar esto, otros paquetes que genera la compilación de Maven deben marcarse con la configuración del complemento Maven del paquete de contenido de FileVault <properties><cloudManagerTarget>none</cloudManageTarget></properties> .
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.

Tiempo de espera de repo

Repo Init proporciona instrucciones, o secuencias de comandos, que definen estructuras JCR, desde estructuras de nodos comunes como árboles de carpetas hasta usuarios, usuarios de servicios, grupos y definición de ACL.
Las ventajas clave de Repo Init son que tienen permisos implícitos para realizar todas las acciones definidas por sus secuencias de comandos y se invocan al principio del ciclo vital de implementación, lo que garantiza que todas las estructuras JCR necesarias existan al ejecutar el código de tiempo.
Mientras que los scripts de Repo Init viven en el ui.config proyecto como scripts, pueden y deben utilizarse para definir las siguientes estructuras mutables:
  • Estructuras de contenido de línea base
  • Usuarios de servicio
  • Usuarios
  • Grupos
  • ACL
Las secuencias de comandos Repo Init se almacenan como scripts entradas de configuraciones de fábrica de RepositoryInitializer OSGi y, por tanto, se pueden dirigir implícitamente al modo de ejecución, lo que permite diferencias entre las secuencias de comandos Repo Init de AEM Author y AEM Publish Services, o incluso entre entornos (Dev, Stage y Prod).
Las configuraciones de OSGi de Repo Init se escriben mejor en el formato .config definir configuraciones .cfg.json OSGi.
Tenga en cuenta que al definir usuarios y grupos, solo los grupos se consideran parte de la aplicación y se debe definir una parte integral de su función aquí. Los usuarios y grupos de la organización deben seguir definidos durante la ejecución en AEM; por ejemplo, si un flujo de trabajo personalizado asigna trabajo a un grupo con nombre, dicho grupo debe definirse mediante Repo Init en la aplicación AEM; sin embargo, si el grupo es meramente organizativo, como "Wendy's Team" y "Sean's Team", se definirán mejor y se gestionarán en tiempo de ejecución en AEM.
Las secuencias de comandos Repo Init deben definirse en el scripts campo en línea y la configuración no references funcionará.
El vocabulario completo para los scripts Repo Init está disponible en la documentación repository-initialization.html#the-repoinit-repository-initialization-language de Apache Sling Repo Init.
Consulte la sección Recortes de inicio de la repo más abajo para ver un fragmento completo.

Paquete de estructura de repositorio

Los paquetes de código requieren configurar la configuración del complemento FileVault Maven para hacer referencia a una <repositoryStructurePackage> que exige la exactitud de las dependencias estructurales (para garantizar que un paquete de código no se instale sobre otro). Puede crear su propio paquete de estructura de repositorio para su proyecto .
Esto solo es necesario para los paquetes de código, es decir, cualquier paquete marcado con <packageType>application</packageType> .
Para obtener información sobre cómo crear un paquete de estructura de repositorio para la aplicación, consulte Desarrollar un paquete de estructura de repositorio.
Tenga en cuenta que los paquetes de contenido ( <packageType>content</packageType> ) no requieren este paquete de estructura de repositorio.
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.

Incrustación de subpaquetes en el paquete de Contenedor

Los paquetes de contenido o código se colocan en una carpeta especial de "coche lateral" y se pueden dirigir para la instalación en AEM autor, AEM publicación o en ambos, mediante la configuración del complemento FileVault Maven <embeddeds> . Tenga en cuenta que no se debe utilizar la <subPackages> configuración.
Entre los casos de uso comunes se incluyen:
  • ACL/permisos que difieren entre los usuarios autores de AEM y los usuarios AEM publicación
  • Configuraciones que se utilizan para admitir actividades solo en AEM autor
  • Código como integraciones con sistemas de back-office, solo necesario para ejecutarse en AEM autor
Para dar destinatario AEM autor, AEM publicar o ambos, el paquete se incrusta en el paquete de all contenedor en una ubicación de carpeta especial, con el siguiente formato:
/apps/<app-name>-packages/(content|application|container)/install(.author|.publish)?
Desglosar la estructura de carpetas:
  • La carpeta de primer nivel debe ser /apps .
  • La carpeta de segundo nivel representa la aplicación con -packages una publicación fija en el nombre de la carpeta. A menudo, solo hay una carpeta de segundo nivel en la que se incrustan todos los subpaquetes, aunque se puede crear cualquier número de carpetas de segundo nivel para representar mejor la estructura lógica de la aplicación:
    • /apps/my-app-packages
    • /apps/my-other-app-packages
    • /apps/vendor-packages
    De forma predeterminada, las carpetas incrustadas de subpaquetes reciben el nombre del sufijo de -packages . Esto garantiza que el código de implementación y los paquetes de contenido no se implementen en las carpetas de destino de ningún subpaquete /apps/<app-name>/... que tenga como resultado un comportamiento de instalación destructivo y cíclico.
  • La carpeta de tercer nivel debe ser application , content o container
    • La application carpeta contiene paquetes de código
    • La content carpeta contiene paquetes de contenido
    • La container carpeta contiene todos los paquetes de aplicaciones adicionales que pueda incluir la aplicación AEM. Este nombre de carpeta corresponde a los tipos de paquete de los paquetes que contiene.
  • La carpeta de cuarto nivel contiene los subpaquetes y debe ser uno de los siguientes:
    • install para realizar la instalación en AEM Author y AEM Publish
    • install.author para instalar solo en AEM Author
    • install.publish para instalar únicamente en AEM publicaciónTenga en cuenta que solo install.author y install.publish son destinatarios compatibles. Otros modos de ejecución no son compatibles.
Por ejemplo, una implementación que contenga AEM creación y publicación de paquetes específicos puede tener el siguiente aspecto:
  • all El paquete contenedor incorpora los siguientes paquetes para crear un artefacto de implementación único
    • ui.apps incrustado en /apps/my-app-packages/application/install implementa código tanto para AEM autor como para AEM publicación.
    • ui.apps.author incrustado en /apps/my-app-packages/application/install.author implementa código solo para AEM autor
    • ui.content integrado en /apps/my-app-packages/content/install implementa contenido y configuración tanto para AEM autor como para AEM publicación
    • ui.content.publish incrustado en /apps/my-app-packages/content/install.publish implementa contenido y configuración para AEM solo publicación
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.

Definición de filtro del paquete de contenedor

Debido a la incrustación del código y los subpaquetes de contenido en el paquete de contenedor, las rutas de destinatario incrustadas deben agregarse a las del proyecto de contenedor filter.xml para garantizar que los paquetes incrustados se incluyen en el paquete de contenedor cuando se generan.
Simplemente agregue las <filter root="/apps/<my-app>-packages"/> entradas de las carpetas de segundo nivel que contengan subpaquetes para la implementación.
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.

Incrustación de paquetes de terceros

Todos los paquetes deben estar disponibles a través del repositorio público de artefactos Maven del Adobe o de un repositorio de artefactos Maven público y accesible, referenciable por terceros.
Si los paquetes de terceros están en el repositorio público de artefactos Maven de Adobe , no se necesita ninguna configuración adicional para que Adobe Cloud Manager resuelva los artefactos.
Si los paquetes de terceros están en un repositorio público de artefactos de terceros de Maven , este repositorio debe estar registrado en el pom.xml del proyecto e incrustado según el método descrito anteriormente .
Los conectores/aplicaciones de terceros deben incrustarse utilizando su all paquete como contenedor en el paquete de contenedor ( all ) del proyecto.
Añadir las dependencias de Maven sigue las prácticas estándar de Maven, y la incrustación de artefactos de terceros (código y paquetes de contenido) se describe más arriba .
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.

Dependencias de paquetes entre los ui.apps de ui.content paquetes

Para garantizar la correcta instalación de los paquetes, se recomienda establecer dependencias entre paquetes.
La regla general es que los paquetes que contienen contenido mutable ( ui.content ) deben depender del código inmutable ( ui.apps ) que admite la representación y el uso del contenido mutable.
Una excepción notable a esta regla general es si el paquete de código inmutable ( ui.apps o cualquier otro) solo contiene paquetes OSGi. En caso afirmativo, ningún paquete AEM debe declarar una dependencia de él. Esto se debe a que los paquetes de código inmutables que solo contienen paquetes OSGi no están registrados en AEM administrador de paquetes y, por lo tanto, cualquier paquete AEM que dependa de él tendrá una dependencia insatisfecha y no se podrá instalar.
Consulte la sección Fragmentos XML de POM más abajo para ver un fragmento completo.
Los patrones comunes para las dependencias de paquetes de contenido son:

Dependencias del paquete de implementación simple

El caso simple define el paquete de contenido ui.content mutable para que dependa del paquete de código ui.apps inmutable.
  • all no tiene dependencias
    • ui.apps no tiene dependencias
    • ui.content depende de ui.apps

Dependencias complejas del paquete de implementación

Las implementaciones complejas se expanden en el caso simple y establecen dependencias entre el contenido mutable correspondiente y los paquetes de código inmutables. Si es necesario, también se pueden establecer dependencias entre paquetes de código inmutables.
  • all no tiene dependencias
    • common.ui.apps.common no tiene dependencias
    • site-a.ui.apps depende de common.ui.apps
    • site-a.ui.content depende de site-a.ui.apps
    • site-b.ui.apps depende de common.ui.apps
    • site-b.ui.content depende de site-b.ui.apps

Desarrollo e implementación locales

Las estructuras y la organización del proyecto que se describen en este artículo son totalmente compatibles con los ejemplos de AEM de desarrollo local.

Recortes XML de POM

Los siguientes son fragmentos de configuración Maven pom.xml que se pueden agregar a los proyectos Maven para alinearse con las recomendaciones anteriores.

Tipos de paquetes

Los paquetes de código y contenido, que se implementan como subpaquetes, deben declarar un tipo de paquete de aplicación o contenido , según lo que contengan.

Tipos de paquetes de contenedor

El proyecto contenedor all/pom.xml no declara un <packageType> .

Tipos de paquetes de código (inmutables)

Los paquetes de código deben configurar su packageType en application .
En la ui.apps/pom.xml , las directivas de configuración de <packageType>application</packageType> compilación de la declaración del filevault-package-maven-plugin complemento declaran su tipo de paquete.
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        <group>${project.groupId}</group>
        <name>my-app.ui.apps</name>
        <packageType>application</packageType>
        <accessControlHandling>merge</accessControlHandling>
        <properties>
          <cloudManagerTarget>none</cloudManagerTarget>
        </properties>
      </configuration>
    </plugin>
    ...

Tipos de paquetes de contenido (mutables)

Los paquetes de contenido deben establecer su packageType valor en content .
En la ui.content/pom.xml , la directiva de configuración de <packageType>content</packageType> compilación de la declaración del filevault-package-maven-plugin complemento declara su tipo de paquete.
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        <group>${project.groupId}</group>
        <name>my-app.ui.content</name>
        <packageType>content</packageType>
        <accessControlHandling>merge</accessControlHandling>
        <properties>
          <cloudManagerTarget>none</cloudManagerTarget>
        </properties>
      </configuration>
    </plugin>
    ...

Marcado de paquetes para la implementación de Adobe Cloud Manager

En todos los proyectos que generan un paquete, excepto en el proyecto de contenedor ( all ), agregue <cloudManagerTarget>none</cloudManagerTarget> a la configuración de la declaración del complemento <properties> para garantizar filevault-package-maven-plugin que Adobe Cloud Manager no los implementa. The container ( all ) package should be the singular package deployed via Cloud Manager, which in turn embeds all required code and content packages.
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        ...
        <properties>
          <cloudManagerTarget>none</cloudManagerTarget>
        </properties>
      </configuration>
    </plugin>
    ...

Tiempo de espera de repo

Las secuencias de comandos Repo Init que contienen las secuencias de comandos Repo Init se definen en la configuración de fábrica de RepositoryInitializer OSGi mediante la scripts propiedad. Tenga en cuenta que, dado que estas secuencias de comandos se definen en las configuraciones de OSGi, se pueden crear fácilmente en el modo de ejecución utilizando la semántica de ../config.<runmode> carpetas habitual.
Tenga en cuenta que, como las secuencias de comandos suelen ser declaraciones multilínea, es más fácil definirlas en el .config archivo que en el formato .cfg.json basado en JSON.
/apps/my-app/config.author/org.apache.sling.jcr.repoinit.RepositoryInitializer-author.config
scripts=["
    create service user my-data-reader-service

    set ACL on /var/my-data
        allow jcr:read for my-data-reader-service
    end

    create path (sling:Folder) /conf/my-app/settings
"]

La propiedad scripts OSGi contiene directivas según la definición del lenguaje repository-initialization.html#the-repoinit-repository-initialization-language Repo de Apache Sling.

Paquete de estructura de repositorio

En ui.apps/pom.xml y en cualquier otro pom.xml que declare un paquete de código ( <packageType>application</packageType> ), agregue la siguiente configuración de paquete de estructura de repositorio al complemento FileVault Maven. Puede crear su propio paquete de estructura de repositorio para su proyecto .
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        ...
        <repositoryStructurePackages>
          <repositoryStructurePackage>
              <groupId>${project.groupId}</groupId>
              <artifactId>ui.apps.structure</artifactId>
              <version>${project.version}</version>
          </repositoryStructurePackage>
        </repositoryStructurePackages>
      </configuration>
    </plugin>
    ...

Incrustación de subpaquetes en el paquete de Contenedor

En la all/pom.xml , agregue las siguientes <embeddeds> directivas a la declaración del filevault-package-maven-plugin complemento. Recuerde, no use la <subPackages> configuración, ya que esto incluirá los subpaquetes en /etc/packages lugar de /apps/my-app-packages/<application|content|container>/install(.author|.publish)? .
...
<plugin>
  <groupId>org.apache.jackrabbit</groupId>
  <artifactId>filevault-package-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
      ...
      <embeddeds>

          <!-- Include the application's ui.apps and ui.content packages -->
          <!-- Ensure the artifactIds are correct -->

          <!-- OSGi Bundle Jar file that deploys to BOTH AEM Author and AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.core</artifactId>
              <type>jar</type>
              <target>/apps/my-app-packages/application/install</target>
          </embedded>

          <!-- Code package that deploys to BOTH AEM Author and AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.apps</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/application/install</target>
          </embedded>

           <!-- OSGi configuration code package that deploys to BOTH AEM Author and AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.config</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/application/install</target>
          </embedded>

          <!-- Code package that deploys ONLY to AEM Author -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.apps.author</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/application/install.author</target>
          </embedded>

          <!-- Content package that deploys to BOTH AEM Author and AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.content</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/content/install</target>
          </embedded>

          <!-- Content package that deploys ONLY to AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.content.publish-only</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/content/install.publish</target>
          </embedded>

          <!-- Include any other extra packages  -->
          <embedded>
              <groupId>com.vendor.x</groupId>
              <artifactId>vendor.plug-in.all</artifactId>
              <type>zip</type>
              <target>/apps/vendor-packages/container/install</target>
          </embedded>
      <embeddeds>
  </configuration>
</plugin>
...

Definición de filtro del paquete de contenedor

En el all del proyecto filter.xml ( all/src/main/content/jcr_root/META-INF/vault/definition/filter.xml ), incluya todas -packages las carpetas que contengan subpaquetes para implementar:
<filter root="/apps/my-app-packages"/>

Si /apps/*-packages se utilizan varios en los destinatarios incrustados, todos deben enumerarse aquí.

Repositorios de muevos de terceros

Añadir más repositorios de Maven puede extender los tiempos de generación, ya que se comprobarán las dependencias de repositorios de Maven adicionales.
En el proyecto del reactor pom.xml , agregue las directivas de repositorio de Maven públicas de terceros necesarias. La configuración completa debe estar disponible <repository> desde el proveedor de repositorio de terceros.
<repositories>
  ...
  <repository>
      <id>3rd-party-repository</id>
      <name>Public 3rd Party Repository</name>
      <url>https://repo.3rdparty.example.com/...</url>
      <releases>
          <enabled>true</enabled>
          <updatePolicy>never</updatePolicy>
      </releases>
      <snapshots>
          <enabled>false</enabled>
      </snapshots>
  </repository>
  ...
</repositories>

Dependencias de paquetes entre los ui.apps de ui.content paquetes

En la ui.content/pom.xml , agregue las siguientes <dependencies> directivas a la declaración del filevault-package-maven-plugin complemento.
...
<plugin>
  <groupId>org.apache.jackrabbit</groupId>
  <artifactId>filevault-package-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
      ...
      <dependencies>
        <!-- Declare the content package dependency in the ui.content/pom.xml on the ui.apps project -->
        <dependency>
            <groupId${project.groupId}</groupId>
            <artifactId>my-app.ui.apps</artifactId>
            <version>${project.version}</version>
        </dependency>
      </dependencies>
    ...
  </configuration>
</plugin>
...

Limpieza de la carpeta de Destinatario del proyecto de Contenedor

En el all/pom.xml complemento agregue el maven-clean-plugin complemento que limpiará el directorio de destinatario antes de crear Maven.
<plugins>
  ...
  <plugin>
    <artifactId>maven-clean-plugin</artifactId>
    <executions>
      <execution>
        <id>auto-clean</id>
        <!-- Run at the beginning of the build rather than the default, which is after the build is done -->
        <phase>initialize</phase>
        <goals>
          <goal>clean</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  ...
</plugins>