You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by at...@apache.org on 2008/06/13 14:02:11 UTC
svn commit: r667492 - in
/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE:
components/portal/src/java/org/apache/jetspeed/healthcheck/
components/portal/src/java/org/apache/jetspeed/healthcheck/validators/
components/portal/src/java/org/a...
Author: ate
Date: Fri Jun 13 05:02:11 2008
New Revision: 667492
URL: http://svn.apache.org/viewvc?rev=667492&view=rev
Log:
JS2-888: New HealthCheck feature contributed by Ruben Carvalho
See: http://issues.apache.org/jira/browse/JS2-888
Great new feature, thanks Ruben!
Added:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java (with props)
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java (with props)
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java (with props)
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java (with props)
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java (with props)
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java (with props)
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/assembly/pipelines.xml
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/web.xml
Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java?rev=667492&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java Fri Jun 13 05:02:11 2008
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+package org.apache.jetspeed.healthcheck.validators;
+
+import java.util.List;
+
+/**
+ * Bean to be used by validators that need to execute a validation query against a list of datasources
+ *
+ * @author <a href="mailto:ruben.carvalho@fmr.com">Ruben Carvalho</a>
+ * @version $Id$
+ */
+public class DataSourcesValidationBean
+{
+ /**
+ * The SQL query.
+ */
+ private String validationQuery;
+ /**
+ * List of datasources.
+ */
+ private List datasources;
+
+ public DataSourcesValidationBean(String validationQuery, List datasources)
+ {
+ this.validationQuery = validationQuery;
+ this.datasources = datasources;
+ }
+
+ /**
+ * Getter method for validationQuery
+ *
+ * @return The validation query.
+ */
+ public String getValidationQuery()
+ {
+ return validationQuery;
+ }
+
+ /**
+ * Getter method for datasources
+ *
+ * @return The list of datasources.
+ */
+ public List getDatasources()
+ {
+ return datasources;
+ }
+}
\ No newline at end of file
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DataSourcesValidationBean.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java?rev=667492&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java Fri Jun 13 05:02:11 2008
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+package org.apache.jetspeed.healthcheck.validators;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.jdbc.support.JdbcUtils;
+
+/**
+ * Validator to check if the defined datasources are up and running
+ *
+ * @author <a href="mailto:ruben.carvalho@fmr.com">Ruben Carvalho</a>
+ * @version $Id$
+ */
+public class DatasourceAvailableHealthCheckValidator implements HealthCheckValidator
+{
+ private static final Log log = LogFactory.getLog(DatasourceAvailableHealthCheckValidator.class);
+ public static boolean isInfoEnabled = log.isInfoEnabled();
+ public static boolean isDebugEnabled = log.isDebugEnabled();
+ /**
+ * Spring property resources. Maps the database name to a list of datasources.
+ */
+ private Map resources;
+ /**
+ * Spring property numberOfRetries.
+ */
+ private int numberOfRetries;
+ /**
+ * Spring property retryDelay.
+ */
+ private long retryDelay;
+ /**
+ * Spring property stopValidationOnError.
+ */
+ private boolean stopValidationOnError;
+ /**
+ * Spring property requireAllValid.
+ */
+ private boolean requireAllValid;
+
+ public DatasourceAvailableHealthCheckValidator(Map resources, int numberOfRetries, long retryDelay,
+ boolean stopValidationOnError, boolean requireAllValid)
+ {
+ this.resources = resources;
+ this.numberOfRetries = numberOfRetries;
+ this.retryDelay = retryDelay;
+ this.stopValidationOnError = stopValidationOnError;
+ this.requireAllValid = requireAllValid;
+ }
+
+ public HealthCheckValidatorResult validate()
+ {
+ if (isDebugEnabled)
+ {
+ log.debug("Starting method: DatasourceAvailableHealthCheckValidator.validate()");
+ }
+ HealthCheckValidatorResult result = new HealthCheckValidatorResult();
+ boolean allDataSourcesStatus = true;
+ StringBuffer messages = new StringBuffer();
+ try
+ {
+ Set dbNames = resources.keySet();
+ for (Iterator it = dbNames.iterator(); it.hasNext();)
+ {
+ String dbName = (String) it.next();
+ if (messages.length()>0)
+ {
+ messages.append(LINE_SEPARATOR);
+ }
+ messages.append(dbName + ":");
+ if (isDebugEnabled)
+ {
+ log.debug("Database: " + dbName);
+ }
+ DataSourcesValidationBean dsBean = (DataSourcesValidationBean) resources.get(dbName);
+ String validationQuery = dsBean.getValidationQuery();
+ boolean dbStatus = true;
+ for (Iterator it2 = dsBean.getDatasources().iterator(); it2.hasNext();)
+ {
+ DataSource ds = (DataSource) it2.next();
+ dbStatus = isDatasourceValid(validationQuery, ds);
+ if (dbStatus)
+ {
+ // the ds is up
+ if (!requireAllValid)
+ {
+ // only 1 datasource is required to be available so
+ // we can interrupt this loop
+ break;
+ }
+ }
+ else
+ {
+ // the ds is not available
+ if (requireAllValid)
+ {
+ // all datasource(s) need to be available so
+ // we can interrupt this loop
+ break;
+ }
+ }
+ }
+ if (dbStatus)
+ {
+ messages.append(" is up");
+ }
+ else
+ {
+ // none of the datasources for this DB is available so
+ // fail the whole validator
+ allDataSourcesStatus = false;
+ messages.append(" is down");
+ }
+ if (stopValidationOnError && !allDataSourcesStatus)
+ {
+ // the validator has failed and stopValidationOnError
+ // is true so we have to interrupt the validator
+ break;
+ }
+ }
+ if (!allDataSourcesStatus)
+ {
+ result.setHealthCheckResult(HealthCheckValidatorResult.VALIDATOR_FAILED);
+ }
+ }
+ catch (Exception e)
+ {
+ // if any exceptions occur, even runtime exceptions, return a failed
+ // result
+ log.error("Exception while running the datasource validator", e);
+ result.setHealthCheckResult(HealthCheckValidatorResult.VALIDATOR_FAILED);
+ messages.append("Exception while running the datasource validator: " + e.getMessage());
+ }
+ if (isDebugEnabled)
+ {
+ log.debug(messages.toString());
+ }
+ result.setResultMessage(messages.toString());
+ return result;
+ }
+
+ /**
+ * Checks is a datasource is valid or not by executing a <code>validationQuery</code>
+ *
+ * @param validationQuery
+ * The query to be executed
+ * @param dataSource
+ * The datasource to be checked
+ * @return Whether the datasource is available or not
+ */
+ private boolean isDatasourceValid(String validationQuery, DataSource dataSource)
+ {
+ boolean dsStatus = true;
+ Connection con = null;
+ Statement stmt = null;
+ try
+ {
+ con = dataSource.getConnection();
+ stmt = con.createStatement();
+ stmt.execute(validationQuery);
+ }
+ catch (SQLException ex)
+ {
+ dsStatus = false;
+ log.error("The datasource is not available", ex);
+ }
+ finally
+ {
+ JdbcUtils.closeStatement(stmt);
+ JdbcUtils.closeConnection(con);
+ }
+ return dsStatus;
+ }
+
+ public int getNumberOfRetries()
+ {
+ return numberOfRetries;
+ }
+
+ public long getRetryDelay()
+ {
+ return retryDelay;
+ }
+}
\ No newline at end of file
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/DatasourceAvailableHealthCheckValidator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java?rev=667492&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java Fri Jun 13 05:02:11 2008
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+package org.apache.jetspeed.healthcheck.validators;
+
+import org.apache.jetspeed.pipeline.valve.HealthCheckValve;
+
+/**
+ * Interface to be implemented by validator classes which will be injected in {@link HealthCheckValve}.
+ *
+ * @author <a href="mailto:ruben.carvalho@fmr.com">Ruben Carvalho</a>
+ * @version $Id$
+ */
+public interface HealthCheckValidator
+{
+ static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ /**
+ * This method performs the validation and returns the status of the execution
+ *
+ * @return An instance of <code>HealthCheckValidatorResult</code> with the result code
+ */
+ HealthCheckValidatorResult validate();
+
+ /**
+ * This method returns the number of times the validate() method should be re-executed if it fails the first time.
+ *
+ * @return Number of times to re-execute validate()
+ */
+ int getNumberOfRetries();
+
+ /**
+ * This method returns the amount of time between each execution of the validate() method
+ *
+ * @return The amount of time between each execution of validate()
+ */
+ long getRetryDelay();
+}
\ No newline at end of file
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java?rev=667492&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java Fri Jun 13 05:02:11 2008
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+package org.apache.jetspeed.healthcheck.validators;
+
+/**
+ * This class is returned as the result of executing the validation method from a Validator class
+ *
+ * @author <a href="mailto:ruben.carvalho@fmr.com">Ruben Carvalho</a>
+ * @version $Id$
+ */
+public class HealthCheckValidatorResult
+{
+ /**
+ * Validator constant which indicates a successful validation
+ */
+ public static final int VALIDATOR_SUCCEEDED = 101;
+
+ /**
+ * Validator constant which indicates a failed validation
+ */
+ public static final int VALIDATOR_FAILED = 100;
+
+ /**
+ * Result code. One of <code>VALIDATOR_*</code>
+ */
+ private int healthCheckResult;
+
+ /**
+ * The result message
+ */
+ private String resultMessage;
+
+ public HealthCheckValidatorResult()
+ {
+ this.healthCheckResult = HealthCheckValidatorResult.VALIDATOR_SUCCEEDED;
+ this.resultMessage = "";
+ }
+
+ public HealthCheckValidatorResult(int healthCheckResult, String resultMessage)
+ {
+ this.healthCheckResult = healthCheckResult;
+ this.resultMessage = resultMessage;
+ }
+
+ /**
+ * This method returns the result of running <code>HealthCheckValidator.validate()</code>.<br> <br> The result
+ * has to be one of the constants VALIDATOR_*
+ *
+ * @return Result from the execution of the validate() method.
+ */
+ public int getHealthCheckResult()
+ {
+ return healthCheckResult;
+ }
+
+ /**
+ * Setter method for healthCheckResult
+ *
+ * @param healthCheckResult
+ * The new code for healthCheckResult
+ */
+ public void setHealthCheckResult(int healthCheckResult)
+ {
+ this.healthCheckResult = healthCheckResult;
+ }
+
+ /**
+ * This method returns a message for this validator's execution.<br> <br> This method should not be used to check
+ * if a validator ran successfully or not. That should be done by checking
+ * <code>healthCheckResult() == VALIDATOR_FAILED</code>
+ *
+ * @return The execution message (if any)
+ */
+ public String getResultMessage()
+ {
+ return resultMessage;
+ }
+
+ /**
+ * Setter method for resultMessage
+ *
+ * @param resultMessage
+ * The new result message
+ */
+ public void setResultMessage(String resultMessage)
+ {
+ this.resultMessage = resultMessage;
+ }
+}
\ No newline at end of file
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/HealthCheckValidatorResult.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java?rev=667492&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java Fri Jun 13 05:02:11 2008
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+package org.apache.jetspeed.healthcheck.validators;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.components.portletregistry.PortletRegistry;
+import org.apache.jetspeed.factory.PortletFactory;
+import org.apache.jetspeed.om.common.portlet.PortletApplication;
+
+/**
+ * Validator to check if the defined required applications have been initialised in the Jetspeed engine
+ *
+ * @author <a href="mailto:ruben.carvalho@fmr.com">Ruben Carvalho</a>
+ * @version $Id$
+ */
+public class PortletApplicationAvailableHeathCheckValidator implements HealthCheckValidator
+{
+ private static final Log log = LogFactory.getLog(PortletApplicationAvailableHeathCheckValidator.class);
+ public static boolean isInfoEnabled = log.isInfoEnabled();
+ public static boolean isDebugEnabled = log.isDebugEnabled();
+ /**
+ * Spring property numberOfRetries.
+ */
+ private int numberOfRetries;
+ /**
+ * Spring property retryDelay.
+ */
+ private long retryDelay;
+ /**
+ * Spring property retryDelay.
+ */
+ private List requiredPortletApplications;
+ /**
+ * Spring property portletRegistry.
+ */
+ private PortletRegistry portletRegistry;
+ /**
+ * Spring property portletFactory.
+ */
+ private PortletFactory portletFactory;
+ /**
+ * Spring property stopValidationOnError.
+ */
+ private boolean stopValidationOnError;
+
+ public PortletApplicationAvailableHeathCheckValidator(List requiredPortletApplications, int numberOfRetries,
+ long retryDelay, PortletRegistry portletRegistry,
+ PortletFactory portletFactory, boolean stopValidationOnError)
+ {
+ this.requiredPortletApplications = requiredPortletApplications;
+ this.numberOfRetries = numberOfRetries;
+ this.retryDelay = retryDelay;
+ this.portletRegistry = portletRegistry;
+ this.portletFactory = portletFactory;
+ this.stopValidationOnError = stopValidationOnError;
+ }
+
+ public HealthCheckValidatorResult validate()
+ {
+ HealthCheckValidatorResult result = new HealthCheckValidatorResult();
+ boolean allPAStatus = true;
+ StringBuffer messages = new StringBuffer();
+ try
+ {
+ // check if all required apps have been registered and are
+ // available.
+ for (Iterator it = requiredPortletApplications.iterator(); it.hasNext();)
+ {
+ // the portlet application name
+ String paName = (String) it.next();
+ if (isDebugEnabled)
+ {
+ log.debug("Checking portlet application: " + paName);
+ }
+ if (messages.length()>0)
+ {
+ messages.append(LINE_SEPARATOR);
+ }
+ messages.append(paName + ": ");
+ PortletApplication pa = portletRegistry.getPortletApplication(paName);
+ boolean thisPAStatus = portletFactory.isPortletApplicationRegistered(pa);
+ if (thisPAStatus)
+ {
+ messages.append("is up");
+ }
+ else
+ {
+ messages.append("is down");
+ allPAStatus = false;
+ if (stopValidationOnError)
+ {
+ break;
+ }
+ }
+ }
+ if (!allPAStatus)
+ {
+ result.setHealthCheckResult(HealthCheckValidatorResult.VALIDATOR_FAILED);
+ }
+ }
+ catch (Exception e)
+ {
+ // if any exceptions occur, even runtime exceptions, return a failed
+ // result
+ log.error("Exception while running the portlet application validator", e);
+ result.setHealthCheckResult(HealthCheckValidatorResult.VALIDATOR_FAILED);
+ messages.append("Exception while running the portlet application validator: " + e.getMessage());
+ }
+ if (isDebugEnabled)
+ {
+ log.debug(messages.toString());
+ }
+ result.setResultMessage(messages.toString());
+ return result;
+ }
+
+ public int getNumberOfRetries()
+ {
+ return numberOfRetries;
+ }
+
+ public long getRetryDelay()
+ {
+ return retryDelay;
+ }
+}
\ No newline at end of file
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/healthcheck/validators/PortletApplicationAvailableHeathCheckValidator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java?rev=667492&view=auto
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java (added)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java Fri Jun 13 05:02:11 2008
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+package org.apache.jetspeed.pipeline.valve;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.healthcheck.validators.HealthCheckValidator;
+import org.apache.jetspeed.healthcheck.validators.HealthCheckValidatorResult;
+import org.apache.jetspeed.pipeline.PipelineException;
+import org.apache.jetspeed.pipeline.valve.AbstractValve;
+import org.apache.jetspeed.pipeline.valve.ValveContext;
+import org.apache.jetspeed.request.RequestContext;
+
+/**
+ * Valve that performs a health check based on the validators injected from a Spring configutation file.
+ *
+ * @author <a href="mailto:ruben.carvalho@fmr.com">Ruben Carvalho</a>
+ * @version $Id$
+ */
+public class HealthCheckValve extends AbstractValve
+{
+ static final String LINE_SEPARATOR = System.getProperty("line.separator");
+ private static final Log log = LogFactory.getLog(HealthCheckValve.class);
+ public static boolean isInfoEnabled = log.isInfoEnabled();
+ public static boolean isDebugEnabled = log.isDebugEnabled();
+ /**
+ * Spring property validators. List of validators to be executed by this Valve
+ */
+ private List validators;
+ /**
+ * Spring property successMessage. This String is added to the response if all validators succeed
+ */
+ private String successMessage;
+ /**
+ * Spring property failMessage. The string to be added to the response if one of the validators fails
+ */
+ private String failMessage;
+ /**
+ * Spring property addValidationMessagesToResponse. Whether messages returned in the validator result should be
+ * appended to the http response or not
+ */
+ private boolean addValidationMessagesToResponse;
+ /**
+ * Spring property stopValidationOnError. Whether the valve execution should continue or stop if one validator fails
+ */
+ private boolean stopValidationOnError;
+
+ public HealthCheckValve(List validators, String successMessage, String failMessage,
+ boolean addValidationMessagesToResponse, boolean stopValidationOnError)
+ {
+ this.validators = validators;
+ this.successMessage = successMessage;
+ this.failMessage = failMessage;
+ this.addValidationMessagesToResponse = addValidationMessagesToResponse;
+ this.stopValidationOnError = stopValidationOnError;
+ }
+
+ public void invoke(RequestContext request, ValveContext context) throws PipelineException
+ {
+ if (isDebugEnabled)
+ {
+ log.debug("Starting method: HealthCheckValve.invoke()");
+ }
+ List messages = new ArrayList();
+ HttpServletResponse response = request.getResponse();
+ boolean healthCheckStatus = true;
+ try
+ {
+ // iterate all validators and execute its validate method.
+ for (Iterator it = validators.iterator(); it.hasNext();)
+ {
+ HealthCheckValidator hcv = (HealthCheckValidator) it.next();
+ if (isDebugEnabled)
+ {
+ log.debug("Starting validator execution: " + hcv.getClass().getName());
+ }
+ HealthCheckValidatorResult result = null;
+ // execute the validator until it succeeds or until the
+ // number of retries runs out
+ for (int i = 0; i <= hcv.getNumberOfRetries(); i++)
+ {
+ result = hcv.validate();
+ if (isDebugEnabled)
+ {
+ log.debug("Validator execution: " +
+ (result.getHealthCheckResult() == HealthCheckValidatorResult.VALIDATOR_SUCCEEDED));
+ }
+ if (result.getHealthCheckResult() == HealthCheckValidatorResult.VALIDATOR_SUCCEEDED)
+ {
+ // the validator succeeded so stop this loop and go for
+ // the next validator
+ break;
+ }
+ if ((i + 1) <= hcv.getNumberOfRetries())
+ {
+ // the validator did not succeed. If there are any
+ // retries left and if a retry delay was defined then
+ // wait before re-executing the same validator
+ if (hcv.getRetryDelay() > 0)
+ {
+ try
+ {
+ Thread.sleep(hcv.getRetryDelay());
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+ }
+ if (result != null)
+ {
+ if (addValidationMessagesToResponse)
+ {
+ messages.add(result.getResultMessage());
+ }
+ if (!(result.getHealthCheckResult() == HealthCheckValidatorResult.VALIDATOR_SUCCEEDED))
+ {
+ // this validator failed so mark the health check as
+ // failed
+ healthCheckStatus = false;
+ if (stopValidationOnError)
+ {
+ // stopValidationOnError is true so stop the health
+ // check
+ break;
+ }
+ }
+ }
+ }
+ PrintWriter pw = response.getWriter();
+ if (healthCheckStatus)
+ {
+ // if all validators succeeded, add the success message to the
+ // http response
+ pw.write(successMessage);
+ }
+ else
+ {
+ pw.write(failMessage);
+ }
+ if (addValidationMessagesToResponse)
+ {
+ for (Iterator it = messages.iterator(); it.hasNext();)
+ {
+ pw.write(LINE_SEPARATOR + (String)it.next());
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ log.error("Exception while running HealthCheckValve", e);
+ // if any exceptions occur, even runtime exceptions, simply reset
+ // the response's buffer and add any messages to it (if required)
+ try
+ {
+ if (!response.isCommitted())
+ {
+ response.resetBuffer();
+ }
+ PrintWriter pw = response.getWriter();
+ pw.write(failMessage);
+ if (addValidationMessagesToResponse)
+ {
+ for (Iterator it = messages.iterator(); it.hasNext();)
+ {
+ pw.write(LINE_SEPARATOR + (String)it.next());
+ }
+ }
+ }
+ catch (Exception e1)
+ {
+ log.error("Exception while running HealthCheckValve", e1);
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal/src/java/org/apache/jetspeed/pipeline/valve/HealthCheckValve.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/assembly/pipelines.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/assembly/pipelines.xml?rev=667492&r1=667491&r2=667492&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/assembly/pipelines.xml (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/assembly/pipelines.xml Fri Jun 13 05:02:11 2008
@@ -378,6 +378,112 @@
<bean id="cleanupPortalURLValve"
class="org.apache.jetspeed.container.url.impl.CleanPathInfoEncodedNavStateFromPortalURLValve"/>
+ <bean id="healthCheckValve" class="org.apache.jetspeed.pipeline.valve.HealthCheckValve" init-method="initialize">
+ <constructor-arg index="0">
+ <!-- Validators -->
+ <list>
+ <ref bean="portletApplicationValidator" />
+ <ref bean="databaseValidator" />
+ </list>
+ </constructor-arg>
+ <constructor-arg index="1">
+ <!-- successMessage -->
+ <value>THE SERVER IS UP</value>
+ </constructor-arg>
+ <constructor-arg index="2">
+ <!-- failMessage -->
+ <value>THE SERVER IS DOWN</value>
+ </constructor-arg>
+ <constructor-arg index="3">
+ <!-- addValidationMessagesToResponse -->
+ <value>false</value>
+ </constructor-arg>
+ <constructor-arg index="4">
+ <!-- stopValidationOnError -->
+ <value>true</value>
+ </constructor-arg>
+ </bean>
+
+ <bean id="portletApplicationValidator" class="org.apache.jetspeed.healthcheck.validators.PortletApplicationAvailableHeathCheckValidator">
+ <constructor-arg index="0">
+ <!-- requiredPortletApplications -->
+ <list>
+ <!-- names of the portlet applications which are required to be available -->
+ <!--
+ <value>j2-admin</value>
+ -->
+ </list>
+ </constructor-arg>
+ <constructor-arg index="1">
+ <!-- numberOfRetries -->
+ <value>0</value>
+ </constructor-arg>
+ <constructor-arg index="2">
+ <!-- retryDelay -->
+ <value>0</value>
+ </constructor-arg>
+ <constructor-arg index="3">
+ <!-- portletRegistry -->
+ <ref bean="portletRegistry" />
+ </constructor-arg>
+ <constructor-arg index="4">
+ <!-- portletFactory -->
+ <ref bean="portletFactory" />
+ </constructor-arg>
+ <constructor-arg index="5">
+ <!-- stopValidationOnError -->
+ <value>true</value>
+ </constructor-arg>
+ </bean>
+
+ <bean id="databaseValidator" class="org.apache.jetspeed.healthcheck.validators.DatasourceAvailableHealthCheckValidator">
+ <constructor-arg index="0">
+ <!-- resources -->
+ <map>
+ <!-- entries to DataSourceValidationBean instances which should be checked
+ see (commented out) example below -->
+ <!--
+ <entry key="mydata">
+ <bean class="org.apache.jetspeed.healthcheck.validators.DataSourcesValidationBean">
+ <constructor-arg index="0">
+ <!- - Oracle database specific validation query - ->
+ <value>SELECT * FROM SYS.DUAL</value>
+ </constructor-arg>
+ <constructor-arg index="1">
+ <list>
+ <!- - list of datasources (all using the same validation query)
+ which needs to be validated - ->
+ <bean id="mydataDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+ <property name="jndiName" value="java:comp/env/jdbc/mydata1" />
+ </bean>
+ <bean id="mydataDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+ <property name="jndiName" value="java:comp/env/jdbc/mydata2" />
+ </bean>
+ </list>
+ </constructor-arg>
+ </bean>
+ </entry>
+ -->
+ </map>
+ </constructor-arg>
+ <constructor-arg index="1">
+ <!-- numberOfRetries -->
+ <value>0</value>
+ </constructor-arg>
+ <constructor-arg index="2">
+ <!-- retryDelay -->
+ <value>0</value>
+ </constructor-arg>
+ <constructor-arg index="3">
+ <!-- stopValidationOnError -->
+ <value>true</value>
+ </constructor-arg>
+ <constructor-arg index="4">
+ <!-- requireAllValid -->
+ <value>true</value>
+ </constructor-arg>
+ </bean>
+
<bean id="jetspeed-pipeline"
class="org.apache.jetspeed.pipeline.JetspeedPipeline"
init-method="initialize"
@@ -638,6 +744,17 @@
</constructor-arg>
</bean>
+ <bean id="healthcheck-pipeline" class="org.apache.jetspeed.pipeline.JetspeedPipeline" init-method="initialize">
+ <constructor-arg>
+ <value>HealthCheckPipeline</value>
+ </constructor-arg>
+ <constructor-arg>
+ <list>
+ <ref bean="healthCheckValve" />
+ </list>
+ </constructor-arg>
+ </bean>
+
<bean id='pipeline-map'
class='java.util.HashMap'>
@@ -681,6 +798,9 @@
<entry key='/dtconfigure'>
<value>dtconfigure-pipeline</value>
</entry>
+ <entry key='/healthcheck'>
+ <value>healthcheck-pipeline</value>
+ </entry>
</map>
</constructor-arg>
</bean>
Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/web.xml?rev=667492&r1=667491&r2=667492&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/web.xml (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/src/webapp/WEB-INF/web.xml Fri Jun 13 05:02:11 2008
@@ -215,6 +215,12 @@
</servlet-name>
<url-pattern>/dtconfigure/*</url-pattern>
</servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>
+ jetspeed
+ </servlet-name>
+ <url-pattern>/healthcheck/*</url-pattern>
+ </servlet-mapping>
<!-- Map *.vm files to Velocity -->
<servlet-mapping>
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org