diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 06189df85b..572fdfbea1 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -1085,8 +1085,9 @@ sandbox_revertselected=Undo Selected sandbox_icon=Browse Website sandbox_snapshot=Create Snapshot sandbox_snapshot_info=Create a snaphost of this sandbox. -sandbox_remove=Delete Sandbox +sandbox_remove=Delete sandbox_refresh=Refresh +sandbox_deploy=Deploy & Preview import_website_content=Bulk Import title_browse_sandbox=Browse Sandbox sandbox_info=Use this view to browse the files and folders within the sandbox for a web project. @@ -1198,14 +1199,18 @@ revert_selected_confirm=Are you sure you want to undo the changes to the selecte revert_all_title=Undo All Items revert_all_desc=To undo the changes to all the files in the sandbox, click OK. revert_all_confirm=Are you sure you want to undo the changes to all files in the sandbox? -deploy_title=Deploy Snapshot -deploy_desc=Select the servers to deploy to and click OK. -deploy_destination=Select the destination servers to deploy to +deploy_snapshot_title=Deploy Snapshot +deploy_snapshot_desc=Select the servers to deploy to and click OK. +deploy_sandbox_title=Deploy Sandbox +deploy_sandbox_desc=Select a test server to deploy to and click OK. +deploy_destination=Select the destination server(s) to deploy to deploy_status=Snapshot {0} is being deployed in the background, refresh this page until the ''View Deployment Report'' link appears. deploying=Deploying... deploy_successful=Deployment Successful deploy_failed=Deployment Failed deploy_server_not_selected=This server has not been selected as the snapshot has already been deployed successfully. +deploy_test_server_not_available=No unallocated test servers are available. +deploy_test_server_allocated=The test server ''{0}'' is allocated to this sandbox. To preview the current deployment click the preview link below (if a URL has been provided) or to deploy the latest changes click the OK button. deploy_started=Started deploy_finished=Finished deployed_by=By @@ -1236,6 +1241,10 @@ deploy_automatically=Auto Deploy edit_deploy_server=Edit Deployment Server Details delete_deploy_server=Delete Deployment Server no_deploy_servers=No deployment servers have been configured. +add_alf_deploy_server_info=Provide details of the Alfresco Server Receiver to add +add_file_deploy_server_info=Provide details of the File System Receiver to add +edit_alf_deploy_server_info=Edit details of the Alfresco Server Receiver +edit_file_deploy_server_info=Edit details of the File System Receiver reason=Reason snapshot=Snapshot content_launch=Content Launch diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 367db22546..ee3488fad4 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -270,9 +270,13 @@ icon="/images/icons/revert_all_large.gif" title-id="revert_all_title" description-id="revert_all_desc" /> - + + + deployAttempts = null; + List deployAttempts = null; FacesContext context = FacesContext.getCurrentInstance(); Map request = context.getExternalContext().getRequestMap(); if (request.get(REQUEST_BEEN_DEPLOYED_KEY) == null) { - // see if there are any deployment attempts for the site + // see if there are any deployment attempts for the staging area NodeRef webProjectRef = this.getWebsite().getNodeRef(); - deployAttempts = getNodeService().getChildAssocs(webProjectRef, - WCMAppModel.ASSOC_DEPLOYMENTATTEMPT, RegexQNamePattern.MATCH_ALL); + String store = (String)nodeService.getProperty(webProjectRef, + WCMAppModel.PROP_AVMSTORE); + deployAttempts = DeploymentUtil.findDeploymentAttempts(store); // add a placeholder object in the request so we don't evaluate this again for this request request.put(REQUEST_BEEN_DEPLOYED_KEY, Boolean.TRUE); @@ -912,7 +913,7 @@ public class AVMBrowseBean implements IContextListener } else { - deployAttempts = (List)request.get(REQUEST_BEEN_DEPLOYED_RESULT); + deployAttempts = (List)request.get(REQUEST_BEEN_DEPLOYED_RESULT); } return (deployAttempts != null && deployAttempts.size() > 0); diff --git a/source/java/org/alfresco/web/bean/wcm/AVMUtil.java b/source/java/org/alfresco/web/bean/wcm/AVMUtil.java index 8ed5ca6417..d6e2790081 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMUtil.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMUtil.java @@ -809,44 +809,6 @@ public final class AVMUtil return webProjectNode; } - - /** - * Retrieves the NodeRef of the deploymentattempt node with the given id - * - * @param attemptId The deployattemptid of the node to be found - * @return The NodeRef of the deploymentattempt node or null if not found - */ - public static NodeRef findDeploymentAttempt(String attemptId) - { - FacesContext fc = FacesContext.getCurrentInstance(); - SearchService searchService = Repository.getServiceRegistry(fc).getSearchService(); - - // construct the query - String query = "@wca\\:deployattemptid:\"" + attemptId + "\""; - - NodeRef attempt = null; - ResultSet results = null; - try - { - // execute the query - results = searchService.query(Repository.getStoreRef(), - SearchService.LANGUAGE_LUCENE, query); - - if (results.length() == 1) - { - attempt = results.getNodeRef(0); - } - } - finally - { - if (results != null) - { - results.close(); - } - } - - return attempt; - } /** * Creates all directories for a path if they do not already exist. diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index 9276db5194..3956b71bf9 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java @@ -1175,7 +1175,7 @@ public class CreateWebsiteWizard extends BaseWizardBean this.currentDeployServer.setProperties(this.editedDeployServerProps); if (logger.isDebugEnabled()) - logger.debug("Updated deploy server config: " + this.currentDeployServer); + logger.debug("Saved transient deploy server config: " + this.currentDeployServer); // reset state this.currentDeployServer = null; diff --git a/source/java/org/alfresco/web/bean/wcm/DeploySnapshotDialog.java b/source/java/org/alfresco/web/bean/wcm/DeployWebsiteDialog.java similarity index 70% rename from source/java/org/alfresco/web/bean/wcm/DeploySnapshotDialog.java rename to source/java/org/alfresco/web/bean/wcm/DeployWebsiteDialog.java index 777bdedf5d..cbdded69df 100644 --- a/source/java/org/alfresco/web/bean/wcm/DeploySnapshotDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/DeployWebsiteDialog.java @@ -33,9 +33,10 @@ import java.util.Map; import javax.faces.context.FacesContext; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.actions.AVMDeploySnapshotAction; +import org.alfresco.repo.avm.actions.AVMDeployWebsiteAction; import org.alfresco.repo.domain.PropertyValue; import org.alfresco.sandbox.SandboxConstants; import org.alfresco.service.cmr.action.Action; @@ -51,25 +52,27 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * Deploys a web project snapshot to one or more remote servers. + * Deploys a website to one or more remote servers. * * @author gavinc */ -public class DeploySnapshotDialog extends BaseDialogBean +public class DeployWebsiteDialog extends BaseDialogBean { private static final long serialVersionUID = 62702082716235924L; protected int versionToDeploy; protected String[] deployTo; - protected String stagingStore; + protected String store; + protected String deployMode; protected NodeRef websiteRef; protected NodeRef webProjectRef; + protected boolean updateTestServer; protected AVMBrowseBean avmBrowseBean; transient private AVMService avmService; transient private ActionService actionService; - private static final Log logger = LogFactory.getLog(DeploySnapshotDialog.class); + private static final Log logger = LogFactory.getLog(DeployWebsiteDialog.class); // ------------------------------------------------------------------------------ // Dialog implementation @@ -81,16 +84,35 @@ public class DeploySnapshotDialog extends BaseDialogBean // setup context for dialog this.deployTo = null; - this.versionToDeploy = Integer.parseInt(parameters.get("version")); - this.avmBrowseBean.getDeploymentMonitorIds().clear(); - this.webProjectRef = this.avmBrowseBean.getWebsite().getNodeRef(); - this.stagingStore = this.avmBrowseBean.getStagingStore(); - String storeRoot = AVMUtil.buildSandboxRootPath(this.stagingStore); + String ver = parameters.get("version"); + if (ver != null && ver.length() > 0) + { + this.versionToDeploy = Integer.parseInt(ver); + } + else + { + this.versionToDeploy = -1; + } + + this.store = parameters.get("store"); + String storeRoot = AVMUtil.buildSandboxRootPath(this.store); this.websiteRef = AVMNodeConverter.ToNodeRef(this.versionToDeploy, storeRoot); + this.deployMode = (this.versionToDeploy == -1) ? + WCMAppModel.CONSTRAINT_TESTSERVER : WCMAppModel.CONSTRAINT_LIVESERVER; + + this.updateTestServer = false; + String updateTestServerParam = parameters.get("updateTestServer"); + if (updateTestServerParam != null) + { + this.updateTestServer = Boolean.parseBoolean(updateTestServerParam); + } + + this.avmBrowseBean.getDeploymentMonitorIds().clear(); + this.webProjectRef = this.avmBrowseBean.getWebsite().getNodeRef(); + if (logger.isDebugEnabled()) - logger.debug("Initialising dialog to deploy version " + this.versionToDeploy + - " of " + this.websiteRef.toString()); + logger.debug("Initialising dialog to deploy: " + this.websiteRef.toString()); } @SuppressWarnings("unchecked") @@ -102,18 +124,17 @@ public class DeploySnapshotDialog extends BaseDialogBean if (this.deployTo != null && this.deployTo.length > 0) { - NodeRef webProjectRef = this.avmBrowseBean.getWebsite().getNodeRef(); List selectedDeployToNames = new ArrayList(); // create a deploymentattempt node to represent this deployment String attemptId = GUID.generate(); Map props = new HashMap(8, 1.0f); props.put(WCMAppModel.PROP_DEPLOYATTEMPTID, attemptId); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTTYPE, WCMAppModel.CONSTRAINT_LIVESERVER); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTSTORE, this.stagingStore); + props.put(WCMAppModel.PROP_DEPLOYATTEMPTTYPE, this.deployMode); + props.put(WCMAppModel.PROP_DEPLOYATTEMPTSTORE, this.store); props.put(WCMAppModel.PROP_DEPLOYATTEMPTVERSION, this.versionToDeploy); props.put(WCMAppModel.PROP_DEPLOYATTEMPTTIME, new Date()); - NodeRef attempt = getNodeService().createNode(webProjectRef, + NodeRef attempt = getNodeService().createNode(this.webProjectRef, WCMAppModel.ASSOC_DEPLOYMENTATTEMPT, WCMAppModel.ASSOC_DEPLOYMENTATTEMPT, WCMAppModel.TYPE_DEPLOYMENTATTEMPT, props).getChildRef(); @@ -128,13 +149,33 @@ public class DeploySnapshotDialog extends BaseDialogBean // get all properties of the target server Map serverProps = getNodeService().getProperties(serverRef); - String serverUri = AVMDeploySnapshotAction.calculateServerUri(serverProps); + String serverUri = AVMDeployWebsiteAction.calculateServerUri(serverProps); String serverName = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERNAME); if (serverName == null || serverName.length() == 0) { serverName = serverUri; } + // if this is a test server deployment we need to allocate the + // test server to the current sandbox so it can re-use it and + // more importantly, no one else can. Before doing that however, + // we need to make sure no one else has taken the server since + // we selected it. + if (WCMAppModel.CONSTRAINT_TESTSERVER.equals(this.deployMode) && + this.updateTestServer == false) + { + String allocatedTo = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO); + if (allocatedTo != null) + { + throw new AlfrescoRuntimeException("testserver.taken", new Object[] {serverName}); + } + else + { + getNodeService().setProperty(serverRef, WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO, + this.store); + } + } + if (logger.isDebugEnabled()) logger.debug("Issuing deployment request for: " + serverName); @@ -150,11 +191,11 @@ public class DeploySnapshotDialog extends BaseDialogBean // create and execute the action asynchronously Map args = new HashMap(1, 1.0f); - args.put(AVMDeploySnapshotAction.PARAM_WEBSITE, webProjectRef); - args.put(AVMDeploySnapshotAction.PARAM_SERVER, serverRef); - args.put(AVMDeploySnapshotAction.PARAM_ATTEMPT, attempt); - args.put(AVMDeploySnapshotAction.PARAM_CALLBACK, monitor); - Action action = getActionService().createAction(AVMDeploySnapshotAction.NAME, args); + args.put(AVMDeployWebsiteAction.PARAM_WEBSITE, webProjectRef); + args.put(AVMDeployWebsiteAction.PARAM_SERVER, serverRef); + args.put(AVMDeployWebsiteAction.PARAM_ATTEMPT, attempt); + args.put(AVMDeployWebsiteAction.PARAM_CALLBACK, monitor); + Action action = getActionService().createAction(AVMDeployWebsiteAction.NAME, args); getActionService().executeAction(action, this.websiteRef, false, true); } else if (logger.isWarnEnabled()) @@ -169,8 +210,8 @@ public class DeploySnapshotDialog extends BaseDialogBean (Serializable)selectedDeployToNames); // set the deploymentattempid property on the store this deployment was for - getAvmService().deleteStoreProperty(this.stagingStore, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); - getAvmService().setStoreProperty(this.stagingStore, SandboxConstants.PROP_LAST_DEPLOYMENT_ID, + getAvmService().deleteStoreProperty(this.store, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); + getAvmService().setStoreProperty(this.store, SandboxConstants.PROP_LAST_DEPLOYMENT_ID, new PropertyValue(DataTypeDefinition.TEXT, attemptId)); // close this dialog and immediately open the monitorDeployment dialog @@ -178,6 +219,9 @@ public class DeploySnapshotDialog extends BaseDialogBean } else { + if (logger.isWarnEnabled()) + logger.warn("Deployment of '" + this.websiteRef.toString() + "' skipped as no servers were selected"); + return outcome; } } @@ -260,6 +304,16 @@ public class DeploySnapshotDialog extends BaseDialogBean return this.deployTo; } + /** + * Returns the type of server to deploy to, either 'live' or 'test'. + * + * @return The type of server to deploy to + */ + public String getDeployMode() + { + return this.deployMode; + } + /** * @return The NodeRef of the web project the deployment reports are being shown for */ @@ -268,6 +322,14 @@ public class DeploySnapshotDialog extends BaseDialogBean return this.webProjectRef; } + /** + * @return The store being deployed + */ + public String getStore() + { + return this.store; + } + /** * @return The version of the snapshot to deploy */ diff --git a/source/java/org/alfresco/web/bean/wcm/DeploymentUtil.java b/source/java/org/alfresco/web/bean/wcm/DeploymentUtil.java new file mode 100644 index 0000000000..5d6692f9c9 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/DeploymentUtil.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.bean.wcm; + +import java.util.ArrayList; +import java.util.List; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMAppModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.util.ISO9075; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Repository; + + +/** + * Helper methods for deployment + * + * @author Gavin Cornwell + */ +public final class DeploymentUtil +{ + public static List findDeploymentAttempts(String store) + { + FacesContext fc = FacesContext.getCurrentInstance(); + SearchService searchService = Repository.getServiceRegistry(fc).getSearchService(); + + // query for all deploymentattempt nodes with the deploymentattemptstore + // set to the given store id + StringBuilder query = new StringBuilder("@"); + query.append(NamespaceService.WCMAPP_MODEL_PREFIX); + query.append("\\:"); + query.append(WCMAppModel.PROP_DEPLOYATTEMPTSTORE.getLocalName()); + query.append(":\""); + query.append(store); + query.append("\""); + + ResultSet results = null; + List attempts = new ArrayList(); + try + { + // execute the query + results = searchService.query(Repository.getStoreRef(), + SearchService.LANGUAGE_LUCENE, query.toString()); + + for (NodeRef attempt : results.getNodeRefs()) + { + attempts.add(attempt); + } + } + finally + { + if (results != null) + { + results.close(); + } + } + + return attempts; + } + + /** + * Retrieves the NodeRef of the deploymentattempt node with the given id + * + * @param attemptId The deployattemptid of the node to be found + * @return The NodeRef of the deploymentattempt node or null if not found + */ + public static NodeRef findDeploymentAttempt(String attemptId) + { + FacesContext fc = FacesContext.getCurrentInstance(); + SearchService searchService = Repository.getServiceRegistry(fc).getSearchService(); + + // construct the query + StringBuilder query = new StringBuilder("@"); + query.append(NamespaceService.WCMAPP_MODEL_PREFIX); + query.append("\\:"); + query.append(WCMAppModel.PROP_DEPLOYATTEMPTID.getLocalName()); + query.append(":\""); + query.append(attemptId); + query.append("\""); + + ResultSet results = null; + NodeRef attempt = null; + try + { + // execute the query + results = searchService.query(Repository.getStoreRef(), + SearchService.LANGUAGE_LUCENE, query.toString()); + + if (results.length() == 1) + { + attempt = results.getNodeRef(0); + } + else if (results.length() > 1) + { + throw new IllegalStateException( + "More than one deployment attempt node was found, there should only be one!"); + } + } + finally + { + if (results != null) + { + results.close(); + } + } + + return attempt; + } + + /** + * Returns the test server allocated to the given store. + * + * @param store The store to get the test server for + * @return The allocated server or null if there isn't one + */ + public static NodeRef findAllocatedTestServer(String store) + { + FacesContext fc = FacesContext.getCurrentInstance(); + SearchService searchService = Repository.getServiceRegistry(fc).getSearchService(); + + // construct the query + StringBuilder query = new StringBuilder("@"); + query.append(NamespaceService.WCMAPP_MODEL_PREFIX); + query.append("\\:"); + query.append(WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO.getLocalName()); + query.append(":\""); + query.append(store); + query.append("\""); + + ResultSet results = null; + NodeRef testServer = null; + try + { + // execute the query + results = searchService.query(Repository.getStoreRef(), + SearchService.LANGUAGE_LUCENE, query.toString()); + + if (results.length() == 1) + { + testServer = results.getNodeRef(0); + } + else if (results.length() > 1) + { + throw new IllegalStateException("More than one allocated test server for store '" + + store + "' was found, should only be one!"); + } + } + finally + { + if (results != null) + { + results.close(); + } + } + + return testServer; + } + + /** + * Returns a list of NodeRefs representing the 'live' servers configured + * for the given web project. + * + * @param webProject Web project to get live servers for + * @return List of live servers + */ + public static List findLiveServers(NodeRef webProject) + { + return findServers(webProject, true, false); + } + + /** + * Returns a list of NodeRefs representing the 'test' servers configured + * for the given web project. + * + * @param webProject Web project to get test servers for + * @param allocated true only returns those servers already allocated + * @return List of test servers + */ + public static List findTestServers(NodeRef webProject, boolean allocated) + { + return findServers(webProject, false, allocated); + } + + + private static List findServers(NodeRef webProject, boolean live, boolean allocated) + { + FacesContext context = FacesContext.getCurrentInstance(); + NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); + SearchService searchService = Repository.getServiceRegistry(context).getSearchService(); + + // build the query + String webProjectName = (String)nodeService.getProperty(webProject, ContentModel.PROP_NAME); + String safeProjectName = ISO9075.encode(webProjectName); + StringBuilder query = new StringBuilder("PATH:\"/"); + query.append(Application.getRootPath(context)); + query.append("/"); + query.append(Application.getWebsitesFolderName(context)); + query.append("/cm:"); + query.append(safeProjectName); + query.append("/*\" AND @"); + query.append(NamespaceService.WCMAPP_MODEL_PREFIX); + query.append("\\:"); + query.append(WCMAppModel.PROP_DEPLOYSERVERTYPE.getLocalName()); + query.append(":\""); + if (live) + { + query.append(WCMAppModel.CONSTRAINT_LIVESERVER); + } + else + { + query.append(WCMAppModel.CONSTRAINT_TESTSERVER); + } + query.append("\""); + + // if required filter the test servers + if (live == false && allocated == false) + { + query.append(" AND ISNULL:\""); + query.append(WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO.toString()); + query.append("\""); + } + + // execute the query + ResultSet results = null; + List servers = new ArrayList(); + try + { + results = searchService.query(Repository.getStoreRef(), + SearchService.LANGUAGE_LUCENE, query.toString()); + + for (NodeRef server : results.getNodeRefs()) + { + servers.add(server); + } + } + finally + { + if (results != null) + { + results.close(); + } + } + + return servers; + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/ViewDeploymentReportDialog.java b/source/java/org/alfresco/web/bean/wcm/ViewDeploymentReportDialog.java index a70f09f7f0..e0696c096f 100644 --- a/source/java/org/alfresco/web/bean/wcm/ViewDeploymentReportDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/ViewDeploymentReportDialog.java @@ -28,7 +28,6 @@ import java.util.Map; import javax.faces.context.FacesContext; -import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.web.app.Application; import org.alfresco.web.bean.dialog.BaseDialogBean; import org.apache.commons.logging.Log; @@ -43,10 +42,7 @@ public class ViewDeploymentReportDialog extends BaseDialogBean { private static final long serialVersionUID = -8054466371051782132L; - protected NodeRef webProjectRef; - protected Integer deployedVersion; - - protected AVMBrowseBean avmBrowseBean; + protected String store; private static final Log logger = LogFactory.getLog(ViewDeploymentReportDialog.class); @@ -58,11 +54,16 @@ public class ViewDeploymentReportDialog extends BaseDialogBean { super.init(parameters); - this.webProjectRef = this.avmBrowseBean.getWebsite().getNodeRef(); + this.store = parameters.get("store"); + if (this.store == null || this.store.length() == 0) + { + throw new IllegalArgumentException("store parameter is mandatory"); + } + if (logger.isDebugEnabled()) - logger.debug("Initialising dialog to view deployment report for " + - this.avmBrowseBean.getStagingStore()); + logger.debug("Initialising dialog to view deployment report for: " + + this.store); } @Override @@ -81,18 +82,10 @@ public class ViewDeploymentReportDialog extends BaseDialogBean // Bean getters and setters /** - * @return The NodeRef of the web project the deployment reports are being shown for + * @return The store to show deployment reports for */ - public NodeRef getWebProjectRef() + public String getStore() { - return this.webProjectRef; + return this.store; } - - /** - * @param avmBrowseBean The AVM BrowseBean instance to use - */ - public void setAvmBrowseBean(AVMBrowseBean avmBrowseBean) - { - this.avmBrowseBean = avmBrowseBean; - } -} +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIDeployWebsite.java b/source/java/org/alfresco/web/ui/wcm/component/UIDeployWebsite.java index 88d6a166c7..63eb8a3cde 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIDeployWebsite.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIDeployWebsite.java @@ -26,6 +26,7 @@ package org.alfresco.web.ui.wcm.component; import java.io.IOException; import java.io.Serializable; +import java.text.MessageFormat; import java.util.List; import java.util.Map; @@ -36,16 +37,15 @@ import javax.faces.el.ValueBinding; import javax.transaction.UserTransaction; import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.actions.AVMDeploySnapshotAction; -import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.repo.avm.actions.AVMDeployWebsiteAction; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMUtil; import org.alfresco.web.bean.wcm.DeploymentMonitor; +import org.alfresco.web.bean.wcm.DeploymentUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -61,6 +61,8 @@ public class UIDeployWebsite extends UIInput protected Integer snapshotVersion = -1; protected Boolean monitorDeployment; protected List monitorIds; + protected String deployMode; + protected String store; private static Log logger = LogFactory.getLog(UIDeployWebsite.class); @@ -104,18 +106,22 @@ public class UIDeployWebsite extends UIInput this.monitorDeployment = (Boolean)values[2]; this.monitorIds = (List)values[3]; this.snapshotVersion = (Integer)values[4]; + this.deployMode = (String)values[5]; + this.store = (String)values[6]; } @Override public Object saveState(FacesContext context) { - Object values[] = new Object[5]; + Object values[] = new Object[7]; // standard component attributes are saved by the super class values[0] = super.saveState(context); values[1] = this.webProjectRef; values[2] = this.monitorDeployment; values[3] = this.monitorIds; values[4] = this.snapshotVersion; + values[5] = this.deployMode; + values[6] = this.store; return values; } @@ -175,54 +181,60 @@ public class UIDeployWebsite extends UIInput if (logger.isDebugEnabled()) logger.debug("Found deployment monitor: " + monitor); - renderServer(context, out, nodeService, monitor.getTargetServer(), false, true, id); + renderServer(context, out, nodeService, monitor.getTargetServer(), false, true, id, true); } } } else { - // get a list of the servers that have been successfully deployed to - /* - NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); - int deployingVersion = this.getSnapshotVersion(); - List serversAlreadyDeployed = new ArrayList(); - List deployReportRefs = nodeService.getChildAssocs( - webProjectRef, WCMAppModel.ASSOC_DEPLOYMENTREPORT, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : deployReportRefs) + if (WCMAppModel.CONSTRAINT_TESTSERVER.equals(getDeployMode())) { - NodeRef report = ref.getChildRef(); - if (report != null) + // determine the state, the sandbox may already have a test server + // allocated, in which case we need to allow the user to preview or + // re-deploy. If this is the first deployment or the test server has + // been removed then show a list of available test servers to choose + // from. + + NodeRef allocatedServer = DeploymentUtil.findAllocatedTestServer(getStore()); + if (allocatedServer != null) { - int deployedVersion = -1; - Boolean success = (Boolean)nodeService.getProperty(report, - WCMAppModel.PROP_DEPLOYSUCCESSFUL); - - Serializable deployVersionObj = nodeService.getProperty(report, - WCMAppModel.PROP_DEPLOYVERSION); - if (deployVersionObj != null && deployVersionObj instanceof Integer) + renderAllocatedTestServer(context, out, nodeService, allocatedServer); + } + else + { + List servers = DeploymentUtil.findTestServers(webProject, false); + if (servers.size() > 0) { - deployedVersion = (Integer)deployVersionObj; + boolean first = true; + for (NodeRef server : servers) + { + renderServer(context, out, nodeService, server, first, false, null, false); + first = false; + } } - - if (success != null && success.booleanValue() && (deployingVersion == deployedVersion)) + else { - serversAlreadyDeployed.add((String)nodeService.getProperty(report, - WCMAppModel.PROP_DEPLOYSERVER)); + // show the none available message + out.write("
 "); + out.write(Application.getMessage(context, "deploy_test_server_not_available")); + out.write("
"); } } } - */ - - // get the servers available to deploy to - List deployServerRefs = nodeService.getChildAssocs( - webProjectRef, WCMAppModel.ASSOC_DEPLOYMENTSERVER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : deployServerRefs) + else { - NodeRef server = ref.getChildRef(); + // TODO: get a list of the servers that have been successfully deployed to - // TODO: determine if the server has already been successfully deployed to - - renderServer(context, out, nodeService, server, true, false, null); + List servers = DeploymentUtil.findLiveServers(webProject); + for (NodeRef server : servers) + { + // TODO: determine if the server has already been successfully deployed to + boolean selected = true; + + renderServer(context, out, nodeService, server, selected, false, null, true); + } } } @@ -332,15 +344,61 @@ public class UIDeployWebsite extends UIInput this.snapshotVersion = snapshotVersion; } + /** + * @return The type of server being deployed to, 'live' or 'test' + */ + public String getDeployMode() + { + ValueBinding vb = getValueBinding("deployMode"); + if (vb != null) + { + this.deployMode = (String)vb.getValue(getFacesContext()); + } + + if (this.deployMode == null || this.deployMode.length() == 0) + { + this.deployMode = WCMAppModel.CONSTRAINT_TESTSERVER; + } + + return this.deployMode; + } + + /** + * @param deployMode The type of server to deploy to, 'live' or 'test' + */ + public void setDeployMode(String deployMode) + { + this.deployMode = deployMode; + } + + /** + * @return The store being deployed to + */ + public String getStore() + { + ValueBinding vb = getValueBinding("store"); + if (vb != null) + { + this.store = (String)vb.getValue(getFacesContext()); + } + + return this.store; + } + + /** + * @param store The store to deploy to + */ + public void setStore(String store) + { + this.store = store; + } + // ------------------------------------------------------------------------------ // Helpers private void renderScript(FacesContext context, ResponseWriter out, List monitorIds) throws IOException { -// // render supporting Yahoo scripts -// Utils.writeYahooScripts(context, out, null); - // create comma separated list of deplyment ids StringBuilder ids = new StringBuilder(); for (int x = 0; x < monitorIds.size(); x++) @@ -430,8 +488,8 @@ public class UIDeployWebsite extends UIInput } private void renderServer(FacesContext context, ResponseWriter out, NodeService nodeService, - NodeRef server, boolean selected, boolean monitoring, String monitorId) - throws IOException + NodeRef server, boolean selected, boolean monitoring, String monitorId, + boolean liveServer) throws IOException { String contextPath = context.getExternalContext().getRequestContextPath(); @@ -440,7 +498,7 @@ public class UIDeployWebsite extends UIInput String serverName = (String)props.get(WCMAppModel.PROP_DEPLOYSERVERNAME); if (serverName == null || serverName.length() == 0) { - serverName = AVMDeploySnapshotAction.calculateServerUri(props); + serverName = AVMDeployWebsiteAction.calculateServerUri(props); } out.write(""); @@ -461,15 +519,24 @@ public class UIDeployWebsite extends UIInput } else { - out.write("
"); - out.write(""); + out.write(""); } @@ -499,7 +566,7 @@ public class UIDeployWebsite extends UIInput out.write(Application.getMessage(context, "deploying")); out.write("
"); } - else if (selected == false) + else if (selected == false && liveServer == true) { out.write("
\n"); } + + private void renderAllocatedTestServer(FacesContext context, ResponseWriter out, NodeService nodeService, + NodeRef server) throws IOException + { + Map serverProps = nodeService.getProperties(server); + String serverName = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERNAME); + if (serverName == null || serverName.length() == 0) + { + serverName = AVMDeployWebsiteAction.calculateServerUri(serverProps); + } + + String pattern = Application.getMessage(context, "deploy_test_server_allocated"); + String msg = MessageFormat.format(pattern, serverName); + + out.write("
 "); + out.write(msg); + + String url = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERURL); + if (url != null && url.length() > 0) + { + out.write(""); + } + + out.write("
"); + + // render a hidden field with the value of the allocated test server + out.write(""); + } } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentReports.java b/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentReports.java index 7d582617a4..7f3053465e 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentReports.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentReports.java @@ -37,7 +37,7 @@ import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.actions.AVMDeploySnapshotAction; +import org.alfresco.repo.avm.actions.AVMDeployWebsiteAction; import org.alfresco.repo.domain.PropertyValue; import org.alfresco.sandbox.SandboxConstants; import org.alfresco.service.cmr.avm.AVMService; @@ -50,7 +50,7 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.wcm.AVMUtil; +import org.alfresco.web.bean.wcm.DeploymentUtil; import org.alfresco.web.ui.common.PanelGenerator; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.SelfRenderingComponent; @@ -65,7 +65,7 @@ import org.springframework.util.StringUtils; */ public class UIDeploymentReports extends SelfRenderingComponent { - protected NodeRef webProjectRef; + protected String store; private static Log logger = LogFactory.getLog(UIDeploymentReports.class); @@ -85,7 +85,7 @@ public class UIDeploymentReports extends SelfRenderingComponent Object values[] = (Object[])state; // standard component attributes are restored by the super class super.restoreState(context, values[0]); - this.webProjectRef = (NodeRef)values[1]; + this.store = (String)values[1]; } public Object saveState(FacesContext context) @@ -93,7 +93,7 @@ public class UIDeploymentReports extends SelfRenderingComponent Object values[] = new Object[2]; // standard component attributes are saved by the super class values[0] = super.saveState(context); - values[1] = this.webProjectRef; + values[1] = this.store; return values; } @@ -115,21 +115,20 @@ public class UIDeploymentReports extends SelfRenderingComponent tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true); tx.begin(); - NodeRef webProject = getValue(); - if (webProject == null) + String storeName = getValue(); + if (storeName == null) { - throw new IllegalArgumentException("The web project must be specified."); + throw new IllegalArgumentException("The store must be specified."); } if (logger.isDebugEnabled()) - logger.debug("Rendering deployment reports for: " + webProject.toString()); + logger.debug("Rendering deployment reports for store: " + storeName); NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); ContentService contentService = Repository.getServiceRegistry(context).getContentService(); AVMService avmService = Repository.getServiceRegistry(context).getAVMService(); - String store = (String)nodeService.getProperty(webProject, WCMAppModel.PROP_AVMSTORE); - PropertyValue val = avmService.getStoreProperty(store, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); + PropertyValue val = avmService.getStoreProperty(storeName, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); String attemptId = null; if (val != null) @@ -146,7 +145,7 @@ public class UIDeploymentReports extends SelfRenderingComponent logger.debug("Retrieving deployment reports for attempt id: " + attemptId); // get the deploymentattempt object - NodeRef attempt = AVMUtil.findDeploymentAttempt(attemptId); + NodeRef attempt = DeploymentUtil.findDeploymentAttempt(attemptId); if (attempt != null) { @@ -179,25 +178,25 @@ public class UIDeploymentReports extends SelfRenderingComponent // Strongly typed component property accessors /** - * @return The NodeRef representation of the web project to show the deployment reports for + * @return The store to show the deployment reports for */ - public NodeRef getValue() + public String getValue() { ValueBinding vb = getValueBinding("value"); if (vb != null) { - this.webProjectRef = (NodeRef)vb.getValue(getFacesContext()); + this.store = (String)vb.getValue(getFacesContext()); } - return this.webProjectRef; + return this.store; } /** - * @param value The NodeRef representation of the web project to show the deployment reports for + * @param value The store to show the deployment reports for */ - public void setValue(NodeRef value) + public void setValue(String value) { - this.webProjectRef = value; + this.store = value; } // ------------------------------------------------------------------------------ @@ -249,7 +248,7 @@ public class UIDeploymentReports extends SelfRenderingComponent } String deployType = WCMAppModel.CONSTRAINT_ALFDEPLOY; - if (server.startsWith(AVMDeploySnapshotAction.FILE_SERVER_PREFIX)) + if (server.startsWith(AVMDeployWebsiteAction.FILE_SERVER_PREFIX)) { deployType = WCMAppModel.CONSTRAINT_FILEDEPLOY; } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentServers.java b/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentServers.java index 8be733998b..6704015e73 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentServers.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIDeploymentServers.java @@ -44,12 +44,13 @@ import javax.faces.model.SelectItem; import javax.transaction.UserTransaction; import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.actions.AVMDeploySnapshotAction; +import org.alfresco.repo.avm.actions.AVMDeployWebsiteAction; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.DeploymentServerConfig; import org.alfresco.web.ui.common.ComponentConstants; +import org.alfresco.web.ui.common.PanelGenerator; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.UIActionLink; import org.alfresco.web.ui.common.component.UIListItem; @@ -154,18 +155,6 @@ public class UIDeploymentServers extends UIInput out.write("
"); List servers = getValue(); - DeploymentServerConfig currentServer = getCurrentServer(); - for (DeploymentServerConfig server: servers) - { - if (currentServer != null && currentServer.getId().equals(server.getId())) - { - renderServerForm(context, out, server, true); - } - else - { - renderServer(context, out, server); - } - } if (getInAddMode()) { @@ -183,6 +172,19 @@ public class UIDeploymentServers extends UIInput } } + DeploymentServerConfig currentServer = getCurrentServer(); + for (DeploymentServerConfig server: servers) + { + if (currentServer != null && currentServer.getId().equals(server.getId())) + { + renderServerForm(context, out, server, true); + } + else + { + renderServer(context, out, server); + } + } + out.write("
"); out.write("\n