Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)

84969: Merged PLATFORM1 (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud)
      83756: ACE-2269	 - Allow AMPs to include literals in version number (e.g. -SNAPSHOT)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@85284 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2014-09-20 09:56:48 +00:00
parent 57da7bc775
commit 6bba4fe0e8
14 changed files with 458 additions and 77 deletions

View File

@@ -24,15 +24,14 @@ import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.tenant.TenantAdminService;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.module.ModuleService;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.PropertyCheck;
import org.alfresco.util.VersionNumber;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Implementation of a {@link org.alfresco.repo.module.ModuleComponent} to provide
@@ -58,9 +57,9 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa
private String moduleId;
private String name;
private String description;
private VersionNumber sinceVersion;
private VersionNumber appliesFromVersion;
private VersionNumber appliesToVersion;
private ModuleVersionNumber sinceVersion;
private ModuleVersionNumber appliesFromVersion;
private ModuleVersionNumber appliesToVersion;
private List<ModuleComponent> dependsOn;
/** Defaults to <tt>true</tt> */
private boolean executeOnceOnly;
@@ -68,9 +67,9 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa
public AbstractModuleComponent()
{
sinceVersion = VersionNumber.VERSION_ZERO;
appliesFromVersion = VersionNumber.VERSION_ZERO;
appliesToVersion = VersionNumber.VERSION_BIG;
sinceVersion = ModuleVersionNumber.VERSION_ZERO;
appliesFromVersion = ModuleVersionNumber.VERSION_ZERO;
appliesToVersion = ModuleVersionNumber.VERSION_BIG;
dependsOn = new ArrayList<ModuleComponent>(0);
executeOnceOnly = true;
executed = new HashMap<String, Boolean>(1);
@@ -226,7 +225,7 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa
/**
* {@inheritDoc}
*/
public VersionNumber getSinceVersionNumber()
public ModuleVersionNumber getSinceVersionNumber()
{
return sinceVersion;
}
@@ -236,13 +235,13 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa
*/
public void setSinceVersion(String version)
{
this.sinceVersion = new VersionNumber(version);
this.sinceVersion = new ModuleVersionNumber(version);
}
/**
* {@inheritDoc}
*/
public VersionNumber getAppliesFromVersionNumber()
public ModuleVersionNumber getAppliesFromVersionNumber()
{
return appliesFromVersion;
}
@@ -253,13 +252,13 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa
*/
public void setAppliesFromVersion(String version)
{
this.appliesFromVersion = new VersionNumber(version);
this.appliesFromVersion = new ModuleVersionNumber(version);
}
/**
* {@inheritDoc}
*/
public VersionNumber getAppliesToVersionNumber()
public ModuleVersionNumber getAppliesToVersionNumber()
{
return appliesToVersion;
}
@@ -270,7 +269,7 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa
*/
public void setAppliesToVersion(String version)
{
this.appliesToVersion = new VersionNumber(version);
this.appliesToVersion = new ModuleVersionNumber(version);
}
/**

View File

@@ -58,17 +58,17 @@ public interface ModuleComponent
/**
* @return Returns the version number of the module for which this component was introduced.
*/
VersionNumber getSinceVersionNumber();
ModuleVersionNumber getSinceVersionNumber();
/**
* @return Returns the smallest version number of the module to which this component applies.
*/
VersionNumber getAppliesFromVersionNumber();
ModuleVersionNumber getAppliesFromVersionNumber();
/**
* @return Returns the largest version number of the module to which this component applies.
*/
VersionNumber getAppliesToVersionNumber();
ModuleVersionNumber getAppliesToVersionNumber();
/**
* A list of module components that <b>must</b> be executed prior to this instance.

View File

@@ -18,6 +18,7 @@
*/
package org.alfresco.repo.module;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -28,9 +29,9 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.registry.RegistryKey;
import org.alfresco.repo.admin.registry.RegistryService;
import org.alfresco.repo.module.tool.ModuleManagementToolException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.Tenant;
@@ -49,6 +50,7 @@ import org.alfresco.util.PropertyCheck;
import org.alfresco.util.VersionNumber;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Helper class to split up some of the code for managing module components. This class handles
@@ -421,13 +423,13 @@ public class ModuleComponentHelper
* @param moduleId
* @return
*/
VersionNumber getVersion(String moduleId)
ModuleVersionNumber getVersion(String moduleId)
{
RegistryKey moduleKeyCurrentVersion = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION);
VersionNumber versionCurrent = (VersionNumber) registryService.getProperty(moduleKeyCurrentVersion);
return versionCurrent;
Serializable versionCurrent = registryService.getProperty(moduleKeyCurrentVersion);
return getModuleVersionNumber(versionCurrent);
}
/**
@@ -456,7 +458,7 @@ public class ModuleComponentHelper
{
// Get the specifics of the missing module
VersionNumber versionCurrent = getVersion(moduleId);
ModuleVersionNumber versionCurrent = getVersion(moduleId);
// The module is missing, so warn
loggerService.warn(I18NUtil.getMessage(MSG_MISSING, moduleId, versionCurrent));
}
@@ -527,7 +529,7 @@ public class ModuleComponentHelper
private void startModule(ModuleDetails module, Set<String> startedModules, Set<ModuleComponent> executedComponents)
{
String moduleId = module.getId();
VersionNumber moduleNewVersion = module.getVersion();
ModuleVersionNumber moduleNewVersion = module.getVersion();
// Double check whether we have done this module already
if (startedModules.contains(moduleId))
@@ -596,8 +598,8 @@ public class ModuleComponentHelper
RegistryKey moduleKeyCurrentVersion = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION);
VersionNumber moduleInstallVersion = (VersionNumber) registryService.getProperty(moduleKeyInstalledVersion);
VersionNumber moduleCurrentVersion = (VersionNumber) registryService.getProperty(moduleKeyCurrentVersion);
Serializable moduleInstallVersion = registryService.getProperty(moduleKeyInstalledVersion);
Serializable moduleCurrentVersion = registryService.getProperty(moduleKeyCurrentVersion);
String msg = null;
if (moduleCurrentVersion == null) // No previous record of it
{
@@ -609,21 +611,23 @@ public class ModuleComponentHelper
}
else // It is an upgrade or is the same
{
ModuleVersionNumber currentModuleVersion = getModuleVersionNumber(moduleCurrentVersion);
// Check that we have an installed version
if (moduleInstallVersion == null)
{
// A current version, but no installed version
logger.warn(I18NUtil.getMessage(WARN_NO_INSTALL_VERSION, moduleId, moduleCurrentVersion));
// Record the install version
registryService.addProperty(moduleKeyInstalledVersion, moduleCurrentVersion);
registryService.addProperty(moduleKeyInstalledVersion, currentModuleVersion);
moduleInstallVersion = moduleCurrentVersion;
}
if (moduleCurrentVersion.compareTo(moduleNewVersion) == 0) // The current version is the same
if (currentModuleVersion.compareTo(moduleNewVersion) == 0) // The current version is the same
{
msg = I18NUtil.getMessage(MSG_STARTING, moduleId, moduleNewVersion);
}
else if (moduleCurrentVersion.compareTo(moduleNewVersion) > 0) // Downgrading not supported
else if (currentModuleVersion.compareTo(moduleNewVersion) > 0) // Downgrading not supported
{
throw AlfrescoRuntimeException.create(ERR_NO_DOWNGRADE, moduleId, moduleCurrentVersion, moduleNewVersion);
}
@@ -652,12 +656,20 @@ public class ModuleComponentHelper
}
}
protected ModuleVersionNumber getModuleVersionNumber(Serializable moduleVersion)
{
if (moduleVersion instanceof ModuleVersionNumber) return (ModuleVersionNumber) moduleVersion;
if (moduleVersion instanceof VersionNumber) return new ModuleVersionNumber((VersionNumber)moduleVersion);
if (moduleVersion instanceof String) return new ModuleVersionNumber((String)moduleVersion);
throw new ModuleManagementToolException("Invalid moduleVersion");
}
/**
* Execute the component, respecting dependencies.
*/
private void executeComponent(
String moduleId,
VersionNumber currentVersion,
ModuleVersionNumber currentVersion,
ModuleComponent component,
Set<ModuleComponent> executedComponents)
{
@@ -676,8 +688,8 @@ public class ModuleComponentHelper
executedComponents.add(component);
// Check the version applicability
VersionNumber minVersion = component.getAppliesFromVersionNumber();
VersionNumber maxVersion = component.getAppliesToVersionNumber();
ModuleVersionNumber minVersion = component.getAppliesFromVersionNumber();
ModuleVersionNumber maxVersion = component.getAppliesToVersionNumber();
if (currentVersion.compareTo(minVersion) < 0 || currentVersion.compareTo(maxVersion) > 0)
{
// It is out of the allowable range for execution so we just ignore it

View File

@@ -49,7 +49,7 @@ public class ModuleDetailsImpl implements ModuleDetails
private String id;
private List<String> aliases;
private VersionNumber version;
private ModuleVersionNumber version;
private String title;
private String description;
private List<String> editions;
@@ -77,6 +77,7 @@ public class ModuleDetailsImpl implements ModuleDetails
* whitespace strings are not supported.
*
* @param properties the set of properties
* @Throws AlfrescoRuntimeException if unable to parse values
*/
public ModuleDetailsImpl(Properties properties)
{
@@ -136,11 +137,11 @@ public class ModuleDetailsImpl implements ModuleDetails
{
try
{
version = new VersionNumber(trimmedProperties.getProperty(PROP_VERSION));
version = new ModuleVersionNumber(trimmedProperties.getProperty(PROP_VERSION));
}
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Unable to parse version information: " + trimmedProperties.getProperty(PROP_VERSION), e);
throw new AlfrescoRuntimeException("Unable to parse version information: " + PROP_VERSION + ", " + trimmedProperties.getProperty(PROP_VERSION), e);
}
}
// TITLE
@@ -152,12 +153,26 @@ public class ModuleDetailsImpl implements ModuleDetails
// REPO MIN
if (trimmedProperties.getProperty(PROP_REPO_VERSION_MIN) != null)
{
repoVersionMin = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MIN));
try
{
repoVersionMin = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MIN));
}
catch (Throwable t)
{
throw new AlfrescoRuntimeException("Unable to parse repo version min: " + PROP_REPO_VERSION_MIN + ", " + repoVersionMin, t);
}
}
// REPO MAX
if (trimmedProperties.getProperty(PROP_REPO_VERSION_MAX) != null)
{
repoVersionMax = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MAX));
try
{
repoVersionMax = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MAX));
}
catch (Throwable t)
{
throw new AlfrescoRuntimeException("Unable to parse repo version max: " + PROP_REPO_VERSION_MAX + ", " + repoVersionMax, t);
}
}
// DEPENDENCIES
this.dependencies = extractDependencies(trimmedProperties);
@@ -174,7 +189,7 @@ public class ModuleDetailsImpl implements ModuleDetails
}
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Unable to parse install date: " + installDateStr, e);
throw new AlfrescoRuntimeException("Unable to parse install date: " + PROP_INSTALL_DATE + ", " + installDateStr, e);
}
}
// INSTALL STATE
@@ -187,7 +202,7 @@ public class ModuleDetailsImpl implements ModuleDetails
}
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Unable to parse install state: " + installStateStr, e);
throw new AlfrescoRuntimeException("Unable to parse install state: " + PROP_INSTALL_STATE +", " + installStateStr, e);
}
}
// Check
@@ -215,7 +230,7 @@ public class ModuleDetailsImpl implements ModuleDetails
* @param title title
* @param description description
*/
public ModuleDetailsImpl(String id, VersionNumber versionNumber, String title, String description)
public ModuleDetailsImpl(String id, ModuleVersionNumber versionNumber, String title, String description)
{
// Set defaults
this();
@@ -345,7 +360,7 @@ public class ModuleDetailsImpl implements ModuleDetails
return aliases;
}
public VersionNumber getVersion()
public ModuleVersionNumber getVersion()
{
return version;
}
@@ -467,7 +482,7 @@ public class ModuleDetailsImpl implements ModuleDetails
private String dependencyId;
private String versionStr;
private List<Pair<VersionNumber, VersionNumber>> versionRanges;
private List<Pair<ModuleVersionNumber, ModuleVersionNumber>> versionRanges;
private ModuleDependencyImpl(String dependencyId, String versionStr)
{
@@ -491,9 +506,9 @@ public class ModuleDetailsImpl implements ModuleDetails
return sb.toString();
}
private static List<Pair<VersionNumber, VersionNumber>> buildVersionRanges(String versionStr)
private static List<Pair<ModuleVersionNumber, ModuleVersionNumber>> buildVersionRanges(String versionStr)
{
List<Pair<VersionNumber, VersionNumber>> versionRanges = new ArrayList<Pair<VersionNumber, VersionNumber>>(1);
List<Pair<ModuleVersionNumber, ModuleVersionNumber>> versionRanges = new ArrayList<Pair<ModuleVersionNumber, ModuleVersionNumber>>(1);
StringTokenizer rangesTokenizer = new StringTokenizer(versionStr, ",");
while (rangesTokenizer.hasMoreTokens())
{
@@ -513,8 +528,8 @@ public class ModuleDetailsImpl implements ModuleDetails
}
// The range must have at least one version in it
StringTokenizer rangeTokenizer = new StringTokenizer(range, "-", false);
VersionNumber versionLower = null;
VersionNumber versionUpper = null;
ModuleVersionNumber versionLower = null;
ModuleVersionNumber versionUpper = null;
while (rangeTokenizer.hasMoreTokens())
{
String version = rangeTokenizer.nextToken();
@@ -524,12 +539,12 @@ public class ModuleDetailsImpl implements ModuleDetails
if (version.equals("*"))
{
// Unbounded lower version
versionLower = VersionNumber.VERSION_ZERO;
versionLower = ModuleVersionNumber.VERSION_ZERO;
}
else
{
// Explicit lower bound
versionLower = new VersionNumber(version);
versionLower = new ModuleVersionNumber(version);
}
}
else if (versionUpper == null)
@@ -537,12 +552,12 @@ public class ModuleDetailsImpl implements ModuleDetails
if (version.equals("*"))
{
// Unbounded upper version
versionUpper = VersionNumber.VERSION_BIG;
versionUpper = ModuleVersionNumber.VERSION_BIG;
}
else
{
// Explicit upper bound
versionUpper = new VersionNumber(version);
versionUpper = new ModuleVersionNumber(version);
}
}
}
@@ -565,7 +580,7 @@ public class ModuleDetailsImpl implements ModuleDetails
versionLower = versionUpper;
}
// Create the range pair
Pair<VersionNumber, VersionNumber> rangePair = new Pair<VersionNumber, VersionNumber>(versionLower, versionUpper);
Pair<ModuleVersionNumber, ModuleVersionNumber> rangePair = new Pair<ModuleVersionNumber, ModuleVersionNumber>(versionLower, versionUpper);
versionRanges.add(rangePair);
}
return versionRanges;
@@ -594,12 +609,12 @@ public class ModuleDetailsImpl implements ModuleDetails
return false;
}
// Check the version number
VersionNumber checkVersion = moduleDetails.getVersion();
ModuleVersionNumber checkVersion = moduleDetails.getVersion();
boolean matched = false;
for (Pair<VersionNumber, VersionNumber> versionRange : versionRanges)
for (Pair<ModuleVersionNumber, ModuleVersionNumber> versionRange : versionRanges)
{
VersionNumber versionLower = versionRange.getFirst();
VersionNumber versionUpper = versionRange.getSecond();
ModuleVersionNumber versionLower = versionRange.getFirst();
ModuleVersionNumber versionUpper = versionRange.getSecond();
if (checkVersion.compareTo(versionLower) < 0)
{
// The version is too low

View File

@@ -196,7 +196,7 @@ public class ModuleServiceImpl implements ApplicationContextAware, ModuleService
if (moduleDetails == null)
{
// Get the specifics of the missing module and add them to the list.
VersionNumber currentVersion = moduleComponentHelper.getVersion(moduleId);
ModuleVersionNumber currentVersion = moduleComponentHelper.getVersion(moduleId);
ModuleDetails newModuleDetails = new ModuleDetailsImpl(moduleId, currentVersion, "", "");

View File

@@ -0,0 +1,94 @@
package org.alfresco.repo.module;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.alfresco.util.VersionNumber;
import org.apache.maven.artifact.versioning.ComparableVersion;
/**
* The exising Alfresco VersionNumber can only be numeric.
* ModuleVersionNumber allows string literals in the version number.
*
* It follows maven conventions and actually uses the ComparableVersion class
* from the maven code base.
*
* @author Gethin James
*/
public class ModuleVersionNumber implements Externalizable
{
private static final long serialVersionUID = 8594906471270433420L;
public static final ModuleVersionNumber VERSION_ZERO = new ModuleVersionNumber("0");;
public static final ModuleVersionNumber VERSION_BIG = new ModuleVersionNumber("999.999.999.99");
protected ComparableVersion delegate;
public ModuleVersionNumber()
{
super();
}
public ModuleVersionNumber(String versionString)
{
delegate = new ComparableVersion(versionString);
}
public ModuleVersionNumber(VersionNumber versionCurrent)
{
this(versionCurrent.toString());
}
public int compareTo(ModuleVersionNumber installingVersion)
{
return delegate.compareTo(installingVersion.delegate);
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((this.delegate == null) ? 0 : this.delegate.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ModuleVersionNumber other = (ModuleVersionNumber) obj;
if (this.delegate == null)
{
if (other.delegate != null) return false;
}
else if (!this.delegate.equals(other.delegate)) return false;
return true;
}
@Override
public String toString()
{
return this.delegate.toString();
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeUTF(delegate.toString());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
String versionString = in.readUTF();
delegate = new ComparableVersion(versionString);
}
}

View File

@@ -75,7 +75,7 @@ public class ModuleDetailsHelper
}
catch (FileNotFoundException error)
{
throw new ModuleManagementToolException("Unable to load module details from property file.", error);
throw new ModuleManagementToolException("Unable to load module details from property file. " + error.getMessage(), error);
}
try
@@ -85,7 +85,7 @@ public class ModuleDetailsHelper
catch (IOException exception)
{
throw new ModuleManagementToolException(
"Unable to load module details from property file.", exception);
"Unable to load module details from property file." + exception.getMessage(), exception);
}
finally
{

View File

@@ -27,6 +27,7 @@ import java.util.Map.Entry;
import java.util.Properties;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.module.ModuleVersionNumber;
import org.alfresco.service.cmr.module.ModuleDetails;
import org.alfresco.service.cmr.module.ModuleInstallState;
import org.alfresco.util.VersionNumber;
@@ -230,7 +231,7 @@ public class ModuleManagementTool implements LogOutput
throw new ModuleManagementToolException("No module.properties file has been found in the installing .amp file '" + ampFileLocation + "'");
}
String installingId = installingModuleDetails.getId();
VersionNumber installingVersion = installingModuleDetails.getVersion();
ModuleVersionNumber installingVersion = installingModuleDetails.getVersion();
//A series of checks
warHelper.checkCompatibleVersion(warFile, installingModuleDetails);
@@ -285,6 +286,10 @@ public class ModuleManagementTool implements LogOutput
TVFS.umount();
}
}
catch (AlfrescoRuntimeException exception)
{
throw new ModuleManagementToolException("An error was encountered during deployment of the AMP into the WAR: " + exception.getMessage(), exception);
}
catch (IOException exception)
{
throw new ModuleManagementToolException("An IO error was encountered during deployment of the AMP into the WAR", exception);
@@ -292,13 +297,13 @@ public class ModuleManagementTool implements LogOutput
}
private void uninstallIfNecessary(String warFileLocation, ModuleDetails installedModuleDetails, boolean preview,
boolean forceInstall, VersionNumber installingVersion) throws IOException
boolean forceInstall, ModuleVersionNumber installingVersion) throws IOException
{
// Now clean up the old instance
if (installedModuleDetails != null)
{
String installedId = installedModuleDetails.getId();
VersionNumber installedVersion = installedModuleDetails.getVersion();
ModuleVersionNumber installedVersion = installedModuleDetails.getVersion();
int compareValue = installedVersion.compareTo(installingVersion);
if (compareValue > 0)
@@ -655,6 +660,7 @@ public class ModuleManagementTool implements LogOutput
* Lists all the currently installed modules in the WAR
*
* @param warLocation the war location
* @throws ModuleManagementToolException
*/
public void listModules(String warLocation)
{
@@ -688,6 +694,10 @@ public class ModuleManagementTool implements LogOutput
is = new TFileInputStream(moduleProperties);
moduleDetails = ModuleDetailsHelper.createModuleDetailsFromPropertiesStream(is);
}
catch (AlfrescoRuntimeException exception)
{
throw new ModuleManagementToolException("Unable to open module properties file '" + moduleProperties.getPath() + "' " + exception.getMessage(), exception);
}
catch (IOException exception)
{
throw new ModuleManagementToolException("Unable to open module properties file '" + moduleProperties.getPath() + "'", exception);

View File

@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Properties;
import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.repo.module.ModuleVersionNumber;
import org.alfresco.util.VersionNumber;
/**
@@ -73,7 +74,7 @@ public interface ModuleDetails extends Serializable
*
* @return module version number
*/
VersionNumber getVersion();
ModuleVersionNumber getVersion();
/**
* Get the title of the module