You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kalumet-commits@incubator.apache.org by jb...@apache.org on 2011/10/29 09:37:45 UTC
svn commit: r1194852 [1/3] - in /incubator/kalumet/trunk: ./ agent/
agent/src/main/java/org/apache/kalumet/agent/updater/
Author: jbonofre
Date: Sat Oct 29 09:37:44 2011
New Revision: 1194852
URL: http://svn.apache.org/viewvc?rev=1194852&view=rev
Log:
Add new updaters.
Added:
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ArchiveUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ConfigurationFileUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ContentManagerUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/DatabaseUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/J2EEApplicationServerUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/J2EEApplicationUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/JDBCConnectionPoolUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/JDBCDataSourceUpdater.java
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/JMSConnectionFactoryUpdater.java
Modified:
incubator/kalumet/trunk/agent/pom.xml
incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/SoftwareUpdater.java
incubator/kalumet/trunk/pom.xml
Modified: incubator/kalumet/trunk/agent/pom.xml
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/agent/pom.xml?rev=1194852&r1=1194851&r2=1194852&view=diff
==============================================================================
--- incubator/kalumet/trunk/agent/pom.xml (original)
+++ incubator/kalumet/trunk/agent/pom.xml Sat Oct 29 09:37:44 2011
@@ -50,6 +50,10 @@
<artifactId>org.apache.kalumet.common</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.kalumet.controller</groupId>
+ <artifactId>org.apache.kalumet.controller.core</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.kalumet</groupId>
<artifactId>org.apache.kalumet.utils</artifactId>
</dependency>
Added: incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ArchiveUpdater.java
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ArchiveUpdater.java?rev=1194852&view=auto
==============================================================================
--- incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ArchiveUpdater.java (added)
+++ incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ArchiveUpdater.java Sat Oct 29 09:37:44 2011
@@ -0,0 +1,372 @@
+/*
+ * 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.kalumet.agent.updater;
+
+import org.apache.kalumet.FileManipulator;
+import org.apache.kalumet.FileManipulatorException;
+import org.apache.kalumet.KalumetException;
+import org.apache.kalumet.agent.Configuration;
+import org.apache.kalumet.agent.utils.EventUtils;
+import org.apache.kalumet.controller.core.J2EEApplicationServerController;
+import org.apache.kalumet.controller.core.J2EEApplicationServerControllerFactory;
+import org.apache.kalumet.model.*;
+import org.apache.kalumet.model.update.UpdateLog;
+import org.apache.kalumet.model.update.UpdateMessage;
+import org.apache.kalumet.utils.NotifierUtils;
+import org.apache.kalumet.utils.PublisherUtils;
+import org.apache.kalumet.utils.VariableUtils;
+import org.apache.kalumet.ws.client.ArchiveClient;
+import org.apache.kalumet.ws.client.ClientException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * J2EE application archive updater.
+ */
+public class ArchiveUpdater {
+
+ private static final transient Logger LOGGER = LoggerFactory.getLogger(ArchiveUpdater.class);
+
+ /**
+ * Wrapper method to update J2EE application archive.
+ *
+ * @param environmentName the target environment name.
+ * @param serverName the target J2EE application server name.
+ * @param applicationName the target J2EE application name.
+ * @param archiveName the target archive name.
+ * @param delegation flag indicating if the update is a delegation from another agent (true), or a client call (false).
+ * @throws UpdateException in case of update failure.
+ */
+ public static void update(String environmentName, String serverName, String applicationName, String archiveName, boolean delegation) throws KalumetException {
+ LOGGER.info("Archive {} update requested by WS", archiveName);
+
+ // load configuration.
+ LOGGER.debug("Loading configuration");
+ Kalumet kalumet = Kalumet.digeste(Configuration.CONFIG_LOCATION);
+ Environment environment = kalumet.getEnvironment(environmentName);
+ if (environment == null) {
+ LOGGER.error("Environment {} is not found in the configuration", environmentName);
+ throw new KalumetException("Environment " + environmentName + " is not found in the configuration");
+ }
+ J2EEApplicationServer server = environment.getJ2EEApplicationServers().getJ2EEApplicationServer(serverName);
+ if (server == null) {
+ LOGGER.error("J2EE application server {} is not found in environment {}", serverName, environmentName);
+ throw new KalumetException("J2EE application server " + serverName + " is not found in environment " + environmentName);
+ }
+ J2EEApplication application = server.getJ2EEApplication(applicationName);
+ if (application == null) {
+ LOGGER.error("J2EE application {} is not found in J2EE application server {}", applicationName, serverName);
+ throw new KalumetException("J2EE application " + applicationName + " is not found in J2EE application server " + serverName);
+ }
+ Archive archive = application.getArchive(archiveName);
+ if (archive == null) {
+ LOGGER.error("Archive {} is not found in J2EE application {}", archiveName, applicationName);
+ throw new KalumetException("Archive " + archiveName + " is not found in J2EE application " + applicationName);
+ }
+
+ // update configuration cache
+ LOGGER.debug("Updating configuration cache");
+ Configuration.CONFIG_CACHE = kalumet;
+
+ // post journal event
+ EventUtils.post(environment, "UPDATE", "Archive " + archiveName + " update requested by WS");
+ // create an update logger
+ UpdateLog updateLog = new UpdateLog("Archive " + archiveName + " update in progress ...", environment.getName(), environment);
+
+ if (!delegation) {
+ // the update is a client call
+ LOGGER.info("Send a notification and waiting for the count down");
+ EventUtils.post(environment, "UPDATE", "Send a notification and waiting for the count down");
+ NotifierUtils.waitAndNotify(environment);
+ }
+
+ try {
+ // call the updater method
+ ArchiveUpdater.update(environment, server, application, archive, updateLog);
+ } catch (Exception e) {
+ LOGGER.error("Archive {} update failed", archiveName, e);
+ EventUtils.post(environment, "ERROR", "Archive " + archiveName + " update failed: " + e.getMessage());
+ if (!delegation) {
+ updateLog.setStatus("Archive " + archiveName + " update failed");
+ updateLog.addUpdateMessage(new UpdateMessage("error", "Archive " + archiveName + " update failed: " + e.getMessage()));
+ LOGGER.info("Publishing update report");
+ PublisherUtils.publish(environment);
+ }
+ throw new UpdateException("Archive " + archiveName + " update failed", e);
+ }
+
+ // update completed
+ LOGGER.info("Archive {} updated", archive.getName());
+ EventUtils.post(environment, "UPDATE", "Archive " + archive.getName() + " updated");
+
+ if (!delegation) {
+ if (updateLog.isUpdated()) {
+ updateLog.setStatus("Archive " + archive.getName() + " updated");
+ } else {
+ updateLog.setStatus("Archive " + archive.getName() + " already up to date");
+ }
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Archive " + archive.getName() + " updated"));
+ LOGGER.info("Publishing update report");
+ PublisherUtils.publish(environment);
+ }
+ }
+
+ /**
+ * Updates a archive.
+ *
+ * @param environment the target <code>Environment</code>.
+ * @param server the target <code>J2EEApplicationServer</code>.
+ * @param application the target JZEE <code>Application</code>.
+ * @param archive the target <code>Archive</code>.
+ * @param updateLog the <code>UpdateLog</code> to use.
+ */
+ public static void update(Environment environment, J2EEApplicationServer server, J2EEApplication application, Archive archive, UpdateLog updateLog) throws UpdateException {
+ LOGGER.info("Updating archive {}", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Updating archive " + archive.getName()));
+ EventUtils.post(environment, "UPDATE", "Updating archive " + archive.getName());
+
+ if (!archive.isActive()) {
+ LOGGER.info("Archive {} is inactive, so not updated", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Archive " + archive.getName() + " is inactive, so not updated"));
+ EventUtils.post(environment, "UPDATE", "Archive " + archive.getName() + " is inactive, so not updated");
+ return;
+ }
+
+ // check to delegate the update
+ if (archive.getAgent() != null && archive.getAgent().trim().length() > 0 && !archive.getAgent().equals(Configuration.AGENT_ID)) {
+ LOGGER.info("Delegating archive {} update to agent {}", archive.getName(), archive.getAgent());
+ EventUtils.post(environment, "UPDATE", "Delegating archive " + archive.getName() + " update to agent " + archive.getAgent());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Delegating archive " + archive.getName() + " update to agent " + archive.getAgent()));
+ Agent delegationAgent = Configuration.CONFIG_CACHE.getAgent(archive.getAgent());
+ if (delegationAgent == null) {
+ LOGGER.error("Agent {} is not found in the configuration", archive.getAgent());
+ throw new UpdateException("Agent " + archive.getAgent() + " is not found in the configuration");
+ }
+ try {
+ LOGGER.debug("Call archive WS");
+ ArchiveClient client = new ArchiveClient(delegationAgent.getHostname(), delegationAgent.getPort());
+ client.update(environment.getName(), server.getName(), application.getName(), archive.getName(), true);
+ } catch (ClientException clientException) {
+ LOGGER.error("Archive " + archive.getName() + " update failed", clientException);
+ throw new UpdateException("Archive " + archive.getName() + " update failed", clientException);
+ }
+ return;
+ }
+
+ // construct the archiveUri
+ String archiveUri = VariableUtils.replace(archive.getUri(), environment.getVariables());
+ if (!FileManipulator.protocolExists(archiveUri)) {
+ // the archive URI is relative (no prefix protocol), use the
+ // application URI to construct the VFS URI
+ LOGGER.debug("Archive URI is relative (no protocol prefix) to J2EE application URI");
+ archiveUri = FileManipulator.format(VariableUtils.replace(application.getUri(), environment.getVariables())) + "!/" + archiveUri;
+ }
+ // get the application cache directory
+ String applicationCacheDir = null;
+ // initialize the file manipulator instance
+ FileManipulator fileManipulator = null;
+ try {
+ applicationCacheDir = FileManipulator.createJ2EEApplicationCacheDir(environment, application);
+ fileManipulator = FileManipulator.getInstance();
+ } catch (FileManipulatorException e) {
+ LOGGER.error("Can't create J2EE application {} cache directory", application.getName(), e);
+ throw new UpdateException("Can't create J2EE application " + application.getName() + " cache directory", e);
+ }
+ // define the archive cache location
+ String archiveCache = applicationCacheDir + "/" + archive.getName();
+ // define the archive installation URI
+ String archiveInstallation = null;
+ if (archive.getPath() == null || archive.getPath().trim().length() < 1) {
+ LOGGER.error("Archive {} path is not defined", archive.getName());
+ throw new UpdateException("Archive " + archive.getName() + " path is not defined");
+ }
+ // the archive path is defined, use it
+ archiveInstallation = VariableUtils.replace(archive.getPath(), environment.getVariables());
+ // get the J2EE application server controller
+ LOGGER.debug("Getting the J2EE application server controller");
+ J2EEApplicationServerController controller = null;
+ try {
+ controller = J2EEApplicationServerControllerFactory.getController(environment, server);
+ } catch (KalumetException e) {
+ LOGGER.error("Can't get the J2EE application server {} controller", server.getName(), e);
+ throw new UpdateException("Can't get the J2EE application server " + server.getName() + " controller", e);
+ }
+ // check if the archive is already deployed
+ try {
+ if (controller.isJ2EEApplicationDeployed(archiveInstallation, archive.getName())) {
+ // the archive is already deployed, check for update
+ LOGGER.info("Archive {} is already deployed, check for update", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Archive " + archive.getName() + " is already deployed, check for update"));
+ EventUtils.post(environment, "UPDATE", "Archive " + archive.getName() + " is already deployed, check for update");
+ if (!fileManipulator.checksumEquals(archiveUri, archiveCache)) {
+ // the archive file is different from the copy in the
+ // application directory, perform an update
+ // update the cache
+ fileManipulator.copy(archiveUri, archiveCache);
+ LOGGER.info("Archive {} (located {}) is different from the cache, performing update", archive.getName(), archiveUri);
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Archive " + archive.getName() + " (located " + archiveUri + ") is different from the cache, performing update"));
+ EventUtils.post(environment, "UPDATE", "Archive " + archive.getName() + " (located " + archiveUri + ") is different from the cache, performing update");
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Copy " + archiveUri + " to " + archiveInstallation));
+ EventUtils.post(environment, "UPDATE", "Copy " + archiveUri + " to " + archiveInstallation);
+ // update the archive path
+ fileManipulator.copy(archiveUri, archiveInstallation);
+ // undeploy the archive
+ LOGGER.info("Undeploying archive {}", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Undeploying archive " + archive.getName()));
+ EventUtils.post(environment, "UPDATE", "Undeploying archive " + archive.getName());
+ controller.undeployJ2EEApplication(archiveInstallation, archive.getName());
+ // deploy the archive
+ LOGGER.info("Deploying archive {}", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Deploying archive " + archive.getName()));
+ EventUtils.post(environment, "UPDATE", "Deploying archive " + archive.getName());
+ controller.deployJ2EEApplication(archiveInstallation, archive.getName(), archive.getClassloaderorder(), archive.getClassloaderpolicy(), VariableUtils.replace(archive.getVhost(), environment.getVariables()));
+ LOGGER.info("Archive {} updated", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Archive " + archive.getName() + " updated"));
+ EventUtils.post(environment, "UPDATE", "Archive " + archive.getName() + " updated");
+ updateLog.setUpdated(true);
+ }
+ } else {
+ // the archive is not deployed
+ LOGGER.info("Archive {} is not deployed, deploying it", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Archive " + archive.getName() + " is not deployed, deploying it"));
+ EventUtils.post(environment, "UPDATE", "Archive " + archive.getName() + " is not deployed, deploying it");
+ // copy the archive agent locally
+ fileManipulator.copy(archiveUri, archiveCache);
+ // copy the archive to the destination path
+ fileManipulator.copy(archiveUri, archiveInstallation);
+ // deploy the archive
+ LOGGER.info("Deploying archive {}", archive.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Deploying archive " + archive.getName()));
+ EventUtils.post(environment, "UPDATE", "Deploying archive " + archive.getName());
+ controller.deployJ2EEApplication(archiveInstallation, archive.getName(), archive.getClassloaderorder(), archive.getClassloaderpolicy(), VariableUtils.replace(archive.getVhost(), environment.getVariables()));
+ updateLog.setUpdated(true);
+ }
+ // as some J2EE application server (like IBM WebSphere) change the archive file during deployment, update
+ // the local archive with a original copy (for next update)
+ LOGGER.debug("Restoring the original archive (before deployment) from {}", archiveUri);
+ fileManipulator.copy(archiveUri, archiveCache);
+ // check if the J2EE application is deployed (it should be)
+ if (!controller.isJ2EEApplicationDeployed(archiveInstallation, archive.getName())) {
+ LOGGER.error("Archive {} is not deployed whereas it should be. Please check the J2EE application server logs", archive.getName());
+ throw new UpdateException("Archive " + archive.getName() + " is not deployed whereas it should be. Please check the J2EE application server logs");
+ }
+ } catch (Exception e) {
+ // the archive update has failed
+ LOGGER.error("Archive {} update failed", archive.getName(), e);
+ try {
+ fileManipulator.delete(archiveCache);
+ } catch (FileManipulatorException fileManipulatorException) {
+ LOGGER.warn("Can't delete " + archiveCache, fileManipulatorException);
+ }
+ throw new UpdateException("Archive " + archive.getName() + " update failed", e);
+ }
+ }
+
+ /**
+ * Wrapper method to check if a archive is up to date or not via WS.
+ *
+ * @param environmentName the target environment name.
+ * @param serverName the target J2EE application server name.
+ * @param applicationName the target J2EE application name.
+ * @param archiveName the target archive name.
+ * @return true if the archive is up to date, false else.
+ * @throws KalumetException in case of status check failure
+ */
+ public static boolean check(String environmentName, String serverName, String applicationName, String archiveName) throws KalumetException {
+ LOGGER.info("Checking status of archive {} via WS", archiveName);
+ // load configuration
+ LOGGER.debug("Load configuration");
+ Kalumet kalumet = Kalumet.digeste(Configuration.CONFIG_LOCATION);
+ Environment environment = kalumet.getEnvironment(environmentName);
+ if (environment == null) {
+ LOGGER.error("Environment {} is not found in the configuration", environmentName);
+ throw new KalumetException("Environment " + environmentName + " is not found in the configuration");
+ }
+ J2EEApplicationServer applicationServer = environment.getJ2EEApplicationServers().getJ2EEApplicationServer(serverName);
+ if (applicationServer == null) {
+ LOGGER.error("J2EE application server {} is not found in environment {}", serverName, environmentName);
+ throw new KalumetException("J2EE application server " + serverName + " is not found in environment " + environmentName);
+ }
+ J2EEApplication application = applicationServer.getJ2EEApplication(applicationName);
+ if (application == null) {
+ LOGGER.error("J2EE application {} is not found in J2EE application server {}", applicationName, serverName);
+ throw new KalumetException("J2EE application " + applicationName + " is not found in J2EE application server " + serverName);
+ }
+ Archive archive = application.getArchive(archiveName);
+ if (archive == null) {
+ LOGGER.error("Archive {} is not found in J2EE application {}", archiveName, applicationName);
+ throw new KalumetException("Archive " + archiveName + " is not found in J2EE application " + applicationName);
+ }
+
+ // check if the check should be delegated to another agent
+ if (archive.getAgent() != null && archive.getAgent().trim().length() > 0 && !archive.getAgent().equals(Configuration.AGENT_ID)) {
+ // the check needs to be delegated to another agent
+ LOGGER.info("Delegating archive {} status check to agent {}", archive.getName(), archive.getAgent());
+ Agent agentDelegation = kalumet.getAgent(archive.getAgent());
+ if (agentDelegation == null) {
+ LOGGER.error("Agent {} is not found in the configuration", archive.getName());
+ throw new KalumetException("Agent " + archive.getAgent() + " is not found in the configuration");
+ }
+ // call the service
+ ArchiveClient client = new ArchiveClient(agentDelegation.getHostname(), agentDelegation.getPort());
+ return client.check(environmentName, serverName, applicationName, archiveName);
+ }
+
+ // initialize file manipulator
+ LOGGER.debug("Initializing file manipulator");
+ FileManipulator fileManipulator = FileManipulator.getInstance();
+
+ // get J2EE application server controller
+ LOGGER.debug("Getting J2EE application server controller");
+ J2EEApplicationServerController controller = J2EEApplicationServerControllerFactory.getController(environment, applicationServer);
+
+ // get application cache directory
+ LOGGER.debug("Getting application cache directory");
+ String applicationCacheDirectory = FileManipulator.createJ2EEApplicationCacheDir(environment, application);
+
+ // construct the archive URI
+ String archiveUri = VariableUtils.replace(archive.getUri(), environment.getVariables());
+ if (!FileManipulator.protocolExists(archiveUri)) {
+ // the archive URI is relative (doesn't contain the protocol prefix), construct the URI using the application URI
+ archiveUri = VariableUtils.replace(application.getUri(), environment.getVariables()) + "!/" + archiveUri;
+ }
+
+ // get the archive cache
+ String archiveCache = applicationCacheDirectory + "/" + archive.getName();
+
+ // get the archive installation path
+ if (archive.getPath() == null || archive.getPath().trim().length() < 1) {
+ LOGGER.error("Archive {} path is not defined", archive.getName());
+ throw new KalumetException("Archive " + archive.getName() + " path is not defined");
+ }
+ String archiveInstallation = VariableUtils.replace(archive.getPath(), environment.getVariables());
+
+ if (controller.isJ2EEApplicationDeployed(archiveInstallation, archive.getName())) {
+ // check if the archive is deployed or not
+ if (fileManipulator.checksumEquals(archiveUri, archiveCache)) {
+ // archive URI and cache are the same
+ LOGGER.debug("Archive URI and agent cache are the same");
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
Added: incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ConfigurationFileUpdater.java
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ConfigurationFileUpdater.java?rev=1194852&view=auto
==============================================================================
--- incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ConfigurationFileUpdater.java (added)
+++ incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ConfigurationFileUpdater.java Sat Oct 29 09:37:44 2011
@@ -0,0 +1,328 @@
+/*
+ * 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.kalumet.agent.updater;
+
+import org.apache.kalumet.FileManipulator;
+import org.apache.kalumet.FileManipulatorException;
+import org.apache.kalumet.KalumetException;
+import org.apache.kalumet.agent.Configuration;
+import org.apache.kalumet.agent.utils.EventUtils;
+import org.apache.kalumet.model.*;
+import org.apache.kalumet.model.update.UpdateLog;
+import org.apache.kalumet.model.update.UpdateMessage;
+import org.apache.kalumet.utils.NotifierUtils;
+import org.apache.kalumet.utils.PublisherUtils;
+import org.apache.kalumet.utils.VariableUtils;
+import org.apache.kalumet.ws.client.ClientException;
+import org.apache.kalumet.ws.client.ConfigurationFileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+
+/**
+ * J2EE application configuration file updater.
+ */
+public class ConfigurationFileUpdater {
+
+ private static final transient Logger LOGGER = LoggerFactory.getLogger(ConfigurationFileUpdater.class);
+
+ /**
+ * Updates a <code>ConfigurationFile</code>.
+ *
+ * @param environment the target <code>Environment</code>.
+ * @param server the target <code>J2EEApplicationServer</code>.
+ * @param application the target <code>J2EEApplication</code>.
+ * @param configurationFile the target <code>ConfigurationFile</code>.
+ * @param updateLog the <code>UpdateLog</code> to use.
+ */
+ public static void update(Environment environment, J2EEApplicationServer server, J2EEApplication application, ConfigurationFile configurationFile, UpdateLog updateLog) throws UpdateException {
+ LOGGER.info("Updating configuration file {}", configurationFile.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Updating configuration file " + configurationFile.getName()));
+ EventUtils.post(environment, "UPDATE", "Updating configuration file " + configurationFile.getName());
+
+ if (!configurationFile.isActive()) {
+ LOGGER.info("Configuration file {} is inactive, so not updated", configurationFile.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Configuration file " + configurationFile.getName() + " is inactive, so not updated"));
+ EventUtils.post(environment, "UPDATE", "Configuration file " + configurationFile.getName() + " is inactive, so not updated");
+ return;
+ }
+
+ // check for update delegation
+ if (configurationFile.getAgent() != null && configurationFile.getAgent().trim().length() > 0 && !configurationFile.getAgent().equals(Configuration.AGENT_ID)) {
+ LOGGER.info("Delegating the configuration file {} update to agent {}", configurationFile.getName(), configurationFile.getAgent());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Delegating the configuration file " + configurationFile.getName() + " update to agent " + configurationFile.getAgent()));
+ EventUtils.post(environment, "UPDATE", "Delegating the configuration file " + configurationFile.getName() + " update to agent " + configurationFile.getAgent());
+ Agent delegationAgent = Configuration.CONFIG_CACHE.getAgent(configurationFile.getAgent());
+ if (delegationAgent == null) {
+ // the delegation agent is not found
+ LOGGER.error("Agent {} is not found in the configuration", configurationFile.getAgent());
+ throw new UpdateException("Agent " + configurationFile.getAgent() + " is not found in the configuration");
+ }
+ try {
+ LOGGER.debug("Call the configuration file WS");
+ ConfigurationFileClient client = new ConfigurationFileClient(delegationAgent.getHostname(), delegationAgent.getPort());
+ client.update(environment.getName(), server.getName(), application.getName(), configurationFile.getName(), true);
+ } catch (ClientException clientException) {
+ // delegation update has failed
+ LOGGER.error("Configuration file {} update failed", configurationFile.getName(), clientException);
+ throw new UpdateException("Configuration file " + configurationFile.getName() + " update failed", clientException);
+ }
+ return;
+ }
+
+ String configurationFileUri = VariableUtils.replace(configurationFile.getUri(), environment.getVariables());
+ if (!FileManipulator.protocolExists(configurationFileUri)) {
+ // the configuration file URI is relative, construct the URI using the J2EE application URI
+ LOGGER.debug("The configuration file URI is relative to the J2EE application URI");
+ configurationFileUri = FileManipulator.format(VariableUtils.replace(application.getUri(), environment.getVariables())) + "!/" + configurationFileUri;
+ }
+
+ // get a file manipulator
+ FileManipulator fileManipulator = null;
+ try {
+ LOGGER.debug("Initializing file manipulator");
+ fileManipulator = FileManipulator.getInstance();
+ } catch (FileManipulatorException fileManipulatorException) {
+ LOGGER.error("Can't initialize file manipulator", fileManipulatorException);
+ throw new UpdateException("Can't initialize file manipulator", fileManipulatorException);
+ }
+
+ // get the application working directory
+ String applicationCacheDir = null;
+ try {
+ LOGGER.debug("Initializing application cache directory");
+ applicationCacheDir = FileManipulator.createJ2EEApplicationCacheDir(environment, application);
+ } catch (FileManipulatorException fileManipulatorException) {
+ LOGGER.error("Can't create J2EE application {} cache directory", application.getName(), fileManipulatorException);
+ throw new UpdateException("Can't create J2EE application " + application.getName() + " cache directory", fileManipulatorException);
+ }
+
+ String configurationFileCache = applicationCacheDir + "/config/" + configurationFile.getName();
+ try {
+ // copy the configuration file in the application cache directory
+ LOGGER.debug("Copying the configuration file {} to the application cache directory", configurationFile.getName());
+ fileManipulator.copy(configurationFileUri, configurationFileCache);
+ } catch (FileManipulatorException fileManipulatorException) {
+ LOGGER.error("Can't copy {} to {}", new Object[]{configurationFileUri, configurationFileCache}, fileManipulatorException);
+ throw new UpdateException("Can't copy " + configurationFileUri + " to " + configurationFileCache, fileManipulatorException);
+ }
+
+ // change mappings in the configuration file
+ LOGGER.debug("Replacing mappings key/value");
+ for (Iterator mappingIterator = configurationFile.getMappings().iterator(); mappingIterator.hasNext(); ) {
+ Mapping mapping = (Mapping) mappingIterator.next();
+ FileManipulator.searchAndReplace(mapping.getKey(), VariableUtils.replace(mapping.getValue(), environment.getVariables()), configurationFileCache);
+ }
+
+ // compare the configuration file with the target one
+ try {
+ if (!fileManipulator.contentEquals(configurationFileCache, VariableUtils.replace(configurationFile.getPath(), environment.getVariables()))) {
+ // the configuration file has changed
+ LOGGER.debug("Configuration file {} has changed", configurationFile.getName());
+ fileManipulator.copy(configurationFileCache, VariableUtils.replace(configurationFile.getPath(), environment.getVariables()));
+ updateLog.setStatus("Update performed");
+ updateLog.setUpdated(true);
+ LOGGER.info("Configuration file {} updated", configurationFile.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Configuration file " + configurationFile.getName() + " updated"));
+ EventUtils.post(environment, "UPDATE", "Configuration file " + configurationFile.getName() + " updated");
+ }
+ } catch (Exception e) {
+ // the configuration file update failed, delete from the cache
+ try {
+ fileManipulator.delete(configurationFileCache);
+ } catch (FileManipulatorException fileManipulatorException) {
+ LOGGER.warn("Can't delete {}", configurationFile.getName(), fileManipulatorException);
+ }
+ LOGGER.error("Configuration file {} update failed", configurationFile.getName(), e);
+ throw new UpdateException("Configuration file " + configurationFile.getName() + " update failed", e);
+ }
+ }
+
+ /**
+ * Wrapper method to update a configuration file via WS.
+ *
+ * @param environmentName the target environment name.
+ * @param serverName the target J2EE application server name.
+ * @param applicationName the target J2EE application name.
+ * @param configurationFileName the target configuration file name.
+ * @param delegation flag indicating if the call is made by another agent (true), or by a client (false).
+ * @throws KalumetException in case of update error.
+ */
+ public static void update(String environmentName, String serverName, String applicationName, String configurationFileName, boolean delegation) throws KalumetException {
+ LOGGER.info("Configuration file {} update requested by WS", configurationFileName);
+
+ // load configuration
+ LOGGER.debug("Loading configuration");
+ Kalumet kalumet = Kalumet.digeste(Configuration.CONFIG_LOCATION);
+ Environment environment = kalumet.getEnvironment(environmentName);
+ if (environment == null) {
+ LOGGER.error("Environment {} is not found in the configuration", environmentName);
+ throw new KalumetException("Environment " + environmentName + " is not found in the configuration");
+ }
+ J2EEApplicationServer applicationServer = environment.getJ2EEApplicationServers().getJ2EEApplicationServer(serverName);
+ if (applicationServer == null) {
+ LOGGER.error("J2EE application server {} is not found in environment {}", serverName, environmentName);
+ throw new KalumetException("J2EE application server " + serverName + " is not found in environment " + environmentName);
+ }
+ J2EEApplication application = applicationServer.getJ2EEApplication(applicationName);
+ if (application == null) {
+ LOGGER.error("J2EE application {} is not found in J2EE application server {}", applicationName, serverName);
+ throw new KalumetException("J2EE application " + applicationName + " is not found in J2EE application server " + serverName);
+ }
+ ConfigurationFile configurationFile = application.getConfigurationFile(configurationFileName);
+ if (configurationFile == null) {
+ LOGGER.error("Configuration file {} is not found in J2EE application {}", configurationFileName, applicationName);
+ throw new KalumetException("Configuration file " + configurationFileName + " is not found in J2EE application " + applicationName);
+ }
+
+ // update cache
+ LOGGER.debug("Updating configuration cache");
+ Configuration.CONFIG_CACHE = kalumet;
+
+ // post event and create update logger
+ EventUtils.post(environment, "UPDATE", "Configuration file " + configurationFile.getName() + " update requested by WS");
+ UpdateLog updateLog = new UpdateLog("Configuration file " + configurationFile.getName() + " update in progress ...", environment.getName(), environment);
+
+ // send and wait a notification if it's not a delegation
+ if (!delegation) {
+ // it's a client call
+ LOGGER.info("Send a notification and waiting for the count down");
+ EventUtils.post(environment, "UPDATE", "Send a notification and waiting for the count down");
+ NotifierUtils.waitAndNotify(environment);
+ }
+
+ try {
+ // call the updater method
+ LOGGER.debug("Call configuration file updater");
+ ConfigurationFileUpdater.update(environment, applicationServer, application, configurationFile, updateLog);
+ } catch (Exception e) {
+ LOGGER.error("Configuration file {} update failed", configurationFile.getName(), e);
+ EventUtils.post(environment, "ERROR", "Configuration file " + configurationFile.getName() + " update failed: " + e.getMessage());
+ if (!delegation) {
+ // it's a client call, send a publisher
+ updateLog.setStatus("Configuration file " + configurationFile.getName() + " update failed");
+ updateLog.addUpdateMessage(new UpdateMessage("error", "Configuration file " + configurationFile.getName() + " update failed: " + e.getMessage()));
+ PublisherUtils.publish(environment);
+ }
+ throw new UpdateException("Configuration file " + configurationFile.getName() + " update FAILED: " + e.getMessage(), e);
+ }
+
+ LOGGER.info("Configuration file {} updated", configurationFile.getName());
+ EventUtils.post(environment, "UPDATE", "Configuration file " + configurationFile.getName() + " updated");
+ if (!delegation) {
+ if (updateLog.isUpdated()) {
+ updateLog.setStatus("Configuration file " + configurationFile.getName() + " updated");
+ } else {
+ updateLog.setStatus("Configuration file " + configurationFile.getName() + " already up to date");
+ }
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Configuration file " + configurationFile.getName() + " updated"));
+ LOGGER.info("Publishing update report");
+ PublisherUtils.publish(environment);
+ }
+ }
+
+ /**
+ * Wrapper method to check if a configuration file is update to date or not via WS.
+ *
+ * @param environmentName the target environment name.
+ * @param serverName the target J2EE application server name.
+ * @param applicationName the target J2EE application name.
+ * @param configurationFileName the target configuration file name.
+ * @return true if the configuration file is up to date, false else.
+ * @throws KalumetException in case of error during configuration file check.
+ */
+ public static boolean check(String environmentName, String serverName, String applicationName, String configurationFileName) throws KalumetException {
+ LOGGER.info("Configuration file {} status check requested by WS", configurationFileName);
+
+ // load configuration.
+ LOGGER.debug("Loading configuration");
+ Kalumet kalumet = Kalumet.digeste(Configuration.CONFIG_LOCATION);
+
+ Environment environment = kalumet.getEnvironment(environmentName);
+ if (environment == null) {
+ LOGGER.error("Environment {} is not found in the configuration", environmentName);
+ throw new KalumetException("Environment " + environmentName + " is not found in the configuration");
+ }
+ J2EEApplicationServer applicationServer = environment.getJ2EEApplicationServers().getJ2EEApplicationServer(serverName);
+ if (applicationServer == null) {
+ LOGGER.error("J2EE application server {} is not found in environment {}", serverName, environmentName);
+ throw new KalumetException("J2EE application server " + serverName + " is not found in environment " + environmentName);
+ }
+ J2EEApplication application = applicationServer.getJ2EEApplication(applicationName);
+ if (application == null) {
+ LOGGER.error("J2EE application {} is not found in J2EE application server {}", applicationName, serverName);
+ throw new KalumetException("J2EE application " + applicationName + " is not found in J2EE application server " + serverName);
+ }
+ ConfigurationFile configurationFile = application.getConfigurationFile(configurationFileName);
+ if (configurationFile == null) {
+ LOGGER.error("Configuration file {} is not found in J2EE application {}", configurationFileName, applicationName);
+ throw new KalumetException("Configuration file " + configurationFileName + " is not found in J2EE application " + applicationName);
+ }
+
+ if (configurationFile.getAgent() != null && configurationFile.getAgent().trim().length() > 0 && !configurationFile.getAgent().equals(Configuration.AGENT_ID)) {
+ // the check needs to be delegate to another agent
+ LOGGER.info("Delegating configuration file {} check to agent {}", configurationFile.getName(), configurationFile.getAgent());
+ Agent agentDelegation = Configuration.CONFIG_CACHE.getAgent(configurationFile.getAgent());
+ if (agentDelegation == null) {
+ LOGGER.error("Agent {} is not found in the configuration", configurationFile.getAgent());
+ throw new KalumetException("Agent " + configurationFile.getAgent() + " is not found in the configuration");
+ }
+ // call the service
+ ConfigurationFileClient client = new ConfigurationFileClient(agentDelegation.getHostname(), agentDelegation.getPort());
+ return client.check(environmentName, serverName, applicationName, configurationFileName);
+ }
+
+ // initialize the file manipulator.
+ LOGGER.debug("Initializing file manipulator");
+ FileManipulator fileManipulator = FileManipulator.getInstance();
+
+ // constructs the configuration file URI.
+ String configurationFileUri = VariableUtils.replace(configurationFile.getUri(), environment.getVariables());
+ if (!FileManipulator.protocolExists(configurationFileUri)) {
+ // the configuration file URI doesn't contain protocol prefix,
+ // constructs the configuration file URI using the application URI
+ LOGGER.debug("Configuration file {} URI is relative to the J2EE application one", configurationFile.getName());
+ configurationFileUri = FileManipulator.format(VariableUtils.replace(application.getUri(), environment.getVariables())) + "!/" + configurationFileUri;
+ }
+
+ // get the application cache directory.
+ LOGGER.debug("Creating the application cache directory");
+ String applicationCacheDir = FileManipulator.createJ2EEApplicationCacheDir(environment, application);
+
+ // get the configuration file cache.
+ LOGGER.debug("Creating the configuration file cache location");
+ String configurationFileCache = applicationCacheDir + "/config/" + configurationFile.getName();
+
+ // copy the configuration file in the application cache directory
+ LOGGER.debug("Copying the configuration file {} to the application cache directory", configurationFile.getName());
+ fileManipulator.copy(configurationFileUri, configurationFileCache);
+
+ // change mappings into the configuration file.
+ LOGGER.debug("Replacing mappings key/value");
+ for (Iterator mappingIterator = configurationFile.getMappings().iterator(); mappingIterator.hasNext(); ) {
+ Mapping mapping = (Mapping) mappingIterator.next();
+ FileManipulator.searchAndReplace(mapping.getKey(), VariableUtils.replace(mapping.getValue(), environment.getVariables()), configurationFileCache);
+ }
+
+ // compare the configuration file with the target one.
+ return fileManipulator.contentEquals(configurationFileCache, VariableUtils.replace(configurationFile.getPath(), environment.getVariables()));
+ }
+
+}
Added: incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ContentManagerUpdater.java
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ContentManagerUpdater.java?rev=1194852&view=auto
==============================================================================
--- incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ContentManagerUpdater.java (added)
+++ incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/ContentManagerUpdater.java Sat Oct 29 09:37:44 2011
@@ -0,0 +1,201 @@
+/*
+ * 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.kalumet.agent.updater;
+
+import org.apache.kalumet.KalumetException;
+import org.apache.kalumet.agent.Configuration;
+import org.apache.kalumet.agent.utils.EventUtils;
+import org.apache.kalumet.model.*;
+import org.apache.kalumet.model.update.UpdateLog;
+import org.apache.kalumet.model.update.UpdateMessage;
+import org.apache.kalumet.utils.NotifierUtils;
+import org.apache.kalumet.utils.PublisherUtils;
+import org.apache.kalumet.utils.VariableUtils;
+import org.apache.kalumet.ws.client.ClientException;
+import org.apache.kalumet.ws.client.ContentManagerClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+/**
+ * Content manager updater.
+ */
+public class ContentManagerUpdater {
+
+ private static final transient Logger LOGGER = LoggerFactory.getLogger(ContentManagerUpdater.class);
+
+ /**
+ * Update a content manager.
+ *
+ * @param environment the target <code>Environment</code>.
+ * @param server the target <code>J2EEApplicationServer</code>.
+ * @param application the target <code>J2EEApplication</code>.
+ * @param contentManager the target <code>ContentManager</code>.
+ * @param updateLog the <code>UpdateLog</code> to use.
+ * @throws UpdateException in case of update failure.
+ */
+ public static void update(Environment environment, J2EEApplicationServer server, J2EEApplication application, ContentManager contentManager, UpdateLog updateLog) throws UpdateException {
+ LOGGER.info("Updating content manager {}", contentManager.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Updating content manager " + contentManager.getName()));
+ EventUtils.post(environment, "UPDATE", "Updating content manager " + contentManager.getName());
+
+ if (!contentManager.isActive()) {
+ // the content manager is not active
+ LOGGER.info("Content manager {} is inactive, so not updated", contentManager.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Content manager " + contentManager.getName() + " is inactive, so not updated"));
+ EventUtils.post(environment, "UPDATE", "Content manager " + contentManager.getName() + " is inactive, so not updated");
+ return;
+ }
+
+ if (contentManager.getAgent() != null && contentManager.getAgent().trim().length() > 0 && !contentManager.getAgent().equals(Configuration.AGENT_ID)) {
+ // the content manager update is delegated to another agent
+ LOGGER.info("Delegating content manager {} update to agent {}", contentManager.getName(), contentManager.getAgent());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Delegating content manager " + contentManager.getName() + " update to agent " + contentManager.getAgent()));
+ EventUtils.post(environment, "UPDATE", "Delegating content manager " + contentManager.getName() + " update to agent " + contentManager.getAgent());
+ Agent delegationAgent = Configuration.CONFIG_CACHE.getAgent(contentManager.getAgent());
+ if (delegationAgent == null) {
+ // the content manager agent is not found in the configuration
+ LOGGER.error("Agent {} is not found in the configuration", contentManager.getAgent());
+ throw new UpdateException("Agent " + contentManager.getAgent() + " is not found in the configuration");
+ }
+ try {
+ // call agent WebService
+ LOGGER.debug("Calling content manager WebService WS");
+ ContentManagerClient client = new ContentManagerClient(delegationAgent.getHostname(), delegationAgent.getPort());
+ client.update(environment.getName(), server.getName(), application.getName(), contentManager.getName(), true);
+ } catch (ClientException clientException) {
+ LOGGER.error("Content manager {} update failed", contentManager.getName(), clientException);
+ throw new UpdateException("Content manager " + contentManager.getName() + " update failed", clientException);
+ }
+ return;
+ }
+
+ try {
+ LOGGER.debug("Loading content manager class name");
+ Class contentManagerClass = Class.forName(VariableUtils.replace(contentManager.getClassname(), environment.getVariables()));
+ Object contentManagerObject = contentManagerClass.newInstance();
+ // call method properties
+ for (Iterator propertyIterator = contentManager.getProperties().iterator(); propertyIterator.hasNext(); ) {
+ Property property = (Property) propertyIterator.next();
+ Method method = contentManagerClass.getMethod("set" + VariableUtils.replace(property.getName(), environment.getVariables()), new Class[]{String.class});
+ method.invoke(contentManagerObject, new Object[]{VariableUtils.replace(property.getValue(), environment.getVariables())});
+ }
+ // call main method
+ Method mainMethod = contentManagerClass.getMethod("main", new Class[]{});
+ mainMethod.invoke(contentManagerObject, new Object[]{});
+ LOGGER.info("Content manager {} updated", contentManager.getName());
+ updateLog.setStatus("update performed");
+ updateLog.setUpdated(true);
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Content manager " + contentManager.getName() + " updated"));
+ EventUtils.post(environment, "UPDATE", "Content manager " + contentManager.getName() + " updated");
+ } catch (Exception e) {
+ LOGGER.error("Content manager {} update failed", contentManager.getName(), e);
+ throw new UpdateException("Content manager " + contentManager.getName() + " update failed", e);
+ }
+ }
+
+ /**
+ * Wrapper method to update a content manager via WS.
+ *
+ * @param environmentName the target environment name.
+ * @param serverName the target J2EE application server name.
+ * @param applicationName the target J2E application name.
+ * @param contentManagerName the target content manager name.
+ * @param delegation flag indicating if the update is called by another agent (true) or by a client (false).
+ * @throws KalumetException in case of update failure.
+ */
+ public static void update(String environmentName, String serverName, String applicationName, String contentManagerName, boolean delegation) throws KalumetException {
+ LOGGER.info("Content manager {} update requested by WS", contentManagerName);
+
+ // load configuration.
+ LOGGER.debug("Loading configuration");
+ Kalumet kalumet = Kalumet.digeste(Configuration.CONFIG_LOCATION);
+
+ // looking for component objects.
+ Environment environment = kalumet.getEnvironment(environmentName);
+ if (environment == null) {
+ LOGGER.error("Environment {} is not found in the configuration", environmentName);
+ throw new KalumetException("Environment " + environmentName + " is not found in the configuration");
+ }
+ J2EEApplicationServer applicationServer = environment.getJ2EEApplicationServers().getJ2EEApplicationServer(serverName);
+ if (applicationServer == null) {
+ LOGGER.error("J2EE application server {} is not found in environment {}", serverName, environment.getName());
+ throw new KalumetException("J2EE application server " + serverName + " is not found in environment " + environment.getName());
+ }
+ J2EEApplication application = applicationServer.getJ2EEApplication(applicationName);
+ if (application == null) {
+ LOGGER.error("J2EE application {} is not found in J2EE application server {}", applicationName, applicationServer.getName());
+ throw new KalumetException("J2EE application " + applicationName + " is not found in J2EE application server " + applicationServer.getName());
+ }
+ ContentManager contentManager = application.getContentManager(contentManagerName);
+ if (contentManager == null) {
+ LOGGER.error("Content manager {} is not found in J2EE application {}", contentManagerName, application.getName());
+ throw new KalumetException("Content manager " + contentManagerName + " is not found in J2EE application " + application.getName());
+ }
+
+ // update configuration cache.
+ LOGGER.debug("Updating configuration cache");
+ Configuration.CONFIG_CACHE = kalumet;
+
+ // post event and create an update log
+ EventUtils.post(environment, "UPDATE", "Content manager " + contentManager.getName() + " update requested by WS");
+ UpdateLog updateLog = new UpdateLog("Content manager " + contentManager.getName() + " update in progress ...", environment.getName(), environment);
+
+ if (!delegation) {
+ // the update is a client call,
+ // send a notification and waiting for the count down
+ LOGGER.info("Send a notification and waiting for the count down");
+ EventUtils.post(environment, "UPDATE", "Send a notification and waiting for the count down");
+ NotifierUtils.waitAndNotify(environment);
+ }
+
+ try {
+ // call the content manager updater
+ LOGGER.debug("Call content manager updater");
+ ContentManagerUpdater.update(environment, applicationServer, application, contentManager, updateLog);
+ } catch (Exception e) {
+ LOGGER.error("Content manager " + contentManager.getName() + " update failed", e);
+ EventUtils.post(environment, "ERROR", "Content manager " + contentManager.getName() + " update failed: " + e.getMessage());
+ if (!delegation) {
+ updateLog.setStatus("Content manager " + contentManager.getName() + " update failed");
+ updateLog.addUpdateMessage(new UpdateMessage("error", "Content manager " + contentManager.getName() + " update failed: " + e.getMessage()));
+ PublisherUtils.publish(environment);
+ }
+ throw new UpdateException("Content manager " + contentManager.getName() + " update failed", e);
+ }
+
+ // update completed
+ LOGGER.info("Content manager {} updated", contentManager.getName());
+ EventUtils.post(environment, "UPDATE", "Content manager " + contentManager.getName() + " updated");
+ if (!delegation) {
+ if (updateLog.isUpdated()) {
+ updateLog.setStatus("Content manager " + contentManager.getName() + " updated");
+ } else {
+ updateLog.setStatus("Content manager " + contentManager.getName() + " already up to date");
+ }
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Content manager " + contentManager.getName() + " updated"));
+ LOGGER.info("Publishing update report");
+ PublisherUtils.publish(environment);
+ }
+
+ }
+
+}
Added: incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/DatabaseUpdater.java
URL: http://svn.apache.org/viewvc/incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/DatabaseUpdater.java?rev=1194852&view=auto
==============================================================================
--- incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/DatabaseUpdater.java (added)
+++ incubator/kalumet/trunk/agent/src/main/java/org/apache/kalumet/agent/updater/DatabaseUpdater.java Sat Oct 29 09:37:44 2011
@@ -0,0 +1,202 @@
+/*
+ * 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.kalumet.agent.updater;
+
+import org.apache.kalumet.KalumetException;
+import org.apache.kalumet.agent.Configuration;
+import org.apache.kalumet.agent.utils.EventUtils;
+import org.apache.kalumet.model.*;
+import org.apache.kalumet.model.update.UpdateLog;
+import org.apache.kalumet.model.update.UpdateMessage;
+import org.apache.kalumet.utils.NotifierUtils;
+import org.apache.kalumet.utils.PublisherUtils;
+import org.apache.kalumet.ws.client.ClientException;
+import org.apache.kalumet.ws.client.DatabaseClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+
+/**
+ * Database updater.
+ */
+public class DatabaseUpdater {
+
+ private static final transient Logger LOGGER = LoggerFactory.getLogger(DatabaseUpdater.class);
+
+ /**
+ * Updates a database.
+ *
+ * @param environment the target <code>Environment</code>.
+ * @param server the target <code>J2EEApplicationServer</code>.
+ * @param application the target <code>J2EEApplication</code>.
+ * @param database the target <code>Database</code>.
+ * @param updateLog the <code>UpdateLog</code> to use.
+ */
+ public static void update(Environment environment, J2EEApplicationServer server, J2EEApplication application, Database database, UpdateLog updateLog) throws UpdateException {
+ LOGGER.info("Updating database {}", database.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Updating database " + database.getName()));
+ EventUtils.post(environment, "UPDATE", "Updating database " + database.getName());
+
+ if (!database.isActive()) {
+ // database is not active
+ LOGGER.info("Database {} is inactive, so not updated", database.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Database " + database.getName() + " is inactive, so not updated"));
+ EventUtils.post(environment, "UPDATE", "Database " + database.getName() + " is inactive, so not updated");
+ return;
+ }
+
+ if (database.getAgent() != null && database.getAgent().trim().length() > 0 && !database.getAgent().equals(Configuration.AGENT_ID)) {
+ // database update delegated to another agent
+ LOGGER.info("Delegating database {} update to agent {}", database.getName(), database.getAgent());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Delegating database " + database.getName() + " update to agent " + database.getAgent()));
+ EventUtils.post(environment, "UPDATE", "Delegating database " + database.getName() + " update to agent " + database.getAgent());
+ Agent delegationAgent = Configuration.CONFIG_CACHE.getAgent(database.getAgent());
+ if (delegationAgent == null) {
+ // database agent is not found in configuration
+ LOGGER.error("Agent {} is not found in the configuration", database.getAgent());
+ throw new UpdateException("Agent " + database.getAgent() + " is not found in the configuration");
+ }
+ try {
+ // call WS
+ LOGGER.debug("Calling database WS");
+ DatabaseClient client = new DatabaseClient(delegationAgent.getHostname(), delegationAgent.getPort());
+ client.update(environment.getName(), server.getName(), application.getName(), database.getName(), true);
+ } catch (ClientException clientException) {
+ LOGGER.error("Database {} update failed", database.getName(), clientException);
+ throw new UpdateException("Database " + database.getName() + " update failed", clientException);
+ }
+ return;
+ }
+
+ // launch SQL scripts on the database
+ LOGGER.debug("Executing SQL scripts");
+ for (Iterator sqlScriptIterator = database.getSqlScripts().iterator(); sqlScriptIterator.hasNext(); ) {
+ SqlScript sqlScript = (SqlScript) sqlScriptIterator.next();
+ try {
+ SqlScriptUpdater.execute(environment, server, application, database, sqlScript, updateLog);
+ } catch (UpdateException updateException) {
+ // the SQL script execution failed
+ if (sqlScript.isBlocker()) {
+ // the SQL script is update blocker
+ LOGGER.error("SQL script {} execution failed", sqlScript.getName(), updateException);
+ updateLog.addUpdateMessage(new UpdateMessage("error", "SQL script " + sqlScript.getName() + " execution failed: " + updateException.getMessage()));
+ EventUtils.post(environment, "ERROR", "SQL script " + sqlScript.getName() + " execution failed: " + updateException.getMessage());
+ throw new UpdateException("SQL script " + sqlScript.getName() + " execution failed", updateException);
+ } else {
+ // the SQL script is not update blocker
+ LOGGER.warn("SQL script " + sqlScript.getName() + " execution failed", updateException);
+ updateLog.addUpdateMessage(new UpdateMessage("warn", "SQL script " + sqlScript.getName() + " execution failed: " + updateException.getMessage()));
+ updateLog.addUpdateMessage(new UpdateMessage("info", "SQL script " + sqlScript.getName() + " is not update blocker, update continues"));
+ EventUtils.post(environment, "WARN", "SQL script " + sqlScript.getName() + " execution failed: " + updateException.getMessage());
+ EventUtils.post(environment, "UPDATE", "SQL script " + sqlScript.getName() + " is not update blocker, update continues");
+ }
+ }
+ }
+
+ // update completed
+ LOGGER.info("Database {} updated", database.getName());
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Database " + database.getName() + " updated"));
+ EventUtils.post(environment, "UPDATE", "Database " + database.getName() + " updated");
+ }
+
+ /**
+ * Wrapper method to update a database via WS.
+ *
+ * @param environmentName the target environment name.
+ * @param serverName the target J2EE application server name.
+ * @param applicationName the target J2EE application name.
+ * @param databaseName the target database name.
+ * @param delegation true if the call is made by another agent, false if the call is made by a client.
+ * @throws KalumetException in case of update failure.
+ */
+ public static void update(String environmentName, String serverName, String applicationName, String databaseName, boolean delegation) throws KalumetException {
+ LOGGER.info("Database {} update requested by WS", databaseName);
+
+ // load configuration.
+ LOGGER.debug("Loading configuration");
+ Kalumet kalumet = Kalumet.digeste(Configuration.CONFIG_LOCATION);
+ Environment environment = kalumet.getEnvironment(environmentName);
+ if (environment == null) {
+ LOGGER.error("Environment {} is not found in the configuration", environmentName);
+ throw new KalumetException("Environment " + environmentName + " is not found in the configuration");
+ }
+ J2EEApplicationServer applicationServer = environment.getJ2EEApplicationServers().getJ2EEApplicationServer(serverName);
+ if (applicationServer == null) {
+ LOGGER.error("J2EE application server {} is not found in environment {}", serverName, environmentName);
+ throw new KalumetException("J2EE application server " + serverName + " is not found in environment " + environmentName);
+ }
+ J2EEApplication application = applicationServer.getJ2EEApplication(applicationName);
+ if (application == null) {
+ LOGGER.error("J2EE application {} is not found in J2EE application server {}", applicationName, serverName);
+ throw new KalumetException("J2EE application " + applicationName + " is not found in J2EE application server " + serverName);
+ }
+ Database database = application.getDatabase(databaseName);
+ if (database == null) {
+ LOGGER.error("Database {} is not found in J2EE application {}", databaseName, applicationName);
+ throw new KalumetException("Database " + databaseName + " is not found in J2EE application " + applicationName);
+ }
+
+ // update configuration cache.
+ LOGGER.debug("Updating configuration cache");
+ Configuration.CONFIG_CACHE = kalumet;
+
+ // post journal event
+ EventUtils.post(environment, "UPDATE", "Database " + databaseName + " update requested by WS");
+ // create an update logger
+ UpdateLog updateLog = new UpdateLog("Database " + databaseName + " update in progress ...", environment.getName(), environment);
+
+ if (!delegation) {
+ // the update is requested by a client
+ LOGGER.info("Send a notification and waiting for the count down");
+ EventUtils.post(environment, "UPDATE", "Send a notification and waiting for the count down");
+ NotifierUtils.waitAndNotify(environment);
+ }
+
+ try {
+ // call the updater
+ LOGGER.debug("Call database updater");
+ DatabaseUpdater.update(environment, applicationServer, application, database, updateLog);
+ } catch (Exception e) {
+ LOGGER.error("Database {} update failed", database.getName(), e);
+ EventUtils.post(environment, "ERROR", "Database " + database.getName() + " update failed: " + e.getMessage());
+ if (!delegation) {
+ updateLog.setStatus("Database " + database.getName() + " update failed");
+ updateLog.addUpdateMessage(new UpdateMessage("error", "Database " + database.getName() + " update failed: " + e.getMessage()));
+ PublisherUtils.publish(environment);
+ }
+ throw new UpdateException("Database " + database.getName() + " update failed", e);
+ }
+
+ // update completed
+ LOGGER.info("Database {} updated", database.getName());
+ EventUtils.post(environment, "UPDATE", "Database " + database.getName() + " updated");
+ if (!delegation) {
+ if (updateLog.isUpdated()) {
+ updateLog.setStatus("Database " + database.getName() + " updated");
+ } else {
+ updateLog.setStatus("Database " + database.getName() + " already up to date");
+ }
+ updateLog.addUpdateMessage(new UpdateMessage("info", "Database " + database.getName() + " updated"));
+ LOGGER.info("Publishing update report");
+ PublisherUtils.publish(environment);
+ }
+ }
+
+}