├── .gitattributes ├── .github └── workflows │ ├── check.yml │ └── release.yml ├── .gitignore ├── .idea └── runConfigurations │ ├── build.xml │ ├── build__quick_.xml │ ├── debug.xml │ └── release.xml ├── LICENSE ├── README.MD ├── build.gradle.kts ├── detekt.yml ├── docs ├── all-package-deploy.gif ├── apache-license-badge.svg ├── blog │ ├── 2020-01-instance-setup │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle.kts │ ├── 2020-02-aem-on-java-11 │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle.kts │ │ └── src │ │ │ └── aem │ │ │ ├── instance │ │ │ └── tail │ │ │ │ └── incidentFilter.txt │ │ │ └── localInstance │ │ │ └── common │ │ │ └── crx-quickstart │ │ │ └── conf │ │ │ └── sling.properties │ └── 2020-09-aem-dispacher-with-ease │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── hosts │ │ ├── hosts.bat │ │ ├── settings.gradle.kts │ │ └── src │ │ └── environment │ │ ├── dispatcher │ │ ├── conf.d │ │ │ ├── available_vhosts │ │ │ │ └── default.vhost │ │ │ ├── dispatcher_vhost.conf │ │ │ ├── enabled_vhosts │ │ │ │ ├── README │ │ │ │ └── default.vhost │ │ │ ├── rewrites │ │ │ │ ├── default_rewrite.rules │ │ │ │ └── rewrite.rules │ │ │ └── variables │ │ │ │ ├── custom.vars │ │ │ │ ├── default.vars │ │ │ │ └── global.vars │ │ ├── conf.dispatcher.d │ │ │ ├── available_farms │ │ │ │ └── default.farm │ │ │ ├── cache │ │ │ │ ├── default_invalidate.any │ │ │ │ ├── default_rules.any │ │ │ │ └── rules.any │ │ │ ├── clientheaders │ │ │ │ ├── clientheaders.any │ │ │ │ └── default_clientheaders.any │ │ │ ├── dispatcher.any │ │ │ ├── enabled_farms │ │ │ │ ├── README │ │ │ │ └── default.farm │ │ │ ├── filters │ │ │ │ ├── default_filters.any │ │ │ │ └── filters.any │ │ │ ├── renders │ │ │ │ └── default_renders.any │ │ │ └── virtualhosts │ │ │ │ ├── default_virtualhosts.any │ │ │ │ └── virtualhosts.any │ │ └── conf │ │ │ └── httpd.conf │ │ └── docker-compose.yml.peb ├── bundle-plugin.md ├── cognifide-logo.png ├── common-plugin.md ├── docker-desktop-share.png ├── environment-dev-task.gif ├── environment-down-task.gif ├── environment-file-structure.png ├── environment-plugin.md ├── environment-up-task.gif ├── gradle-aem-multi-build.gif ├── instance-file-structure.png ├── instance-plugin.md ├── instance-status-task.png ├── instance-workflow-task.png ├── launcher.md ├── local-instance-plugin.md ├── logo-gh-thumbnail.png ├── logo-square-mini.png ├── logo-square.png ├── logo.png ├── package-plugin.md ├── package-sync-plugin.md └── wtt-logo.png ├── gh-md-toc ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── launcher ├── build.gradle.kts └── src │ ├── functionalTest │ └── kotlin │ │ └── com │ │ └── cognifide │ │ └── gradle │ │ └── aem │ │ └── launcher │ │ └── LauncherTest.kt │ └── main │ └── kotlin │ └── com │ └── cognifide │ └── gradle │ └── aem │ └── launcher │ ├── BuildScaffolder.kt │ ├── EnvCloudScaffolder.kt │ ├── EnvInstanceOnlyScaffolder.kt │ ├── EnvOnPremScaffolder.kt │ ├── Launcher.kt │ ├── LauncherException.kt │ └── MiscScaffolder.kt ├── settings.gradle.kts └── src ├── asset ├── localInstance │ ├── defaults │ │ ├── cbp.exe │ │ ├── control │ │ │ ├── start.bat │ │ │ ├── start.sh │ │ │ ├── status.bat │ │ │ ├── status.sh │ │ │ ├── stop.bat │ │ │ └── stop.sh │ │ └── service │ │ │ ├── start.sh │ │ │ ├── status.sh │ │ │ ├── stop.sh │ │ │ ├── systemd.conf │ │ │ └── sysvinit.sh │ └── service │ │ ├── start.sh │ │ ├── status.sh │ │ ├── stop.sh │ │ ├── systemd.conf │ │ └── sysvinit.sh ├── oakrun │ └── admin-reset.groovy.peb ├── package │ ├── defaults │ │ └── META-INF │ │ │ ├── MANIFEST.MF │ │ │ └── vault │ │ │ ├── config.xml │ │ │ ├── definition │ │ │ ├── .content.xml │ │ │ └── thumbnail.png │ │ │ ├── filter.xml │ │ │ ├── nodetypes.cnd │ │ │ ├── properties.xml │ │ │ └── settings.xml │ └── validator │ │ ├── OAKPAL_OPEAR │ │ └── plan.json │ │ └── initial │ │ └── META-INF │ │ └── vault │ │ ├── nodetypes.cnd │ │ └── privileges.xml └── vlt │ └── filter.tmp.xml ├── functionalTest └── kotlin │ └── com │ └── cognifide │ └── gradle │ └── aem │ ├── PluginsTest.kt │ ├── bundle │ └── BundlePluginTest.kt │ ├── common │ └── CommonPluginTest.kt │ ├── instance │ ├── InstancePluginTest.kt │ └── local │ │ └── LocalInstancePluginTest.kt │ ├── pkg │ ├── PackagePluginTest.kt │ └── PackageSyncPluginTest.kt │ └── test │ ├── AemBuildResult.kt │ └── AemBuildTest.kt ├── main └── kotlin │ └── com │ └── cognifide │ └── gradle │ └── aem │ ├── AemDefaultTask.kt │ ├── AemException.kt │ ├── AemExtension.kt │ ├── AemPlugin.kt │ ├── AemTask.kt │ ├── AemVersion.kt │ ├── bundle │ ├── BundleException.kt │ ├── BundlePlugin.kt │ └── tasks │ │ ├── BundleInstall.kt │ │ ├── BundleJar.kt │ │ └── BundleUninstall.kt │ ├── common │ ├── CommonOptions.kt │ ├── CommonPlugin.kt │ ├── asset │ │ └── AssetManager.kt │ ├── bundle │ │ ├── BundleException.kt │ │ └── BundleFile.kt │ ├── cli │ │ ├── CliApp.kt │ │ ├── CliException.kt │ │ ├── JarApp.kt │ │ └── JarException.kt │ ├── file │ │ └── FileOperations.kt │ ├── instance │ │ ├── Auth.kt │ │ ├── ControlTrigger.kt │ │ ├── FileSync.kt │ │ ├── Ims.kt │ │ ├── ImsException.kt │ │ ├── Instance.kt │ │ ├── InstanceAction.kt │ │ ├── InstanceException.kt │ │ ├── InstanceFactory.kt │ │ ├── InstanceHttpClient.kt │ │ ├── InstanceManager.kt │ │ ├── InstanceService.kt │ │ ├── InstanceSync.kt │ │ ├── InstanceUrl.kt │ │ ├── LocalInstance.kt │ │ ├── LocalInstanceException.kt │ │ ├── LocalInstanceManager.kt │ │ ├── Location.kt │ │ ├── Purpose.kt │ │ ├── ServiceComposer.kt │ │ ├── StatusReporter.kt │ │ ├── action │ │ │ ├── AwaitDownAction.kt │ │ │ ├── AwaitUpAction.kt │ │ │ ├── CheckAction.kt │ │ │ ├── DefaultAction.kt │ │ │ └── ReloadAction.kt │ │ ├── check │ │ │ ├── BundlesCheck.kt │ │ │ ├── Check.kt │ │ │ ├── CheckFactory.kt │ │ │ ├── CheckGroup.kt │ │ │ ├── CheckProgress.kt │ │ │ ├── CheckRunner.kt │ │ │ ├── ComponentsCheck.kt │ │ │ ├── CustomCheck.kt │ │ │ ├── DefaultCheck.kt │ │ │ ├── EventsCheck.kt │ │ │ ├── HelpCheck.kt │ │ │ ├── HelpException.kt │ │ │ ├── InstallerCheck.kt │ │ │ ├── TimeoutCheck.kt │ │ │ ├── UnavailableCheck.kt │ │ │ └── UnchangedCheck.kt │ │ ├── local │ │ │ ├── BackupManager.kt │ │ │ ├── BackupSource.kt │ │ │ ├── BackupType.kt │ │ │ ├── DistType.kt │ │ │ ├── InstallResolver.kt │ │ │ ├── JavaAgentResolver.kt │ │ │ ├── OpenMode.kt │ │ │ ├── QuickstartResolver.kt │ │ │ ├── Script.kt │ │ │ ├── Source.kt │ │ │ └── Status.kt │ │ ├── oak │ │ │ ├── OakRun.kt │ │ │ ├── OakRunException.kt │ │ │ └── OakRunScript.kt │ │ ├── provision │ │ │ ├── Action.kt │ │ │ ├── Condition.kt │ │ │ ├── InstanceStep.kt │ │ │ ├── ProvisionException.kt │ │ │ ├── Provisioner.kt │ │ │ ├── Status.kt │ │ │ ├── Step.kt │ │ │ └── step │ │ │ │ ├── ConfigureCryptoStep.kt │ │ │ │ ├── ConfigureReplicationAgentStep.kt │ │ │ │ ├── ConfigureWorkflowLauncherStep.kt │ │ │ │ ├── CustomStep.kt │ │ │ │ ├── DeployPackageSource.kt │ │ │ │ ├── DeployPackageStep.kt │ │ │ │ └── ImportMappingsStep.kt │ │ ├── rcp │ │ │ ├── RcpClient.kt │ │ │ └── RcpSummary.kt │ │ ├── service │ │ │ ├── auth │ │ │ │ ├── AuthException.kt │ │ │ │ └── AuthManager.kt │ │ │ ├── crx │ │ │ │ ├── Crx.kt │ │ │ │ └── CrxException.kt │ │ │ ├── groovy │ │ │ │ ├── GroovyConsole.kt │ │ │ │ ├── GroovyConsoleException.kt │ │ │ │ ├── GroovyEvalResult.kt │ │ │ │ ├── GroovyEvalStatus.kt │ │ │ │ ├── GroovyEvalSummary.kt │ │ │ │ └── GroovyEvaluator.kt │ │ │ ├── ims │ │ │ │ ├── AccessObject.kt │ │ │ │ ├── Integration.kt │ │ │ │ ├── Secret.kt │ │ │ │ └── TechnicalAccount.kt │ │ │ ├── osgi │ │ │ │ ├── Bundle.kt │ │ │ │ ├── BundleState.kt │ │ │ │ ├── Component.kt │ │ │ │ ├── ComponentState.kt │ │ │ │ ├── Configuration.kt │ │ │ │ ├── ConfigurationPid.kt │ │ │ │ ├── ConfigurationState.kt │ │ │ │ ├── Event.kt │ │ │ │ ├── EventState.kt │ │ │ │ ├── OsgiException.kt │ │ │ │ └── OsgiFramework.kt │ │ │ ├── pkg │ │ │ │ ├── BuildResponse.kt │ │ │ │ ├── DeleteResponse.kt │ │ │ │ ├── ErrorPattern.kt │ │ │ │ ├── HtmlResponse.kt │ │ │ │ ├── InstallResponse.kt │ │ │ │ ├── ListResponse.kt │ │ │ │ ├── Package.kt │ │ │ │ ├── PackageDependency.kt │ │ │ │ ├── PackageDeployment.kt │ │ │ │ ├── PackageFilter.kt │ │ │ │ ├── PackageFilterRule.kt │ │ │ │ ├── PackageManager.kt │ │ │ │ ├── PackageMetadata.kt │ │ │ │ ├── UninstallResponse.kt │ │ │ │ └── UploadResponse.kt │ │ │ ├── repository │ │ │ │ ├── Node.kt │ │ │ │ ├── Properties.kt │ │ │ │ ├── Query.kt │ │ │ │ ├── QueryCriteria.kt │ │ │ │ ├── QueryParams.kt │ │ │ │ ├── QueryResult.kt │ │ │ │ ├── ReplicationAgent.kt │ │ │ │ ├── Repository.kt │ │ │ │ ├── RepositoryChange.kt │ │ │ │ ├── RepositoryError.kt │ │ │ │ ├── RepositoryException.kt │ │ │ │ ├── RepositoryHttpClient.kt │ │ │ │ ├── RepositoryResult.kt │ │ │ │ ├── RepositoryType.kt │ │ │ │ └── ResourceType.kt │ │ │ ├── sling │ │ │ │ ├── SlingException.kt │ │ │ │ ├── SlingInstaller.kt │ │ │ │ └── SlingInstallerState.kt │ │ │ ├── status │ │ │ │ ├── Status.kt │ │ │ │ └── StatusException.kt │ │ │ └── workflow │ │ │ │ ├── WorkflowException.kt │ │ │ │ ├── WorkflowLauncher.kt │ │ │ │ ├── WorkflowLauncherType.kt │ │ │ │ ├── WorkflowManager.kt │ │ │ │ └── WorkflowModel.kt │ │ └── tail │ │ │ ├── InstanceAnalyzer.kt │ │ │ ├── InstanceLogInfo.kt │ │ │ ├── Log.kt │ │ │ ├── LogChunk.kt │ │ │ ├── LogDestination.kt │ │ │ ├── LogFilter.kt │ │ │ ├── LogInfo.kt │ │ │ ├── LogNotifier.kt │ │ │ ├── LogParser.kt │ │ │ ├── LogSource.kt │ │ │ ├── LogTailer.kt │ │ │ ├── NoLogInfo.kt │ │ │ ├── Tailer.kt │ │ │ ├── TailerException.kt │ │ │ └── io │ │ │ ├── ConsolePrinter.kt │ │ │ ├── FileDestination.kt │ │ │ ├── LogFiles.kt │ │ │ └── UrlSource.kt │ ├── mvn │ │ ├── Artifact.kt │ │ ├── ArtifactType.kt │ │ ├── Dependency.kt │ │ ├── DependencyGraph.kt │ │ ├── DeployPackageOrder.kt │ │ ├── ModuleDescriptor.kt │ │ ├── ModuleResolver.kt │ │ ├── ModuleType.kt │ │ ├── MvnBuild.kt │ │ ├── MvnException.kt │ │ ├── MvnGav.kt │ │ └── MvnModule.kt │ ├── pkg │ │ ├── BundleChecking.kt │ │ ├── PackageDefinition.kt │ │ ├── PackageException.kt │ │ ├── PackageFile.kt │ │ ├── PackageFileFilter.kt │ │ ├── PackageOptions.kt │ │ ├── PackageValidator.kt │ │ ├── PackageWrapper.kt │ │ ├── validator │ │ │ ├── OakpalResult.kt │ │ │ └── OakpalSeverity.kt │ │ └── vault │ │ │ ├── CndSync.kt │ │ │ ├── CndSyncType.kt │ │ │ ├── FilterElement.kt │ │ │ ├── FilterFile.kt │ │ │ ├── FilterRule.kt │ │ │ ├── FilterRuleType.kt │ │ │ ├── FilterType.kt │ │ │ ├── VaultClient.kt │ │ │ ├── VaultDefinition.kt │ │ │ ├── VaultException.kt │ │ │ └── VaultSummary.kt │ ├── tasks │ │ ├── Bundle.kt │ │ ├── Instance.kt │ │ ├── InstanceFileSync.kt │ │ ├── LocalInstance.kt │ │ └── Package.kt │ └── utils │ │ ├── Checksum.kt │ │ ├── FileUtil.kt │ │ ├── JcrUtil.kt │ │ ├── LineSeparator.kt │ │ ├── ProcessKiller.kt │ │ ├── Utils.kt │ │ └── WebBrowser.kt │ ├── instance │ ├── InstancePlugin.kt │ ├── LocalInstancePlugin.kt │ └── tasks │ │ ├── InstanceAwait.kt │ │ ├── InstanceBackup.kt │ │ ├── InstanceCreate.kt │ │ ├── InstanceDeploy.kt │ │ ├── InstanceDestroy.kt │ │ ├── InstanceDown.kt │ │ ├── InstanceGroovyEval.kt │ │ ├── InstanceKill.kt │ │ ├── InstanceProvision.kt │ │ ├── InstanceRcp.kt │ │ ├── InstanceReload.kt │ │ ├── InstanceResetup.kt │ │ ├── InstanceResolve.kt │ │ ├── InstanceRestart.kt │ │ ├── InstanceSetup.kt │ │ ├── InstanceStatus.kt │ │ ├── InstanceTail.kt │ │ ├── InstanceUp.kt │ │ └── InstanceWorkflow.kt │ └── pkg │ ├── PackagePlugin.kt │ ├── PackageSyncPlugin.kt │ └── tasks │ ├── PackageActivate.kt │ ├── PackageCompose.kt │ ├── PackageConfig.kt │ ├── PackageDelete.kt │ ├── PackageDeploy.kt │ ├── PackageInstall.kt │ ├── PackagePrepare.kt │ ├── PackagePurge.kt │ ├── PackageSync.kt │ ├── PackageUninstall.kt │ ├── PackageUpload.kt │ ├── PackageValidate.kt │ ├── PackageVlt.kt │ ├── compose │ ├── BundleInstalled.kt │ ├── BundleInstalledBuilt.kt │ ├── BundleInstalledResolved.kt │ ├── PackageNested.kt │ ├── PackageNestedBuilt.kt │ ├── PackageNestedResolved.kt │ └── RepositoryArchive.kt │ └── sync │ ├── Cleaner.kt │ ├── CleanerRule.kt │ └── Downloader.kt └── test ├── kotlin └── com │ └── cognifide │ └── gradle │ └── aem │ ├── bundle │ └── BundlePluginTest.kt │ ├── common │ ├── CommonPluginTest.kt │ ├── instance │ │ ├── InstanceFactoryTest.kt │ │ ├── provision │ │ │ └── step │ │ │ │ └── DeployPackageSourceTest.kt │ │ ├── service │ │ │ └── pkg │ │ │ │ └── PackageResponseTest.kt │ │ └── tail │ │ │ └── InstanceTailTest.kt │ └── utils │ │ ├── FileUtilTest.kt │ │ └── UtilsTest.kt │ ├── instance │ ├── InstancePluginTest.kt │ └── LocalInstancePluginTest.kt │ ├── pkg │ ├── PackagePluginTest.kt │ └── PackageSyncPluginTest.kt │ └── test │ └── AemTest.kt └── resources └── com └── cognifide └── gradle └── aem └── common └── instance ├── service └── pkg │ └── package-response │ ├── example-delete.txt │ └── failure-dependency-exception.txt └── tail ├── 10-logs-error.log ├── aggregating ├── disjoint │ ├── first-chunk-error.log │ └── second-chunk-error.log ├── multiline │ ├── incomplete-multiline-logs-error.log │ ├── multiline-logs-error.log │ ├── multiline-long.log │ └── multiline-short.log └── overlapping │ ├── first-chunk-error.log │ └── second-chunk-error.log └── logs-chunk.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Handle line endings automatically for files detected as text 2 | # and leave all files detected as binary untouched. 3 | * text=auto 4 | 5 | # The above will handle all files NOT found below 6 | # 7 | # These files are text and should be normalized (Convert crlf => lf) 8 | *.css text 9 | *.df text 10 | *.htm text 11 | *.html text 12 | *.java text 13 | *.kt text 14 | *.js text 15 | *.json text 16 | *.jsp text 17 | *.jspf text 18 | *.jspx text 19 | *.properties text 20 | *.sh text 21 | *.tld text 22 | *.txt text 23 | *.tag text 24 | *.tagx text 25 | *.xml text 26 | *.yml text 27 | 28 | # These files are binary and should be left untouched 29 | # (binary is a macro for -text -diff) 30 | *.class binary 31 | *.dll binary 32 | *.ear binary 33 | *.gif binary 34 | *.ico binary 35 | *.jar binary 36 | *.jpg binary 37 | *.jpeg binary 38 | *.png binary 39 | *.so binary 40 | *.war binary -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: Check 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | check: 13 | name: Run Gradle 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: Set up JDK 11 20 | uses: actions/setup-java@v2 21 | with: 22 | java-version: 11 23 | distribution: adopt 24 | 25 | - name: Build & run functional tests 26 | run: ./gradlew -i -S build functionalTest 27 | 28 | - name: Publish unit test results 29 | uses: mikepenz/action-junit-report@v2 30 | if: always() 31 | with: 32 | report_paths: | 33 | **/target/**/TEST-*.xml 34 | **/build/**/TEST-*.xml 35 | **/cypress/results/**/TEST-*.xml 36 | github_token: ${{ secrets.GITHUB_TOKEN }} 37 | 38 | - name: Publish unit test reports 39 | uses: actions/upload-artifact@v2 40 | if: always() 41 | with: 42 | name: gap-unit-tests-reports 43 | path: build/reports/tests/test 44 | 45 | - name: Publish functional test reports 46 | uses: actions/upload-artifact@v2 47 | if: always() 48 | with: 49 | name: gap-functional-tests-reports 50 | path: build/reports/tests/functionalTest 51 | 52 | - name: Publish launcher functional test reports 53 | uses: actions/upload-artifact@v2 54 | if: always() 55 | with: 56 | name: gap-launcher-functional-tests-reports 57 | path: launcher/build/reports/tests/functionalTest -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | release: 7 | name: Run Gradle 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: fregante/setup-git-user@v1 13 | 14 | - name: Set up JDK 11 15 | uses: actions/setup-java@v2 16 | with: 17 | java-version: 11 18 | distribution: adopt 19 | 20 | - name: Build, release then publish assets 21 | run: | 22 | ./gradlew -i -S fullRelease \ 23 | -Pgithub.token=${{ secrets.GITHUB_TOKEN }} \ 24 | -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} \ 25 | -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -------------------------------------------------------------------------------- /.idea/runConfigurations/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 17 | 19 | true 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/runConfigurations/build__quick_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 17 | 19 | true 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/runConfigurations/debug.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/runConfigurations/release.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/all-package-deploy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/all-package-deploy.gif -------------------------------------------------------------------------------- /docs/apache-license-badge.svg: -------------------------------------------------------------------------------- 1 | LicenseLicenseApache-2.0Apache-2.0 -------------------------------------------------------------------------------- /docs/blog/2020-01-instance-setup/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.cognifide.aem.instance.local") version "14.4.1" 3 | } 4 | 5 | aem { 6 | instance { 7 | provisioner { 8 | enableCrxDe() 9 | deployPackage("https://github.com/Adobe-Consulting-Services/acs-aem-commons/releases/download/acs-aem-commons-4.0.0/acs-aem-commons-content-4.0.0-min.zip") 10 | deployPackage("org.jetbrains.kotlin:kotlin-osgi-bundle:1.4.10") 11 | deployPackage("https://github.com/icfnext/aem-groovy-console/releases/download/13.0.0/aem-groovy-console-13.0.0.zip") 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /docs/blog/2020-01-instance-setup/gradle.properties: -------------------------------------------------------------------------------- 1 | # AEM distribution 2 | localInstance.quickstart.jarUrl=smb://smb-host/aem/6.5.0/cq-quickstart-6.5.0.jar 3 | localInstance.quickstart.licenseUrl=/Users/user.name/aem/6.5.0/license.properties 4 | 5 | fileTransfer.user=user.name 6 | fileTransfer.password= 7 | fileTransfer.domain=COMPANY_DOMAIN 8 | 9 | # Instance description 10 | instance.local-author.httpUrl=http://localhost:4502 11 | instance.local-author.type=local 12 | instance.local-author.runModes=local,nosamplecontent 13 | instance.local-author.jvmOpts=-server -Xmx2048m -XX:MaxPermSize=512M -Djava.awt.headless=true 14 | 15 | instance.local-publish.httpUrl=http://localhost:4503 16 | instance.local-publish.type=local 17 | instance.local-publish.runModes=local,nosamplecontent 18 | instance.local-publish.jvmOpts=-server -Xmx2048m -XX:MaxPermSize=512M -Djava.awt.headless=true -------------------------------------------------------------------------------- /docs/blog/2020-01-instance-setup/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/blog/2020-01-instance-setup/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /docs/blog/2020-01-instance-setup/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /docs/blog/2020-01-instance-setup/settings.gradle.kts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/blog/2020-01-instance-setup/settings.gradle.kts -------------------------------------------------------------------------------- /docs/blog/2020-02-aem-on-java-11/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.cognifide.aem.instance.local") version "14.4.1" 3 | } 4 | 5 | aem { 6 | instance { 7 | provisioner { 8 | enableCrxDe() 9 | deployPackage("https://github.com/Adobe-Consulting-Services/acs-aem-commons/releases/download/acs-aem-commons-4.0.0/acs-aem-commons-content-4.0.0-min.zip") 10 | deployPackage("org.jetbrains.kotlin:kotlin-osgi-bundle:1.4.10") 11 | deployPackage("https://github.com/icfnext/aem-groovy-console/releases/download/13.0.0/aem-groovy-console-13.0.0.zip") 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /docs/blog/2020-02-aem-on-java-11/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/blog/2020-02-aem-on-java-11/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /docs/blog/2020-02-aem-on-java-11/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /docs/blog/2020-02-aem-on-java-11/settings.gradle.kts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/blog/2020-02-aem-on-java-11/settings.gradle.kts -------------------------------------------------------------------------------- /docs/blog/2020-02-aem-on-java-11/src/aem/instance/tail/incidentFilter.txt: -------------------------------------------------------------------------------- 1 | libs.granite.ui.components.coral.foundation.table Failed to wrap datasource for lookahead 2 | org.apache.sling.commons.compiler.impl.EclipseJavaCompiler Using unsupported java version '11', assuming latest supported version '9' -------------------------------------------------------------------------------- /docs/blog/2020-02-aem-on-java-11/src/aem/localInstance/common/crx-quickstart/conf/sling.properties: -------------------------------------------------------------------------------- 1 | org.osgi.framework.system.packages.extra=com.sun.org.apache.xpath.internal;version\="{dollar}{felix.detect.java.version}" 2 | org.osgi.framework.bootdelegation=sun.*,com.sun.*,jdk.internal.reflect,jdk.internal.reflect.* -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/gradle.properties: -------------------------------------------------------------------------------- 1 | # AEM distribution 2 | localInstance.quickstart.jarUrl=smb://smb-host/aem/6.5.0/cq-quickstart-6.5.0.jar 3 | localInstance.quickstart.licenseUrl=/Users/user.name/aem/6.5.0/license.properties 4 | 5 | fileTransfer.user=user.name 6 | fileTransfer.password= 7 | fileTransfer.domain=COMPANY_DOMAIN 8 | 9 | # Instance description 10 | instance.local-author.httpUrl=http://localhost:4502 11 | instance.local-author.type=local 12 | instance.local-author.runModes=local 13 | instance.local-author.jvmOpts=-server -Xmx2048m -XX:MaxPermSize=512M -Djava.awt.headless=true 14 | 15 | instance.local-publish.httpUrl=http://localhost:4503 16 | instance.local-publish.type=local 17 | instance.local-publish.runModes=local 18 | instance.local-publish.jvmOpts=-server -Xmx2048m -XX:MaxPermSize=512M -Djava.awt.headless=true -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/blog/2020-09-aem-dispacher-with-ease/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/hosts: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./gradlew environmentHosts -q | sudo tee -a /etc/hosts 4 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/hosts.bat: -------------------------------------------------------------------------------- 1 | gradlew.bat environmentHosts -q > .gap.hosts.tmp & powershell -command "Start-Process cmd -ArgumentList '/C cd %CD% && type .gap.hosts.tmp >> C:\Windows\System32\drivers\etc\hosts' -Verb runas" 2 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "aem-dispatcher-with-ease" -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.d/enabled_vhosts/README: -------------------------------------------------------------------------------- 1 | # 2 | # Enabled virtual hosts will be symlinked here. Their names should match the pattern '*.vhost' 3 | # 4 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.d/rewrites/rewrite.rules: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the rewrite rules, and can be customized. 3 | # 4 | # By default, it includes just the rewrite rules. You can 5 | # add rewrite rules to this file but you should still include 6 | # the default rewrite rules. 7 | 8 | Include conf.d/rewrites/default_rewrite.rules 9 | 10 | # rewrite for root redirect 11 | RewriteRule ^/?$ /content/${CONTENT_FOLDER_NAME}/us/en.html [PT,L] 12 | 13 | RewriteCond %{REQUEST_URI} !^/apps 14 | RewriteCond %{REQUEST_URI} !^/bin 15 | RewriteCond %{REQUEST_URI} !^/content 16 | RewriteCond %{REQUEST_URI} !^/etc 17 | RewriteCond %{REQUEST_URI} !^/home 18 | RewriteCond %{REQUEST_URI} !^/libs 19 | RewriteCond %{REQUEST_URI} !^/saml_login 20 | RewriteCond %{REQUEST_URI} !^/system 21 | RewriteCond %{REQUEST_URI} !^/tmp 22 | RewriteCond %{REQUEST_URI} !^/var 23 | RewriteCond %{REQUEST_URI} (.html|.jpe?g|.png|.svg)$ 24 | RewriteRule ^/(.*)$ /content/${CONTENT_FOLDER_NAME}/$1 [PT,L] 25 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.d/variables/custom.vars: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the variables defined within a virtual host definition 3 | # 4 | # By default, it is empty and does not define any variable 5 | # 6 | Define CONTENT_FOLDER_NAME we-retail -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.d/variables/default.vars: -------------------------------------------------------------------------------- 1 | Define DOCROOT /var/www/localhost/cache 2 | Define AEM_HOST host.docker.internal 3 | Define AEM_IP host.docker.internal 4 | Define AEM_PORT 4503 5 | 6 | Define DISP_LOG_LEVEL Warn 7 | Define REWRITE_LOG_LEVEL Warn 8 | Define EXPIRATION_TIME A2592000 -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.d/variables/global.vars: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the variables defined for all virtual hosts 3 | # 4 | 5 | # Log level for the dispatcher 6 | # 7 | # Possible values are: Error, Warn, Info, Debug and Trace1 8 | # Default value: Warn 9 | # 10 | # Define DISP_LOG_LEVEL Warn 11 | 12 | # Log level for mod_rewrite 13 | # 14 | # Possible values are: Error, Warn, Info, Debug and Trace1 - Trace8 15 | # Default value: Warn 16 | # 17 | # To debug your RewriteRules, it is recommended to raise your log 18 | # level to Trace2. 19 | # 20 | # More information can be found at: 21 | # https://httpd.apache.org/docs/current/mod/mod_rewrite.html#logging 22 | # 23 | # Define REWRITE_LOG_LEVEL Warn 24 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/cache/default_invalidate.any: -------------------------------------------------------------------------------- 1 | # 2 | # This is the default list of hosts that are allowed to invalidate (flush) the cache 3 | # on the dispatcher. 4 | # 5 | # DO NOT EDIT this file, your changes will have no impact on your deployment. 6 | # 7 | 8 | # Contains the AEM backend that is allowed to invalidate the cache on the dispatcher 9 | /0001 { 10 | /type "deny" 11 | /glob "*.*.*.*" 12 | } 13 | /0002 { 14 | /type "allow" 15 | /glob "${AEM_IP}" 16 | } 17 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/cache/default_rules.any: -------------------------------------------------------------------------------- 1 | # 2 | # These are the default cache rules. 3 | # 4 | # DO NOT EDIT this file, your changes will have no impact on your deployment. 5 | # 6 | # Instead modify rules.any. 7 | # 8 | 9 | # Put entries of items you do or don't want to cache in apaches doc root 10 | # the globbing pattern to be compared against the url 11 | # example: * -> everything 12 | # : /foo/bar.* -> only the /foo/bar documents 13 | # : /foo/bar/* -> all pages below /foo/bar 14 | # : /foo/bar[./]* -> all pages below and /foo/bar itself 15 | # : *.html -> all .html files 16 | # Default allow all items to cache 17 | /0000 { 18 | /glob "*" 19 | /type "allow" 20 | } 21 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/cache/rules.any: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the cache rules, and can be customized. 3 | # 4 | # By default, it includes the default rules. 5 | # 6 | 7 | $include "./default_rules.any" 8 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/clientheaders/clientheaders.any: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the request headers, and can be customized. 3 | # 4 | # By default, it includes the default client headers. 5 | # 6 | 7 | $include "./default_clientheaders.any" 8 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/clientheaders/default_clientheaders.any: -------------------------------------------------------------------------------- 1 | # 2 | # This is the default list of request headers to forward to AEM. 3 | # 4 | # DO NOT EDIT this file, your changes will have no impact on your deployment. 5 | # 6 | # Instead modify clientheaders.any. 7 | # 8 | 9 | "X-Forwarded-Proto" 10 | "X-Forwarded-SSL-Certificate" 11 | "X-Forwarded-SSL-Client-Cert" 12 | "X-Forwarded-SSL" 13 | "X-Forwarded-Protocol" 14 | "CSRF-Token" 15 | "referer" 16 | "user-agent" 17 | "from" 18 | "content-type" 19 | "content-length" 20 | "accept-charset" 21 | "accept-encoding" 22 | "accept-language" 23 | "accept" 24 | "host" 25 | "if-match" 26 | "if-none-match" 27 | "if-range" 28 | "if-unmodified-since" 29 | "max-forwards" 30 | "range" 31 | "cookie" 32 | "depth" 33 | "translate" 34 | "expires" 35 | "date" 36 | "if" 37 | "lock-token" 38 | "x-expected-entity-length" 39 | "destination" 40 | "Sling-uploadmode" 41 | "x-requested-with" 42 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/dispatcher.any: -------------------------------------------------------------------------------- 1 | # 2 | # This is a file provided by the runtime environment and only included for 3 | # illustration purposes. 4 | # 5 | # DO NOT EDIT this file, your changes will have no impact on your deployment. 6 | # 7 | 8 | /farms { 9 | # Include all *.farm files in enabled_farms 10 | $include "enabled_farms/*.farm" 11 | } 12 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/enabled_farms/README: -------------------------------------------------------------------------------- 1 | # 2 | # Enabled farms will be symlinked here. Their names should match the pattern '*.farm' 3 | # 4 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/filters/filters.any: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the filter ACL, and can be customized. 3 | # 4 | # By default, it includes the default filter ACL. 5 | # 6 | 7 | $include "./default_filters.any" 8 | 9 | # Allow components JSON model 10 | /0101 { /type "allow" /extension "json" /selectors "model" /path "/content/*" } 11 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/renders/default_renders.any: -------------------------------------------------------------------------------- 1 | # 2 | # This is the default list of backends that the dispatcher contacts. 3 | # 4 | # DO NOT EDIT this file, your changes will have no impact on your deployment. 5 | # 6 | 7 | /0 { 8 | /hostname "${AEM_HOST}" 9 | /port "${AEM_PORT}" 10 | /timeout "10000" 11 | } 12 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/virtualhosts/default_virtualhosts.any: -------------------------------------------------------------------------------- 1 | # 2 | # This is the default list of virtual hosts (or domain names) that the dispatcher 3 | # will handle. 4 | # 5 | # DO NOT EDIT this file, your changes will have no impact on your deployment. 6 | # 7 | # Instead modify virtualhosts.any. 8 | # 9 | 10 | "*" 11 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/dispatcher/conf.dispatcher.d/virtualhosts/virtualhosts.any: -------------------------------------------------------------------------------- 1 | # 2 | # This file contains the list of virtual hosts (or domain names) that the dispatcher 3 | # will handle. 4 | # 5 | # By default, it includes the default list of virtual hosts. 6 | # 7 | 8 | $include "./default_virtualhosts.any" 9 | -------------------------------------------------------------------------------- /docs/blog/2020-09-aem-dispacher-with-ease/src/environment/docker-compose.yml.peb: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | dispatcher: 4 | image: centos/httpd:latest 5 | command: ["tail", "-f", "--retry", "/usr/local/apache2/logs/error.log"] 6 | deploy: 7 | replicas: 1 8 | ports: 9 | - "80:80" 10 | networks: 11 | - docker-net 12 | volumes: 13 | - "{{ docker.rootPath }}/src/environment/dispatcher/conf/httpd.conf:/etc/httpd/conf/httpd.conf" 14 | - "{{ docker.rootPath }}/src/environment/dispatcher/conf.d:/etc/httpd/conf.d" 15 | - "{{ docker.rootPath }}/src/environment/dispatcher/conf.dispatcher.d:/etc/httpd/conf.dispatcher.d" 16 | - "{{ docker.workPath }}/dispatcher/modules/mod_dispatcher.so:/etc/httpd/modules/mod_dispatcher.so" 17 | - "{{ docker.workPath }}/dispatcher/logs:/etc/httpd/logs" 18 | {% if docker.runtime.safeVolumes %} 19 | - "{{ docker.workPath }}/dispatcher/cache:/var/www/localhost/cache" 20 | - "{{ docker.workPath }}/dispatcher/htdocs:/var/www/localhost/htdocs" 21 | {% endif %} 22 | {% if docker.runtime.hostInternalIpMissing %} 23 | extra_hosts: 24 | - "host.docker.internal:{{ docker.runtime.hostInternalIp }}" 25 | {% endif %} 26 | networks: 27 | docker-net: -------------------------------------------------------------------------------- /docs/cognifide-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/cognifide-logo.png -------------------------------------------------------------------------------- /docs/docker-desktop-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/docker-desktop-share.png -------------------------------------------------------------------------------- /docs/environment-dev-task.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/environment-dev-task.gif -------------------------------------------------------------------------------- /docs/environment-down-task.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/environment-down-task.gif -------------------------------------------------------------------------------- /docs/environment-file-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/environment-file-structure.png -------------------------------------------------------------------------------- /docs/environment-plugin.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/environment-plugin.md -------------------------------------------------------------------------------- /docs/environment-up-task.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/environment-up-task.gif -------------------------------------------------------------------------------- /docs/gradle-aem-multi-build.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/gradle-aem-multi-build.gif -------------------------------------------------------------------------------- /docs/instance-file-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/instance-file-structure.png -------------------------------------------------------------------------------- /docs/instance-status-task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/instance-status-task.png -------------------------------------------------------------------------------- /docs/instance-workflow-task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/instance-workflow-task.png -------------------------------------------------------------------------------- /docs/logo-gh-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/logo-gh-thumbnail.png -------------------------------------------------------------------------------- /docs/logo-square-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/logo-square-mini.png -------------------------------------------------------------------------------- /docs/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/logo-square.png -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/logo.png -------------------------------------------------------------------------------- /docs/wtt-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/docs/wtt-logo.png -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=16.0.10 2 | release.useAutomaticVersion=true 3 | org.gradle.jvmargs=-Xmx1024m -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /launcher/src/main/kotlin/com/cognifide/gradle/aem/launcher/LauncherException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.launcher 2 | 3 | import org.gradle.api.GradleException 4 | 5 | class LauncherException : GradleException { 6 | constructor(message: String) : super(message) 7 | } 8 | -------------------------------------------------------------------------------- /launcher/src/main/kotlin/com/cognifide/gradle/aem/launcher/MiscScaffolder.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.launcher 2 | 3 | class MiscScaffolder(private val launcher: Launcher) { 4 | 5 | fun scaffold() { 6 | appendGitIgnore() 7 | } 8 | 9 | private fun appendGitIgnore() = launcher.workFile(".gitignore") { 10 | val content = if (launcher.appDirNested) { 11 | """ 12 | ### Gradle/GAP ### 13 | .gradle/ 14 | build/ 15 | /gradle.properties 16 | /gap.jar 17 | /${launcher.appDirPath} 18 | """.trimIndent() 19 | } else { 20 | """ 21 | ### Gradle/GAP ### 22 | .gradle/ 23 | build/ 24 | /gradle.properties 25 | /gap.jar 26 | """.trimIndent() 27 | } 28 | 29 | if (!exists()) { 30 | println("Saving Git ignore file '$this'") 31 | writeText("${launcher.eol}${content}${launcher.eol}") 32 | } else if (!readText().contains(content)) { 33 | println("Appending lines to Git ignore file '$this'") 34 | appendText("${launcher.eol}${content}${launcher.eol}") 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "aem-plugin" 2 | 3 | include(":launcher") 4 | -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/cbp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/src/asset/localInstance/defaults/cbp.exe -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/control/start.bat: -------------------------------------------------------------------------------- 1 | set JAVA_EXECUTABLE="{{ instance.javaExecutablePath }}" 2 | 3 | set CQ_PORT={{instance.httpPort}} 4 | set CQ_RUNMODE={{instance.runModesString}} 5 | set CQ_JVM_OPTS={{instance.jvmOptsString}} 6 | set CQ_START_OPTS={{instance.startOptsString}} 7 | 8 | call crx-quickstart\bin\start.bat -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/control/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export JAVA_EXECUTABLE='{{ instance.javaExecutablePath }}' 4 | 5 | export CQ_PORT={{instance.httpPort}} 6 | export CQ_RUNMODE='{{instance.runModesString}}' 7 | export CQ_JVM_OPTS='{{instance.jvmOptsString}}' 8 | export CQ_START_OPTS='{{instance.startOptsString}}' 9 | 10 | chmod u+x crx-quickstart/bin/start 11 | ./crx-quickstart/bin/start -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/control/status.bat: -------------------------------------------------------------------------------- 1 | set JAVA_EXECUTABLE="{{ instance.javaExecutablePath }}" 2 | 3 | call crx-quickstart\bin\status.bat -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/control/status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export JAVA_EXECUTABLE='{{ instance.javaExecutablePath }}' 4 | 5 | chmod u+x crx-quickstart/bin/status 6 | ./crx-quickstart/bin/status -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/control/stop.bat: -------------------------------------------------------------------------------- 1 | set JAVA_EXECUTABLE="{{ instance.javaExecutablePath }}" 2 | 3 | call crx-quickstart\bin\stop.bat -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/control/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export JAVA_EXECUTABLE='{{ instance.javaExecutablePath }}' 4 | 5 | chmod u+x crx-quickstart/bin/stop 6 | ./crx-quickstart/bin/stop -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/service/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | (cd {{ rootProject.projectDir }} && {{ service.opts['environmentCommand'] }} && {{ service.opts['startCommand'] }} -Pinstance.name={{ instance.name }}) -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/service/status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | (cd {{ rootProject.projectDir }} && {{ service.opts['environmentCommand'] }} && {{ service.opts['statusCommand'] }} -Pinstance.name={{ instance.name }}) -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/service/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | (cd {{ rootProject.projectDir }} && {{ service.opts['environmentCommand'] }} && {{ service.opts['stopCommand'] }} -Pinstance.name={{ instance.name }}) -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/service/systemd.conf: -------------------------------------------------------------------------------- 1 | # AEM instance service managed by Gradle AEM Plugin 2 | 3 | [Unit] 4 | Description=AEM instance '{{ instance.name }}' 5 | After=multi-user.target 6 | Requires=network.target 7 | 8 | [Service] 9 | Type=oneshot 10 | RemainAfterExit=true 11 | 12 | # TODO use PID & handle restrictions 13 | #Type=forking 14 | #GuessMainPID=no 15 | #PIDFile={{ instance.pidFile }} 16 | 17 | User={{ service.opts['user'] }} 18 | Group={{ service.opts['group'] }} 19 | 20 | LimitNOFILE={{ service.opts['limitNoFile'] }} 21 | KillMode=none 22 | 23 | ExecStart={{instance.dir}}/service/start.sh 24 | ExecStop={{instance.dir}}/service/stop.sh 25 | 26 | TimeoutStartSec=1810 27 | TimeoutStopSec=190 28 | 29 | [Install] 30 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /src/asset/localInstance/defaults/service/sysvinit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: aem_{{ instance.purposeId }} 4 | # Required-Start: $local_fs $remote_fs $network $syslog $named 5 | # Required-Stop: $local_fs $remote_fs $network $syslog $named 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start AEM instance 9 | # Description: Init script for AEM instance {{ instance.purposeId }} 10 | ### END INIT INFO 11 | 12 | . /lib/lsb/init-functions 13 | 14 | NAME=aem_{{ instance.purposeId }} 15 | AEM_USER={{ service.opts['user'] }} 16 | 17 | START={{ instance.dir }}/service/start.sh 18 | STOP={{ instance.dir }}/service/stop.sh 19 | STATUS={{ instance.dir }}/service/status.sh 20 | 21 | aem_start() { 22 | su - "${AEM_USER}" -c "sh ${START}" 23 | } 24 | 25 | aem_stop() { 26 | su - "${AEM_USER}" -c "sh ${STOP}" 27 | } 28 | 29 | aem_status() { 30 | su - "${AEM_USER}" -c "sh ${STATUS}" 31 | } 32 | 33 | case "$1" in 34 | start) 35 | aem_start 36 | ;; 37 | stop) 38 | aem_stop 39 | ;; 40 | status) 41 | aem_status 42 | ;; 43 | restart) 44 | aem_stop 45 | aem_start 46 | ;; 47 | *) 48 | echo "Usage: $NAME {start|stop|status|restart}" 49 | exit 1 50 | ;; 51 | esac -------------------------------------------------------------------------------- /src/asset/localInstance/service/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | (cd {{ rootProject.projectDir }} && {{ service.opts['environmentCommand'] }} && {{ service.opts['startCommand'] }}) -------------------------------------------------------------------------------- /src/asset/localInstance/service/status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | (cd {{ rootProject.projectDir }} && {{ service.opts['environmentCommand'] }} && {{ service.opts['statusCommand'] }}) -------------------------------------------------------------------------------- /src/asset/localInstance/service/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | (cd {{ rootProject.projectDir }} && {{ service.opts['environmentCommand'] }} && {{ service.opts['stopCommand'] }}) -------------------------------------------------------------------------------- /src/asset/localInstance/service/systemd.conf: -------------------------------------------------------------------------------- 1 | # AEM multiple instances service managed by Gradle AEM Plugin 2 | 3 | [Unit] 4 | Description=AEM instances 5 | After=multi-user.target 6 | Requires=network.target 7 | 8 | [Service] 9 | Type=oneshot 10 | RemainAfterExit=true 11 | 12 | User={{ service.opts['user'] }} 13 | Group={{ service.opts['group'] }} 14 | 15 | LimitNOFILE={{ service.opts['limitNoFile'] }} 16 | KillMode=none 17 | 18 | ExecStart={{service.opts['dir']}}/start.sh 19 | ExecStop={{service.opts['dir']}}/stop.sh 20 | 21 | TimeoutStartSec=1810 22 | TimeoutStopSec=190 23 | 24 | [Install] 25 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /src/asset/localInstance/service/sysvinit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: aem 4 | # Required-Start: $local_fs $remote_fs $network $syslog $named 5 | # Required-Stop: $local_fs $remote_fs $network $syslog $named 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start AEM instances 9 | # Description: Init script for AEM instances 10 | ### END INIT INFO 11 | 12 | . /lib/lsb/init-functions 13 | 14 | NAME=aem 15 | AEM_USER={{ service.opts['user'] }} 16 | 17 | START={{ service.opts['dir'] }}/start.sh 18 | STOP={{ service.opts['dir'] }}/stop.sh 19 | STATUS={{ service.opts['dir'] }}/status.sh 20 | 21 | aem_start() { 22 | su - "${AEM_USER}" -c "sh ${START}" 23 | } 24 | 25 | aem_stop() { 26 | su - "${AEM_USER}" -c "sh ${STOP}" 27 | } 28 | 29 | aem_status() { 30 | su - "${AEM_USER}" -c "sh ${STATUS}" 31 | } 32 | 33 | case "$1" in 34 | start) 35 | aem_start 36 | ;; 37 | stop) 38 | aem_stop 39 | ;; 40 | status) 41 | aem_status 42 | ;; 43 | restart) 44 | aem_stop 45 | aem_start 46 | ;; 47 | *) 48 | echo "Usage: $NAME {start|stop|status|restart}" 49 | exit 1 50 | ;; 51 | esac -------------------------------------------------------------------------------- /src/asset/oakrun/admin-reset.groovy.peb: -------------------------------------------------------------------------------- 1 | import org.apache.jackrabbit.oak.spi.security.user.util.PasswordUtil 2 | import org.apache.jackrabbit.oak.spi.commit.CommitInfo 3 | import org.apache.jackrabbit.oak.spi.commit.EmptyHook 4 | 5 | class Global { 6 | static userNode = null; 7 | } 8 | 9 | void findUserNode(ub) { 10 | if (ub.hasProperty("rep:principalName")) { 11 | if ("rep:principalName = {{user}}".equals(ub.getProperty("rep:principalName").toString())) { 12 | Global.userNode = ub; 13 | } 14 | } 15 | ub.childNodeNames.each { it -> 16 | if (Global.userNode == null) { 17 | findUserNode(ub.getChildNode(it)); 18 | } 19 | } 20 | } 21 | 22 | ub = session.store.root.builder(); 23 | findUserNode(ub.getChildNode("home").getChildNode("users")); 24 | 25 | if (Global.userNode) { 26 | println("Found user node: " + Global.userNode.toString()); 27 | Global.userNode.setProperty("rep:password", PasswordUtil.buildPasswordHash("{{password}}")); 28 | session.store.merge(ub, EmptyHook.INSTANCE, CommitInfo.EMPTY); 29 | } else { 30 | println("Could not find user node!"); 31 | } 32 | -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | {{manifest}} -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/vault/definition/.content.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/vault/definition/thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wttech/gradle-aem-plugin/18d6cab33481f8f883c6139267fb059f7f6047ae/src/asset/package/defaults/META-INF/vault/definition/thumbnail.png -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/vault/filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% for filter in definition.filters %}{{ filter | raw }} 4 | {% endfor %} 5 | 6 | -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/vault/nodetypes.cnd: -------------------------------------------------------------------------------- 1 | {% for lib in definition.nodeTypeLibs %}{{ lib | raw }} 2 | {% endfor %} 3 | 4 | {% for line in definition.nodeTypeLines %}{{ line | raw }} 5 | {% endfor %} -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/vault/properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% if definition.description is not empty %} 5 | {{definition.description}} 6 | {{definition.description}} 7 | {% endif %} 8 | {{definition.group}} 9 | {{definition.name}} 10 | {{definition.version}} 11 | {% if definition.createdBy is not empty %} 12 | {{definition.createdBy}} 13 | {% endif %} 14 | {% for e in definition.properties %}{{e.value | raw}} 15 | {% endfor %} 16 | 17 | -------------------------------------------------------------------------------- /src/asset/package/defaults/META-INF/vault/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/asset/package/validator/OAKPAL_OPEAR/plan.json: -------------------------------------------------------------------------------- 1 | { 2 | "checklists": [ 3 | "net.adamcin.oakpal.core/basic" 4 | ], 5 | "installHookPolicy": "SKIP", 6 | "checks": [ 7 | { 8 | "name": "basic/subpackages", 9 | "config": { 10 | "denyAll": false 11 | } 12 | }, 13 | { 14 | "name": "basic/acHandling", 15 | "config": { 16 | "levelSet": "no_unsafe" 17 | } 18 | }, 19 | { 20 | "name": "net.adamcin.oakpal.core/basic/composite-store-alignment", 21 | "config": { 22 | "severity": "MINOR" 23 | } 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /src/asset/package/validator/initial/META-INF/vault/privileges.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/asset/vlt/filter.tmp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% for path in paths %} 4 | 5 | {% endfor %} 6 | 7 | -------------------------------------------------------------------------------- /src/functionalTest/kotlin/com/cognifide/gradle/aem/PluginsTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem 2 | 3 | import com.cognifide.gradle.aem.test.AemBuildTest 4 | import org.junit.jupiter.api.Test 5 | 6 | class PluginsTest : AemBuildTest() { 7 | 8 | @Test 9 | fun `should apply all plugins at once`() { 10 | val projectDir = prepareProject("plugins-all") { 11 | settingsGradle("") 12 | 13 | buildGradle( 14 | """ 15 | plugins { 16 | id("com.cognifide.aem.instance.local") 17 | id("com.cognifide.aem.bundle") 18 | id("com.cognifide.aem.package") 19 | id("com.cognifide.aem.package.sync") 20 | } 21 | 22 | aem { 23 | // ... 24 | } 25 | """ 26 | ) 27 | } 28 | 29 | runBuild(projectDir, "tasks", "-Poffline") { 30 | assertTask(":tasks") 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/functionalTest/kotlin/com/cognifide/gradle/aem/common/CommonPluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common 2 | import com.cognifide.gradle.aem.test.AemBuildTest 3 | import org.junit.jupiter.api.Test 4 | 5 | class CommonPluginTest : AemBuildTest() { 6 | 7 | @Test 8 | fun `should apply plugin correctly`() { 9 | val projectDir = prepareProject("common-minimal") { 10 | settingsGradle("") 11 | 12 | buildGradle( 13 | """ 14 | plugins { 15 | id("com.cognifide.aem.common") 16 | } 17 | 18 | aem { 19 | // anything 20 | } 21 | """ 22 | ) 23 | } 24 | 25 | runBuild(projectDir, "tasks") { 26 | assertTask(":tasks") 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/functionalTest/kotlin/com/cognifide/gradle/aem/pkg/PackageSyncPluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg 2 | import com.cognifide.gradle.aem.test.AemBuildTest 3 | import org.junit.jupiter.api.Test 4 | 5 | class PackageSyncPluginTest : AemBuildTest() { 6 | 7 | @Test 8 | fun `should apply plugin correctly`() { 9 | val projectDir = prepareProject("package-sync-minimal") { 10 | settingsGradle("") 11 | 12 | buildGradle( 13 | """ 14 | plugins { 15 | id("com.cognifide.aem.package.sync") 16 | } 17 | """ 18 | ) 19 | } 20 | 21 | runBuild(projectDir, "tasks", "-Poffline") { 22 | assertTask(":tasks") 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/AemDefaultTask.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem 2 | 3 | import com.cognifide.gradle.common.CommonDefaultTask 4 | import org.gradle.api.tasks.Internal 5 | 6 | open class AemDefaultTask : CommonDefaultTask(), AemTask { 7 | 8 | @Internal 9 | final override val aem = project.aem 10 | 11 | init { 12 | group = AemTask.GROUP 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/AemException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem 2 | 3 | import com.cognifide.gradle.common.CommonException 4 | 5 | open class AemException : CommonException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/AemPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem 2 | 3 | import com.cognifide.gradle.common.utils.Formats 4 | import java.io.Serializable 5 | 6 | class AemPlugin : Serializable { 7 | 8 | lateinit var pluginVersion: String 9 | 10 | lateinit var gradleVersion: String 11 | 12 | companion object { 13 | 14 | const val PKG = "com.cognifide.gradle.aem" 15 | 16 | val BUILD by lazy { 17 | fromJson( 18 | AemPlugin::class.java.getResourceAsStream("/build.json") 19 | .bufferedReader().use { it.readText() } 20 | ) 21 | } 22 | 23 | const val ID = "gradle-aem-plugin" 24 | 25 | const val NAME = "Gradle AEM Plugin" 26 | 27 | val NAME_WITH_VERSION: String get() = "$NAME ${BUILD.pluginVersion}" 28 | 29 | private fun fromJson(json: String): AemPlugin = Formats.toObjectFromJson(json) 30 | 31 | private var once = false 32 | 33 | @Synchronized 34 | fun once(callback: AemPlugin.() -> Unit) { 35 | if (!once) { 36 | callback(BUILD) 37 | once = true 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/AemTask.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem 2 | 3 | import org.gradle.api.Task 4 | import org.gradle.api.tasks.Internal 5 | 6 | interface AemTask : Task { 7 | 8 | @get:Internal 9 | val aem: AemExtension 10 | 11 | companion object { 12 | const val GROUP = "AEM" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/bundle/BundleException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.bundle 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | class BundleException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/bundle/tasks/BundleUninstall.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.bundle.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Bundle 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class BundleUninstall : Bundle() { 9 | 10 | @TaskAction 11 | fun uninstall() { 12 | sync.action { osgi.uninstallBundle(it) } 13 | common.notifier.notify("Bundle uninstalled", "${files.fileNames} on ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Uninstalls OSGi bundle on instance(s)." 18 | } 19 | 20 | companion object { 21 | const val NAME = "bundleUninstall" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/CommonPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.AemPlugin 5 | import com.cognifide.gradle.common.CommonDefaultPlugin 6 | import org.gradle.api.Project 7 | import org.gradle.api.plugins.BasePlugin 8 | import org.gradle.api.tasks.testing.Test 9 | 10 | /** 11 | * Provides 'aem' extension to build script on which all other build logic is based. 12 | */ 13 | class CommonPlugin : CommonDefaultPlugin() { 14 | 15 | override fun Project.configureProject() { 16 | AemPlugin.apply { once { logger.info("Using: $NAME_WITH_VERSION") } } 17 | 18 | plugins.apply(BasePlugin::class.java) 19 | 20 | val aem = AemExtension(this) 21 | extensions.add(AemExtension.NAME, aem) 22 | 23 | aem.common.javaSupport.version.convention("11") // valid for instance creation and bundle compilation 24 | tasks.withType(Test::class.java) { it.javaLauncher.convention(aem.common.javaSupport.launcher) } // use same Java to launch AEM and to run tests on it 25 | } 26 | 27 | companion object { 28 | const val ID = "com.cognifide.aem.common" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/bundle/BundleException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.bundle 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | class BundleException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/bundle/BundleFile.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.bundle 2 | 3 | import aQute.bnd.osgi.Jar 4 | import com.cognifide.gradle.aem.common.instance.service.osgi.Bundle 5 | import java.io.File 6 | import java.io.Serializable 7 | 8 | class BundleFile(val file: File) : Serializable { 9 | 10 | val jar = Jar(file) 11 | 12 | val symbolicName: String = jar.manifest.mainAttributes.getValue(Bundle.ATTRIBUTE_SYMBOLIC_NAME) 13 | ?: throw BundleException("File is not a valid OSGi bundle: $file") 14 | 15 | val version: String = jar.manifest.mainAttributes.getValue(Bundle.ATTRIBUTE_VERSION) 16 | 17 | val description: String = jar.manifest.mainAttributes.getValue(Bundle.ATTRIBUTE_DESCRIPTION) ?: "" 18 | 19 | val group: String get() = symbolicName.substringBeforeLast(".") 20 | 21 | override fun toString(): String = "BundleFile(symbolicName='$symbolicName', version='$version', file='$file')" 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/cli/CliException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.cli 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | open class CliException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/cli/JarApp.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.cli 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.common.build.DependencyFile 5 | import org.gradle.process.ExecResult 6 | import org.gradle.process.JavaExecSpec 7 | import org.gradle.process.internal.streams.SafeStreams 8 | import java.io.File 9 | 10 | open class JarApp(val aem: AemExtension) { 11 | 12 | val dependencyNotation = aem.obj.string() 13 | 14 | fun exec(workingDir: File, command: String) = exec(workingDir, command.split(" ")) 15 | 16 | fun exec(workingDir: File, args: Iterable) = exec { 17 | workingDir(workingDir) 18 | args(listOf(jar) + args) 19 | } 20 | 21 | fun exec(vararg args: Any) = exec(args.asIterable()) 22 | 23 | fun exec(args: Iterable) = exec { args(listOf(jar) + args) } 24 | 25 | @Suppress("TooGenericExceptionCaught") 26 | fun exec(options: JavaExecSpec.() -> Unit = {}): ExecResult { 27 | return try { 28 | aem.project.javaexec { 29 | it.apply { 30 | executable(aem.common.javaSupport.launcherPath) 31 | standardInput = SafeStreams.emptyInput() 32 | standardOutput = SafeStreams.systemOut() 33 | errorOutput = SafeStreams.systemErr() 34 | mainClass.set("-jar") 35 | options() 36 | } 37 | } 38 | } catch (e: Exception) { 39 | throw JarException("Jar application '${dependencyNotation.get()}' cannot be executed properly! Cause: ${e.message}", e) 40 | } 41 | } 42 | 43 | val jar: File get() = DependencyFile(aem.project, dependencyNotation.get()).file 44 | } 45 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/cli/JarException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.cli 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | open class JarException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/Auth.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | import com.cognifide.gradle.aem.common.instance.service.auth.AuthException 4 | import com.cognifide.gradle.common.CommonException 5 | import java.util.* 6 | 7 | class Auth(val instance: LocalInstance) { 8 | 9 | val credentials: Pair 10 | get() = when { 11 | updateNeeded -> instance.user.get() to passwordPrevious 12 | else -> instance.user.get() to instance.password.get() 13 | } 14 | 15 | val updateNeeded: Boolean get() = instance.password.get() != passwordPrevious 16 | 17 | val passwordPrevious: String get() = passwordProperty ?: Instance.PASSWORD_DEFAULT 18 | 19 | fun update() { 20 | if (updateNeeded) { 21 | instance.sync.authManager.updatePassword(instance.user.get(), passwordPrevious, instance.password.get()) 22 | saveProperties() 23 | } 24 | } 25 | 26 | private val passwordProperty: String? get() = properties["admin.password"]?.toString() 27 | 28 | private val properties get() = Properties().apply { 29 | if (propertiesFile.exists()) { 30 | propertiesFile.inputStream().buffered().use { load(it) } 31 | } 32 | } 33 | 34 | private val propertiesFile get() = instance.dir.resolve("config/auth.properties") 35 | 36 | private fun saveProperties() = try { 37 | propertiesFile.parentFile.mkdirs() 38 | propertiesFile.bufferedWriter().use { 39 | Properties().apply { put("admin.password", instance.password.get()) }.store(it, null) 40 | } 41 | } catch (e: CommonException) { 42 | throw AuthException("Cannot save auth properties to file '$propertiesFile' for $instance!", e) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/ImsException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | class ImsException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/InstanceAction.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | interface InstanceAction { 4 | 5 | fun perform(instances: Collection) 6 | } 7 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/InstanceException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | open class InstanceException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/InstanceService.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | open class InstanceService(val sync: InstanceSync) { 4 | 5 | // Shorthands 6 | 7 | val aem = sync.aem 8 | 9 | val instance = sync.instance 10 | 11 | val project = sync.aem.project 12 | 13 | val common = aem.common 14 | 15 | val logger = aem.logger 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/LocalInstanceException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | open class LocalInstanceException : InstanceException { 4 | 5 | constructor(message: String, cause: Throwable) : super(message, cause) 6 | 7 | constructor(message: String) : super(message) 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/Location.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | /** 6 | * Indicates if particular instance should be managed by the local instance plugin or not. 7 | */ 8 | enum class Location { 9 | 10 | /** 11 | * Managed by the plugin which could change it state (make up/down and destroy). 12 | */ 13 | LOCAL, 14 | 15 | /** 16 | * Managed externally. Plugin is unable to control it state. 17 | */ 18 | REMOTE; 19 | 20 | companion object { 21 | 22 | fun byInstance(instance: Instance) = when (instance) { 23 | is LocalInstance -> LOCAL 24 | else -> REMOTE 25 | } 26 | 27 | fun of(type: String?) = find(type) 28 | ?: throw AemException("Invalid instance physical type '$type'! Supported values are only: 'local' and 'remote'.") 29 | 30 | fun find(type: String?) = values().find { type.equals(it.name, ignoreCase = true) } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/action/CheckAction.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.action 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.instance.Instance 5 | import com.cognifide.gradle.aem.common.instance.check.CheckRunner 6 | import com.cognifide.gradle.aem.common.instance.names 7 | 8 | /** 9 | * Verify instances using custom runner and set of checks. 10 | */ 11 | class CheckAction(aem: AemExtension) : DefaultAction(aem) { 12 | 13 | val runner = CheckRunner(aem) 14 | 15 | fun runner(options: CheckRunner.() -> Unit) { 16 | runner.apply(options) 17 | } 18 | 19 | override fun perform(instances: Collection) { 20 | if (instances.isEmpty()) { 21 | logger.info("No instances to check.") 22 | return 23 | } 24 | 25 | logger.info("Checking instance(s): ${instances.names}") 26 | 27 | runner.check(instances) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/action/DefaultAction.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.action 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.instance.InstanceAction 5 | 6 | abstract class DefaultAction(protected val aem: AemExtension) : InstanceAction { 7 | 8 | protected val common = aem.common 9 | 10 | protected val logger = aem.logger 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/action/ReloadAction.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.action 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.instance.Instance 5 | import com.cognifide.gradle.aem.common.instance.InstanceException 6 | import java.util.concurrent.CopyOnWriteArrayList 7 | 8 | /** 9 | * Reloads all instances (both remote and local instances). 10 | */ 11 | class ReloadAction(aem: AemExtension) : DefaultAction(aem) { 12 | 13 | override fun perform(instances: Collection) { 14 | if (instances.isEmpty()) { 15 | aem.logger.info("No instances to reload.") 16 | return 17 | } 18 | 19 | reload(instances) 20 | } 21 | 22 | private fun reload(instances: Collection) { 23 | val reloaded = CopyOnWriteArrayList() 24 | 25 | common.parallel.with(instances) { 26 | try { 27 | sync.osgiFramework.restart() 28 | reloaded += this 29 | } catch (e: InstanceException) { // still await up timeout will fail 30 | aem.logger.error("Instance is unavailable: $this") 31 | aem.logger.info("Error details", e) 32 | } 33 | } 34 | 35 | if (reloaded.isNotEmpty()) { 36 | val unavailable = instances - reloaded 37 | 38 | aem.logger.info("Reloading instance(s): ${reloaded.size} triggered, ${unavailable.size} unavailable") 39 | } else { 40 | throw InstanceException("All instances are unavailable.") 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/BundlesCheck.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | import com.cognifide.gradle.aem.common.utils.shortenClass 4 | 5 | @Suppress("MagicNumber") 6 | class BundlesCheck(group: CheckGroup) : DefaultCheck(group) { 7 | 8 | val symbolicNamesIgnored = aem.obj.strings { convention(listOf()) } 9 | 10 | init { 11 | sync.apply { 12 | http.connectionTimeout.convention(1_500) 13 | http.connectionRetries.convention(false) 14 | } 15 | } 16 | 17 | override fun check() { 18 | logger.info("Checking OSGi bundles on $instance") 19 | 20 | val state = state(sync.osgiFramework.determineBundleState()) 21 | 22 | if (state.unknown) { 23 | statusLogger.error( 24 | "Bundles unknown", 25 | "Unknown bundle state on $instance" 26 | ) 27 | return 28 | } 29 | 30 | val unstable = state.bundlesExcept(symbolicNamesIgnored.get()).filter { !it.stable } 31 | if (unstable.isNotEmpty()) { 32 | statusLogger.error( 33 | when (unstable.size) { 34 | 1 -> "Bundle unstable '${unstable.first().symbolicName.shortenClass()}'" 35 | in 2..10 -> "Bundles unstable (${unstable.size})" 36 | else -> "Bundles stable (${state.stablePercent})" 37 | }, 38 | "Unstable bundles detected (${unstable.size}) on $instance:\n${logValues(unstable)}" 39 | ) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/Check.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | import org.gradle.api.provider.Property 4 | 5 | interface Check { 6 | 7 | val enabled: Property 8 | 9 | fun check() 10 | 11 | val status: String 12 | 13 | val success: Boolean 14 | 15 | val failure: Boolean get() = !success 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/CheckFactory.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | class CheckFactory(val group: CheckGroup) { 4 | 5 | fun custom(callback: CustomCheck.() -> Unit) = CustomCheck(group, callback) 6 | 7 | fun bundles(options: BundlesCheck.() -> Unit = {}) = BundlesCheck(group).apply(options) 8 | 9 | fun installer(options: InstallerCheck.() -> Unit = {}) = InstallerCheck(group).apply(options) 10 | 11 | fun components(options: ComponentsCheck.() -> Unit = {}) = ComponentsCheck(group).apply(options) 12 | 13 | fun events(options: EventsCheck.() -> Unit = {}) = EventsCheck(group).apply(options) 14 | 15 | fun timeout(options: TimeoutCheck.() -> Unit = {}) = TimeoutCheck(group).apply(options) 16 | 17 | fun unavailable(options: UnavailableCheck.() -> Unit = {}) = UnavailableCheck(group).apply(options) 18 | 19 | fun unchanged(options: UnchangedCheck.() -> Unit = {}) = UnchangedCheck(group).apply(options) 20 | 21 | fun help(options: HelpCheck.() -> Unit = {}) = HelpCheck(group).apply(options) 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/CheckGroup.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.cognifide.gradle.common.build.CollectingLogger 5 | import org.apache.commons.lang3.builder.HashCodeBuilder 6 | 7 | class CheckGroup( 8 | val runner: CheckRunner, 9 | val instance: Instance, 10 | checkFactory: CheckFactory.() -> List 11 | ) { 12 | 13 | val stateBuilder = HashCodeBuilder() 14 | 15 | val statusLogger = CollectingLogger() 16 | 17 | var checks: List = CheckFactory(this).run(checkFactory) 18 | 19 | @Suppress("TooGenericExceptionCaught", "LoopWithTooManyJumpStatements") 20 | fun check() { 21 | val checksEnabled = checks.filter { it.enabled.get() } 22 | for (check in checksEnabled) { 23 | try { 24 | check.check() 25 | if (check.failure) { 26 | break 27 | } 28 | } catch (e: Exception) { 29 | runner.abortCause = e 30 | break 31 | } 32 | } 33 | } 34 | 35 | fun log() { 36 | statusLogger.entries.forEach { 37 | runner.logger.log(it.level, it.details) 38 | } 39 | } 40 | 41 | fun state(value: Any) { 42 | stateBuilder.append(value) 43 | } 44 | 45 | val state: Int get() = stateBuilder.toHashCode() 46 | 47 | val done: Boolean get() = checks.all { it.success } 48 | 49 | val status get() = if (done) "Passed" else "Not passed" 50 | 51 | val summary: String get() = checks.firstOrNull { it.failure }?.status ?: "Passed" 52 | } 53 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/CustomCheck.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | class CustomCheck(group: CheckGroup, private val callback: CustomCheck.() -> Unit) : DefaultCheck(group) { 4 | 5 | override fun check() = callback() 6 | } 7 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/HelpException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | open class HelpException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/check/UnchangedCheck.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.check 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | /** 6 | * Check that protects against false-positive CRX package deployments. 7 | * 8 | * It awaits instance state to be changed at least one time. 9 | * If it does not, it just make a little delay to be sure that this state is not temporary. 10 | */ 11 | class UnchangedCheck(group: CheckGroup) : DefaultCheck(group) { 12 | 13 | val awaitTime = aem.obj.long { convention(TimeUnit.SECONDS.toMillis(3)) } 14 | 15 | override fun check() { 16 | if (progress.stateChanges <= 1 && progress.stateTime < awaitTime.get()) { 17 | statusLogger.error( 18 | "State unchanged", 19 | "Awaiting state to be changed on $instance" 20 | ) 21 | return 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/BackupSource.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | import com.cognifide.gradle.common.file.transfer.FileEntry 4 | import java.io.File 5 | 6 | class BackupSource(val type: BackupType, val fileEntry: FileEntry, val fileResolver: () -> File) { 7 | 8 | val file: File get() = fileResolver() 9 | 10 | override fun equals(other: Any?): Boolean { 11 | if (this === other) return true 12 | if (javaClass != other?.javaClass) return false 13 | 14 | other as BackupSource 15 | 16 | if (type != other.type) return false 17 | if (fileEntry != other.fileEntry) return false 18 | 19 | return true 20 | } 21 | 22 | override fun hashCode(): Int { 23 | var result = type.hashCode() 24 | result = 31 * result + fileEntry.hashCode() 25 | return result 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/BackupType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | /** 4 | * Indicates backup file source. 5 | */ 6 | enum class BackupType { 7 | /** 8 | * File located at local file system (created by instance backup task). 9 | */ 10 | LOCAL, 11 | 12 | /** 13 | * File downloaded from remote server (via file transfer). 14 | */ 15 | REMOTE; 16 | 17 | val dirName get() = name.lowercase() 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/DistType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | enum class DistType { 4 | SDK, 5 | ON_PREM 6 | } 7 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/InstallResolver.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.common.file.resolver.FileResolver 5 | import com.cognifide.gradle.common.utils.using 6 | 7 | class InstallResolver(private val aem: AemExtension) { 8 | 9 | private val common = aem.common 10 | 11 | private val fileResolver = FileResolver(common).apply { 12 | downloadDir.convention(aem.obj.buildDir("localInstance/install")) 13 | aem.prop.file("localInstance.install.downloadDir")?.let { downloadDir.set(it) } 14 | aem.prop.list("localInstance.install.urls")?.forEachIndexed { index, url -> 15 | val no = index + 1 16 | val fileName = url.substringAfterLast("/").substringBeforeLast(".") 17 | 18 | group("cmd.$no.$fileName") { get(url) } 19 | } 20 | } 21 | 22 | fun files(configurer: FileResolver.() -> Unit) = fileResolver.using(configurer) 23 | 24 | fun files(vararg values: Any) = fileResolver.getAll(values.asIterable()) 25 | 26 | fun files(values: Iterable) = fileResolver.getAll(values) 27 | 28 | val files get() = fileResolver.files 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/JavaAgentResolver.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | import com.cognifide.gradle.aem.common.instance.LocalInstanceManager 4 | import com.cognifide.gradle.common.file.resolver.FileResolver 5 | import com.cognifide.gradle.common.utils.using 6 | 7 | class JavaAgentResolver(private val manager: LocalInstanceManager) { 8 | 9 | private val aem = manager.aem 10 | 11 | private val common = manager.aem.common 12 | 13 | private val fileResolver = FileResolver(common).apply { 14 | downloadDir.convention(manager.rootDir.dir("javaAgent")) 15 | aem.prop.file("localInstance.javaAgent.downloadDir")?.let { downloadDir.set(it) } 16 | aem.prop.list("localInstance.javaAgent.urls")?.forEachIndexed { index, url -> 17 | val no = index + 1 18 | val fileName = url.substringAfterLast("/").substringBeforeLast(".") 19 | 20 | group("cmd.$no.$fileName") { get(url) } 21 | } 22 | } 23 | 24 | fun files(configurer: FileResolver.() -> Unit) = fileResolver.using(configurer) 25 | 26 | fun files(vararg values: Any) = fileResolver.getAll(values.asIterable()) 27 | 28 | fun files(values: Iterable) = fileResolver.getAll(values) 29 | 30 | val files get() = fileResolver.files 31 | 32 | fun openTelemetry() = 33 | files("https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar") 34 | 35 | fun openTelemetry(version: String) = 36 | files("https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v$version/opentelemetry-javaagent.jar") 37 | 38 | fun jacoco(version: String) = 39 | files("https://repo1.maven.org/maven2/org/jacoco/org.jacoco.agent/$version/org.jacoco.agent-$version-runtime.jar") 40 | } 41 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/OpenMode.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | import com.cognifide.gradle.aem.common.instance.LocalInstanceException 4 | 5 | /** 6 | * Controls when browser will be opened when instance is up. 7 | */ 8 | enum class OpenMode { 9 | 10 | /** 11 | * Only once when instance is initialized (up first time). 12 | */ 13 | ONCE, 14 | 15 | /** 16 | * Always when instance is up (also after restarting). 17 | */ 18 | ALWAYS, 19 | 20 | /** 21 | * Browser will never be opened when instance is up. 22 | */ 23 | NEVER; 24 | 25 | companion object { 26 | fun of(name: String): OpenMode { 27 | return values().find { it.name.equals(name, true) } 28 | ?: throw LocalInstanceException("Unsupported local instance open mode named: $name") 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/Source.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | import com.cognifide.gradle.aem.common.instance.LocalInstanceException 4 | 5 | enum class Source { 6 | 7 | /** 8 | * Create instances from most recent backup (local or remote) or fallback to creating from the scratch 9 | * if there is no backup available. 10 | */ 11 | AUTO, 12 | 13 | /** 14 | * Force creating instances from the scratch. 15 | */ 16 | SCRATCH, 17 | 18 | /** 19 | * Force using backup from any source. 20 | */ 21 | BACKUP_ANY, 22 | 23 | /** 24 | * Force using backup available at remote source (available by using 'localInstance.backup.downloadUrl' 25 | * or 'localInstance.backup.uploadUrl'). 26 | */ 27 | BACKUP_REMOTE, 28 | 29 | /** 30 | * Force using local backup (created by task 'instanceBackup'). 31 | */ 32 | BACKUP_LOCAL; 33 | 34 | companion object { 35 | fun of(name: String): Source { 36 | return values().find { it.name.equals(name, true) } 37 | ?: throw LocalInstanceException("Unsupported local instance source named: $name") 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/local/Status.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.local 2 | 3 | import com.cognifide.gradle.common.utils.capitalizeChar 4 | 5 | @Suppress("MagicNumber") 6 | class Status(val type: Type, val exitValue: String) { 7 | 8 | val text: String get() = when (type) { 9 | Type.UNRECOGNIZED -> "${type.displayName} ($exitValue)" 10 | else -> type.displayName 11 | } 12 | 13 | val running: Boolean get() = type == Type.RUNNING 14 | 15 | val runnable: Boolean get() = Type.RUNNABLE.contains(type) 16 | 17 | val unrecognized: Boolean get() = type == Type.UNRECOGNIZED 18 | 19 | @Suppress("MagicNumber") 20 | enum class Type(val exitValue: String) { 21 | RUNNING("0"), 22 | DEAD("1"), 23 | NOT_RUNNING("3"), 24 | UNKNOWN("4"), 25 | UNRECOGNIZED(""); 26 | 27 | val displayName: String get() = name.lowercase().replace("_", " ").capitalizeChar() 28 | 29 | override fun toString() = displayName 30 | 31 | companion object { 32 | val RUNNABLE = arrayOf(NOT_RUNNING, UNKNOWN) 33 | 34 | fun byExitValue(exitValue: Int) = values().find { it.exitValue == exitValue.toString() } ?: UNRECOGNIZED 35 | } 36 | } 37 | 38 | override fun toString() = text 39 | 40 | companion object { 41 | val UNRECOGNIZED = Status(Type.UNRECOGNIZED, Type.UNRECOGNIZED.exitValue) 42 | 43 | fun byExitValue(exitValue: Int) = Status(Type.byExitValue(exitValue), exitValue.toString()) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/oak/OakRun.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.oak 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.cli.JarApp 5 | import com.cognifide.gradle.aem.common.instance.LocalInstance 6 | import com.cognifide.gradle.common.utils.using 7 | import java.io.File 8 | 9 | class OakRun(val aem: AemExtension, val instance: LocalInstance) { 10 | 11 | private val logger = aem.logger 12 | 13 | val jarApp = JarApp(aem).apply { 14 | dependencyNotation.apply { 15 | convention("org.apache.jackrabbit:oak-run:1.36") 16 | aem.prop.string("oakrun.jar.dependency")?.let { set(it) } 17 | } 18 | } 19 | 20 | fun jarApp(options: JarApp.() -> Unit) = jarApp.using(options) 21 | 22 | fun resetPassword(user: String, password: String) { 23 | try { 24 | logger.info("Resetting user '$user' password for $instance using OakRun") 25 | 26 | val template = aem.assetManager.readFile("oakrun/admin-reset.groovy.peb").bufferedReader().readText() 27 | val content = aem.prop.expand( 28 | template, 29 | mapOf( 30 | "user" to user, 31 | "password" to password 32 | ) 33 | ) 34 | runGroovyScript(content) 35 | } catch (e: OakRunException) { 36 | throw OakRunException("Cannot reset password for '$instance'!", e) 37 | } 38 | } 39 | 40 | fun runGroovyScript(content: String) { 41 | val script = OakRunScript(this, content) 42 | script.exec() 43 | } 44 | 45 | fun runGroovyScript(file: File) = runGroovyScript(file.bufferedReader().readText()) 46 | } 47 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/oak/OakRunException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.oak 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | open class OakRunException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/oak/OakRunScript.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.oak 2 | 3 | import com.cognifide.gradle.aem.common.cli.JarException 4 | import java.io.File 5 | import java.io.IOException 6 | import java.util.* 7 | 8 | class OakRunScript(private val oakRun: OakRun, private val content: String) { 9 | 10 | private val aem = oakRun.aem 11 | 12 | private val logger = aem.logger 13 | 14 | private val scriptFile = oakRun.instance.dir.resolve("tmp/oakrun/${UUID.randomUUID()}.groovy") 15 | 16 | private val storeDir = oakRun.instance.dir.resolve("crx-quickstart/repository/segmentstore") 17 | 18 | fun exec() = try { 19 | save() 20 | load() 21 | } finally { 22 | clean() 23 | } 24 | 25 | private fun save(): File = try { 26 | scriptFile.apply { 27 | parentFile.mkdirs() 28 | writeText(content) 29 | } 30 | } catch (e: IOException) { 31 | throw OakRunException("Cannot save script '$scriptFile' to be loaded by OakRun!", e) 32 | } 33 | 34 | private fun load() = try { 35 | oakRun.jarApp.exec("console", storeDir, "--read-write", ":load $scriptFile") 36 | } catch (e: JarException) { 37 | logger.debug("OakRun script '$scriptFile' contents:\n$content") 38 | throw OakRunException("Cannot load script '$scriptFile' using OakRun!", e) 39 | } 40 | 41 | private fun clean() { 42 | if (scriptFile.exists()) { 43 | scriptFile.delete() 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/provision/Action.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.provision 2 | 3 | class Action(val step: InstanceStep, val status: Status) 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/provision/ProvisionException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.provision 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | open class ProvisionException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/provision/Status.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.provision 2 | 3 | enum class Status { 4 | ENDED, 5 | FAILED, 6 | SKIPPED 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/provision/step/ConfigureWorkflowLauncherStep.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.provision.step 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.cognifide.gradle.aem.common.instance.provision.ProvisionException 5 | import com.cognifide.gradle.aem.common.instance.provision.Provisioner 6 | import com.cognifide.gradle.aem.common.instance.provision.Step 7 | import com.cognifide.gradle.aem.common.instance.service.workflow.WorkflowLauncher 8 | 9 | class ConfigureWorkflowLauncherStep(provisioner: Provisioner, val wid: String) : Step(provisioner) { 10 | 11 | lateinit var workflowAction: WorkflowLauncher.() -> Unit 12 | 13 | fun workflow(action: WorkflowLauncher.() -> Unit) { 14 | this.workflowAction = action 15 | } 16 | 17 | override fun validate() { 18 | if (!::workflowAction.isInitialized) { 19 | throw ProvisionException("Step '${id.get()}' has no workflow action defined!") 20 | } 21 | } 22 | 23 | override fun action(instance: Instance) { 24 | instance.sync { 25 | workflowManager.launcher(wid).apply(workflowAction) 26 | } 27 | } 28 | 29 | init { 30 | id.set("configureWorkflowLauncher/$wid") 31 | description.convention("Configuring workflow launcher with id '$wid'") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/provision/step/CustomStep.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.provision.step 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.cognifide.gradle.aem.common.instance.InstanceSync 5 | import com.cognifide.gradle.aem.common.instance.provision.ProvisionException 6 | import com.cognifide.gradle.aem.common.instance.provision.Provisioner 7 | import com.cognifide.gradle.aem.common.instance.provision.Step 8 | 9 | class CustomStep(provisioner: Provisioner) : Step(provisioner) { 10 | 11 | fun validate(callback: () -> Unit) { 12 | this.validateCallback = callback 13 | } 14 | 15 | private var validateCallback: () -> Unit = {} 16 | 17 | override fun validate() { 18 | if (!id.isPresent) { 19 | throw ProvisionException("Step ID is not defined!") 20 | } 21 | if (!::actionCallback.isInitialized) { 22 | throw ProvisionException("Step '${id.get()}' action is not defined!") 23 | } 24 | 25 | validateCallback() 26 | } 27 | 28 | fun init(callback: () -> Unit) { 29 | this.initCallback = callback 30 | } 31 | 32 | private var initCallback: () -> Unit = {} 33 | 34 | override fun init() { 35 | initCallback() 36 | } 37 | 38 | fun action(callback: Instance.() -> Unit) { 39 | this.actionCallback = callback 40 | } 41 | 42 | private lateinit var actionCallback: Instance.() -> Unit 43 | 44 | override fun action(instance: Instance) { 45 | actionCallback(instance) 46 | } 47 | 48 | fun sync(callback: InstanceSync.() -> Unit) = action { sync(callback) } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/provision/step/ImportMappingsStep.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.provision.step 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.cognifide.gradle.aem.common.instance.provision.ProvisionException 5 | import com.cognifide.gradle.aem.common.instance.provision.Provisioner 6 | import com.cognifide.gradle.aem.common.instance.provision.Step 7 | 8 | class ImportMappingsStep(provisioner: Provisioner, val fileName: String) : Step(provisioner) { 9 | 10 | val jsonFile get() = provisioner.manager.configDir.get().asFile.resolve("mapping/$fileName") 11 | 12 | val root = aem.obj.string { 13 | convention("/etc/map/http") 14 | } 15 | 16 | override fun validate() { 17 | if (!jsonFile.exists()) { 18 | throw ProvisionException("Mapping file to be imported does not exist '$jsonFile'!") 19 | } 20 | } 21 | 22 | override fun action(instance: Instance) { 23 | instance.sync { 24 | repository.import(root.get(), jsonFile) 25 | } 26 | } 27 | 28 | init { 29 | id.set("importMappings/$fileName") 30 | description.convention("Importing mappings file '$fileName'") 31 | version.set(aem.obj.provider { versionFrom(jsonFile, root.get()) }) 32 | condition { onPublish() && once() } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/rcp/RcpSummary.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.rcp 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.cognifide.gradle.common.utils.Formats 5 | 6 | data class RcpSummary( 7 | val source: Instance, 8 | val target: Instance, 9 | val copiedPaths: Long, 10 | val duration: Long 11 | ) { 12 | val durationString: String 13 | get() = Formats.duration(duration) 14 | 15 | override fun toString(): String { 16 | return "RcpSummary(copiedPaths=$copiedPaths, duration=$durationString, source=$source, target=$target)" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/auth/AuthException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.auth 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | class AuthException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/auth/AuthManager.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.auth 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceService 4 | import com.cognifide.gradle.aem.common.instance.InstanceSync 5 | import com.cognifide.gradle.common.CommonException 6 | 7 | class AuthManager(sync: InstanceSync) : InstanceService(sync) { 8 | 9 | fun updatePassword(user: String, currentPassword: String, newPassword: String) { 10 | logger.info("Updating password for user '$user' on $instance") 11 | 12 | val node = sync.repository.query { 13 | path("/home/users") 14 | type("rep:User") 15 | or { 16 | propertyEquals("rep:authorizableId", user) 17 | propertyEquals("rep:principalName", user) 18 | } 19 | limit(1) 20 | }.nodeSequence().firstOrNull() ?: throw AuthException("Cannot find user '$user' for updating password on $instance!") 21 | 22 | try { 23 | sync.http.postUrlencoded( 24 | "${node.path}.rw.userprops.html", 25 | mapOf( 26 | ":currentPassword" to currentPassword, 27 | "rep:password" to newPassword 28 | ) 29 | ) 30 | } catch (e: CommonException) { 31 | throw AuthException("Cannot update password for user '$user' on $instance!") 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/crx/CrxException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.crx 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | class CrxException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/groovy/GroovyConsoleException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.groovy 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | class GroovyConsoleException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/groovy/GroovyEvalResult.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.groovy 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore 4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 5 | import org.apache.commons.lang3.StringUtils 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | class GroovyEvalResult { 9 | 10 | lateinit var exceptionStackTrace: String 11 | 12 | lateinit var data: String 13 | 14 | lateinit var output: String 15 | 16 | lateinit var runningTime: String 17 | 18 | lateinit var script: String 19 | 20 | var result: String? = null 21 | 22 | @get:JsonIgnore 23 | val error: Boolean 24 | get() = exceptionStackTrace.isNotBlank() 25 | 26 | @get:JsonIgnore 27 | val success: Boolean 28 | get() = !error 29 | 30 | override fun toString(): String { 31 | return StringBuilder().apply { 32 | append("${javaClass.simpleName}(output='${shorten(output)}', runningTime='$runningTime'") 33 | append(", exceptionStackTrace='${shorten(exceptionStackTrace)}', result='$result'") 34 | append(", script='${shorten(script)}', data='${shorten(data)}')") 35 | }.toString() 36 | } 37 | 38 | companion object { 39 | private const val ABBREVIATE_WIDTH = 200 40 | 41 | private fun shorten(text: String) = StringUtils.abbreviate(text.trim(), ABBREVIATE_WIDTH) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/groovy/GroovyEvalStatus.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.groovy 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import java.io.File 5 | 6 | data class GroovyEvalStatus( 7 | val script: File, 8 | val instance: Instance, 9 | val success: Boolean, 10 | val error: String 11 | ) { 12 | val fail: Boolean 13 | get() = !success 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/groovy/GroovyEvalSummary.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.groovy 2 | 3 | import com.cognifide.gradle.common.utils.Formats 4 | 5 | data class GroovyEvalSummary( 6 | val statuses: List, 7 | val duration: Long 8 | ) { 9 | val total: Int 10 | get() = statuses.size 11 | 12 | val failed: Int 13 | get() = statuses.count { it.fail } 14 | 15 | val succeeded: Int 16 | get() = statuses.count { it.success } 17 | 18 | val succeededPercent 19 | get() = Formats.percentExplained(succeeded, total) 20 | 21 | val durationString: String 22 | get() = Formats.duration(duration) 23 | 24 | override fun toString(): String { 25 | return "${javaClass.simpleName}(successes=$succeeded, failed=$failed, total=$total, duration=$durationString)" 26 | } 27 | 28 | companion object { 29 | fun empty() = GroovyEvalSummary(listOf(), 0L) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/ims/AccessObject.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.ims 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | 6 | /** 7 | * Serves as a placeholder for json response from 8 | * Adobe Identity Management Services 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | data class AccessObject( 12 | 13 | @JsonProperty("access_token") 14 | val accessToken: String, 15 | 16 | ) 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/ims/Integration.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.ims 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | 6 | @JsonIgnoreProperties(ignoreUnknown = true) 7 | data class Integration( 8 | 9 | val privateKey: String, 10 | 11 | @JsonProperty("org") 12 | val orgId: String, 13 | 14 | @JsonProperty("id") 15 | val technicalAccountId: String, 16 | 17 | val technicalAccount: TechnicalAccount, 18 | 19 | @JsonProperty("imsEndpoint") 20 | val imsHost: String, 21 | 22 | val metascopes: String, 23 | ) 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/ims/Secret.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.ims 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | 5 | /** 6 | * Serves as a placeholder for secret json file 7 | * fetched from AEMaaCS instance 8 | */ 9 | @JsonIgnoreProperties(ignoreUnknown = true) 10 | data class Secret(val integration: Integration) 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/ims/TechnicalAccount.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.ims 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | data class TechnicalAccount(val clientId: String, val clientSecret: String) 7 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/osgi/ConfigurationPid.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.osgi 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.fasterxml.jackson.annotation.JsonIgnore 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 6 | import com.fasterxml.jackson.annotation.JsonProperty 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | class ConfigurationPid { 10 | 11 | @JsonIgnore 12 | lateinit var instance: Instance 13 | 14 | @JsonProperty 15 | lateinit var id: String 16 | 17 | @JsonProperty 18 | lateinit var name: String 19 | 20 | @JsonProperty("has_config") 21 | var hasConfig: Boolean = false 22 | 23 | @JsonProperty 24 | var fpid: String? = null 25 | 26 | @JsonProperty 27 | var nameHint: String? = null 28 | } 29 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/osgi/ConfigurationState.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.osgi 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.fasterxml.jackson.annotation.JsonIgnore 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 6 | import com.fasterxml.jackson.annotation.JsonProperty 7 | 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | class ConfigurationState { 10 | 11 | @JsonIgnore 12 | lateinit var instance: Instance 13 | 14 | @JsonProperty 15 | lateinit var pids: List 16 | 17 | val unknown: Boolean get() = pids.isEmpty() 18 | 19 | override fun toString(): String = "ConfigurationState(instance='${instance.name}', total='${pids.size}')" 20 | 21 | companion object { 22 | fun unknown(): ConfigurationState = ConfigurationState().apply { pids = listOf() } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/osgi/EventState.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.osgi 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.fasterxml.jackson.annotation.JsonIgnore 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 6 | import com.fasterxml.jackson.annotation.JsonProperty 7 | import org.apache.commons.lang3.builder.EqualsBuilder 8 | import org.apache.commons.lang3.builder.HashCodeBuilder 9 | 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | class EventState private constructor() { 12 | 13 | @JsonIgnore 14 | lateinit var instance: Instance 15 | 16 | @JsonProperty("data") 17 | lateinit var events: List 18 | 19 | lateinit var status: String 20 | 21 | @get:JsonIgnore 22 | val unknown: Boolean get() = events.isEmpty() 23 | 24 | override fun equals(other: Any?): Boolean { 25 | if (this === other) return true 26 | if (javaClass != other?.javaClass) return false 27 | 28 | other as EventState 29 | 30 | return EqualsBuilder() 31 | .append(events, other.events) 32 | .isEquals 33 | } 34 | 35 | override fun hashCode(): Int = HashCodeBuilder() 36 | .append(events) 37 | .toHashCode() 38 | 39 | override fun toString(): String = "EventState(instance='${instance.name}', status='$status')" 40 | 41 | companion object { 42 | fun unknown(): EventState = EventState().apply { events = listOf() } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/osgi/OsgiException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.osgi 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | open class OsgiException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/BuildResponse.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | class BuildResponse private constructor() { 7 | 8 | var success: Boolean = false 9 | 10 | lateinit var msg: String 11 | 12 | lateinit var path: String 13 | } 14 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/DeleteResponse.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import java.io.InputStream 4 | 5 | class DeleteResponse private constructor(private val rawHtml: String) : HtmlResponse(rawHtml) { 6 | 7 | override fun getErrorPatterns(): List { 8 | return ERROR_PATTERNS 9 | } 10 | 11 | override val status: Status 12 | get() { 13 | return if (rawHtml.contains(DELETE_SUCCESS)) { 14 | Status.SUCCESS 15 | } else { 16 | Status.FAIL 17 | } 18 | } 19 | 20 | companion object { 21 | 22 | private const val DELETE_SUCCESS = "Package deleted in" 23 | 24 | private val ERROR_PATTERNS = emptyList() 25 | 26 | private val STATUS_TAGS = listOf(DELETE_SUCCESS) 27 | 28 | fun from(input: InputStream, bufferSize: Int): DeleteResponse { 29 | return DeleteResponse(filter(input, ERROR_PATTERNS, STATUS_TAGS, bufferSize)) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/ErrorPattern.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import java.util.regex.Pattern 4 | 5 | data class ErrorPattern(val pattern: Pattern, val printStackTrace: Boolean, val message: String = "") 6 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/ListResponse.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.fasterxml.jackson.annotation.JsonIgnore 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | class ListResponse private constructor() { 9 | 10 | @JsonIgnore 11 | lateinit var instance: Instance 12 | 13 | lateinit var results: List 14 | 15 | fun resolve(group: String, name: String, version: String): Package? { 16 | return resolveByCoordinates(group, name, version) ?: resolveByConventionPath(group, name, version) 17 | } 18 | 19 | private fun resolveByCoordinates(group: String, name: String, version: String): Package? { 20 | if (group.isBlank() && name.isBlank()) { 21 | return null 22 | } 23 | 24 | val result = results.find { result -> 25 | (result.group == group) && (result.name == name) && (result.version == version) 26 | } 27 | 28 | if (result != null) { 29 | return result 30 | } 31 | 32 | return null 33 | } 34 | 35 | private fun resolveByConventionPath(group: String, name: String, version: String): Package? { 36 | return results.firstOrNull { result -> result.path == Package.conventionPath(group, name, version) } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/PackageDependency.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import org.apache.commons.lang3.builder.EqualsBuilder 5 | import org.apache.commons.lang3.builder.HashCodeBuilder 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | class PackageDependency { 9 | 10 | lateinit var name: String 11 | 12 | lateinit var id: String 13 | 14 | override fun equals(other: Any?): Boolean { 15 | if (this === other) return true 16 | if (javaClass != other?.javaClass) return false 17 | 18 | other as PackageDependency 19 | 20 | return EqualsBuilder() 21 | .append(name, other.name) 22 | .append(id, other.id) 23 | .isEquals 24 | } 25 | 26 | override fun hashCode() = HashCodeBuilder() 27 | .append(name) 28 | .append(id) 29 | .toHashCode() 30 | 31 | override fun toString() = "PackageDependency(name='$name', id='$id')" 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/PackageDeployment.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | /** 4 | * Eagerly computes all information needed to examine if package should be (re)deployed or not. 5 | */ 6 | class PackageDeployment(val metadata: PackageMetadata, checksum: String) { 7 | 8 | val installedExternally = metadata.installedExternally 9 | 10 | val installedExternallyAt = metadata.installedCurrent 11 | 12 | val checksumChanged = !metadata.validChecksum(checksum) 13 | 14 | val needed get() = checksumChanged || installedExternally 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/PackageFilter.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import org.apache.commons.lang3.builder.EqualsBuilder 5 | import org.apache.commons.lang3.builder.HashCodeBuilder 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | class PackageFilter private constructor() { 9 | 10 | lateinit var root: String 11 | 12 | lateinit var rules: List 13 | 14 | override fun equals(other: Any?): Boolean { 15 | if (this === other) return true 16 | if (javaClass != other?.javaClass) return false 17 | 18 | other as PackageFilter 19 | 20 | return EqualsBuilder() 21 | .append(root, other.root) 22 | .append(rules, other.rules) 23 | .isEquals 24 | } 25 | 26 | override fun hashCode() = HashCodeBuilder() 27 | .append(root) 28 | .append(rules) 29 | .toHashCode() 30 | 31 | override fun toString() = "PackageFilter(root='$root', rules=$rules)" 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/PackageFilterRule.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import org.apache.commons.lang3.builder.EqualsBuilder 5 | import org.apache.commons.lang3.builder.HashCodeBuilder 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | class PackageFilterRule private constructor() { 9 | 10 | lateinit var modifier: String 11 | 12 | lateinit var pattern: String 13 | 14 | override fun equals(other: Any?): Boolean { 15 | if (this === other) return true 16 | if (javaClass != other?.javaClass) return false 17 | 18 | other as PackageFilterRule 19 | 20 | return EqualsBuilder() 21 | .append(modifier, other.modifier) 22 | .append(pattern, other.pattern) 23 | .isEquals 24 | } 25 | 26 | override fun hashCode() = HashCodeBuilder() 27 | .append(modifier) 28 | .append(pattern) 29 | .toHashCode() 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/UninstallResponse.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import java.io.InputStream 4 | import java.util.regex.Pattern 5 | 6 | class UninstallResponse private constructor(private val rawHtml: String) : HtmlResponse(rawHtml) { 7 | 8 | override fun getErrorPatterns(): List { 9 | return ERROR_PATTERNS 10 | } 11 | 12 | override val status: Status 13 | get() { 14 | return if (rawHtml.contains(UNINSTALL_SUCCESS)) { 15 | Status.SUCCESS 16 | } else { 17 | Status.FAIL 18 | } 19 | } 20 | 21 | companion object { 22 | private const val UNINSTALL_SUCCESS = " get() = result.hits.map { Node(repository, it["jcr:path"] as String, it) } 6 | 7 | fun nodeSequence(): Sequence = sequence { 8 | yieldAll(nodes) 9 | 10 | if (result.more) { 11 | var criteriaMore = criteria.forMore() 12 | do { 13 | val query = repository.query(criteriaMore) 14 | yieldAll(query.nodes) 15 | criteriaMore = criteriaMore.forMore() 16 | } while (query.result.more) 17 | } 18 | } 19 | 20 | override fun toString(): String = "Query(criteria=$criteria, result=$result)" 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/QueryResult.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | class QueryResult { 7 | 8 | var success: Boolean = false 9 | 10 | var results: Long = 0 11 | 12 | var total: Long = 0 13 | 14 | val more: Boolean = true 15 | 16 | var offset: Long = 0 17 | 18 | var hits: List> = listOf() 19 | 20 | override fun toString(): String = "QueryResult(success=$success, results=$results, total=$total, more=$more, offset=$offset)" 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/RepositoryChange.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | class RepositoryChange { 7 | 8 | lateinit var type: String 9 | 10 | lateinit var argument: String 11 | 12 | override fun toString(): String { 13 | return "RepositoryChange(type='$type', argument='$argument')" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/RepositoryError.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | 6 | @JsonIgnoreProperties(ignoreUnknown = true) 7 | class RepositoryError { 8 | 9 | @JsonProperty("class") 10 | lateinit var className: String 11 | 12 | lateinit var message: String 13 | 14 | override fun toString(): String { 15 | return "RepositoryError(class='$className', message='$message')" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/RepositoryException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | class RepositoryException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/RepositoryHttpClient.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.instance.Instance 5 | import com.cognifide.gradle.aem.common.instance.InstanceHttpClient 6 | import com.cognifide.gradle.common.http.ResponseException 7 | import org.apache.http.HttpResponse 8 | 9 | class RepositoryHttpClient(aem: AemExtension, instance: Instance) : InstanceHttpClient(aem, instance) { 10 | 11 | override fun throwStatusException(response: HttpResponse) { 12 | throw ResponseException( 13 | "Repository error. Unexpected response from $instance: ${response.statusLine}\n" + 14 | response.entity.content.bufferedReader().readText() 15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/RepositoryResult.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties 4 | import com.fasterxml.jackson.annotation.JsonProperty 5 | 6 | @JsonIgnoreProperties(ignoreUnknown = true) 7 | class RepositoryResult { 8 | 9 | lateinit var title: String 10 | 11 | lateinit var path: String 12 | 13 | @JsonProperty("status.code") 14 | var statusCode: Int = -1 15 | 16 | @JsonProperty("status.message") 17 | var statusMessage: String? = null 18 | 19 | lateinit var referer: String 20 | 21 | lateinit var location: String 22 | 23 | lateinit var parentLocation: String 24 | 25 | var error: RepositoryError? = null 26 | 27 | lateinit var changes: List 28 | 29 | val success: Boolean 30 | get() = !fail 31 | 32 | val fail: Boolean 33 | get() = error != null 34 | 35 | override fun toString(): String { 36 | return "RepositoryResult(title='$title', path='$path', statusCode=$statusCode, statusMessage=$statusMessage)" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/repository/ResourceType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.repository 2 | 3 | enum class ResourceType(val value: String) { 4 | ASSET("dam:Asset"), 5 | PAGE("cq:Page"), 6 | FILE("nt:file"), 7 | PAGE_CONTENT("cq:PageContent"), 8 | ASSET_CONTENT("dam:AssetContent"), 9 | WORKFLOW_MODEL("cq:WorkflowModel"), 10 | USER("rep:User"); 11 | 12 | companion object { 13 | fun of(type: String) = values().find { it.value.equals(type, ignoreCase = true) } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/sling/SlingException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.sling 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | open class SlingException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/status/StatusException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.status 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | class StatusException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/workflow/WorkflowException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.workflow 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | open class WorkflowException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/service/workflow/WorkflowLauncherType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.workflow 2 | 3 | enum class WorkflowLauncherType(val ids: List) { 4 | DAM_ASSET( 5 | listOf( 6 | "asset_processing_on_sdk_mod", 7 | "asset_processing_on_sdk_create", 8 | "update_asset_create", 9 | "update_asset_create_without_DM", 10 | "update_asset_mod", 11 | "update_asset_mod_reupload", 12 | "update_asset_mod_without_DM", 13 | "update_asset_mod_without_DM_reupload", 14 | "dam_xmp_writeback" 15 | ) 16 | ); 17 | 18 | companion object { 19 | fun of(type: String) = values().find { it.name.equals(type, ignoreCase = true) } 20 | 21 | fun ids(type: String) = ids(listOf(type)) 22 | 23 | fun ids(types: Iterable) = types.flatMap { of(it)?.ids ?: listOf(it) } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/InstanceLogInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import java.time.ZoneId 5 | 6 | class InstanceLogInfo(private val instance: Instance) : LogInfo { 7 | 8 | override val name: String get() = instance.name 9 | 10 | override val zoneId: ZoneId get() = instance.zoneId 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/LogChunk.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | 5 | class LogChunk(val instance: Instance, val logs: List) { 6 | 7 | val size: Int get() = logs.size 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/LogDestination.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | interface LogDestination { 4 | fun dump(logs: List) 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/LogInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import java.time.ZoneId 4 | 5 | interface LogInfo { 6 | 7 | val name: String 8 | 9 | val zoneId: ZoneId 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/LogNotifier.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import com.cognifide.gradle.aem.common.instance.tail.io.LogFiles 4 | import com.cognifide.gradle.common.notifier.NotifierFacade 5 | import kotlinx.coroutines.DelicateCoroutinesApi 6 | import kotlinx.coroutines.GlobalScope 7 | import kotlinx.coroutines.channels.ReceiveChannel 8 | import kotlinx.coroutines.channels.consumeEach 9 | import kotlinx.coroutines.launch 10 | import org.gradle.api.logging.LogLevel 11 | import java.awt.Desktop 12 | import java.net.URI 13 | 14 | @OptIn(DelicateCoroutinesApi::class) 15 | class LogNotifier( 16 | private val notificationChannel: ReceiveChannel, 17 | private val notifier: NotifierFacade, 18 | private val logFiles: LogFiles 19 | ) { 20 | 21 | fun listenTailed() { 22 | GlobalScope.launch { 23 | notificationChannel.consumeEach { logs -> 24 | val file = snapshotErrorsToSeparateFile(logs) 25 | notifyLogErrors(logs, file) 26 | } 27 | } 28 | } 29 | 30 | private fun notifyLogErrors(chunk: LogChunk, file: URI) { 31 | val errors = chunk.size 32 | val message = chunk.logs.lastOrNull()?.cause ?: "" 33 | val instance = chunk.instance.name 34 | 35 | notifier.notify("$errors error(s) on $instance", message, LogLevel.WARN) { 36 | if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { 37 | Desktop.getDesktop().browse(file) 38 | } 39 | } 40 | } 41 | 42 | private fun snapshotErrorsToSeparateFile(chunk: LogChunk): URI { 43 | return logFiles.writeToIncident(chunk.instance.name) { out -> 44 | chunk.logs.forEach { 45 | out.write("${it.text}\n") 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/LogSource.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import java.io.BufferedReader 4 | 5 | interface LogSource { 6 | 7 | fun readChunk(parser: (BufferedReader) -> List): List 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/LogTailer.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.instance.tail.io.ConsolePrinter 5 | import kotlinx.coroutines.DelicateCoroutinesApi 6 | import kotlinx.coroutines.GlobalScope 7 | import kotlinx.coroutines.channels.SendChannel 8 | import kotlinx.coroutines.launch 9 | 10 | @OptIn(DelicateCoroutinesApi::class) 11 | class LogTailer( 12 | val aem: AemExtension, 13 | private val source: LogSource, 14 | private val destination: LogDestination, 15 | info: LogInfo = NoLogInfo(), 16 | private val logsAnalyzerChannel: SendChannel? = null, 17 | private val printer: ConsolePrinter = ConsolePrinter.none() 18 | ) { 19 | 20 | private val parser = LogParser(aem, info) 21 | 22 | private var lastLogChecksum = "" 23 | 24 | fun tail() { 25 | val logs = source.readChunk(parser::parse) 26 | val newLogs = determineNewLogs(logs) 27 | 28 | if (newLogs.isNotEmpty()) { 29 | lastLogChecksum = newLogs.last().checksum 30 | sendLogsToBeAnalyzed(newLogs) 31 | destination.dump(newLogs) 32 | printer.dump(newLogs) 33 | } 34 | } 35 | 36 | private fun sendLogsToBeAnalyzed(newLogs: List) { 37 | if (logsAnalyzerChannel == null) return 38 | GlobalScope.launch { 39 | newLogs.forEach { logsAnalyzerChannel.send(it) } 40 | } 41 | } 42 | 43 | private fun determineNewLogs(logs: List): List { 44 | val lastFetchedLog = logs.asReversed().find { lastLogChecksum == it.checksum } 45 | return when { 46 | lastFetchedLog == null -> logs 47 | logs.last() === lastFetchedLog -> emptyList() 48 | else -> logs.slice(logs.indexOf(lastFetchedLog) + 1 until logs.size) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/NoLogInfo.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import java.time.ZoneId 4 | 5 | class NoLogInfo : LogInfo { 6 | 7 | override val name: String = "unspecified" 8 | 9 | override val zoneId: ZoneId = ZoneId.systemDefault() 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/TailerException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail 2 | 3 | import com.cognifide.gradle.aem.common.instance.InstanceException 4 | 5 | class TailerException : InstanceException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/io/ConsolePrinter.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail.io 2 | 3 | import com.cognifide.gradle.aem.common.instance.tail.Log 4 | import com.cognifide.gradle.aem.common.instance.tail.LogInfo 5 | import com.cognifide.gradle.aem.common.instance.tail.NoLogInfo 6 | 7 | class ConsolePrinter( 8 | logInfo: LogInfo, 9 | private val log: (String) -> Unit, 10 | private val incidentMaxAgeInMillis: Long = 5000 11 | ) { 12 | init { 13 | log("Printing logs for ${logInfo.name} to console.") 14 | } 15 | 16 | fun dump(newLogs: List) = newLogs.filterNot { it.isOlderThan(incidentMaxAgeInMillis) }.forEach { log(it.logWithLocalTimestamp) } 17 | 18 | companion object { 19 | fun none() = ConsolePrinter(NoLogInfo(), {}) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/io/FileDestination.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail.io 2 | 3 | import com.cognifide.gradle.aem.common.instance.tail.Log 4 | import com.cognifide.gradle.aem.common.instance.tail.LogDestination 5 | 6 | class FileDestination(private val instanceName: String, private val logFiles: LogFiles) : LogDestination { 7 | 8 | init { 9 | logFiles.clearMain(instanceName) 10 | logFiles.clearIncidents(instanceName) 11 | } 12 | 13 | override fun dump(logs: List) { 14 | if (logs.isEmpty()) { 15 | return 16 | } 17 | 18 | logFiles.writeToMain(instanceName) { out -> 19 | logs.forEach { log -> 20 | out.append("${log.text}\n") 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/instance/tail/io/UrlSource.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.tail.io 2 | 3 | import com.cognifide.gradle.aem.common.instance.Instance 4 | import com.cognifide.gradle.aem.common.instance.tail.LogSource 5 | import com.cognifide.gradle.aem.common.instance.tail.Tailer 6 | import com.cognifide.gradle.common.http.RequestException 7 | import java.io.BufferedReader 8 | 9 | class UrlSource( 10 | private val tailer: Tailer, 11 | private val instance: Instance 12 | ) : LogSource { 13 | 14 | private val logger = tailer.aem.logger 15 | 16 | private var wasStable = true 17 | 18 | override fun readChunk(parser: (BufferedReader) -> List) = 19 | handleInstanceUnavailability { 20 | instance.sync.http { 21 | get(tailer.errorLogEndpoint(instance)) { 22 | asStream(it).bufferedReader().use(parser) 23 | } 24 | } 25 | } 26 | 27 | private fun handleInstanceUnavailability(parser: () -> List) = 28 | try { 29 | val chunk = parser() 30 | if (!wasStable) { 31 | logger.lifecycle("Tailing resumed for $instance") 32 | wasStable = true 33 | } 34 | chunk 35 | } catch (ex: RequestException) { 36 | if (wasStable) { 37 | logger.warn("Tailing paused for $instance due to:\n '${ex.message}'\nAwaiting resumption.") 38 | } 39 | wasStable = false 40 | emptyList() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/Artifact.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | class Artifact(val notation: String) { 4 | 5 | val id get() = notation.substringBeforeLast(":") 6 | 7 | val type get() = ArtifactType.byExtension(notation.substringAfterLast(":")) 8 | 9 | override fun toString() = "Artifact(id='$id', type='$type')" 10 | 11 | override fun equals(other: Any?): Boolean { 12 | if (this === other) return true 13 | if (javaClass != other?.javaClass) return false 14 | other as Artifact 15 | if (notation != other.notation) return false 16 | return true 17 | } 18 | 19 | override fun hashCode() = notation.hashCode() 20 | } 21 | 22 | fun String.toArtifact() = Artifact(this) 23 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/ArtifactType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | import com.cognifide.gradle.common.utils.capitalizeChar 4 | 5 | enum class ArtifactType { 6 | POM, 7 | ZIP, 8 | JAR, 9 | RUN; 10 | 11 | val extension get() = name.lowercase() 12 | 13 | val task get() = "mvn${extension.capitalizeChar()}" 14 | 15 | companion object { 16 | fun byExtension(value: String) = values().firstOrNull { it.extension == value } 17 | ?: error("Artifact type cannot be determined by extension '$value'!") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/Dependency.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | class Dependency(val from: Artifact, val to: Artifact) { 4 | 5 | val notation get() = "${from.notation} ${if (redundant) "~>" else "->"} ${to.notation}" 6 | 7 | var redundant = false 8 | 9 | override fun toString() = "Dependency(from=$from, to=$to, redundant=$redundant)" 10 | 11 | override fun equals(other: Any?): Boolean { 12 | if (this === other) return true 13 | if (javaClass != other?.javaClass) return false 14 | other as Dependency 15 | if (from != other.from) return false 16 | if (to != other.to) return false 17 | 18 | return true 19 | } 20 | 21 | override fun hashCode(): Int { 22 | var result = from.hashCode() 23 | result = 31 * result + to.hashCode() 24 | return result 25 | } 26 | } 27 | 28 | fun Map.Entry.toDependency() = Dependency(this.key.toArtifact(), this.value.toArtifact()) 29 | 30 | fun Pair.toDependency() = Dependency(this.first.toArtifact(), this.second.toArtifact()) 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/DeployPackageOrder.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | enum class DeployPackageOrder { 4 | PRECEDENCE, 5 | GRAPH; 6 | 7 | companion object { 8 | fun of(value: String) = values().find { value.equals(it.name, ignoreCase = true) } 9 | ?: throw MvnException("Unsupported build deploy package order '$value' specified for Maven build!") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/ModuleType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | enum class ModuleType(val artifact: ArtifactType) { 4 | POM(ArtifactType.POM), 5 | JAR(ArtifactType.JAR), 6 | PACKAGE(ArtifactType.ZIP), 7 | FRONTEND(ArtifactType.ZIP), 8 | DISPATCHER(ArtifactType.ZIP), 9 | RUN(ArtifactType.RUN) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/MvnException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | class MvnException : AemException { 6 | constructor(message: String, cause: Throwable) : super(message, cause) 7 | 8 | constructor(message: String) : super(message) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/mvn/MvnGav.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.mvn 2 | 3 | import groovy.util.* 4 | import groovy.xml.XmlParser 5 | import java.io.File 6 | 7 | data class MvnGav( 8 | val groupId: String?, 9 | val artifactId: String, 10 | val version: String? 11 | ) { 12 | companion object { 13 | fun readDir(moduleDir: File) = readFile(moduleDir.resolve("pom.xml")) 14 | 15 | fun readFile(pomFile: File) = pomFile.takeIf { it.exists() }?.let { pom -> 16 | val xml = XmlParser().parse(pom) 17 | fun xmlProp(name: String) = 18 | (((xml.get(name) as NodeList).getOrNull(0) as Node?)?.value() as NodeList?)?.getOrNull(0)?.toString() 19 | MvnGav( 20 | xmlProp("groupId"), 21 | xmlProp("artifactId") ?: error("Artifact ID not found in '$pom'!"), 22 | xmlProp("version") 23 | ) 24 | } ?: throw MvnException("Cannot read Maven GAV file '$pomFile!") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/BundleChecking.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg 2 | 3 | enum class BundleChecking { 4 | NONE, 5 | WARN, 6 | EXCLUDE, 7 | FAIL; 8 | 9 | companion object { 10 | fun of(name: String) = values().find { it.name.equals(name, true) } 11 | ?: throw PackageException("Unsupported bundle checking: $name") 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/PackageException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | class PackageException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/PackageFile.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg 2 | 3 | import com.cognifide.gradle.aem.common.instance.service.pkg.Package 4 | import com.cognifide.gradle.common.zip.ZipFile 5 | import com.fasterxml.jackson.annotation.JsonIgnore 6 | import org.jsoup.Jsoup 7 | import org.jsoup.nodes.Document 8 | import org.jsoup.parser.Parser 9 | import java.io.File 10 | import java.io.Serializable 11 | 12 | class PackageFile(val file: File) : Serializable { 13 | 14 | @JsonIgnore 15 | val properties: Document 16 | 17 | val group: String 18 | 19 | val name: String 20 | 21 | val version: String 22 | 23 | init { 24 | if (!file.exists()) { 25 | throw PackageException("Package does not exist: $file!") 26 | } 27 | 28 | val zip = ZipFile(file) 29 | if (!zip.contains(Package.VLT_PROPERTIES)) { 30 | throw PackageException("Package is not a valid CRX package: $file!") 31 | } 32 | 33 | this.properties = zip.readFileAsText(Package.VLT_PROPERTIES).run { 34 | Jsoup.parse(this, "", Parser.xmlParser()) 35 | } 36 | this.group = properties.select("entry[key=group]").text() 37 | ?: throw PackageException("CRX package '$file' does not have property 'group' specified.") 38 | this.name = properties.select("entry[key=name]").text() 39 | ?: throw PackageException("CRX package '$file' does not have property 'name' specified.") 40 | this.version = properties.select("entry[key=version]").text() 41 | ?: throw PackageException("CRX package '$file' does not have property 'version' specified.") 42 | } 43 | 44 | fun property(name: String): String? = properties.select("entry[key=$name]").text() 45 | 46 | override fun toString(): String { 47 | return "PackageFile(group='$group' name='$name', version='$version', path='$file')" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/PackageWrapper.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.common.bundle.BundleFile 5 | import java.io.File 6 | 7 | class PackageWrapper(val aem: AemExtension) { 8 | 9 | val workDir = aem.obj.dir { convention(aem.obj.buildDir("package/wrapper")) } 10 | 11 | val bundlePath = aem.obj.string { convention("/apps/gap/wrapper/install") } 12 | 13 | fun definition(definition: PackageDefinition.(BundleFile) -> Unit) { 14 | this.definition = definition 15 | } 16 | 17 | private var definition: PackageDefinition.(BundleFile) -> Unit = {} 18 | 19 | fun wrap(file: File): File = when (file.extension) { 20 | "jar" -> wrapJar(file) 21 | "zip" -> file 22 | else -> throw PackageException("File '$file' must have '*.jar' or '*.zip' extension") 23 | } 24 | 25 | fun wrapJar(jar: File): File { 26 | val pkgName = jar.nameWithoutExtension 27 | val pkg = File(workDir.get().asFile, "$pkgName.zip") 28 | if (pkg.exists()) { 29 | aem.logger.info("CRX package wrapping OSGi bundle already exists: $pkg") 30 | return pkg 31 | } 32 | 33 | aem.logger.info("Wrapping OSGi bundle to CRX package: $jar") 34 | 35 | val bundle = BundleFile(jar) 36 | val bundlePath = "${bundlePath.get()}/${jar.name}" 37 | 38 | return aem.composePackage { 39 | this.archivePath.set(pkg) 40 | this.description.set(bundle.description) 41 | this.group.set(bundle.group) 42 | this.name.set(bundle.symbolicName) 43 | this.version.set(bundle.version) 44 | 45 | filter(bundlePath) 46 | content { copyJcrFile(jar, bundlePath) } 47 | 48 | definition(bundle) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/validator/OakpalResult.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.validator 2 | 3 | @Suppress("MagicNumber") 4 | enum class OakpalResult(val exitCode: Int) { 5 | UNKNOWN_ERROR(-1), 6 | SUCCESS(0), 7 | GENERAL_ERROR(1), 8 | ABORTED_SCAN(9), 9 | SEVERE_VIOLATION(10), 10 | MAJOR_VIOLATION(11), 11 | MINOR_VIOLATION(12); 12 | 13 | val cause get() = name.replace("_", " ").lowercase() 14 | 15 | companion object { 16 | fun byExitCode(value: Int) = values().find { it.exitCode == value } ?: UNKNOWN_ERROR 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/validator/OakpalSeverity.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.validator 2 | 3 | import com.cognifide.gradle.aem.common.pkg.PackageException 4 | 5 | enum class OakpalSeverity { 6 | MINOR, 7 | MAJOR, 8 | SEVERE; 9 | 10 | companion object { 11 | fun of(value: String) = values().find { it.name.equals(value, ignoreCase = true) } 12 | ?: throw PackageException("OakPAL severity named '$value' is not supported!") 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/CndSyncType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | import com.cognifide.gradle.aem.common.pkg.PackageException 4 | 5 | enum class CndSyncType { 6 | ALWAYS, 7 | PRESERVE, 8 | NEVER; 9 | 10 | companion object { 11 | 12 | fun find(name: String) = values().firstOrNull { it.name.equals(name, true) } 13 | 14 | fun of(name: String) = find(name) 15 | ?: throw PackageException("Unsupported CND file sync mode '$name'!") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/FilterElement.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | import org.gradle.api.tasks.Internal 4 | import org.jsoup.Jsoup 5 | import org.jsoup.nodes.Element 6 | import org.jsoup.parser.Parser 7 | import java.io.Serializable 8 | 9 | class FilterElement(val root: String) : Serializable { 10 | 11 | var mode: String? = null 12 | 13 | var type: FilterType = FilterType.UNKNOWN 14 | 15 | var rules: List = listOf() 16 | 17 | val excludes get() = rules.filter { it.type == FilterRuleType.EXCLUDE } 18 | 19 | val includes get() = rules.filter { it.type == FilterRuleType.INCLUDE } 20 | 21 | @get:Internal 22 | val element: Element 23 | get() = Element(FILTER_TAG).apply { 24 | attr(ROOT_ATTR, root) 25 | mode?.takeIf { it.isNotBlank() }?.let { attr(MODE_ATTR, it) } 26 | rules.forEach { appendChild(it.element) } 27 | } 28 | 29 | override fun toString() = element.toString().replace(">", "/>") 30 | 31 | companion object { 32 | 33 | fun of(root: String, definition: FilterElement.() -> Unit = {}) = FilterElement(root).apply(definition) 34 | 35 | fun parse(xml: String): List { 36 | val document = Jsoup.parse(xml, "", Parser.xmlParser()) 37 | val elements = document.select(FILTER_TAG) 38 | 39 | return elements.map { element -> 40 | of(element.attr(ROOT_ATTR)) { 41 | type = FilterType.UNKNOWN 42 | rules = FilterRule.manyOf(element) 43 | mode = element.attr(MODE_ATTR) 44 | } 45 | } 46 | } 47 | 48 | const val FILTER_TAG = "filter" 49 | 50 | const val MODE_ATTR = "mode" 51 | 52 | const val ROOT_ATTR = "root" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/FilterRule.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | import org.gradle.api.tasks.Internal 4 | import org.jsoup.nodes.Element 5 | import java.io.Serializable 6 | 7 | class FilterRule(val type: FilterRuleType, val pattern: String) : Serializable { 8 | 9 | private val tag get() = type.name.lowercase() 10 | 11 | @get:Internal 12 | val element get() = Element(tag).apply { attr(ATTR_PATTERN, pattern) } 13 | 14 | override fun toString() = element.toString().replace(">", "/>") 15 | 16 | companion object { 17 | const val ATTR_PATTERN = "pattern" 18 | 19 | fun manyOf(filter: Element) = filter.select(FilterRuleType.tags().joinToString(",")).map { 20 | FilterRule(FilterRuleType.of(it.tagName()), it.attr(ATTR_PATTERN)) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/FilterRuleType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | enum class FilterRuleType { 4 | INCLUDE, 5 | EXCLUDE; 6 | 7 | companion object { 8 | fun find(name: String) = values().firstOrNull { it.name.equals(name, true) } 9 | 10 | fun of(name: String) = find(name) ?: throw VaultException("Unsupported Vault filter rule '$name'!") 11 | 12 | fun tags() = values().map { it.name.lowercase() } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/FilterType.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | enum class FilterType { 4 | UNKNOWN, 5 | DIR, 6 | FILE 7 | } 8 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/VaultException.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | 5 | class VaultException : AemException { 6 | 7 | constructor(message: String, cause: Throwable) : super(message, cause) 8 | 9 | constructor(message: String) : super(message) 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/pkg/vault/VaultSummary.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.pkg.vault 2 | 3 | import com.cognifide.gradle.common.utils.Formats 4 | import java.io.File 5 | 6 | data class VaultSummary(val command: String, val contentDir: File, val duration: Long) { 7 | 8 | val durationString: String 9 | get() = Formats.duration(duration) 10 | 11 | override fun toString(): String { 12 | return "VaultSummary(command=$command, contentDir=$contentDir, duration=$durationString)" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/tasks/Bundle.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.tasks 2 | 3 | open class Bundle : InstanceFileSync() 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/tasks/Instance.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import com.cognifide.gradle.aem.common.instance.Instance 5 | import com.cognifide.gradle.aem.common.instance.InstanceException 6 | import org.gradle.api.tasks.Internal 7 | 8 | open class Instance : AemDefaultTask() { 9 | 10 | @Internal 11 | val instances = aem.obj.list { 12 | convention(aem.obj.provider { aem.instances }) 13 | } 14 | 15 | @get:Internal 16 | val anyInstances: List by lazy { 17 | instances.get().apply { 18 | if (aem.commonOptions.verbose.get() && isEmpty()) { 19 | throw InstanceException("No instances defined or matching filter '${aem.commonOptions.envFilter}'!") 20 | } 21 | } 22 | } 23 | 24 | @get:Internal 25 | val instanceManager get() = aem.instanceManager 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/tasks/InstanceFileSync.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import com.cognifide.gradle.aem.common.instance.Instance 5 | import com.cognifide.gradle.aem.common.instance.InstanceException 6 | import com.cognifide.gradle.common.utils.using 7 | import org.gradle.api.tasks.Internal 8 | import org.gradle.api.tasks.TaskAction 9 | import java.io.File 10 | import com.cognifide.gradle.aem.common.instance.FileSync as Base 11 | 12 | open class InstanceFileSync : AemDefaultTask() { 13 | 14 | @get:Internal 15 | val instanceManager get() = aem.instanceManager 16 | 17 | @get:Internal 18 | val sync by lazy { Base(instanceManager) } 19 | 20 | fun sync(options: Base.() -> Unit) = sync.using(options) 21 | 22 | @TaskAction 23 | protected open fun doSync() { 24 | sync.sync() 25 | } 26 | 27 | @get:Internal 28 | val files: Set get() = sync.files.files 29 | 30 | fun files(vararg paths: Any) { 31 | sync.files.from(paths) 32 | } 33 | 34 | @get:Internal 35 | val instances: List by lazy { 36 | sync.instances.get().apply { 37 | if (aem.commonOptions.verbose.get() && isEmpty()) { 38 | throw InstanceException("No instances defined or matching filter '${aem.commonOptions.envFilter}'!") 39 | } 40 | } 41 | } 42 | 43 | fun instances(vararg instances: Instance) { 44 | sync.instances.set(instances.asIterable()) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/tasks/LocalInstance.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import com.cognifide.gradle.aem.common.instance.LocalInstance 5 | import org.gradle.api.tasks.Internal 6 | 7 | open class LocalInstance : AemDefaultTask() { 8 | 9 | @Internal 10 | val instances = aem.obj.list { 11 | convention(aem.obj.provider { aem.localInstances }) 12 | } 13 | 14 | @get:Internal 15 | val anyInstances: List by lazy { 16 | instances.get().apply { 17 | if (aem.commonOptions.verbose.get() && isEmpty()) { 18 | logger.info("No local instances defined or matching filter '${aem.commonOptions.envFilter}'!") 19 | } 20 | } 21 | } 22 | 23 | @get:Internal 24 | val localInstanceManager get() = aem.localInstanceManager 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/tasks/Package.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.tasks 2 | 3 | open class Package : InstanceFileSync() 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/Checksum.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import org.apache.commons.codec.digest.DigestUtils 4 | import java.io.File 5 | 6 | object Checksum { 7 | 8 | fun md5(file: File): String = file.inputStream().use { DigestUtils.md5Hex(it) } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/FileUtil.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import org.apache.commons.io.FilenameUtils 4 | import org.apache.commons.io.input.ReversedLinesFileReader 5 | import java.io.File 6 | import java.nio.charset.StandardCharsets 7 | import java.util.* 8 | 9 | object FileUtil { 10 | 11 | fun sanitizeName(name: String): String = name.replace("[:\\\\/*?|<> &]".toRegex(), "_") 12 | 13 | fun sanitizePath(path: String): String { 14 | val source = FilenameUtils.separatorsToUnix(path) 15 | val letter = if (source.contains(":/")) source.substringBefore(":/") else null 16 | val pathNoLetter = source.substringAfter(":/") 17 | val pathSanitized = pathNoLetter.split("/").joinToString("/") { sanitizeName(it) } 18 | return if (letter != null) "$letter:/$pathSanitized" else pathSanitized 19 | } 20 | 21 | fun systemPath(path: String) = FilenameUtils.separatorsToSystem(path) 22 | 23 | fun readLastLines(file: File, count: Int): List { 24 | return ReversedLinesFileReader(file, StandardCharsets.UTF_8).readLines(count) 25 | } 26 | 27 | fun readProperties(file: File) = when { 28 | file.exists() -> Properties().apply { file.bufferedReader().use { load(it) } }.toMap().entries.associate { it.key.toString() to it.value.toString() } 29 | else -> mapOf() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/JcrUtil.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import com.cognifide.gradle.common.utils.formats.ISO8601 4 | import java.util.* 5 | import java.util.regex.Pattern 6 | 7 | object JcrUtil { 8 | 9 | fun date(date: Date = Date()): String = dateFormat(date) 10 | 11 | fun dateParse(value: String): Date = ISO8601.parse(value).time 12 | 13 | fun dateFormat(date: Calendar): String = ISO8601.format(date) 14 | 15 | fun dateFormat(date: Date): String = dateFormat(dateToCalendar(date)) 16 | 17 | fun dateToCalendar(date: Date): Calendar = Calendar.getInstance().apply { time = date } 18 | 19 | /** 20 | * Converts e.g ':jcr:content' to '_jcr_content' (part of JCR path to be valid OS path). 21 | */ 22 | fun manglePath(path: String): String = when { 23 | !path.contains("/") -> manglePathInternal("/$path").removePrefix("/") 24 | else -> manglePathInternal(path) 25 | } 26 | 27 | private fun manglePathInternal(path: String): String { 28 | var mangledPath = path 29 | if (path.contains(":")) { 30 | val matcher = MANGLE_NAMESPACE_PATTERN.matcher(path) 31 | val buffer = StringBuffer() 32 | while (matcher.find()) { 33 | val namespace = matcher.group(1) 34 | matcher.appendReplacement(buffer, "/_${namespace}_") 35 | } 36 | matcher.appendTail(buffer) 37 | mangledPath = buffer.toString() 38 | } 39 | return mangledPath 40 | } 41 | 42 | private val MANGLE_NAMESPACE_PATTERN: Pattern = Pattern.compile("/([^:/]+):") 43 | } 44 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/LineSeparator.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | /** 4 | * @see 5 | */ 6 | enum class LineSeparator(val value: String) { 7 | 8 | LF("\n"), 9 | CRLF("\r\n"), 10 | CR("\r"), 11 | LFCR("\n\r"), 12 | SYSTEM(System.lineSeparator()); 13 | 14 | companion object { 15 | 16 | fun of(name: String?) = find(name) 17 | ?: throw IllegalArgumentException("Unsupported line separator specified: $name. Valid are: ${values()}") 18 | 19 | fun find(name: String?) = values().find { it.name.equals(name, true) } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/ProcessKiller.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | import com.cognifide.gradle.aem.AemExtension 5 | import com.cognifide.gradle.aem.common.instance.LocalInstanceException 6 | import org.buildobjects.process.ProcBuilder 7 | import org.gradle.internal.os.OperatingSystem 8 | import java.util.concurrent.TimeUnit 9 | 10 | class ProcessKiller(private val aem: AemExtension) { 11 | 12 | private var options: ProcBuilder.() -> Unit = {} 13 | 14 | fun options(options: ProcBuilder.() -> Unit) { 15 | this.options = options 16 | } 17 | 18 | @Suppress("TooGenericExceptionCaught", "SpreadOperator", "MagicNumber") 19 | fun kill(pid: Int, options: ProcBuilder.() -> Unit = {}) { 20 | try { 21 | val os = OperatingSystem.current() 22 | val command = when { 23 | os.isWindows -> "taskkill /F /PID" 24 | os.isUnix -> "kill -9" 25 | else -> throw LocalInstanceException("Instance killing is not supported on current OS ($os)!") 26 | } 27 | 28 | val allArgs = command.split(" ") 29 | val executable = allArgs.first() 30 | val args = allArgs.drop(1) + pid.toString() 31 | 32 | ProcBuilder(executable, *args.toTypedArray()) 33 | .withWorkingDirectory(aem.project.projectDir) 34 | .withTimeoutMillis(TimeUnit.SECONDS.toMillis(10)) 35 | .withExpectedExitStatuses(0) 36 | .apply(this.options) 37 | .apply(options) 38 | .run() 39 | } catch (e: Exception) { 40 | throw AemException("Instance killing failed for PID '$pid'! Cause: ${e.message}", e) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import org.apache.commons.lang3.StringUtils 4 | import java.io.File 5 | 6 | val Collection.fileNames 7 | get() = if (isNotEmpty()) joinToString(", ") { it.name } else "none" 8 | 9 | fun String.normalizeSeparators(separator: String): String = this.replace(":", separator) 10 | .replace("-", separator) 11 | .replace(".", separator) 12 | .removePrefix(separator) 13 | .removeSuffix(separator) 14 | 15 | @Suppress("MagicNumber") 16 | fun String.shortenClass(maxLength: Int = 32): String { 17 | val pkgs = split(".").toMutableList() 18 | var result = this 19 | if (result.length > maxLength && pkgs.size >= 3) { 20 | for (i in 1 until (pkgs.size - 1)) { 21 | pkgs[i] = pkgs[i].first().toString() 22 | result = pkgs.joinToString(".") 23 | if (result.length <= maxLength) { 24 | break 25 | } 26 | } 27 | } 28 | return StringUtils.abbreviateMiddle(result, "*", maxLength) 29 | } 30 | 31 | @Suppress("UNCHECKED_CAST") 32 | fun Map.filterNotNull(): Map = filterValues { it != null } as Map 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/common/utils/WebBrowser.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import com.cognifide.gradle.aem.AemException 4 | import com.cognifide.gradle.aem.AemExtension 5 | import org.buildobjects.process.ProcBuilder 6 | import org.gradle.internal.os.OperatingSystem 7 | import java.util.concurrent.TimeUnit 8 | 9 | class WebBrowser(private val aem: AemExtension) { 10 | 11 | private var options: ProcBuilder.() -> Unit = {} 12 | 13 | fun options(options: ProcBuilder.() -> Unit) { 14 | this.options = options 15 | } 16 | 17 | @Suppress("TooGenericExceptionCaught", "MagicNumber") 18 | fun open(url: String, options: ProcBuilder.() -> Unit = {}) { 19 | try { 20 | val os = OperatingSystem.current() 21 | val command = when { 22 | os.isWindows -> "explorer" 23 | os.isMacOsX -> "open" 24 | else -> "sensible-browser" 25 | } 26 | 27 | ProcBuilder(command, url) 28 | .withWorkingDirectory(aem.project.projectDir) 29 | .withTimeoutMillis(TimeUnit.SECONDS.toMillis(30)) 30 | .ignoreExitStatus() 31 | .apply(this.options) 32 | .apply(options) 33 | .run() 34 | } catch (e: Exception) { 35 | throw AemException("Browser opening command failed! Cause: ${e.message}", e) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceAwait.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.action.AwaitUpAction 4 | import com.cognifide.gradle.aem.common.tasks.Instance 5 | import org.gradle.api.tasks.TaskAction 6 | 7 | open class InstanceAwait : Instance() { 8 | 9 | private var awaitUpOptions: AwaitUpAction.() -> Unit = {} 10 | 11 | fun awaitUp(options: AwaitUpAction.() -> Unit) { 12 | this.awaitUpOptions = options 13 | } 14 | 15 | @TaskAction 16 | fun await() { 17 | instanceManager.examinePrerequisites(anyInstances) 18 | instanceManager.awaitUp(anyInstances, awaitUpOptions) 19 | } 20 | 21 | init { 22 | description = "Await for healthy condition of all AEM instances." 23 | } 24 | 25 | companion object { 26 | const val NAME = "instanceAwait" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceCreate.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.* 4 | import com.cognifide.gradle.aem.common.tasks.LocalInstance 5 | import org.gradle.api.tasks.TaskAction 6 | 7 | open class InstanceCreate : LocalInstance() { 8 | 9 | @TaskAction 10 | fun create() { 11 | localInstanceManager.examineJavaAvailable() 12 | 13 | val createdInstances = localInstanceManager.create(anyInstances) 14 | if (createdInstances.isNotEmpty()) { 15 | common.notifier.lifecycle("Instance(s) created", "Which: ${createdInstances.names}") 16 | } 17 | } 18 | 19 | init { 20 | description = "Creates local AEM instance(s)." 21 | } 22 | 23 | companion object { 24 | const val NAME = "instanceCreate" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceDestroy.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.LocalInstance 5 | import org.gradle.api.tasks.TaskAction 6 | 7 | open class InstanceDestroy : LocalInstance() { 8 | 9 | @TaskAction 10 | fun destroy() { 11 | val destroyedInstances = localInstanceManager.destroy(anyInstances) 12 | if (destroyedInstances.isNotEmpty()) { 13 | common.notifier.notify("Instance(s) destroyed", "Which: ${destroyedInstances.names}") 14 | } 15 | } 16 | 17 | init { 18 | description = "Destroys local AEM instance(s)." 19 | } 20 | 21 | companion object { 22 | const val NAME = "instanceDestroy" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceDown.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.action.AwaitDownAction 4 | import com.cognifide.gradle.aem.common.instance.names 5 | import com.cognifide.gradle.aem.common.tasks.LocalInstance 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class InstanceDown : LocalInstance() { 9 | 10 | private var awaitDownOptions: AwaitDownAction.() -> Unit = {} 11 | 12 | fun awaitDown(options: AwaitDownAction.() -> Unit) { 13 | this.awaitDownOptions = options 14 | } 15 | 16 | @TaskAction 17 | fun down() { 18 | localInstanceManager.base.examinePrerequisites(anyInstances) 19 | 20 | val downInstances = localInstanceManager.down(anyInstances, awaitDownOptions) 21 | if (downInstances.isNotEmpty()) { 22 | common.notifier.notify("Instance(s) down", "Which: ${downInstances.names}") 23 | } 24 | } 25 | 26 | init { 27 | description = "Turns off local AEM instance(s)." 28 | } 29 | 30 | companion object { 31 | const val NAME = "instanceDown" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceGroovyEval.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import com.cognifide.gradle.aem.common.instance.service.groovy.GroovyEvaluator 5 | import org.gradle.api.tasks.TaskAction 6 | 7 | open class InstanceGroovyEval : AemDefaultTask() { 8 | 9 | private var options: GroovyEvaluator.() -> Unit = {} 10 | 11 | fun options(options: GroovyEvaluator.() -> Unit) { 12 | this.options = options 13 | } 14 | 15 | @TaskAction 16 | fun eval() = aem.groovyEval { 17 | aem.prop.string("instance.groovyEval.script")?.let { scriptPattern.set(it) } 18 | aem.prop.string("instance.groovyEval.scriptSuffix")?.let { scriptSuffix.set(it) } 19 | aem.prop.map("instance.groovyEval.data")?.let { data.set(it) } 20 | aem.prop.boolean("instance.groovyEval.faulty")?.let { faulty.set(it) } 21 | 22 | options() 23 | 24 | val scripts = findScripts() 25 | if (scripts.isEmpty()) { 26 | logger.lifecycle("Lack of Groovy script(s) to evaluate matching pattern '$scriptPattern'") 27 | } else { 28 | val summary = evalScripts(scripts) 29 | common.notifier.lifecycle( 30 | "Evaluated Groovy script(s)", 31 | "Succeeded: ${summary.succeededPercent}. Elapsed time: ${summary.durationString}" 32 | ) 33 | } 34 | } 35 | 36 | init { 37 | description = "Evaluate Groovy script(s) on instance(s)." 38 | } 39 | 40 | companion object { 41 | const val NAME = "instanceGroovyEval" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceKill.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.LocalInstance 5 | import org.gradle.api.tasks.TaskAction 6 | 7 | open class InstanceKill : LocalInstance() { 8 | 9 | @TaskAction 10 | fun kill() { 11 | localInstanceManager.base.examinePrerequisites(anyInstances) 12 | 13 | val killedInstances = localInstanceManager.kill(anyInstances) 14 | if (killedInstances.isNotEmpty()) { 15 | common.notifier.lifecycle("Instance(s) killed", "Which: ${killedInstances.names}") 16 | } 17 | } 18 | 19 | init { 20 | description = "Kill local AEM instance process(es)" 21 | } 22 | 23 | companion object { 24 | const val NAME = "instanceKill" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceReload.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.action.AwaitUpAction 4 | import com.cognifide.gradle.aem.common.instance.action.ReloadAction 5 | import com.cognifide.gradle.aem.common.instance.names 6 | import com.cognifide.gradle.aem.common.tasks.Instance 7 | import org.gradle.api.tasks.TaskAction 8 | 9 | open class InstanceReload : Instance() { 10 | 11 | private var reloadOptions: ReloadAction.() -> Unit = {} 12 | 13 | fun reload(options: ReloadAction.() -> Unit) { 14 | this.reloadOptions = options 15 | } 16 | 17 | private var awaitUpOptions: AwaitUpAction.() -> Unit = {} 18 | 19 | fun awaitUp(options: AwaitUpAction.() -> Unit) { 20 | this.awaitUpOptions = options 21 | } 22 | 23 | @TaskAction 24 | fun reload() { 25 | instanceManager.awaitReloaded(anyInstances, reloadOptions, awaitUpOptions) 26 | common.notifier.lifecycle("Instance(s) reloaded", "Which: ${anyInstances.names}") 27 | } 28 | 29 | init { 30 | description = "Reloads all AEM instance(s)." 31 | } 32 | 33 | companion object { 34 | const val NAME = "instanceReload" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceResetup.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | 5 | open class InstanceResetup : AemDefaultTask() { 6 | 7 | init { 8 | description = "Destroys then sets up local AEM instance(s)." 9 | } 10 | 11 | companion object { 12 | const val NAME = "instanceResetup" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceResolve.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import org.gradle.api.tasks.TaskAction 5 | 6 | open class InstanceResolve : AemDefaultTask() { 7 | 8 | @TaskAction 9 | fun resolve() { 10 | aem.instanceManager.resolveFiles() 11 | aem.localInstanceManager.resolveFiles() 12 | } 13 | 14 | init { 15 | description = "Resolves instance files from remote sources before running other tasks" 16 | } 17 | 18 | companion object { 19 | const val NAME = "instanceResolve" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceRestart.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | 5 | open class InstanceRestart : AemDefaultTask() { 6 | 7 | init { 8 | description = "Turns off then on local AEM instance(s)." 9 | } 10 | 11 | companion object { 12 | const val NAME = "instanceRestart" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceSetup.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | 5 | open class InstanceSetup : AemDefaultTask() { 6 | 7 | init { 8 | description = "Creates and turns on local AEM instance(s) with satisfied dependencies and application built." 9 | } 10 | 11 | companion object { 12 | const val NAME = "instanceSetup" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceStatus.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.tasks.Instance 4 | import org.gradle.api.tasks.TaskAction 5 | 6 | open class InstanceStatus : Instance() { 7 | 8 | @TaskAction 9 | fun status() { 10 | common.progress(anyInstances.size) { 11 | step = "Initializing" 12 | instanceManager.statusReporter.init() 13 | 14 | step = "Checking statuses" 15 | common.parallel.map(anyInstances) { instance -> 16 | increment("Instance '${instance.name}'") { 17 | instance to instanceManager.statusReporter.report(instance) 18 | } 19 | }.sortedBy { it.first.name }.forEach { println(it.second) } 20 | } 21 | } 22 | 23 | init { 24 | description = "Prints status of AEM instances and installed packages." 25 | } 26 | 27 | companion object { 28 | const val NAME = "instanceStatus" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceTail.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.tasks.Instance 4 | import org.gradle.api.tasks.TaskAction 5 | 6 | open class InstanceTail : Instance() { 7 | 8 | @TaskAction 9 | fun tail() { 10 | logger.lifecycle("Tailing logs from:\n${anyInstances.joinToString("\n") { "Instance '${it.name}' at URL '${it.httpUrl.get()}'" }}") 11 | logger.lifecycle("Filter incidents using file: ${instanceManager.tailer.incidentFilter.get()}") 12 | 13 | instanceManager.tailer.tail(anyInstances) 14 | } 15 | 16 | init { 17 | description = "Tails logs from all configured instances (local & remote) and notifies about unknown errors." 18 | } 19 | 20 | companion object { 21 | const val NAME = "instanceTail" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/instance/tasks/InstanceUp.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.action.AwaitUpAction 4 | import com.cognifide.gradle.aem.common.instance.names 5 | import com.cognifide.gradle.aem.common.tasks.LocalInstance 6 | import org.gradle.api.tasks.Internal 7 | import org.gradle.api.tasks.TaskAction 8 | 9 | open class InstanceUp : LocalInstance() { 10 | 11 | private var awaitOptions = AwaitUpAction.noPackageDeployOptions() 12 | 13 | /** 14 | * Controls instance awaiting. 15 | */ 16 | fun await(options: AwaitUpAction.() -> Unit) { 17 | this.awaitOptions = options 18 | } 19 | 20 | /** 21 | * Ensure that already running instance are truly running (checking much more than status script only). 22 | */ 23 | @Internal 24 | val ensured = aem.obj.boolean { 25 | convention(true) 26 | aem.prop.boolean("instance.up.ensured")?.let { set(it) } 27 | } 28 | 29 | @TaskAction 30 | fun up() { 31 | localInstanceManager.base.examinePrerequisites(anyInstances) 32 | 33 | val upInstances = localInstanceManager.up(anyInstances, awaitOptions) 34 | 35 | if (ensured.get()) { 36 | val alreadyUpInstances = anyInstances - upInstances 37 | if (alreadyUpInstances.isNotEmpty()) { 38 | localInstanceManager.base.awaitUp(alreadyUpInstances, awaitOptions) 39 | } 40 | } 41 | 42 | localInstanceManager.customize(anyInstances) 43 | 44 | if (upInstances.isNotEmpty()) { 45 | common.notifier.lifecycle("Instance(s) up", "Which: ${upInstances.names}") 46 | } 47 | } 48 | 49 | init { 50 | description = "Turns on local AEM instance(s)." 51 | } 52 | 53 | companion object { 54 | const val NAME = "instanceUp" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/PackageSyncPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg 2 | 3 | import com.cognifide.gradle.aem.common.CommonPlugin 4 | import com.cognifide.gradle.aem.pkg.tasks.PackageConfig 5 | import com.cognifide.gradle.aem.pkg.tasks.PackageSync 6 | import com.cognifide.gradle.aem.pkg.tasks.PackageVlt 7 | import com.cognifide.gradle.common.CommonDefaultPlugin 8 | import org.gradle.api.Project 9 | import org.gradle.api.Task 10 | import org.gradle.language.base.plugins.LifecycleBasePlugin 11 | 12 | /** 13 | * Provides tasks useful for synchronizing JCR content from running AEM instance into built CRX package. 14 | */ 15 | class PackageSyncPlugin : CommonDefaultPlugin() { 16 | 17 | override fun Project.configureProject() { 18 | setupDependentPlugins() 19 | setupTasks() 20 | } 21 | 22 | private fun Project.setupDependentPlugins() { 23 | plugins.apply(CommonPlugin::class.java) 24 | } 25 | 26 | private fun Project.setupTasks() = tasks { 27 | val clean = named(LifecycleBasePlugin.CLEAN_TASK_NAME) 28 | 29 | register(PackageVlt.NAME) 30 | register(PackageSync.NAME) { 31 | mustRunAfter(clean) 32 | } 33 | register(PackageConfig.NAME) 34 | } 35 | 36 | companion object { 37 | const val ID = "com.cognifide.aem.package.sync" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageActivate.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class PackageActivate : Package() { 9 | 10 | @TaskAction 11 | override fun doSync() { 12 | super.doSync() 13 | common.notifier.notify("Package activated", "${files.fileNames} on ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Activates CRX package on instance(s)." 18 | sync.action { packageManager.activate(it) } 19 | aem.prop.boolean("package.activate.awaited")?.let { sync.awaited.set(it) } 20 | } 21 | 22 | companion object { 23 | const val NAME = "packageActivate" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageDelete.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class PackageDelete : Package() { 9 | 10 | @TaskAction 11 | override fun doSync() { 12 | super.doSync() 13 | common.notifier.notify("Package deleted", "${files.fileNames} on ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Deletes AEM package on instance(s)." 18 | sync.action { packageManager.delete(it) } 19 | sync.awaited.convention(false) 20 | } 21 | 22 | companion object { 23 | const val NAME = "packageDelete" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageDeploy.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.Input 7 | import org.gradle.api.tasks.TaskAction 8 | 9 | open class PackageDeploy : Package() { 10 | 11 | /** 12 | * Enables deployment via CRX package activation from author to publishers when e.g they are not accessible. 13 | */ 14 | @Input 15 | val distributed = aem.obj.boolean { 16 | convention(false) 17 | aem.prop.boolean("package.deploy.distributed")?.let { set(it) } 18 | } 19 | 20 | @TaskAction 21 | override fun doSync() { 22 | super.doSync() 23 | common.notifier.notify("Package deployed", "${files.fileNames} on ${instances.names}") 24 | } 25 | 26 | init { 27 | description = "Deploys CRX package on instance(s). Upload then install (and optionally activate)." 28 | 29 | sync.actionAwaited { packageManager.deploy(it, distributed.get()) } 30 | sync.instances.convention( 31 | aem.obj.provider { 32 | if (distributed.get()) { 33 | aem.authorInstances 34 | } else { 35 | aem.instances 36 | } 37 | } 38 | ) 39 | 40 | aem.prop.boolean("package.deploy.awaited")?.let { sync.awaited.set(it) } 41 | } 42 | 43 | companion object { 44 | const val NAME = "packageDeploy" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageInstall.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class PackageInstall : Package() { 9 | 10 | @TaskAction 11 | override fun doSync() { 12 | super.doSync() 13 | common.notifier.notify("Package installed", "${files.fileNames} from ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Installs AEM package on instance(s)." 18 | 19 | sync.action { packageManager.install(it) } 20 | aem.prop.boolean("package.install.awaited")?.let { sync.awaited.set(it) } 21 | } 22 | 23 | companion object { 24 | const val NAME = "packageInstall" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackagePurge.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class PackagePurge : Package() { 9 | 10 | @TaskAction 11 | override fun doSync() { 12 | super.doSync() 13 | common.notifier.notify("Package purged", "${files.fileNames} from ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Uninstalls and then deletes CRX package on AEM instance(s)." 18 | sync.actionAwaited { packageManager.purge(it) } 19 | aem.prop.boolean("package.purge.awaited")?.let { sync.awaited.set(it) } 20 | } 21 | 22 | companion object { 23 | const val NAME = "packagePurge" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageUninstall.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class PackageUninstall : Package() { 9 | 10 | @TaskAction 11 | override fun doSync() { 12 | super.doSync() 13 | common.notifier.notify("Package uninstalled", "${files.fileNames} from ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Uninstalls AEM package on instance(s)." 18 | sync.action { packageManager.uninstall(it) } 19 | aem.prop.boolean("package.uninstall.awaited")?.let { sync.awaited.set(it) } 20 | } 21 | 22 | companion object { 23 | const val NAME = "packageUninstall" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageUpload.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.common.instance.names 4 | import com.cognifide.gradle.aem.common.tasks.Package 5 | import com.cognifide.gradle.aem.common.utils.fileNames 6 | import org.gradle.api.tasks.TaskAction 7 | 8 | open class PackageUpload : Package() { 9 | 10 | @TaskAction 11 | override fun doSync() { 12 | super.doSync() 13 | common.notifier.notify("Package uploaded", "${files.fileNames} from ${instances.names}") 14 | } 15 | 16 | init { 17 | description = "Uploads AEM package to instance(s)." 18 | sync.action { packageManager.upload(it) } 19 | sync.awaited.convention(false) 20 | } 21 | 22 | companion object { 23 | const val NAME = "packageUpload" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageValidate.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import com.cognifide.gradle.aem.common.pkg.PackageValidator 5 | import org.gradle.api.tasks.* 6 | 7 | open class PackageValidate : AemDefaultTask() { 8 | 9 | @InputFiles 10 | val packages = aem.obj.files() 11 | 12 | @Nested 13 | val validator = PackageValidator(aem).apply { 14 | workDir.convention(aem.obj.buildDir(name)) 15 | } 16 | 17 | fun validator(options: PackageValidator.() -> Unit) { 18 | validator.apply(options) 19 | } 20 | 21 | @TaskAction 22 | fun validate() { 23 | validator.perform(packages.files) 24 | } 25 | 26 | init { 27 | description = "Validates built CRX package" 28 | enabled = aem.prop.boolean("package.validate.enabled") ?: false 29 | } 30 | 31 | companion object { 32 | const val NAME = "packageValidate" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/PackageVlt.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks 2 | 3 | import com.cognifide.gradle.aem.AemDefaultTask 4 | import com.cognifide.gradle.aem.common.pkg.vault.VaultClient 5 | import org.gradle.api.tasks.TaskAction 6 | 7 | open class PackageVlt : AemDefaultTask() { 8 | 9 | fun options(configurer: VaultClient.() -> Unit) { 10 | this.options = configurer 11 | } 12 | 13 | private var options: VaultClient.() -> Unit = {} 14 | 15 | @TaskAction 16 | open fun run() = aem.vlt { 17 | aem.prop.string("package.vlt.command")?.let { command.set(it) } 18 | aem.prop.string("package.vlt.path")?.let { contentRelativePath.set(it) } 19 | 20 | options() 21 | 22 | val summary = run() 23 | 24 | common.notifier.notify( 25 | "Executing Vault command", 26 | "Command '${summary.command}' finished. Duration: ${summary.durationString}" 27 | ) 28 | } 29 | 30 | init { 31 | description = "Execute any Vault command." 32 | } 33 | 34 | companion object { 35 | const val NAME = "packageVlt" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/BundleInstalled.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | import org.gradle.api.provider.Property 4 | import org.gradle.api.tasks.Input 5 | import org.gradle.api.tasks.Optional 6 | 7 | interface BundleInstalled : RepositoryArchive { 8 | 9 | @get:Input 10 | @get:Optional 11 | val runMode: Property 12 | 13 | @get:Input 14 | @get:Optional 15 | val startLevel: Property 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/BundleInstalledBuilt.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | import com.cognifide.gradle.aem.bundle.tasks.bundle 4 | import com.cognifide.gradle.aem.common.pkg.vault.FilterType 5 | import com.cognifide.gradle.aem.pkg.tasks.PackageCompose 6 | import org.gradle.api.tasks.TaskProvider 7 | import org.gradle.api.tasks.bundling.Jar 8 | 9 | class BundleInstalledBuilt(target: PackageCompose, private val task: TaskProvider) : BundleInstalled { 10 | 11 | private val aem = target.aem 12 | 13 | override val file = aem.obj.file { convention(task.flatMap { it.archiveFile }) } 14 | 15 | override val dirPath = aem.obj.string { convention(task.flatMap { it.bundle.installPath }) } 16 | 17 | override val fileName = aem.obj.string { convention(task.flatMap { it.archiveFileName }) } 18 | 19 | override val vaultFilter = aem.obj.boolean { convention(task.flatMap { it.bundle.vaultFilter }) } 20 | 21 | override val vaultFilterType = aem.obj.typed { convention(FilterType.FILE) } 22 | 23 | override val runMode = aem.obj.string { convention(task.flatMap { it.bundle.installRunMode }) } 24 | 25 | override val startLevel = aem.obj.int { convention(task.flatMap { it.bundle.installStartLevel }) } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/BundleInstalledResolved.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | import com.cognifide.gradle.aem.common.pkg.vault.FilterType 4 | import com.cognifide.gradle.aem.pkg.tasks.PackageCompose 5 | import org.gradle.api.tasks.Input 6 | 7 | class BundleInstalledResolved(private val target: PackageCompose, @Input val notation: Any) : BundleInstalled { 8 | 9 | private val aem = target.aem 10 | 11 | private val resolvedFile by lazy { aem.common.resolveFile(notation) } 12 | 13 | override val file = aem.obj.file { fileProvider(aem.obj.provider { resolvedFile }) } 14 | 15 | override val dirPath = aem.obj.string { convention(target.bundlePath) } 16 | 17 | override val fileName = aem.obj.string { convention(aem.obj.provider { resolvedFile.name }) } 18 | 19 | override val vaultFilter = aem.obj.boolean { convention(target.vaultFilters) } 20 | 21 | override val vaultFilterType = aem.obj.typed { convention(FilterType.FILE) } 22 | 23 | override val runMode = aem.obj.string() 24 | 25 | override val startLevel = aem.obj.int() 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/PackageNested.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | interface PackageNested : RepositoryArchive 4 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/PackageNestedBuilt.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | import com.cognifide.gradle.aem.common.pkg.vault.FilterType 4 | import com.cognifide.gradle.aem.pkg.tasks.PackageCompose 5 | import org.gradle.api.tasks.TaskProvider 6 | 7 | class PackageNestedBuilt(target: PackageCompose, private val task: TaskProvider) : PackageNested { 8 | 9 | private val aem = target.aem 10 | 11 | override val file = aem.obj.file { convention(task.flatMap { it.archiveFile }) } 12 | 13 | override val dirPath = aem.obj.string { convention(task.flatMap { t -> t.nestedPath.map { "$it/${t.vaultDefinition.group.get()}" } }) } 14 | 15 | override val fileName = aem.obj.string { convention(task.flatMap { it.archiveFileName }) } 16 | 17 | override val vaultFilter = aem.obj.boolean { convention(task.flatMap { it.vaultFilters }) } 18 | 19 | override val vaultFilterType = aem.obj.typed { convention(FilterType.FILE) } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/PackageNestedResolved.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | import com.cognifide.gradle.aem.common.pkg.PackageFile 4 | import com.cognifide.gradle.aem.common.pkg.vault.FilterType 5 | import com.cognifide.gradle.aem.pkg.tasks.PackageCompose 6 | import com.cognifide.gradle.common.build.DependencyFile 7 | import org.gradle.api.tasks.Input 8 | 9 | class PackageNestedResolved(private val target: PackageCompose, @Input val notation: Any) : PackageNested { 10 | 11 | private val aem = target.aem 12 | 13 | private val resolvedFile by lazy { aem.common.resolveFile(DependencyFile.hintNotation(notation, "zip")) } 14 | 15 | override val file = aem.obj.file { fileProvider(aem.obj.provider { resolvedFile }) } 16 | 17 | override val dirPath = aem.obj.string { convention(target.nestedPath.map { "$it/${PackageFile(resolvedFile).group}" }) } 18 | 19 | override val fileName = aem.obj.string { convention(aem.obj.provider { resolvedFile.name }) } 20 | 21 | override val vaultFilter = aem.obj.boolean { convention(target.vaultFilters) } 22 | 23 | override val vaultFilterType = aem.obj.typed { convention(FilterType.FILE) } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/com/cognifide/gradle/aem/pkg/tasks/compose/RepositoryArchive.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg.tasks.compose 2 | 3 | import com.cognifide.gradle.aem.common.pkg.vault.FilterType 4 | import org.gradle.api.file.RegularFileProperty 5 | import org.gradle.api.provider.Property 6 | import org.gradle.api.tasks.Input 7 | import org.gradle.api.tasks.InputFile 8 | import java.io.Serializable 9 | 10 | interface RepositoryArchive : Serializable { 11 | 12 | @get:InputFile 13 | val file: RegularFileProperty 14 | 15 | @get:Input 16 | val fileName: Property 17 | 18 | @get:Input 19 | val dirPath: Property 20 | 21 | @get:Input 22 | val vaultFilter: Property 23 | 24 | @get:Input 25 | val vaultFilterType: Property 26 | 27 | fun vaultFilterFile() { 28 | vaultFilterType.set(FilterType.FILE) 29 | } 30 | 31 | fun vaultFilterDir() { 32 | vaultFilterType.set(FilterType.DIR) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/bundle/BundlePluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.bundle 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.bundle.tasks.BundleInstall 5 | import com.cognifide.gradle.aem.bundle.tasks.BundleUninstall 6 | import com.cognifide.gradle.aem.pkg.PackagePlugin 7 | import com.cognifide.gradle.aem.test.AemTest 8 | import org.gradle.api.internal.plugins.PluginApplicationException 9 | import org.gradle.api.plugins.JavaPlugin 10 | import org.gradle.api.tasks.bundling.Jar 11 | import org.junit.jupiter.api.Assertions.assertEquals 12 | import org.junit.jupiter.api.Test 13 | import org.junit.jupiter.api.assertThrows 14 | 15 | class BundlePluginTest : AemTest() { 16 | 17 | @Test 18 | fun `should register extension and tasks`() = usingProject { 19 | plugins.apply(BundlePlugin.ID) 20 | 21 | extensions.getByName(AemExtension.NAME) 22 | 23 | val jar = tasks.named(JavaPlugin.JAR_TASK_NAME, Jar::class.java).get() 24 | assertEquals("test.jar", jar.archiveFile.get().asFile.name) 25 | 26 | tasks.getByName(BundleInstall.NAME) 27 | tasks.getByName(BundleUninstall.NAME) 28 | } 29 | 30 | @Test 31 | fun `should not be applied after package plugin`() = usingProject { 32 | plugins.apply(PackagePlugin.ID) 33 | assertThrows { 34 | plugins.apply(BundlePlugin.ID) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/common/CommonPluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.AemTask 5 | import com.cognifide.gradle.aem.test.AemTest 6 | import org.junit.jupiter.api.Assertions.assertEquals 7 | import org.junit.jupiter.api.Assertions.assertNotNull 8 | import org.junit.jupiter.api.Assertions.assertTrue 9 | import org.junit.jupiter.api.Test 10 | 11 | class CommonPluginTest : AemTest() { 12 | 13 | @Test 14 | fun `plugin registers extension`() = usingProject { 15 | plugins.apply(CommonPlugin.ID) 16 | 17 | extensions.getByName(AemExtension.NAME) 18 | extensions.getByType(AemExtension::class.java).apply { 19 | val instances = instanceManager.defined.get() 20 | 21 | assertEquals(2, instances.size) 22 | 23 | instances[0].apply { 24 | assertEquals("local-author", name) 25 | assertTrue(author) 26 | assertNotNull(this.toString()) 27 | } 28 | instances[1].apply { 29 | assertEquals("local-publish", name) 30 | assertTrue(publish) 31 | assertNotNull(this.toString()) 32 | } 33 | 34 | assertEquals("/apps/test/install", packageOptions.installPath.get()) 35 | } 36 | 37 | assertTrue( 38 | tasks.none { it.group == AemTask.GROUP }, 39 | "Common plugin should not provide any tasks which belongs to group AEM." 40 | ) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/common/instance/InstanceFactoryTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import org.gradle.testfixtures.ProjectBuilder 5 | import org.junit.jupiter.api.Assertions.assertEquals 6 | import org.junit.jupiter.api.Test 7 | 8 | class InstanceFactoryTest { 9 | 10 | @Test 11 | fun `should create instance with correct url`() { 12 | val testUrl = "https://author-7777.adobeaemcloud.com" 13 | val instance = InstanceFactory(aem).createByUrl(testUrl) 14 | assertEquals(instance.httpUrl.get(), testUrl) 15 | } 16 | 17 | @Test 18 | fun `should create remote instance with correct url`() { 19 | val testUrl = "https://author-7777.adobeaemcloud.com" 20 | val instance = InstanceFactory(aem).remoteByUrl(testUrl) 21 | assertEquals(instance.httpUrl.get(), testUrl) 22 | } 23 | 24 | @Test 25 | fun `should create local instance with correct url`() { 26 | val testUrl = "http://localhost.com:7777" 27 | val instance = InstanceFactory(aem).localByUrl(testUrl) 28 | assertEquals(instance.httpUrl.get(), testUrl) 29 | } 30 | 31 | private val project get() = ProjectBuilder.builder().build() 32 | private val aem get() = AemExtension(project.also { it.plugins.apply("com.cognifide.aem.instance") }) 33 | } 34 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/common/instance/service/pkg/PackageResponseTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.instance.service.pkg 2 | 3 | import org.junit.jupiter.api.Assertions.assertEquals 4 | import org.junit.jupiter.api.Assertions.assertTrue 5 | import org.junit.jupiter.api.Test 6 | import java.io.InputStream 7 | 8 | class PackageResponseTest { 9 | 10 | @Test 11 | fun shouldContainDependencyPackageException() { 12 | val response = InstallResponse.from(importFileAsStream("failure-dependency-exception.txt"), 4096) 13 | assertTrue(response.hasPackageErrors(setOf(DEPENDENCY_EXCEPTION))) 14 | } 15 | 16 | @Test 17 | fun shouldFinishWithSuccessStatus() { 18 | val response = DeleteResponse.from(importFileAsStream("example-delete.txt"), 4096) 19 | assertEquals(response.status, HtmlResponse.Status.SUCCESS) 20 | } 21 | 22 | companion object { 23 | private const val DEPENDENCY_EXCEPTION = "org.apache.jackrabbit.vault.packaging.DependencyException" 24 | 25 | private fun importFileAsStream(fileName: String): InputStream { 26 | return this::class.java.getResource("package-response/$fileName").openStream() 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/common/utils/FileUtilTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import com.cognifide.gradle.aem.common.utils.FileUtil.sanitizePath 4 | import org.junit.jupiter.api.Assertions.assertEquals 5 | import org.junit.jupiter.api.Test 6 | 7 | class FileUtilTest { 8 | 9 | @Test 10 | fun `should sanitize path properly`() { 11 | assertEquals("/home/punky/gap/a_b/c/d/e", sanitizePath("/home/punky/gap/a_b/c/d/e")) 12 | assertEquals("/home/punky/gap/a_b/c/d/e", sanitizePath("/home/punky/gap/a b/c/d/e")) 13 | assertEquals("/home/punky/gap/a_b/c/d/e", sanitizePath("/home/punky/gap/a&b/c/d/e")) 14 | assertEquals("C:/gap/a_b/c/d/e", sanitizePath("""C:\gap\a&b\c\d\e""")) 15 | assertEquals("C:/gap/a_b/c/d/e", sanitizePath("C:/gap/a&b/c/d/e")) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/common/utils/UtilsTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.common.utils 2 | 3 | import org.junit.jupiter.api.Assertions.assertEquals 4 | import org.junit.jupiter.params.ParameterizedTest 5 | import org.junit.jupiter.params.provider.CsvSource 6 | 7 | class UtilsTest { 8 | 9 | @ParameterizedTest 10 | @CsvSource( 11 | value = [ 12 | "SomeClass,32,SomeClass", 13 | "com.company.SomeClass,32,com.company.SomeClass", 14 | "org.osgi.service.component.runtime.ServiceComponentRuntime,32,org.o.s.c.r.Serv*omponentRuntime", 15 | "org.osgi.service.component.runtime.ServiceComponentRuntime,40,org.o.s.c.r.ServiceComponentRuntime" 16 | ] 17 | ) 18 | fun `should shorten class properly`(input: String, maxLength: Int, expected: String) { 19 | assertEquals(expected, input.shortenClass(maxLength)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/instance/InstancePluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.instance.tasks.InstanceRcp 5 | import com.cognifide.gradle.aem.instance.tasks.InstanceSetup 6 | import com.cognifide.gradle.aem.pkg.PackagePlugin 7 | import com.cognifide.gradle.aem.test.AemTest 8 | import org.gradle.api.internal.plugins.PluginApplicationException 9 | import org.junit.jupiter.api.Test 10 | import org.junit.jupiter.api.assertThrows 11 | 12 | class InstancePluginTest : AemTest() { 13 | 14 | @Test 15 | fun `plugin registers extension and tasks`() = usingProject { 16 | plugins.apply(InstancePlugin.ID) 17 | 18 | extensions.getByName(AemExtension.NAME) 19 | tasks.getByName(InstanceSetup.NAME) 20 | tasks.getByName(InstanceRcp.NAME) 21 | } 22 | 23 | @Test 24 | fun `should not be applied after package plugin`() = usingProject { 25 | plugins.apply(PackagePlugin.ID) 26 | assertThrows { 27 | plugins.apply(InstancePlugin.ID) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/instance/LocalInstancePluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.instance 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.instance.tasks.InstanceDown 5 | import com.cognifide.gradle.aem.instance.tasks.InstanceRcp 6 | import com.cognifide.gradle.aem.instance.tasks.InstanceSetup 7 | import com.cognifide.gradle.aem.instance.tasks.InstanceUp 8 | import com.cognifide.gradle.aem.pkg.PackagePlugin 9 | import com.cognifide.gradle.aem.test.AemTest 10 | import org.gradle.api.internal.plugins.PluginApplicationException 11 | import org.junit.jupiter.api.Assertions.assertTrue 12 | import org.junit.jupiter.api.Test 13 | import org.junit.jupiter.api.assertThrows 14 | 15 | class LocalInstancePluginTest : AemTest() { 16 | 17 | @Test 18 | fun `plugin registers extension and tasks`() = usingProject { 19 | plugins.apply(LocalInstancePlugin.ID) 20 | assertTrue(plugins.hasPlugin(InstancePlugin.ID)) 21 | 22 | extensions.getByName(AemExtension.NAME) 23 | tasks.getByName(InstanceUp.NAME) 24 | tasks.getByName(InstanceDown.NAME) 25 | 26 | tasks.getByName(InstanceSetup.NAME) 27 | tasks.getByName(InstanceRcp.NAME) 28 | } 29 | 30 | @Test 31 | fun `should not be applied after package plugin`() = usingProject { 32 | plugins.apply(PackagePlugin.ID) 33 | assertThrows { 34 | plugins.apply(LocalInstancePlugin.ID) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/pkg/PackagePluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.pkg.tasks.PackageActivate 5 | import com.cognifide.gradle.aem.pkg.tasks.PackageCompose 6 | import com.cognifide.gradle.aem.pkg.tasks.PackageDelete 7 | import com.cognifide.gradle.aem.pkg.tasks.PackageDeploy 8 | import com.cognifide.gradle.aem.pkg.tasks.PackageInstall 9 | import com.cognifide.gradle.aem.pkg.tasks.PackagePrepare 10 | import com.cognifide.gradle.aem.pkg.tasks.PackagePurge 11 | import com.cognifide.gradle.aem.pkg.tasks.PackageUninstall 12 | import com.cognifide.gradle.aem.pkg.tasks.PackageUpload 13 | import com.cognifide.gradle.aem.test.AemTest 14 | import org.junit.jupiter.api.Assertions.assertEquals 15 | import org.junit.jupiter.api.Test 16 | 17 | class PackagePluginTest : AemTest() { 18 | 19 | @Test 20 | fun `plugin registers extension and tasks`() = usingProject { 21 | plugins.apply(PackagePlugin.ID) 22 | 23 | extensions.getByName(AemExtension.NAME) 24 | 25 | tasks.getByName(PackageActivate.NAME) 26 | 27 | val compose = tasks.named(PackageCompose.NAME, PackageCompose::class.java).get() 28 | assertEquals("test.zip", compose.archiveFile.get().asFile.name) 29 | 30 | tasks.getByName(PackageDelete.NAME) 31 | tasks.getByName(PackageDeploy.NAME) 32 | tasks.getByName(PackageInstall.NAME) 33 | tasks.getByName(PackagePrepare.NAME) 34 | tasks.getByName(PackagePurge.NAME) 35 | tasks.getByName(PackageUninstall.NAME) 36 | tasks.getByName(PackageUpload.NAME) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/pkg/PackageSyncPluginTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.pkg 2 | 3 | import com.cognifide.gradle.aem.AemExtension 4 | import com.cognifide.gradle.aem.pkg.tasks.PackageSync 5 | import com.cognifide.gradle.aem.pkg.tasks.PackageVlt 6 | import com.cognifide.gradle.aem.test.AemTest 7 | import org.junit.jupiter.api.Test 8 | 9 | class PackageSyncPluginTest : AemTest() { 10 | 11 | @Test 12 | fun `plugin registers extension and tasks`() = usingProject { 13 | plugins.apply(PackageSyncPlugin.ID) 14 | 15 | extensions.getByName(AemExtension.NAME) 16 | tasks.getByName(PackageSync.NAME) 17 | tasks.getByName(PackageVlt.NAME) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/kotlin/com/cognifide/gradle/aem/test/AemTest.kt: -------------------------------------------------------------------------------- 1 | package com.cognifide.gradle.aem.test 2 | 3 | import com.cognifide.gradle.common.utils.using 4 | import org.gradle.api.Project 5 | import org.gradle.testfixtures.ProjectBuilder 6 | 7 | open class AemTest { 8 | 9 | fun usingProject(callback: Project.() -> Unit) = ProjectBuilder.builder().build().using(callback) 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/com/cognifide/gradle/aem/common/instance/service/pkg/package-response/example-delete.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 21 |

Deleting package


Package deleted in 87ms.
24 | 25 | -------------------------------------------------------------------------------- /src/test/resources/com/cognifide/gradle/aem/common/instance/tail/aggregating/disjoint/first-chunk-error.log: -------------------------------------------------------------------------------- 1 | 14.01.2019 12:04:54.613 *ERROR* [ccc2013950868-66] cag.cccccc.ccccg.cccccccc caccDcccccgcg: Eaaca ccccggcgg ccccccgc ccgccc://208.0:0/OSGI-INF/cccccccc/cccccccc.cacccacccg : XML ccagcgg cgccccccg acccc accccgg cccccccc: Acca.gcccc ccggcgg c. cacccg (ccgccccg:START_TAG @59:110 cg ccgccc://208.0:0/OSGI-INF/cccccccc/cccccccc.cacccacccg) 2 | 14.01.2019 12:04:58.230 *INFO* [ccc2013950868-63] cag.cccccc.ccccaccccc.gcccc.cccccgcgg.cccc.AcccgcccLcg ccc.cccccgc.ccc:cgccccc:1.0.0-SNAPSHOT: CREATE 3 | 14.01.2019 12:04:58.230 *INFO* [ccc2013950868-63] cag.cccccc.ccccaccccc.gcccc.cccccgcgg.cccc.AcccgcccLcg ccc.cccccgc.ccc:cgccccc:1.0.0-SNAPSHOT: UPLOAD 4 | 14.01.2019 12:04:58.341 *INFO* [ccc2013950868-69] ccc.ccc.cag.cccccgcgg.cccc.SccggIggcccccaSccccacIccc Sccgg cggccccca gccc /gcgccc/gccgg/cggccccca/cca/cccgcIggccccccccg/0c146cc6-0c08-4c41-9549-49c58251cc8c/ccc.ccc.cag.cccccgcgg.cccc.SccggIggcccccaSccccacIccc/72ccc4c6-c0c1-4c0c-cc0c-4c32488c53cc caccccc. 5 | 14.01.2019 12:04:58.519 *INFO* [ccc2013950868-69] ccc.ccc.cag.cccccgcgg.cccc.J2EEPccccgcMcgcgca Fccgc cggcccccccc cc /cccg/cgccccc/cggcccc/.gcccggcac -------------------------------------------------------------------------------- /src/test/resources/com/cognifide/gradle/aem/common/instance/tail/aggregating/disjoint/second-chunk-error.log: -------------------------------------------------------------------------------- 1 | 14.01.2019 12:04:58.539 *INFO* [mmd2013950868-69] bfm.mdmddd.mmdmfmdddm.dmddm.dmdmmmdbm.dddd.AdmdddmhLbm dbd.dbddmbh.mdd:ddmdddd:1.0.0-SNAPSHOT: INSTALL 2 | 14.01.2019 12:04:58.545 *INFO* [mmd2013950868-69] dbd.dmh.dfd.dmdmmmdbm.dddd.SddbmIbdmmdddfSdddbfmIddd Sddbm dbdmmdddf bbdd /dhdmdd/dddbm/dbdmmdddf/mdf/dmdddIbdmmddmmdbb/0d146md6-0d08-4d41-9549-49d58251dm8d/dbd.dmh.dfd.dmdmmmdbm.dddd.SddbmIbdmmdddfSdddbfmIddd/72ddd4d6-d0t1-4d0d-md0d-4m32488d53dd fddbddd. 3 | 14.01.2019 12:04:58.545 *INFO* [mmd2013950868-69] dbd.dmh.dfd.dmdmmmdbm.dddd.J2EEPmdmmmdMmbmmdf Sdmbbdf ddmddmdd dbmdbmdmd mdf dbdmmddmddd. dddmhdbm dbdmmddmmdbb tbf 2 dddbbdd. 4 | 14.01.2019 12:04:58.674 *INFO* [JdfIbdmmdddf.3] bfm.mdmddd.dddbm.dbdmmdddf.dfbddddf.mdf.dddd.JdfIbdmmdddf Rdmddmdfdbm fddbdfdd tdmd OSGd dbdmmdddf: [IbdmmddmdddRddbdfdd, dfdbfdmh=200, dd=/mddd/ddmdddd/dbdmmdd/ddmdddd-1.0.0-SNAPSHOT.mmf] 5 | 14.01.2019 12:04:58.773 *INFO* [OdmdIbdmmdddfIddd] dbd.dbddmbh.mdd.ddmdddd BdbdddEddbm STOPPING -------------------------------------------------------------------------------- /src/test/resources/com/cognifide/gradle/aem/common/instance/tail/aggregating/multiline/multiline-short.log: -------------------------------------------------------------------------------- 1 | rrf.rrrrel.csssrrcskl.crrrfk /eskr/resllleskr/rcslsll/rrcsess3.cr:69409: WARNING - slclsrcskel rrkl 2 | cllscl lcsl; 3 | ^^^^^^^^^^^^ 4 | --------------------------------------------------------------------------------