diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/ServerInfo.java b/application-admintools-api/src/main/java/com/xwiki/admintools/ServerInfo.java index 6e08cdac..3a781960 100644 --- a/application-admintools-api/src/main/java/com/xwiki/admintools/ServerInfo.java +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/ServerInfo.java @@ -34,8 +34,8 @@ public interface ServerInfo { /** * Verify if the path to a specific server is found. If a server path is provided in the XWiki configurations, it - * verifies if the path corresponds to a server. Otherwise, it searches the server location in system properties - * and system environment. + * verifies if the path corresponds to a server. Otherwise, it searches the server location in system properties and + * system environment. * * @return {@code true} if the server is used, {@code false} otherwise. */ @@ -62,6 +62,13 @@ public interface ServerInfo */ String getXwikiCfgFolderPath(); + /** + * Access the path to the XWiki installation folder. + * + * @return the path to the XWiki installation folder. + */ + String getXWikiInstallFolderPath(); + /** * Update the possible paths to the configuration files. */ diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheck.java b/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheck.java index a1f9d0ef..bd012aea 100644 --- a/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheck.java +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheck.java @@ -22,6 +22,8 @@ import org.xwiki.component.annotation.Role; import org.xwiki.stability.Unstable; +import com.xwiki.admintools.jobs.CustomJobResult; + /** * Check for issues in the current wiki. * @@ -35,7 +37,7 @@ public interface HealthCheck /** * Execute the health check on the wiki instance. * - * @return a {@link HealthCheckResult} with the relevant info regarding the checked issue. + * @return a {@link CustomJobResult} with the relevant info regarding the checked issue. */ - HealthCheckResult check(); + CustomJobResult check(); } diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheckResult.java b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/CustomJobResult.java similarity index 78% rename from application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheckResult.java rename to application-admintools-api/src/main/java/com/xwiki/admintools/jobs/CustomJobResult.java index 6890a6c9..a40614b0 100644 --- a/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheckResult.java +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/CustomJobResult.java @@ -17,26 +17,26 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -package com.xwiki.admintools.health; +package com.xwiki.admintools.jobs; import java.util.List; import org.xwiki.stability.Unstable; /** - * Result of a health check. Stores a custom message for the summary of the result, the severity level represented by - * {@link HealthCheckResultLevel}. The result may also contain a {@link List} of additional parameters used if there - * is need to store more information about the result. + * Result of a job. Stores a custom message for the summary of the result, the severity level represented by + * {@link CustomJobResultLevel}. The result may also contain a {@link List} of additional parameters used if there is + * need to store more information about the result. * * @version $Id$ * @since 1.0 */ @Unstable -public class HealthCheckResult +public class CustomJobResult { private String message; - private HealthCheckResultLevel level; + private CustomJobResultLevel level; private List parameters; @@ -47,7 +47,7 @@ public class HealthCheckResult * @param level severity level of a result. * @param parameters current value of the checked resource. */ - public HealthCheckResult(String message, HealthCheckResultLevel level, Object... parameters) + public CustomJobResult(String message, CustomJobResultLevel level, Object... parameters) { this.message = message; this.level = level; @@ -79,7 +79,7 @@ public List getParameters() * * @return the severity level of an error. */ - public HealthCheckResultLevel getLevel() + public CustomJobResultLevel getLevel() { return level; } diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheckResultLevel.java b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/CustomJobResultLevel.java similarity index 74% rename from application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheckResultLevel.java rename to application-admintools-api/src/main/java/com/xwiki/admintools/jobs/CustomJobResultLevel.java index 99540893..25272a28 100644 --- a/application-admintools-api/src/main/java/com/xwiki/admintools/health/HealthCheckResultLevel.java +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/CustomJobResultLevel.java @@ -17,32 +17,32 @@ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ -package com.xwiki.admintools.health; +package com.xwiki.admintools.jobs; import org.xwiki.stability.Unstable; /** - * Represents the severity type of {@link HealthCheckResult}, where "INFO" is for informative results, "WARN" for + * Represents the severity level of a job, where "INFO" is for informative results, "WARN" for * warnings and "ERROR" for critical issues. * * @version $Id$ * @since 1.0 */ @Unstable -public enum HealthCheckResultLevel +public enum CustomJobResultLevel { /** - * Used to mark a {@link HealthCheckResult} as an error. + * Used to mark a {@link CustomJobResultLevel} as an error. */ ERROR, /** - * Used to mark a {@link HealthCheckResult} as a warning. + * Used to mark a {@link CustomJobResultLevel} as a warning. */ WARN, /** - * Used to mark a {@link HealthCheckResult} as informative. + * Used to mark a {@link CustomJobResultLevel} as informative. */ INFO } diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/HealthCheckJobStatus.java b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/HealthCheckJobStatus.java index 3cbf8df4..a6068480 100644 --- a/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/HealthCheckJobStatus.java +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/HealthCheckJobStatus.java @@ -28,9 +28,6 @@ import org.xwiki.observation.ObservationManager; import org.xwiki.stability.Unstable; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; - /** * The status of the health check job. * @@ -40,7 +37,7 @@ @Unstable public class HealthCheckJobStatus extends DefaultJobStatus { - private final List healthCheckResults = new LinkedList<>(); + private final List customJobResults = new LinkedList<>(); /** * Create a new health check job status. @@ -60,11 +57,11 @@ public HealthCheckJobStatus(String jobType, HealthCheckJobRequest request, Obser /** * Get the list issues list from the job. * - * @return list with {@link HealthCheckResult} containing errors. + * @return list with {@link CustomJobResult} containing errors. */ - public List getHealthCheckResults() + public List getJobResults() { - return healthCheckResults; + return customJobResults; } /** @@ -73,8 +70,8 @@ public List getHealthCheckResults() * @param level represents the searched level of severity. * @return {@code true} if there is any match for the given level, or {@code false} otherwise. */ - public boolean hasLevel(HealthCheckResultLevel level) + public boolean hasLevel(CustomJobResultLevel level) { - return this.healthCheckResults.stream().anyMatch(checkResult -> Objects.equals(level, checkResult.getLevel())); + return this.customJobResults.stream().anyMatch(checkResult -> Objects.equals(level, checkResult.getLevel())); } } diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/PackageUploadJobRequest.java b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/PackageUploadJobRequest.java new file mode 100644 index 00000000..9fd31e7c --- /dev/null +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/PackageUploadJobRequest.java @@ -0,0 +1,72 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xwiki.admintools.jobs; + +import java.util.List; + +import org.xwiki.job.AbstractRequest; +import org.xwiki.stability.Unstable; + +/** + * Represents a request to start a package upload job. + * + * @version $Id$ + * @since 1.1 + */ +@Unstable +public class PackageUploadJobRequest extends AbstractRequest +{ + private String fileRef; + + /** + * Default constructor. + */ + public PackageUploadJobRequest() + { + setDefaultId(); + } + + /** + * Creates a specific request for package upload job. + * + * @param fileRef the attachment reference. + * @param jobId the ID of the request. + */ + public PackageUploadJobRequest(String fileRef, List jobId) + { + this.fileRef = fileRef; + setId(jobId); + } + + /** + * Get the attachment reference. + * + * @return a {@link String} representing the attachment reference. + */ + public String getFileRef() + { + return this.fileRef; + } + + private void setDefaultId() + { + setId(List.of("adminTools", "import")); + } +} diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/PackageUploadJobStatus.java b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/PackageUploadJobStatus.java new file mode 100644 index 00000000..164e662e --- /dev/null +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/jobs/PackageUploadJobStatus.java @@ -0,0 +1,87 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xwiki.admintools.jobs; + +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import org.xwiki.job.DefaultJobStatus; +import org.xwiki.logging.LoggerManager; +import org.xwiki.observation.ObservationManager; +import org.xwiki.stability.Unstable; + +/** + * The status of a package upload job. + * + * @version $Id$ + * @since 1.1 + */ +@Unstable +public class PackageUploadJobStatus extends DefaultJobStatus +{ + private List uploadLogs = new LinkedList<>(); + + /** + * Create a new import job status. + * + * @param jobType the job type. + * @param request the request provided when the job was started. + * @param observationManager the observation manager. + * @param loggerManager the logger manager. + */ + public PackageUploadJobStatus(String jobType, PackageUploadJobRequest request, + ObservationManager observationManager, LoggerManager loggerManager) + { + super(jobType, request, null, observationManager, loggerManager); + setCancelable(true); + } + + /** + * Get the list result list from the job. + * + * @return list with {@link CustomJobResult} containing the results. + */ + public List getJobResults() + { + return uploadLogs; + } + + /** + * Add a new log to the job results. + * + * @param statusLog the new log result. + */ + public void addLog(CustomJobResult statusLog) + { + uploadLogs.add(statusLog); + } + + /** + * Check if any job result has a specific level of severity. + * + * @param level represents the searched level of severity. + * @return {@code true} if there is any match for the given level, or {@code false} otherwise. + */ + public boolean hasLevel(CustomJobResultLevel level) + { + return this.uploadLogs.stream().anyMatch(checkResult -> Objects.equals(level, checkResult.getLevel())); + } +} diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/rest/AdminToolsResource.java b/application-admintools-api/src/main/java/com/xwiki/admintools/rest/AdminToolsResource.java index 09965a38..1ec244bb 100644 --- a/application-admintools-api/src/main/java/com/xwiki/admintools/rest/AdminToolsResource.java +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/rest/AdminToolsResource.java @@ -23,10 +23,12 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import org.xwiki.rest.XWikiRestComponent; import org.xwiki.rest.XWikiRestException; +import org.xwiki.stability.Unstable; /** * Provides the APIs needed by the Admin Tools server in order to download and view configuration files and logs. @@ -66,4 +68,19 @@ public interface AdminToolsResource extends XWikiRestComponent @POST @Path("/flushCache") Response flushCache() throws XWikiRestException; + + /** + * Start a package upload job based on the attachment reference that was sent. + * + * @param attachReference the reference of the attachment. + * @param startTime the start time of the request. + * @return HTML status code 202 to hint that the upload job has started. + * @throws XWikiRestException if an error occurred while creating the job. + * @since 1.1 + */ + @POST + @Path("/import") + @Unstable + Response uploadPackageArchive(@QueryParam("attach") String attachReference, + @QueryParam("startTime") String startTime) throws XWikiRestException; } diff --git a/application-admintools-api/src/main/java/com/xwiki/admintools/uploadPackageJob/UploadPackageJobResource.java b/application-admintools-api/src/main/java/com/xwiki/admintools/uploadPackageJob/UploadPackageJobResource.java new file mode 100644 index 00000000..aba38432 --- /dev/null +++ b/application-admintools-api/src/main/java/com/xwiki/admintools/uploadPackageJob/UploadPackageJobResource.java @@ -0,0 +1,151 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xwiki.admintools.uploadPackageJob; + +import java.io.ByteArrayOutputStream; +import java.io.File; + +import org.xwiki.stability.Unstable; + +/** + * Store data for package upload job process. + * + * @version $Id$ + * @since 1.1 + */ +@Unstable +public class UploadPackageJobResource +{ + private File targetFile; + + private File backupFile; + + private ByteArrayOutputStream newFileContent; + + private String newFileName; + + private boolean uploaded; + + /** + * Default constructor. + */ + public UploadPackageJobResource() + { + uploaded = false; + } + + /** + * Get the content of the new file. + * + * @return the content of the new file. + */ + public ByteArrayOutputStream getNewFileContent() + { + return newFileContent; + } + + /** + * See {@link #getNewFileContent()}. + * + * @param newFileContent the new file content. + */ + public void setNewFileContent(ByteArrayOutputStream newFileContent) + { + this.newFileContent = newFileContent; + } + + /** + * Get the backup file. + * + * @return the backup file. + */ + public File getBackupFile() + { + return backupFile; + } + + /** + * See {@link #getBackupFile()}. + * + * @param backupFile the backup file. + */ + public void setBackupFile(File backupFile) + { + this.backupFile = backupFile; + } + + /** + * Get the file that will be replaced or saved. + * + * @return the update target file. + */ + public File getTargetFile() + { + return targetFile; + } + + /** + * See {@link #getTargetFile()}. + * + * @param targetFile the update target file. + */ + public void setTargetFile(File targetFile) + { + this.targetFile = targetFile; + } + + /** + * Get the new file name. + * + * @return the name of the new file. + */ + public String getNewFileName() + { + return newFileName; + } + + /** + * See {@link #getNewFileName()}. + * + * @param newFileName the name of the new file. + */ + public void setNewFileName(String newFileName) + { + this.newFileName = newFileName; + } + + /** + * Set the upload flag to {@code true}. + */ + public void setUploaded() + { + this.uploaded = true; + } + + /** + * Get the upload flag. + * + * @return the upload flag. + */ + public boolean isUploaded() + { + return uploaded; + } +} diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/AbstractServerInfo.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/AbstractServerInfo.java index b6902e7a..f0ff4be6 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/AbstractServerInfo.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/AbstractServerInfo.java @@ -38,6 +38,8 @@ public abstract class AbstractServerInfo implements ServerInfo protected String[] xwikiCfgPossiblePaths; + protected String[] xwikiInstallPossiblePaths; + @Inject @Named("default") protected AdminToolsConfiguration adminToolsConfig; @@ -74,4 +76,15 @@ public String getXwikiCfgFolderPath() } return null; } + + @Override + public String getXWikiInstallFolderPath() + { + for (String xwikiLibraryFolderPath : this.xwikiInstallPossiblePaths) { + if ((new File(xwikiLibraryFolderPath)).isDirectory()) { + return xwikiLibraryFolderPath; + } + } + return null; + } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/TomcatInfo.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/TomcatInfo.java index 9a333a1e..71dd99ab 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/TomcatInfo.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/data/identifiers/TomcatInfo.java @@ -80,6 +80,10 @@ public void updatePossiblePaths() this.xwikiCfgPossiblePaths = new String[] { "/etc/xwiki/", "/usr/local/xwiki/WEB-INF/", "/opt/xwiki/WEB-INF/", String.format("%s/webapps/ROOT/WEB-INF/", this.serverPath), String.format("%s/webapps/xwiki/WEB-INF/", this.serverPath) }; + + this.xwikiInstallPossiblePaths = + new String[] { "/etc/xwiki/lib/", "/usr/local/xwiki/", "/opt/xwiki/", + String.format("%s/webapps/xwiki/", this.serverPath) }; } @Override diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationDatabaseHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationDatabaseHealthCheck.java index b7d31849..3c4ea674 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationDatabaseHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationDatabaseHealthCheck.java @@ -26,8 +26,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; import com.xwiki.admintools.internal.data.identifiers.CurrentServer; /** @@ -49,22 +49,22 @@ public class ConfigurationDatabaseHealthCheck extends AbstractConfigurationHealt private CurrentServer currentServer; @Override - public HealthCheckResult check() + public CustomJobResult check() { String usedDatabase = getConfigurationProviderJSON().get("databaseName"); if (usedDatabase == null) { logger.warn("Database not found!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.database.warn", - HealthCheckResultLevel.ERROR); + return new CustomJobResult("adminTools.dashboard.healthcheck.database.warn", + CustomJobResultLevel.ERROR); } if (currentServer.getSupportedDBs().stream() .anyMatch(d -> usedDatabase.toLowerCase().contains(d.toLowerCase()))) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.database.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.database.info", + CustomJobResultLevel.INFO); } logger.error("Used database is not supported!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.database.notSupported", - HealthCheckResultLevel.ERROR, usedDatabase); + return new CustomJobResult("adminTools.dashboard.healthcheck.database.notSupported", + CustomJobResultLevel.ERROR, usedDatabase); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationJavaHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationJavaHealthCheck.java index 13e8b432..9fcac677 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationJavaHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationJavaHealthCheck.java @@ -29,8 +29,8 @@ import org.xwiki.extension.version.internal.DefaultVersion; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; import com.xwiki.admintools.health.XWikiVersions; /** @@ -51,22 +51,22 @@ public class ConfigurationJavaHealthCheck extends AbstractConfigurationHealthChe private static final String REGEX = "\\."; @Override - public HealthCheckResult check() + public CustomJobResult check() { Map configurationJson = getConfigurationProviderJSON(); String javaVersionString = configurationJson.get("javaVersion"); if (javaVersionString == null) { logger.warn("Java version not found!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.java.warn", HealthCheckResultLevel.WARN); + return new CustomJobResult("adminTools.dashboard.healthcheck.java.warn", CustomJobResultLevel.WARN); } String xwikiVersionString = configurationJson.get("xwikiVersion"); float javaVersion = parseJavaVersionFloat(javaVersionString); if (!isJavaXWikiCompatible(xwikiVersionString, javaVersion)) { logger.error("Java version is not compatible with the current XWiki installation!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.java.error", HealthCheckResultLevel.ERROR, + return new CustomJobResult("adminTools.dashboard.healthcheck.java.error", CustomJobResultLevel.ERROR, javaVersionString, xwikiVersionString); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.java.info", HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.java.info", CustomJobResultLevel.INFO); } private float parseJavaVersionFloat(String javaVersionString) diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationOSHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationOSHealthCheck.java index 0e8c2b06..936bd893 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationOSHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/configuration/ConfigurationOSHealthCheck.java @@ -27,8 +27,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking the OS configuration. @@ -46,13 +46,13 @@ public class ConfigurationOSHealthCheck extends AbstractConfigurationHealthCheck public static final String HINT = "configurationOS"; @Override - public HealthCheckResult check() + public CustomJobResult check() { Map dataJSON = getConfigurationProviderJSON(); if (dataJSON.get("osName") == null || dataJSON.get("osVersion") == null || dataJSON.get("osArch") == null) { logger.warn("There has been an error while gathering OS info!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.os.warn", HealthCheckResultLevel.WARN); + return new CustomJobResult("adminTools.dashboard.healthcheck.os.warn", CustomJobResultLevel.WARN); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.os.info", HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.os.info", CustomJobResultLevel.INFO); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/CacheMemoryHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/CacheMemoryHealthCheck.java index 87bc88bb..7dbbd136 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/CacheMemoryHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/CacheMemoryHealthCheck.java @@ -28,8 +28,8 @@ import org.xwiki.configuration.ConfigurationSource; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking instance document cache performance. @@ -54,21 +54,21 @@ public class CacheMemoryHealthCheck implements HealthCheck private Logger logger; @Override - public HealthCheckResult check() + public CustomJobResult check() { String storeCacheCapacity = configurationSource.getProperty("xwiki.store.cache.capacity"); if (storeCacheCapacity == null) { logger.warn("Store cache capacity not defined. Set by default at 500."); - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.cache.null", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.cache.null", + CustomJobResultLevel.INFO); } int cacheCapacity = Integer.parseInt(storeCacheCapacity); if (cacheCapacity < 500) { logger.warn("Store cache capacity is set to [{}].", storeCacheCapacity); - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.cache.low", - HealthCheckResultLevel.WARN, cacheCapacity); + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.cache.low", + CustomJobResultLevel.WARN, cacheCapacity); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.cache.info", - HealthCheckResultLevel.INFO, cacheCapacity); + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.cache.info", + CustomJobResultLevel.INFO, cacheCapacity); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/MemoryHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/MemoryHealthCheck.java index fc40b6fd..a4d2c209 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/MemoryHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/memory/MemoryHealthCheck.java @@ -32,8 +32,8 @@ import com.xpn.xwiki.XWiki; import com.xpn.xwiki.XWikiContext; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking instance memory performance. @@ -57,7 +57,7 @@ public class MemoryHealthCheck implements HealthCheck private Logger logger; @Override - public HealthCheckResult check() + public CustomJobResult check() { XWiki wiki = xcontextProvider.get().getWiki(); float maxMemory = wiki.maxMemory(); @@ -66,19 +66,19 @@ public HealthCheckResult check() DecimalFormat format = new DecimalFormat("0.#"); if (maxMemoryGB < 1) { logger.error("JVM memory is less than 1024MB. Currently: [{}]", maxMemoryGB * 1024); - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.maxcapacity.error", - HealthCheckResultLevel.ERROR, (maxMemoryGB * 1024f)); + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.maxcapacity.error", + CustomJobResultLevel.ERROR, (maxMemoryGB * 1024f)); } if (totalFreeMemory < 512) { logger.error("JVM instance has only [{}]MB free memory left!", totalFreeMemory); - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.free.error", - HealthCheckResultLevel.ERROR, totalFreeMemory); + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.free.error", + CustomJobResultLevel.ERROR, totalFreeMemory); } else if (totalFreeMemory < 1024) { logger.warn("Instance memory is running low. Currently only [{}]MB free left.", totalFreeMemory); - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.free.warn", - HealthCheckResultLevel.WARN, totalFreeMemory); + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.free.warn", + CustomJobResultLevel.WARN, totalFreeMemory); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.memory.info", HealthCheckResultLevel.INFO, + return new CustomJobResult("adminTools.dashboard.healthcheck.memory.info", CustomJobResultLevel.INFO, totalFreeMemory / 1024); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/CPUHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/CPUHealthCheck.java index df392a5e..b276cbfc 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/CPUHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/CPUHealthCheck.java @@ -27,8 +27,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; import oshi.SystemInfo; import oshi.hardware.CentralProcessor; @@ -53,7 +53,7 @@ public class CPUHealthCheck implements HealthCheck private Logger logger; @Override - public HealthCheckResult check() + public CustomJobResult check() { SystemInfo systemInfo = new SystemInfo(); HardwareAbstractionLayer hardware = systemInfo.getHardware(); @@ -62,12 +62,12 @@ public HealthCheckResult check() int maxFreq = (int) (processor.getMaxFreq() / (1024 * 1024)); if (cpuCores > 2 && maxFreq > 2048) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.performance.cpu.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.performance.cpu.info", + CustomJobResultLevel.INFO); } String cpuSpecifications = String.format("CPU cores %d - frequency %d", cpuCores, maxFreq); logger.warn("The CPU does not satisfy the minimum system requirements! [{}]", cpuSpecifications); - return new HealthCheckResult("adminTools.dashboard.healthcheck.performance.cpu.warn", - HealthCheckResultLevel.WARN, cpuCores, maxFreq); + return new CustomJobResult("adminTools.dashboard.healthcheck.performance.cpu.warn", + CustomJobResultLevel.WARN, cpuCores, maxFreq); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalMemoryHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalMemoryHealthCheck.java index 1aaf0a06..2b1bf9d3 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalMemoryHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalMemoryHealthCheck.java @@ -29,8 +29,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; import oshi.SystemInfo; import oshi.hardware.HardwareAbstractionLayer; @@ -54,7 +54,7 @@ public class PhysicalMemoryHealthCheck implements HealthCheck private Logger logger; @Override - public HealthCheckResult check() + public CustomJobResult check() { SystemInfo systemInfo = new SystemInfo(); HardwareAbstractionLayer hardware = systemInfo.getHardware(); @@ -62,13 +62,13 @@ public HealthCheckResult check() float totalMemory = (float) hardware.getMemory().getTotal() / (1024 * 1024 * 1024); DecimalFormat format = new DecimalFormat("0.#"); if (totalMemory > 2) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.performance.memory.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.performance.memory.info", + CustomJobResultLevel.INFO); } String systemCapacityMessage = format.format(totalMemory); logger.warn("There is not enough memory to safely run the XWiki installation! Physical memory detected: [{}]", systemCapacityMessage); - return new HealthCheckResult("adminTools.dashboard.healthcheck.performance.memory.warn", - HealthCheckResultLevel.WARN, systemCapacityMessage); + return new CustomJobResult("adminTools.dashboard.healthcheck.performance.memory.warn", + CustomJobResultLevel.WARN, systemCapacityMessage); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalSpaceHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalSpaceHealthCheck.java index 99409f18..912d4755 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalSpaceHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/performance/PhysicalSpaceHealthCheck.java @@ -32,8 +32,8 @@ import com.xwiki.admintools.ServerInfo; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; import com.xwiki.admintools.internal.data.identifiers.CurrentServer; /** @@ -58,7 +58,7 @@ public class PhysicalSpaceHealthCheck implements HealthCheck private Logger logger; @Override - public HealthCheckResult check() + public CustomJobResult check() { File diskPartition; ServerInfo server = currentServer.getCurrentServer(); @@ -77,12 +77,12 @@ public HealthCheckResult check() float freeSpace = (float) freePartitionSpace / (1024 * 1024 * 1024); if (freeSpace > 16) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.performance.space.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.performance.space.info", + CustomJobResultLevel.INFO); } logger.warn("There is not enough free space for the XWiki installation! Current free space is [{}]", freeSpace); - return new HealthCheckResult("adminTools.dashboard.healthcheck.performance.space.warn", - HealthCheckResultLevel.WARN, freeSpace, diskPartition.getAbsolutePath()); + return new CustomJobResult("adminTools.dashboard.healthcheck.performance.space.warn", + CustomJobResultLevel.WARN, freeSpace, diskPartition.getAbsolutePath()); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ActiveEncodingHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ActiveEncodingHealthCheck.java index a15eddfb..9baada57 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ActiveEncodingHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ActiveEncodingHealthCheck.java @@ -25,8 +25,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking XWiki active encoding. @@ -44,20 +44,20 @@ public class ActiveEncodingHealthCheck extends AbstractSecurityHealthCheck public static final String HINT = "activeEncoding"; @Override - public HealthCheckResult check() + public CustomJobResult check() { String activeEnc = getSecurityProviderJSON().get(HINT); if (activeEnc == null) { logger.warn("Active encoding could not be detected!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.xwiki.active.notFound", - HealthCheckResultLevel.WARN); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.xwiki.active.notFound", + CustomJobResultLevel.WARN); } boolean isActiveEncSafe = isSafeEncoding(activeEnc, "XWiki active"); if (!isActiveEncSafe) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.xwiki.active.warn", - HealthCheckResultLevel.WARN, activeEnc); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.xwiki.active.warn", + CustomJobResultLevel.WARN, activeEnc); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.xwiki.active.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.xwiki.active.info", + CustomJobResultLevel.INFO); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ConfigurationEncodingHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ConfigurationEncodingHealthCheck.java index d555ce9c..ecf2ca50 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ConfigurationEncodingHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/ConfigurationEncodingHealthCheck.java @@ -25,8 +25,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking XWiki configuration encoding. @@ -44,21 +44,21 @@ public class ConfigurationEncodingHealthCheck extends AbstractSecurityHealthChec public static final String HINT = "configurationEncoding"; @Override - public HealthCheckResult check() + public CustomJobResult check() { String configEnc = getSecurityProviderJSON().get(HINT); if (configEnc == null) { logger.warn("Configuration encoding could not be detected!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.xwiki.config.notFound", - HealthCheckResultLevel.WARN); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.xwiki.config.notFound", + CustomJobResultLevel.WARN); } boolean isConfigEncSafe = isSafeEncoding(configEnc, "XWiki configuration"); if (!isConfigEncSafe) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.xwiki.config.warn", - HealthCheckResultLevel.WARN, configEnc); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.xwiki.config.warn", + CustomJobResultLevel.WARN, configEnc); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.xwiki.config.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.xwiki.config.info", + CustomJobResultLevel.INFO); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/FileEncodingHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/FileEncodingHealthCheck.java index ef31601b..89b49cbb 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/FileEncodingHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/FileEncodingHealthCheck.java @@ -25,8 +25,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking system file encoding. @@ -44,20 +44,20 @@ public class FileEncodingHealthCheck extends AbstractSecurityHealthCheck public static final String HINT = "fileEncoding"; @Override - public HealthCheckResult check() + public CustomJobResult check() { String fileEnc = getSecurityProviderJSON().get(HINT); if (fileEnc == null) { logger.warn("File encoding could not be detected!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.system.file.notFound", - HealthCheckResultLevel.WARN); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.system.file.notFound", + CustomJobResultLevel.WARN); } boolean isSafeFileEnc = isSafeEncoding(fileEnc, "System file"); if (!isSafeFileEnc) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.system.file.warn", - HealthCheckResultLevel.WARN, fileEnc); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.system.file.warn", + CustomJobResultLevel.WARN, fileEnc); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.system.file.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.system.file.info", + CustomJobResultLevel.INFO); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/LangEncodingHealthCheck.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/LangEncodingHealthCheck.java index 9ff7553a..48abe1d3 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/LangEncodingHealthCheck.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/checks/security/LangEncodingHealthCheck.java @@ -25,8 +25,8 @@ import org.xwiki.component.annotation.Component; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; /** * Implementation of {@link HealthCheck} for checking system language configuration. @@ -44,20 +44,20 @@ public class LangEncodingHealthCheck extends AbstractSecurityHealthCheck public static final String HINT = "languageEncoding"; @Override - public HealthCheckResult check() + public CustomJobResult check() { String langEnc = getSecurityProviderJSON().get("LANG"); if (langEnc == null) { logger.warn("Language encoding could not be detected!"); - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.system.lang.notFound", - HealthCheckResultLevel.WARN); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.system.lang.notFound", + CustomJobResultLevel.WARN); } boolean isSafeLangEnc = isSafeEncoding(langEnc.split("\\.")[1], "System language"); if (!isSafeLangEnc) { - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.system.lang.warn", - HealthCheckResultLevel.WARN, langEnc); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.system.lang.warn", + CustomJobResultLevel.WARN, langEnc); } - return new HealthCheckResult("adminTools.dashboard.healthcheck.security.system.lang.info", - HealthCheckResultLevel.INFO); + return new CustomJobResult("adminTools.dashboard.healthcheck.security.system.lang.info", + CustomJobResultLevel.INFO); } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/job/HealthCheckJob.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/job/HealthCheckJob.java index 6add3c56..a22ce33e 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/job/HealthCheckJob.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/health/job/HealthCheckJob.java @@ -33,7 +33,7 @@ import com.xpn.xwiki.XWikiContext; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; +import com.xwiki.admintools.jobs.CustomJobResult; import com.xwiki.admintools.jobs.HealthCheckJobRequest; import com.xwiki.admintools.jobs.HealthCheckJobStatus; @@ -93,8 +93,8 @@ protected void runInternal() } else { progressManager.startStep(this); // We start the check for the current HealthCheck in the iterator. - HealthCheckResult checkResult = healthCheckIterator.next().check(); - status.getHealthCheckResults().add(checkResult); + CustomJobResult checkResult = healthCheckIterator.next().check(); + status.getJobResults().add(checkResult); progressManager.endStep(this); Thread.yield(); } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/rest/DefaultAdminToolsResource.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/rest/DefaultAdminToolsResource.java index 06b6efd7..33309c7c 100644 --- a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/rest/DefaultAdminToolsResource.java +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/rest/DefaultAdminToolsResource.java @@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; import java.util.Map; import javax.inject.Inject; @@ -34,6 +35,8 @@ import org.apache.commons.lang.exception.ExceptionUtils; import org.slf4j.Logger; import org.xwiki.component.annotation.Component; +import org.xwiki.job.Job; +import org.xwiki.job.JobExecutor; import org.xwiki.rest.internal.resources.pages.ModifiablePageResource; import org.xwiki.security.authorization.AccessDeniedException; import org.xwiki.security.authorization.ContextualAuthorizationManager; @@ -43,6 +46,8 @@ import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.web.XWikiRequest; import com.xwiki.admintools.internal.files.ImportantFilesManager; +import com.xwiki.admintools.internal.uploadJob.UploadJob; +import com.xwiki.admintools.jobs.PackageUploadJobRequest; import com.xwiki.admintools.rest.AdminToolsResource; /** @@ -64,6 +69,9 @@ public class DefaultAdminToolsResource extends ModifiablePageResource implements @Inject private ImportantFilesManager importantFilesManager; + @Inject + private JobExecutor jobExecutor; + @Inject private ContextualAuthorizationManager contextualAuthorizationManager; @@ -134,4 +142,28 @@ public Response flushCache() throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } + + @Override + public Response uploadPackageArchive(String attachReference, String startTime) + { + try { + this.contextualAuthorizationManager.checkAccess(Right.ADMIN); + + List jobId = List.of("adminTools", "import", attachReference, startTime); + Job job = this.jobExecutor.getJob(jobId); + if (job == null) { + PackageUploadJobRequest packageUploadJobRequest = new PackageUploadJobRequest(attachReference, jobId); + this.jobExecutor.execute(UploadJob.JOB_TYPE, packageUploadJobRequest); + return Response.status(202).type(MediaType.TEXT_PLAIN_TYPE).build(); + } else { + return Response.status(102).type(MediaType.TEXT_PLAIN_TYPE).build(); + } + } catch (AccessDeniedException deniedException) { + logger.warn("Failed to begin the package upload due to insufficient rights."); + throw new WebApplicationException(Response.Status.UNAUTHORIZED); + } catch (Exception e) { + logger.warn("Failed to begin package upload job. Root cause: [{}]", ExceptionUtils.getRootCauseMessage(e)); + throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); + } + } } diff --git a/application-admintools-default/src/main/java/com/xwiki/admintools/internal/uploadJob/UploadJob.java b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/uploadJob/UploadJob.java new file mode 100644 index 00000000..9aed45b2 --- /dev/null +++ b/application-admintools-default/src/main/java/com/xwiki/admintools/internal/uploadJob/UploadJob.java @@ -0,0 +1,321 @@ +/* + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package com.xwiki.admintools.internal.uploadJob; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + +import org.apache.commons.lang.exception.ExceptionUtils; +import org.xwiki.component.annotation.Component; +import org.xwiki.job.AbstractJob; +import org.xwiki.job.GroupedJob; +import org.xwiki.job.JobGroupPath; +import org.xwiki.model.reference.AttachmentReference; +import org.xwiki.model.reference.AttachmentReferenceResolver; +import org.xwiki.stability.Unstable; + +import com.xpn.xwiki.XWikiContext; +import com.xpn.xwiki.XWikiException; +import com.xpn.xwiki.doc.XWikiDocument; +import com.xwiki.admintools.internal.data.identifiers.CurrentServer; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; +import com.xwiki.admintools.jobs.PackageUploadJobRequest; +import com.xwiki.admintools.jobs.PackageUploadJobStatus; +import com.xwiki.admintools.uploadPackageJob.UploadPackageJobResource; + +/** + * The Admin Tools package upload job. + * + * @version $Id$ + * @since 1.1 + */ +@Component +@Named(UploadJob.JOB_TYPE) +@Unstable +public class UploadJob extends AbstractJob implements GroupedJob +{ + /** + * Admin Tools package upload job type. + */ + public static final String JOB_TYPE = "admintools.uploadpackage"; + + private static final String NEW_FILE_PATH_FORMAT = "%s/%s"; + + private static final String FILE_TYPE_BACKUP = "backup"; + + private static final String FILE_TYPE_TARGET = "target"; + + @Inject + private CurrentServer currentServer; + + @Inject + private Provider xcontextProvider; + + @Inject + @Named("current") + private AttachmentReferenceResolver attachmentReferenceResolver; + + private List jobResourceList = new ArrayList<>(); + + @Override + public String getType() + { + return JOB_TYPE; + } + + @Override + public JobGroupPath getGroupPath() + { + return new JobGroupPath(List.of("adminTools", "import", request.getFileRef())); + } + + @Override + protected PackageUploadJobStatus createNewStatus(PackageUploadJobRequest request) + { + return new PackageUploadJobStatus(JOB_TYPE, request, observationManager, loggerManager); + } + + /** + * Run the package upload job. + */ + @Override + protected void runInternal() + { + try { + jobResourceList.clear(); + if (!status.isCanceled()) { + this.progressManager.pushLevelProgress(this); + String path = currentServer.getCurrentServer().getXWikiInstallFolderPath(); + InputStream fileInputStream = getInputStream(); + try (ZipInputStream zis = new ZipInputStream(fileInputStream)) { + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (!entry.isDirectory()) { + progressManager.startStep(this); + UploadPackageJobResource jobResource = maybeBackupFile(path, entry.getName()); + processFileContent(zis, jobResource); + jobResourceList.add(jobResource); + progressManager.endStep(this); + Thread.yield(); + } + zis.closeEntry(); + } + } + batchSave(); + } + } catch (Exception e) { + logger.error(ExceptionUtils.getRootCauseMessage(e)); + progressManager.endStep(this); + Thread.yield(); + batchRestore(); + throw new RuntimeException(e); + } finally { + this.progressManager.popLevelProgress(this); + } + } + + private InputStream getInputStream() throws XWikiException + { + XWikiContext xcontext = this.xcontextProvider.get(); + AttachmentReference attachmentReference = attachmentReferenceResolver.resolve(request.getFileRef()); + XWikiDocument parentDoc = xcontext.getWiki().getDocument(attachmentReference.getDocumentReference(), xcontext); + return parentDoc.getAttachment(attachmentReference.getName()).getContentInputStream(xcontext); + } + + private void processFileContent(ZipInputStream zis, UploadPackageJobResource jobResource) throws IOException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = zis.read(buffer)) > 0) { + baos.write(buffer, 0, len); + } + jobResource.setNewFileContent(baos); + } + + private void batchRestore() + { + for (UploadPackageJobResource jobResource : jobResourceList) { + progressManager.startStep(this); + File backupFile = jobResource.getBackupFile(); + File targetFile = jobResource.getTargetFile(); + + if (!jobResource.isUploaded()) { + if (!handleFileDeletion(backupFile, FILE_TYPE_BACKUP)) { + continue; + } + } else if (backupFile == null) { + if (!handleFileDeletion(targetFile, FILE_TYPE_TARGET)) { + continue; + } + } else { + try { + String newFilePath = + String.format(NEW_FILE_PATH_FORMAT, targetFile.getParent(), jobResource.getNewFileName()); + File newFile = new File(newFilePath); + boolean newFileDeleteFailure = !handleFileDeletion(newFile, FILE_TYPE_TARGET); + Files.copy(backupFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + boolean backupFileDeleteFailure = !handleFileDeletion(backupFile, FILE_TYPE_BACKUP); + if (newFileDeleteFailure || backupFileDeleteFailure) { + continue; + } + } catch (IOException e) { + backupFailureMessage("copy", backupFile.getName(), targetFile.getName()); + continue; + } + } + CustomJobResult log = + new CustomJobResult("adminTools.jobs.upload.batch.backup.success", CustomJobResultLevel.INFO, + jobResource.getNewFileName()); + status.addLog(log); + progressManager.endStep(this); + Thread.yield(); + } + } + + private boolean handleFileDeletion(File file, String fileType) + { + if (file != null) { + try { + Files.deleteIfExists(file.toPath()); + } catch (IOException e) { + backupFailureMessage(fileType, file.getName()); + progressManager.endStep(this); + Thread.yield(); + return false; + } + } + return true; + } + + private void backupFailureMessage(String translation, String... parameters) + { + String translationHint = String.format("adminTools.jobs.upload.batch.backup.%s.fail", translation); + CustomJobResult log = new CustomJobResult(translationHint, CustomJobResultLevel.ERROR, parameters); + status.addLog(log); + } + + private void batchSave() throws IOException + { + for (UploadPackageJobResource jobResource : jobResourceList) { + progressManager.startStep(this); + File targetFile = jobResource.getTargetFile(); + if (targetFile.exists()) { + String filePath = jobResource.getTargetFile().getParent(); + if (!targetFile.delete()) { + CustomJobResult log = + new CustomJobResult("adminTools.jobs.upload.batch.save.fail", CustomJobResultLevel.ERROR, + targetFile.getName()); + status.addLog(log); + throw new RuntimeException( + String.format("Failed to delete original file [%s].", targetFile.getName())); + } + File newFile = new File(String.format(NEW_FILE_PATH_FORMAT, filePath, jobResource.getNewFileName())); + Files.write(newFile.toPath(), jobResource.getNewFileContent().toByteArray()); + } else { + Files.write(targetFile.toPath(), jobResource.getNewFileContent().toByteArray()); + } + jobResource.setUploaded(); + CustomJobResult log = + new CustomJobResult("adminTools.jobs.upload.batch.save.success", CustomJobResultLevel.INFO, + jobResource.getNewFileName()); + status.addLog(log); + progressManager.endStep(this); + Thread.yield(); + } + } + + private UploadPackageJobResource maybeBackupFile(String xwikiInstallationPath, String archiveFilePath) + { + File targetFile = new File(xwikiInstallationPath + archiveFilePath); + UploadPackageJobResource uploadPackageJobResource = new UploadPackageJobResource(); + String fileName = targetFile.getName(); + uploadPackageJobResource.setNewFileName(fileName); + if (targetFile.exists()) { + createBackupFile(targetFile.getAbsolutePath() + ".bak", targetFile, uploadPackageJobResource, fileName); + } else { + String extension = archiveFilePath.substring(archiveFilePath.lastIndexOf(".")); + if (extension.equals(".jar")) { + String simpleFileName = extractNameBeforeVersion(fileName); + String directoryPath = targetFile.getParent(); + String[] filesList = new File(directoryPath).list( + ((dir, name) -> name.startsWith(simpleFileName) && name.endsWith(extension))); + if (filesList == null || filesList.length > 1) { + CustomJobResult log = + new CustomJobResult("adminTools.jobs.upload.assessoriginal.fail", CustomJobResultLevel.ERROR, + fileName); + status.addLog(log); + throw new RuntimeException( + String.format("Unable to correctly assess the original file for %s.", fileName)); + } else if (filesList.length == 1) { + String oldFilePath = String.format(NEW_FILE_PATH_FORMAT, directoryPath, filesList[0]); + targetFile = new File(oldFilePath); + createBackupFile(String.format("%s.bak", oldFilePath), targetFile, uploadPackageJobResource, + fileName); + } + } + } + uploadPackageJobResource.setTargetFile(targetFile); + return uploadPackageJobResource; + } + + private void createBackupFile(String backupFilePath, File targetFile, + UploadPackageJobResource uploadPackageJobResource, String fileName) + { + File backupFile = new File(backupFilePath); + try { + Files.copy(targetFile.toPath(), backupFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + CustomJobResult log = new CustomJobResult("adminTools.jobs.upload.backup.fail", CustomJobResultLevel.ERROR, + backupFile.getName(), fileName); + status.addLog(log); + throw new RuntimeException(e); + } + uploadPackageJobResource.setBackupFile(backupFile); + CustomJobResult log = new CustomJobResult("adminTools.jobs.upload.backup.success", CustomJobResultLevel.INFO, + backupFile.getName(), fileName); + status.addLog(log); + } + + private String extractNameBeforeVersion(String input) + { + String regex = "^([\\w-]+(?:-[\\w-]+)*)(?=(-\\d+|\\.[^.]+$))"; + Matcher matcher = Pattern.compile(regex).matcher(input); + if (matcher.find()) { + return matcher.group(1); + } + return input; + } +} diff --git a/application-admintools-default/src/main/resources/META-INF/components.txt b/application-admintools-default/src/main/resources/META-INF/components.txt index e2458b91..178253d4 100644 --- a/application-admintools-default/src/main/resources/META-INF/components.txt +++ b/application-admintools-default/src/main/resources/META-INF/components.txt @@ -26,6 +26,7 @@ com.xwiki.admintools.internal.health.checks.performance.PhysicalSpaceHealthCheck com.xwiki.admintools.internal.health.checks.memory.CacheMemoryHealthCheck com.xwiki.admintools.internal.health.checks.memory.MemoryHealthCheck com.xwiki.admintools.internal.health.job.HealthCheckJob +com.xwiki.admintools.internal.uploadJob.UploadJob com.xwiki.admintools.internal.rest.DefaultAdminToolsResource com.xwiki.admintools.internal.usage.InstanceUsageManager com.xwiki.admintools.internal.usage.RecycleBinsProvider diff --git a/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm b/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm index aa32f24e..d4965a15 100644 --- a/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm +++ b/application-admintools-default/src/main/resources/templates/filesSectionTemplate.vm @@ -33,14 +33,12 @@ $escapetool.xml($services.localization.render('adminTools.dashboard.download.view.description')) +
  • + #set ($packagesUploadURL = $xwiki.getDocument('AdminTools.ImportPackage').getURL('view')) + + $escapetool.xml($services.localization.render('adminTools.packages.dashboard.uploadpackages')) +
  • #warning($escapetool.xml($services.localization.render('adminTools.dashboard.download.warning'))) diff --git a/application-admintools-default/src/test/java/com/xwiki/admintools/internal/health/job/HealthCheckJobTest.java b/application-admintools-default/src/test/java/com/xwiki/admintools/internal/health/job/HealthCheckJobTest.java index f3b08a80..21e477d5 100644 --- a/application-admintools-default/src/test/java/com/xwiki/admintools/internal/health/job/HealthCheckJobTest.java +++ b/application-admintools-default/src/test/java/com/xwiki/admintools/internal/health/job/HealthCheckJobTest.java @@ -32,8 +32,8 @@ import com.xpn.xwiki.XWikiContext; import com.xwiki.admintools.health.HealthCheck; -import com.xwiki.admintools.health.HealthCheckResult; -import com.xwiki.admintools.health.HealthCheckResultLevel; +import com.xwiki.admintools.jobs.CustomJobResult; +import com.xwiki.admintools.jobs.CustomJobResultLevel; import com.xwiki.admintools.jobs.HealthCheckJobRequest; import com.xwiki.admintools.jobs.HealthCheckJobStatus; @@ -77,14 +77,14 @@ void runInternal() healthCheckList.add(secondHealthCheck); when(listProvider.get()).thenReturn(healthCheckList); - when(firstHealthCheck.check()).thenReturn(new HealthCheckResult("err", HealthCheckResultLevel.ERROR, "error")); - when(secondHealthCheck.check()).thenReturn(new HealthCheckResult("safe", HealthCheckResultLevel.INFO)); + when(firstHealthCheck.check()).thenReturn(new CustomJobResult("err", CustomJobResultLevel.ERROR, "error")); + when(secondHealthCheck.check()).thenReturn(new CustomJobResult("safe", CustomJobResultLevel.INFO)); healthCheckJob.initialize(new HealthCheckJobRequest()); healthCheckJob.runInternal(); HealthCheckJobStatus healthCheckJobStatus = healthCheckJob.getStatus(); - assertEquals(2, healthCheckJobStatus.getHealthCheckResults().size()); - assertTrue(healthCheckJobStatus.hasLevel(HealthCheckResultLevel.ERROR)); + assertEquals(2, healthCheckJobStatus.getJobResults().size()); + assertTrue(healthCheckJobStatus.hasLevel(CustomJobResultLevel.ERROR)); } @Test diff --git a/application-admintools-ui/pom.xml b/application-admintools-ui/pom.xml index 01343e18..ae218cf9 100644 --- a/application-admintools-ui/pom.xml +++ b/application-admintools-ui/pom.xml @@ -100,6 +100,9 @@ .*/AdminTools/WikisRecycleBins\.xml .*/AdminTools/WikisSize\.xml .*/AdminTools/SpammedPages\.xml + .*/AdminTools/EmptyPages\.xml + .*/AdminTools/ImportPackage\.xml + .*/AdminTools/Packages/WebHome\.xml diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml index c0b08b92..da76017a 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/AdminToolsJS.xml @@ -192,7 +192,7 @@ require(['jquery', 'xwiki-meta', 'xwiki-job-runner', 'xwiki-l10n!admin-tools-cac const reinitialiseHealthCheckResources = function() { $.get(getHealthCheckActionPageURL(), function(data) { let progressBar = $(data).find('div.ui-progress'); - $('#healthCheck').find('.health-check-result-message').replaceWith(progressBar); + $('#healthCheck').find('.job-result-message').replaceWith(progressBar); reinitializeJobJS() }); }; @@ -293,6 +293,58 @@ require(['jquery', 'xwiki-meta', 'xwiki-job-runner', 'xwiki-l10n!admin-tools-cac }); $(event.currentTarget).closest('.modal').modal('toggle'); }); + + $(function() { + // Since the associated liveData is refreshed on file upload, we don't need a response container. + const input = document.querySelector('#adminToolsAddPackage input[type=file]'); + if (input && XWiki.FileUploader) { + new XWiki.FileUploader(input, { + 'progressAutohide': true, + 'responseContainer' : document.createElement('div') + }); + } + }); + + const runPackageUploadJob = function(targetURL) { + $.post(targetURL).done(function() {}) + .fail(function(error) { + console.log('Failed to start upload job. Cause: ' + error.statusText); + new XWiki.widgets.Notification(l10n.get('error'), 'error'); + }); + }; + + $(document).on('click', '.admintools-start-upload', function (event) { + event.preventDefault(); + let packageName = $(this).data('package-name'); + let packageRef = $(this).data('package-ref'); + let startTime = Date.now(); + let referenceString = 'AdminTools.Packages.Package-' + packageName.replace('.', '\\.') + startTime; + let jobDocumentRef = XWiki.Model.resolve(referenceString, XWiki.EntityType.DOCUMENT, + XWiki.currentDocument.documentReference); + let jobDocument = new XWiki.Document(jobDocumentRef); + let targetURL = $(this).data('upload-url') + "&startTime=" + startTime; + let pageData = { + "template": "AdminTools.Code.PackageUploadTemplate", + "AdminTools.Code.PackageUploadClass_0_package": packageRef, + "AdminTools.Code.PackageUploadClass_0_startTime": startTime, + parent: 'AdminTools.WebHome', + form_token: xwikiMeta.form_token, + title: packageName + }; + $.ajax({ + url: new XWiki.Document(jobDocumentRef).getURL('save'), + type: 'POST', + data: pageData, + success: function (response) { + runPackageUploadJob(targetURL); + window.location.href = new XWiki.Document(jobDocumentRef).getURL('view'); + }, + error: function (xhr, status, error) { + console.error("Failed to create the upload page:", error); + alert("An error occurred while creating the upload page."); + } + }); + }); }); @@ -305,4 +357,158 @@ require(['jquery', 'xwiki-meta', 'xwiki-job-runner', 'xwiki-l10n!admin-tools-cac onDemand + + AdminTools.Code.AdminToolsJS + 0 + XWiki.UIExtensionClass + dbfe04bd-eebd-43ff-9290-237e98119410 + + XWiki.UIExtensionClass + + + + + + + + + 0 + 0 + select + + async_cached + 3 + Cached + 0 + com.xpn.xwiki.objects.classes.BooleanClass + + + 0 + 0 + select + forbidden + 0 + 1 + async_context + 4 + Context elements + 0 + , + |, + 5 + 0 + action=Action|doc.reference=Document|icon.theme=Icon theme|locale=Language|rendering.defaultsyntax=Default syntax|rendering.restricted=Restricted|rendering.targetsyntax=Target syntax|request.base=Request base URL|request.cookies|request.headers|request.parameters=Request parameters|request.remoteAddr|request.url=Request URL|request.wiki=Request wiki|user=User|wiki=Wiki + com.xpn.xwiki.objects.classes.StaticListClass + + + 0 + 0 + select + + async_enabled + 2 + Asynchronous rendering + 0 + com.xpn.xwiki.objects.classes.BooleanClass + + + 0 + Text + content + 1 + Executed Content + 0 + 25 + 120 + 0 + com.xpn.xwiki.objects.classes.TextAreaClass + + + 0 + extensionPointId + 5 + Extension Point ID + 30 + 0 + com.xpn.xwiki.objects.classes.StringClass + + + 0 + name + 6 + Extension ID + 30 + 0 + com.xpn.xwiki.objects.classes.StringClass + + + PureText + 0 + PureText + parameters + 7 + Extension Parameters + 0 + 10 + 40 + 0 + com.xpn.xwiki.objects.classes.TextAreaClass + + + 0 + 0 + select + forbidden + 0 + 0 + scope + 8 + Extension Scope + 0 + + |, + 1 + 0 + wiki=Current Wiki|user=Current User|global=Global + com.xpn.xwiki.objects.classes.StaticListClass + + + + 0 + + + + + + 0 + + + {{velocity}} +{{html clean="false"}} +#set ($isPackageStore = $doc.documentReference.equals($services.model.resolveDocument('AdminTools.Code.PackagesStore'))) +#set ($packageRef = $escapetool.xml($services.model.serialize($attachment.getReference(), 'default'))) +#if ($isPackageStore && $services.security.authorization.hasAccess('admin', $xcontext.user) && $attachment.getFilename().contains(".zip")) +<a class="admintools-start-upload action" data-upload-url="$request.getContextPath()/rest/admintools/import?attach=${packageRef}" + data-package-name="${escapetool.xml($attachment.getFilename())}" data-package-ref="${packageRef}" + title="$services.localization.render('confluencepro.migration.livetable._actions.select')" href="#"> + <span class="action-icon">$services.icon.renderHTML('play')</span><span class="action-label">Upload package + </span> +</a> +#end +{{/html}} +{{/velocity}} + + + org.xwiki.platform.attachment.actions + + + admintools.package.attachment.actions + + + + + + wiki + + diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/ApplicationsPanelEntry.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/ApplicationsPanelEntry.xml index b413f1a4..e72e3f4c 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/ApplicationsPanelEntry.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/ApplicationsPanelEntry.xml @@ -20,7 +20,7 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> - + AdminTools.Code ApplicationsPanelEntry diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckMacros.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckMacros.xml index c0bb33de..e0598174 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckMacros.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckMacros.xml @@ -36,86 +36,9 @@ false xwiki/2.1 true - {{velocity output='false'}} -#macro (getHealthCheckJobStatusJSON $status $json) - #set ($results = []) - #foreach ($result in $status.getHealthCheckResults()) - #set ($discard = $results.add({ - 'level': $result.getLevel().name().toLowerCase(), - 'renderedMessage': "#printResult($result)" - })) - #end - #set ($json = $NULL) - #setVariable("$json" { - 'id': $status.request.id, - 'state': $status.state, - 'progress': { - 'offset': $status.progress.offset - }, - 'log': { - 'offset': 0, - 'items': $results - } - }) -#end -#macro (healthCheckOutputJobStatus $jobStatus) - #getHealthCheckJobStatusJSON($jobStatus, $json, $translationPrefix) - #set ($json.message = "#healthCheckJobFinishedMessage($jobStatus)") - $response.setContentType('application/json') - $jsontool.serialize($json) -#end -#macro (healthCheckJobFinishedMessage $status) - #if ($status.error) - #set($messageKeys = ["job.status.${status.jobType}.error", 'job.status.error']) - #set($healthCheckReportMessage = $services.localization.render($messageKeys)) - #set($messageClass = 'errormessage health-check-result-message') - #elseif ($status.hasLevel('ERROR')) - #set($healthCheckReportMessage = $services.localization.render('adminTools.dashboard.healthcheck.message.error')) - #set($messageClass = 'errormessage health-check-result-message') - #elseif ($status.hasLevel('WARN')) - #set($healthCheckReportMessage = $services.localization.render('adminTools.dashboard.healthcheck.message.warning')) - #set($messageClass = 'warningmessage health-check-result-message') - #else - #set($healthCheckReportMessage = $services.localization.render('adminTools.dashboard.healthcheck.message.success')) - #set($messageClass = 'successmessage health-check-result-message') - #end - <div class="box $messageClass"> - $escapetool.xml($healthCheckReportMessage) - </div> -#end -#macro (printResult $healthCheckResult) - <div> - $escapetool.xml($services.localization.render($healthCheckResult.getMessage(), $healthCheckResult.getParameters())) - </div> -#end -#macro (printHealthCheckResults $status) - #if ($status.state != 'FINISHED') - #set($loading = true) - #end - #set($healthCheckResults = $status.getHealthCheckResults()) - <ul class="log"> - #foreach ($healthCheckResult in $healthCheckResults) - #set ($resultLevel = $healthCheckResult.getLevel().name().toLowerCase()) - ## Display the last result item as loading if the associated task is not finished. - <li class="log-item log-item-${resultLevel}#if ($loading && !$foreach.hasNext) log-item-loading#end"> - #printResult($healthCheckResult) - </li> - #end - </ul> -#end -#macro (displayHealthCheckResults $status $collapsed) - <dl class="xform"> - <dt> - <label class="collapse-toggle#if ($collapsed || $status.state == 'WAITING') collapsed#end" - data-target-xpath="parent::*/following-sibling::*"> - <span class="icon-closed">$services.icon.renderHTML('caret-right')</span> - <span class="icon-opened">$services.icon.renderHTML('caret-down')</span> - $escapetool.xml($services.localization.render('adminTools.dashboard.healthcheck.result')) - </label> - </dt> - <dd>#printHealthCheckResults($status)</dd> - </dl> -#end + {{include reference="AdminTools.Code.JobCommonMacros" /}} + +{{velocity output='false'}} #macro (healthCheckUI) #set ($mainReference = $services.model.createDocumentReference('', ['AdminTools', 'Code'], 'ConfigurationClass')) #if ($services.licensing.licensor.hasLicensureForEntity($mainReference)) @@ -123,8 +46,10 @@ #set ($discard = $xwiki.jsx.use('AdminTools.Code.AdminToolsJS')) #includeMacros("AdminTools.Code.Macros") #set ($jobId = $services.admintools.getHealthCheckJobId()) - #set ($healthJobStatusURL = $xwiki.getURL('AdminTools.Code.HealthCheckJob', 'get', $escapetool.url({ + #set ($translationPrefix = 'adminTools.dashboard.healthcheck') + #set ($healthJobStatusURL = $xwiki.getURL('AdminTools.Code.JobOutput', 'get', $escapetool.url({ 'jobId': $jobId, + 'translationPrefix': $translationPrefix, 'outputSyntax': 'plain' }))) #set ($healthJobStatus = $services.job.getJobStatus($jobId)) @@ -153,10 +78,10 @@ #if ($healthJobStatus.state != 'FINISHED') #displayJobProgressBar($healthJobStatus) #else - #healthCheckJobFinishedMessage($healthJobStatus, $translationPrefix, $successKey, $errorKey, $canceledKey) + #customJobFinishedMessage($healthJobStatus, $translationPrefix) #end #if ($showLogs || $isAdvancedUser || $isSuperAdmin || $hasAdmin) - #displayHealthCheckResults($healthJobStatus true) + #displayJobResults($healthJobStatus true) #end </div> <hr/> diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/JobCommonMacros.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/JobCommonMacros.xml new file mode 100644 index 00000000..4b1b34e5 --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/JobCommonMacros.xml @@ -0,0 +1,120 @@ + + + + + + AdminTools.Code + JobCommonMacros + + + 0 + xwiki:XWiki.Admin + WebHome + xwiki:XWiki.Admin + xwiki:XWiki.Admin + 1.1 + JobCommonMacros + + false + xwiki/2.1 + true + {{velocity output='false'}} +#macro (getCustomJobStatusJSON $status $json) + #set ($results = []) + #foreach ($result in $status.getJobResults()) + #set ($discard = $results.add({ + 'level': $result.getLevel().name().toLowerCase(), + 'renderedMessage': "#printResult($result)" + })) + #end + #set ($json = $NULL) + #setVariable("$json" { + 'id': $status.request.id, + 'state': $status.state, + 'progress': { + 'offset': $status.progress.offset + }, + 'log': { + 'offset': 0, + 'items': $results + } + }) +#end +#macro (outputJobStatus $jobStatus, $translationPrefix) + #getCustomJobStatusJSON($jobStatus, $json) + #set ($json.message = "#customJobFinishedMessage($jobStatus, $!{translationPrefix})") + $response.setContentType('application/json') + $jsontool.serialize($json) +#end +#macro (customJobFinishedMessage $status, $translationPrefix) + #if ($status.error) + #set($messageKeys = ["job.status.${status.jobType}.error", 'job.status.error']) + #set($jobReportMessage = $services.localization.render($messageKeys)) + #set($messageClass = 'errormessage job-result-message') + #elseif ($status.hasLevel('ERROR')) + #set($jobReportMessage = $services.localization.render($translationPrefix + ".message.error")) + #set($messageClass = 'errormessage job-result-message') + #elseif ($status.hasLevel('WARN')) + #set($jobReportMessage = $services.localization.render($translationPrefix + ".message.warning")) + #set($messageClass = 'warningmessage job-result-message') + #else + #set($jobReportMessage = $services.localization.render($translationPrefix + ".message.success")) + #set($messageClass = 'successmessage job-result-message') + #end + <div class="box $messageClass"> + $escapetool.xml($jobReportMessage) + </div> +#end +#macro (printResult $jobResult) + <div> + $escapetool.xml($services.localization.render($jobResult.getMessage(), $jobResult.getParameters())) + </div> +#end +#macro (printJobResults $status) + #if ($status.state != 'FINISHED') + #set($loading = true) + #end + #set($jobResults = $status.getJobResults()) + <ul class="log"> + #foreach ($jobResult in $jobResults) + #set ($resultLevel = $jobResult.getLevel().name().toLowerCase()) + ## Display the last result item as loading if the associated task is not finished. + <li class="log-item log-item-${resultLevel}#if ($loading && !$foreach.hasNext) log-item-loading#end"> + #printResult($jobResult) + </li> + #end + </ul> +#end +#macro (displayJobResults $status $collapsed) + <dl class="xform"> + <dt> + <label class="collapse-toggle#if ($collapsed || $status.state == 'WAITING') collapsed#end" + data-target-xpath="parent::*/following-sibling::*"> + <span class="icon-closed">$services.icon.renderHTML('caret-right')</span> + <span class="icon-opened">$services.icon.renderHTML('caret-down')</span> + $escapetool.xml($services.localization.render('adminTools.jobs.result.hint')) + </label> + </dt> + <dd>#printJobResults($status)</dd> + </dl> +#end +{{/velocity}} + diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckJob.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/JobOutput.xml similarity index 81% rename from application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckJob.xml rename to application-admintools-ui/src/main/resources/AdminTools/Code/JobOutput.xml index 31303706..38f6e599 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/HealthCheckJob.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/JobOutput.xml @@ -20,29 +20,31 @@ * 02110-1301 USA, or see the FSF site: http://www.fsf.org. --> - + AdminTools.Code - HealthCheckJob + JobOutput 0 xwiki:XWiki.Admin - AdminTools.WebHome + WebHome xwiki:XWiki.Admin xwiki:XWiki.Admin 1.1 - HealthCheckJob + JobOutput false xwiki/2.1 true - {{velocity}} + {{include reference="AdminTools.Code.JobCommonMacros" /}} + +{{velocity}} #template('job_macros.vm') -#includeMacros("AdminTools.Code.HealthCheckMacros") #set($jobId = $request.getParameterValues('jobId')) +#set($translationPrefix = $request.getParameter('translationPrefix')) #set($jobStatus = $services.job.getJobStatus($jobId)) #if ($jobStatus) - #healthCheckOutputJobStatus($jobStatus) + #outputJobStatus($jobStatus, $translationPrefix) #else $response.setStatus(404) {{error}}{{translation key="admintools.job.notFound"/}}{{/error}} diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml index 32baf2b7..db3f648d 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/Macros.xml @@ -283,5 +283,20 @@ </div> </div> #end +#macro (displayUploadedPackagesLiveData) +=$services.icon.render('book') {{translation key='adminTools.packages.started.livedata.title'/}}= +{{liveData + id="adminToolsPackageUploads" + properties="doc.title,job_status,doc.author,doc.date" + source="liveTable" + sourceParameters="resultPage=AdminTools.Code.PackagesJSON&className=AdminTools.Code.PackageUploadClass&translationPrefix=adminTools.packages.upload.livetable." + sort='doc.date:desc'}}{ + "meta": { + "propertyDescriptors": [ + { "id": "job_status", "displayer": "html", "filterable": "false", "sortable": "false"} + ] + } +}{{/liveData}} +#end {{/velocity}} diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadClass.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadClass.xml new file mode 100644 index 00000000..2f7dec5c --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadClass.xml @@ -0,0 +1,166 @@ + + + + + + AdminTools.Code + PackageUploadClass + + + 0 + xwiki:XWiki.Admin + AdminTools.WebHome + xwiki:XWiki.Admin + xwiki:XWiki.Admin + 1.1 + PackageUploadClass + + false + xwiki/2.1 + true + + + AdminTools.Code.PackageUploadClass + + + + + + + + + + 0 + + package + 1 + 1 + package + 30 + 0 + + + com.xpn.xwiki.objects.classes.StringClass + + + + 0 + + startTime + 2 + long + startTime + 30 + 0 + + + com.xpn.xwiki.objects.classes.NumberClass + + + + AdminTools.Code.PackageUploadClass + 0 + XWiki.ClassSheetBinding + cdb072df-0777-4c4e-b374-84c46d7fe53a + + XWiki.ClassSheetBinding + + + + + + + + + 0 + + + 0 + input + + + 0 + sheet + 1 + 1 + Sheet + 0 + + + 30 + none + + 0 + + + + com.xpn.xwiki.objects.classes.PageClass + + + + PackageUploadSheet + + + + AdminTools.Code.PackageUploadClass + 0 + XWiki.DocumentSheetBinding + 1fbf9df6-3274-4294-bfde-2a8eb10d7b5f + + XWiki.DocumentSheetBinding + + + + + + + + + 0 + + + 0 + input + + + 0 + sheet + 1 + 1 + Sheet + 0 + + + 30 + none + + 0 + + + + com.xpn.xwiki.objects.classes.PageClass + + + + XWiki.ClassSheet + + + diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadSheet.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadSheet.xml new file mode 100644 index 00000000..2b1df4d7 --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadSheet.xml @@ -0,0 +1,91 @@ + + + + + + AdminTools.Code + PackageUploadSheet + + + 0 + xwiki:XWiki.Admin + AdminTools.Code.PackageUploadClass + xwiki:XWiki.Admin + xwiki:XWiki.Admin + 1.1 + + <comment/> + <minorEdit>false</minorEdit> + <syntaxId>xwiki/2.1</syntaxId> + <hidden>true</hidden> + <content>{{include reference="AdminTools.Code.JobCommonMacros" /}} + +{{velocity output='false'}} +#template('job_macros.vm') +#set ($discard = $xwiki.jsfx.use('uicomponents/job/job.js', true)) +#macro (uploadJobProgress) + #set ($xobject = $doc.getObject('AdminTools.Code.PackageUploadClass')) + #set ($uploadJobId = ['adminTools','import',"${xobject.get('package')}", "${xobject.get('startTime')}"]) + #set ($translationPrefix = 'adminTools.jobs.upload') + #set ($jobStatusURL = $xwiki.getURL('AdminTools.Code.JobOutput', 'get', $escapetool.url({ + 'jobId': $uploadJobId, + 'translationPrefix': $translationPrefix, + 'outputSyntax': 'plain' + }))) + #set ($uploadJobStatus = $services.job.getJobStatus($uploadJobId)) + <div class="xcontent job-status" data-url="${jobStatusURL}"> + #if ($uploadJobStatus) + #if ($uploadJobStatus.state != 'FINISHED') + #displayJobProgressBar($uploadJobStatus) + #else + #customJobFinishedMessage($uploadJobStatus, $translationPrefix) + #end + #if ($showLogs || $isAdvancedUser || $isSuperAdmin || $hasAdmin) + #displayJobResults($uploadJobStatus false) + #end + #else + #error($escapetool.xml($services.localization.render('adminTools.jobs.upload.start.fail', + [${xobject.get('package')}, ${xobject.get('startTime')}]))) + #end + </div> + #set ($packagesUploadURL = $xwiki.getDocument('AdminTools.ImportPackage').getURL('view')) + <a href="${packagesUploadURL}"> + $escapetool.xml($services.localization.render('adminTools.packages.return'))</a> +#end +{{/velocity}} + +{{velocity}} +#set ($mainReference = $services.model.createDocumentReference('', ['AdminTools', 'Code'], 'ConfigurationClass')) +#if ($services.licensing.licensor.hasLicensureForEntity($mainReference)) + #if ($hasAdmin) + {{html clean='false' wiki='true'}} + #uploadJobProgress() + {{/html}} + #else + {{error}}$services.rendering.escape($services.localization.render('adminTools.dashboard.missingRights'), + $xwiki.currentContentSyntaxId){{/error}} + #end +#else + {{missingLicenseMessage extensionName="adminTools.extension.name"/}} +#end +{{/velocity}} +</content> +</xwikidoc> diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadTemplate.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadTemplate.xml new file mode 100644 index 00000000..9aae0f32 --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/PackageUploadTemplate.xml @@ -0,0 +1,90 @@ +<?xml version="1.1" encoding="UTF-8"?> + +<!-- + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. +--> + +<xwikidoc version="1.5" reference="AdminTools.Code.PackageUploadTemplate" locale=""> + <web>AdminTools.Code</web> + <name>PackageUploadTemplate</name> + <language/> + <defaultLanguage/> + <translation>0</translation> + <creator>xwiki:XWiki.Admin</creator> + <parent>AdminTools.Code.PackageUploadClass</parent> + <author>xwiki:XWiki.Admin</author> + <contentAuthor>xwiki:XWiki.Admin</contentAuthor> + <version>1.1</version> + <title>PackageUploadTemplate + + false + xwiki/2.1 + true + + + AdminTools.Code.PackageUploadTemplate + 0 + AdminTools.Code.PackageUploadClass + b8c420d3-90e0-4e96-a5c3-585659b19ac8 + + AdminTools.Code.PackageUploadClass + + + + + + + + + + 0 + + package + 1 + 1 + package + 30 + 0 + + + com.xpn.xwiki.objects.classes.StringClass + + + + 0 + + startTime + 2 + long + startTime + 30 + 0 + + + com.xpn.xwiki.objects.classes.NumberClass + + + + + + + + + + diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/PackagesJSON.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/PackagesJSON.xml new file mode 100644 index 00000000..8f1e8e5a --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/PackagesJSON.xml @@ -0,0 +1,86 @@ + + + + + + AdminTools.Code + PackagesJSON + + + 0 + xwiki:XWiki.Admin + AdminTools.ImportPackage + xwiki:XWiki.Admin + xwiki:XWiki.Admin + 1.1 + PackagesJSON + + false + xwiki/2.1 + true + {{include reference="AdminTools.Code.Macros" /}} +{{include reference="XWiki.LiveTableResultsMacros" /}} + +{{velocity wiki='false'}} +#if($xcontext.action == 'get' && "$!{request.outputSyntax}" == 'plain') + $response.setContentType('application/json') + #set($map = {}) + #gridresult_buildJSON("$!request.classname" $request.collist.split(',') $map) + ## Add the status of the executed/executing job. + #macro (packageUploadStatus $message) + <div class="packageUploadState"> + <div class="packageUploadStateText">$message</div> + </div> + #end + #foreach($row in $map.get('rows')) + #set ($rowDocRef = $services.model.resolveDocument($row.get('doc_fullName'))) + #set ($rowDoc = $xwiki.getDocument($rowDocRef)) + #set ($xobject = $rowDoc.getObject('AdminTools.Code.PackageUploadClass')) + #set ($uploadJobId = ['adminTools','import',"${xobject.get('package')}", "${xobject.get('startTime')}"]) + #set ($uploadJobStatus = $services.job.getJobStatus($uploadJobId)) + #set ($jobState = $uploadJobStatus.state) + #if ("$!jobState" == '' || $jobState == 'NONE') + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.none'))")) + #elseif ($jobState == 'WAITING') + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.waiting'))")) + #elseif ($jobState == 'RUNNING') + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.running'))")) + #elseif ($uploadJobStatus.hasLevel('ERROR')) + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.error'))")) + #elseif ($uploadJobStatus.hasLevel('WARN')) + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.warn'))")) + #elseif ($uploadJobStatus.hasLevel('INFO')) + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.success'))")) + #else + #set ($discard = $row.put('job_status', + "$escapetool.xml($services.localization.render('adminTools.jobs.upload.state.noinfo'))")) + #end + #end + $jsontool.serialize($map) +#end +{{/velocity}} + diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/PackagesStore.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/PackagesStore.xml new file mode 100644 index 00000000..b5f1e94c --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/PackagesStore.xml @@ -0,0 +1,40 @@ + + + + + + AdminTools.Code + PackagesStore + + + 0 + xwiki:XWiki.Admin + AdminTools.WebHome + xwiki:XWiki.Admin + xwiki:XWiki.Admin + 1.1 + + <comment/> + <minorEdit>false</minorEdit> + <syntaxId>xwiki/2.1</syntaxId> + <hidden>true</hidden> + <content/> +</xwikidoc> diff --git a/application-admintools-ui/src/main/resources/AdminTools/Code/Translations.xml b/application-admintools-ui/src/main/resources/AdminTools/Code/Translations.xml index 2c5a2c7d..def6cadb 100644 --- a/application-admintools-ui/src/main/resources/AdminTools/Code/Translations.xml +++ b/application-admintools-ui/src/main/resources/AdminTools/Code/Translations.xml @@ -125,7 +125,6 @@ adminTools.dashboard.healthcheck.message.success=No issue found! adminTools.dashboard.healthcheck.message.warning=Some issues have been found, for more details please see the results below. adminTools.dashboard.healthcheck.message.error=Critical issues were found, please consult the results below! adminTools.dashboard.healthcheck.operations=Instance operations -adminTools.dashboard.healthcheck.result=Health check results adminTools.dashboard.healthcheck.linkLabel=help links ##Instance usage @@ -157,6 +156,39 @@ adminTools.dashboard.security.pwd=Working directory adminTools.dashboard.security.title=Security +## Jobs +adminTools.jobs.upload.start.fail=Failed to start job for file [{0}] at time [{1}]. +adminTools.jobs.upload.message.success=Upload was successful! +adminTools.jobs.upload.backup.success=Backup file [{0}] created for file [{1}]. +adminTools.jobs.upload.backup.fail=Could not create backup file [{0}] for file [{1}]. +adminTools.jobs.upload.assessoriginal.fail=Unable to correctly assess the original file for [{0}]. +adminTools.jobs.upload.batch.save.success=Successfully uploaded file [{0}]. +adminTools.jobs.upload.batch.save.fail=Failed to upload [{0}]. Reason: failed to delete original file [{1}]. +adminTools.jobs.upload.batch.backup.backup.fail=Manual action required: failed to automatically remove backup file [{0}]. +adminTools.jobs.upload.batch.backup.target.fail=Manual action required: failed to automatically remove new file [{0}]. +adminTools.jobs.upload.batch.backup.copy.fail=Manual action required: failed to automatically restore backup file [{0}] for new file [{1}]. +adminTools.jobs.upload.batch.backup.success=Successfully restored backup and removed new file [{0}]. +adminTools.jobs.result.hint=Job results +adminTools.jobs.upload.state.none=NO JOB FOUND +adminTools.jobs.upload.state.waiting=WAITING +adminTools.jobs.upload.state.running=RUNNING +adminTools.jobs.upload.state.error=ERROR +adminTools.jobs.upload.state.warn=WARNING +adminTools.jobs.upload.state.success=DONE +adminTools.jobs.upload.state.noinfo=NO INFO + + +##Packages +adminTools.packages.upload.livetable.doc.title=Package name +adminTools.packages.upload.livetable.job_status=Upload status +adminTools.packages.upload.livetable.doc.author=Initiator +adminTools.packages.upload.livetable.doc.date=Upload date +adminTools.packages.upload.livedata.title=Choose or load a package to upload +adminTools.packages.started.livedata.title=Uploaded packages +adminTools.packages.dashboard.uploadpackages=Upload a package +adminTools.packages.return=Return to the upload overview + + ##Help links adminTools.helpPage.browser.support=Browser support adminTools.helpPage.browser.title=Browser diff --git a/application-admintools-ui/src/main/resources/AdminTools/ImportPackage.xml b/application-admintools-ui/src/main/resources/AdminTools/ImportPackage.xml new file mode 100644 index 00000000..c09cce86 --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/ImportPackage.xml @@ -0,0 +1,211 @@ +<?xml version="1.1" encoding="UTF-8"?> + +<!-- + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. +--> + +<xwikidoc version="1.5" reference="AdminTools.ImportPackage" locale=""> + <web>AdminTools</web> + <name>ImportPackage</name> + <language/> + <defaultLanguage>en</defaultLanguage> + <translation>0</translation> + <creator>xwiki:XWiki.Admin</creator> + <parent>AdminTools.WebHome</parent> + <author>xwiki:XWiki.Admin</author> + <contentAuthor>xwiki:XWiki.Admin</contentAuthor> + <version>1.1</version> + <title>Import Package + + false + xwiki/2.1 + false + {{include reference="AdminTools.Code.Macros"/}} + +{{velocity output="false"}} +#template('attachment_macros.vm') +#set ($discard = $xwiki.jsx.use('AdminTools.Code.AdminToolsJS')) +$xwiki.jsfx.use('uicomponents/widgets/upload.js', {'forceSkinAction': true, 'language': ${xcontext.locale}}) +$xwiki.ssfx.use('uicomponents/widgets/upload.css', true) +## Reuse Attachments tab delete action events for the uploaded packages livedata. +$xwiki.jsfx.use('js/xwiki/viewers/attachments.js', {'forceSkinAction': true, 'language': ${xcontext.locale}}) +#set ($discard = $xwiki.jsx.use('AppWithinMinutes.LiveTableViewSheet', {'currentApp': $doc.getDocumentReference()})) +{{/velocity}} + +{{velocity}} +#set ($mainReference = $services.model.createDocumentReference('', ['AdminTools', 'Code'], 'ConfigurationClass')) +#if ($services.licensing.licensor.hasLicensureForEntity($mainReference)) + #if ($hasAdmin) + =$services.icon.render('box') {{translation key='adminTools.packages.upload.livedata.title'/}}= + #set ($storeDoc = $xwiki.getDocument('AdminTools.Code.PackagesStore')) + #showAttachmentsLiveData($storeDoc 'docAttachments') + + {{html clean='false'}} + <form action="$storeDoc.getURL("upload")" enctype="multipart/form-data" method="post" id="adminToolsAddPackage"> + <div> + ## CSRF prevention + <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> + <fieldset> + <div class="fileupload-field"> + <label class="sr-only" for="adminToolsUploadPackage">$escapetool.xml( + $services.localization.render('core.viewers.attachments.upload.file'))</label> + <input id="adminToolsUploadPackage" type="file" name="filepath" size=40 class="uploadFileInput noitems" + data-max-file-size=$!escapetool.xml($xwiki.getSpacePreference('upload_maxsize')) accept=".zip"/> + </div> + </fieldset> + </div> + </form> + <br/> + {{/html}} + #displayUploadedPackagesLiveData + #else + {{error}}$services.rendering.escape($services.localization.render('adminTools.dashboard.missingRights'), + $xwiki.currentContentSyntaxId){{/error}} + #end +#else + {{missingLicenseMessage extensionName="adminTools.extension.name"/}} +#end +{{/velocity}} + + AdminTools.ImportPackage + 0 + XWiki.StyleSheetExtension + ebae5d4f-793d-4c49-9c03-f5ecf01af55f + + XWiki.StyleSheetExtension + + + + + + + + + 0 + long + 0 + select + forbidden + 0 + 0 + cache + 5 + Caching policy + 0 + + |, + 1 + 0 + long|short|default|forbid + com.xpn.xwiki.objects.classes.StaticListClass + + + PureText + 0 + PureText + code + 2 + Code + 0 + 20 + 50 + 0 + com.xpn.xwiki.objects.classes.TextAreaClass + + + 0 + 0 + select + forbidden + 0 + 0 + contentType + 6 + Content Type + 0 + + |, + 1 + 0 + CSS|LESS + com.xpn.xwiki.objects.classes.StaticListClass + + + 0 + name + 1 + Name + 30 + 0 + com.xpn.xwiki.objects.classes.StringClass + + + 0 + select + yesno + parse + 4 + Parse content + 0 + com.xpn.xwiki.objects.classes.BooleanClass + + + 0 + 0 + select + forbidden + 0 + 0 + use + 3 + Use this extension + 0 + + |, + 1 + 0 + currentPage|onDemand|always + com.xpn.xwiki.objects.classes.StaticListClass + + + + long + + + #packagelistcontainer .upload-link { + background: url("$xwiki.getSkinFile('icons/silk/add.png')") no-repeat left 0.2em; + display: block; + height: 1.4em; + width: 16px; +} + + + CSS + + + AdminTools_ImportPackage + + + 1 + + + currentPage + + + diff --git a/application-admintools-ui/src/main/resources/AdminTools/Packages/WebHome.xml b/application-admintools-ui/src/main/resources/AdminTools/Packages/WebHome.xml new file mode 100644 index 00000000..0ab0327a --- /dev/null +++ b/application-admintools-ui/src/main/resources/AdminTools/Packages/WebHome.xml @@ -0,0 +1,56 @@ + + + + + + AdminTools.Packages + WebHome + + en + 0 + xwiki:XWiki.Admin + Main.WebHome + xwiki:XWiki.Admin + xwiki:XWiki.Admin + 1.1 + Packages + + false + xwiki/2.1 + false + {{include reference="AdminTools.Code.Macros"/}} + +{{velocity}} +#set ($mainReference = $services.model.createDocumentReference('', ['AdminTools', 'Code'], 'ConfigurationClass')) +#if ($services.licensing.licensor.hasLicensureForEntity($mainReference)) + #if ($hasAdmin) + #displayUploadedPackagesLiveData + #else + {{error}}$services.rendering.escape($services.localization.render('adminTools.dashboard.missingRights'), + $xwiki.currentContentSyntaxId){{/error}} + #end +#else + {{missingLicenseMessage extensionName="adminTools.extension.name"/}} +#end + +{{/velocity}} + +