This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.installer.hc-1.0.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-installer-hc.git
commit d3dcf757419f31b45357eb373a1498303dd4e0eb Author: Konrad Windszus <[email protected]> AuthorDate: Wed Aug 17 11:13:19 2016 +0000 SLING-5888 new hc module for making sure that bundles/configurations have been successfully installed by the OSGi installer git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/installer/hc@1756614 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 108 +++++++++++++ .../installer/hc/OsgiInstallerHealthCheck.java | 169 +++++++++++++++++++++ 2 files changed, 277 insertions(+) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..df07ccc --- /dev/null +++ b/pom.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor + license agreements. See the NOTICE file distributed with this work for additional + information regarding copyright ownership. The ASF licenses this file to + you under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of + the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required + by applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. See the License for the specific + language governing permissions and limitations under the License. --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>28</version> + <relativePath /> + </parent> + + <artifactId>org.apache.sling.installer.hc</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>Apache Sling Installer Health Checks</name> + <description> + Provides Sling health checks related to the Sling Installer. + </description> + + <scm> + <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/installer/healthcheck</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/installer/healthcheck</developerConnection> + <url>http://svn.apache.org/viewvc/sling/installer/healthcheck</url> + </scm> + + <!-- make compile with java 7 --> + <properties> + <sling.java.version>7</sling.java.version> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.cmpn</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.osgi</artifactId> + <version>2.2.0</version> + <scope>provided</scope> + </dependency> + <!-- reference old API bundle to generate broader import ranges making + this HC bundle compliant with older versions as well --> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.installer.api</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.5</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.hc.core</artifactId> + <version>1.0.4</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.hc.annotations</artifactId> + <version>1.0.4</version> + <scope>provided</scope> + </dependency> + </dependencies> +</project> diff --git a/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java b/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java new file mode 100644 index 0000000..3a7b578 --- /dev/null +++ b/src/main/java/org/apache/sling/installer/hc/OsgiInstallerHealthCheck.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The SF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.sling.installer.hc; + +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.apache.sling.hc.annotations.SlingHealthCheck; +import org.apache.sling.hc.api.HealthCheck; +import org.apache.sling.hc.api.Result; +import org.apache.sling.hc.util.FormattingResultLog; +import org.apache.sling.installer.api.InstallableResource; +import org.apache.sling.installer.api.info.InfoProvider; +import org.apache.sling.installer.api.info.InstallationState; +import org.apache.sling.installer.api.info.Resource; +import org.apache.sling.installer.api.info.ResourceGroup; +import org.osgi.service.cm.ConfigurationAdmin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SlingHealthCheck(name = OsgiInstallerHealthCheck.HC_NAME, description = "Checks that all OSGi configurations/bundles are successfully installed by the OSGi Installer (and are not skipped for some reason).", tags = "osgi") +public class OsgiInstallerHealthCheck implements HealthCheck { + protected static final String HC_NAME = "OSGi Installer Health Check"; + + @Reference + private InfoProvider infoProvider; + + private static final Logger LOG = LoggerFactory.getLogger(OsgiInstallerHealthCheck.class); + + private static final String DEFAULT_URL_PREFIX = "jcrinstall:/apps/"; + + @Property(label = "URL Prefixes to consider", description = "Only those OSGi configurations/bundles whose location are starting with one of the given URL prefixes are checked (whether they are installed correctly). Open /system/console/osgi-installer for a list of valid prefixes. The bundles/configs with those prefixes are asserted to be successfully installed under all circumstances!", cardinality = 1, value = DEFAULT_URL_PREFIX) + static final String PROP_URL_PREFIXES = "urlPrefixes"; + + @Property(label = "Check Bundles", description = "If enabled bundles are checked (restricted to the ones matching one of the prefixes)", boolValue = true) + static final String PROP_CHECK_BUNDLES = "checkBundles"; + + @Property(label = "Check Configurations", description = "If enabled configurations are checked (restricted to the ones matching one of the prefixes)", boolValue = true) + static final String PROP_CHECK_CONFIGURATIONS = "checkConfigurations"; + + private String[] urlPrefixes; + private boolean checkBundles; + private boolean checkConfigurations; + + private final static String DOCUMENTATION_URL = "https://sling.apache.org/documentation/bundles/osgi-installer.html#health-check"; + + @Reference + private ConfigurationAdmin configurationAdmin; + + @Activate + public void activate(Map<String, ?> properties) { + urlPrefixes = PropertiesUtil.toStringArray(properties.get(PROP_URL_PREFIXES), + new String[] { DEFAULT_URL_PREFIX }); + checkBundles = PropertiesUtil.toBoolean(properties.get(PROP_CHECK_BUNDLES), true); + checkConfigurations = PropertiesUtil.toBoolean(properties.get(PROP_CHECK_CONFIGURATIONS), true); + } + + @Override + public Result execute() { + InstallationState installationState = infoProvider.getInstallationState(); + FormattingResultLog hcLog = new FormattingResultLog(); + + int numCheckedConfigurations = 0; + int numCheckedBundles = 0; + // go through all resource groups of the OSGi Installer + for (final ResourceGroup group : installationState.getInstalledResources()) { + String type = evaluateGroup(group, hcLog); + switch (type) { + case InstallableResource.TYPE_CONFIG: + numCheckedConfigurations++; + break; + case InstallableResource.TYPE_BUNDLE: + numCheckedBundles++; + break; + } + } + hcLog.info("Checked {} OSGi bundles and {} configurations.", numCheckedBundles, numCheckedConfigurations); + if (hcLog.getAggregateStatus().ordinal() >= Result.Status.WARN.ordinal()) { + hcLog.info("Refer to the OSGI installers documentation page at {} for further details on how to fix those issues.", DOCUMENTATION_URL); + } + return new Result(hcLog); + } + + /** + * @param group + * the resource group to evaluate + * @param hcLog + * the log to fill during the health check + * @return the type of resources in this group ("bundle" or "config") or empty string, if the group was not + * considered by this health check + */ + private String evaluateGroup(ResourceGroup group, FormattingResultLog hcLog) { + Resource invalidResource = null; + String resourceType = ""; + // go through all resources within the given group + for (Resource resource : group.getResources()) { + // check for the correct type + resourceType = resource.getType(); + switch (resourceType) { + case InstallableResource.TYPE_CONFIG: + if (!checkConfigurations) { + LOG.debug("Skip resource '{}' as it is a configuration", resource.getEntityId()); + return ""; + } + break; + case InstallableResource.TYPE_BUNDLE: + if (!checkBundles) { + LOG.debug("Skip resource '{}' as it is a bundle", resource.getEntityId()); + return ""; + } + break; + default: + LOG.debug("Skip resource '{}' as it is neither a bundle nor a configuration but a {}", + resource.getEntityId(), resourceType); + return ""; + } + if (StringUtils.startsWithAny(resource.getURL(), urlPrefixes)) { + switch (resource.getState()) { + case IGNORED: // means a considered resource was found and it is invalid + // still the other resources need to be evaluated + case INSTALL: + if (invalidResource == null) { + invalidResource = resource; + } + break; + default: + // means a considered resource was found and it is valid + // no need to evaluate other resources from this group + return resourceType; + } + } else { + LOG.debug("Skipping resource '{}' as its URL is not starting with any of these prefixes'{}'", resource, + StringUtils.join(urlPrefixes, ",")); + } + } + if (invalidResource != null) { + if (resourceType.equals(InstallableResource.TYPE_CONFIG)) { + hcLog.critical( + "The installer state of the OSGi configuration resource '{}' is {}, probably because a later version of that bundle is already installed!", + invalidResource, invalidResource.getState()); + } else { + hcLog.critical( + "The installer state of the OSGi bundle resource '{}' is {}, config might have been manually overwritten!", + invalidResource, invalidResource.getState()); + } + } + return resourceType; + } + +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
