mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Patch checkpoint.
Service descriptor changes including introduction of schema number. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2161 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -40,16 +40,23 @@ public abstract class AbstractPatch implements Patch
|
||||
private static Log logger = LogFactory.getLog(AbstractPatch.class);
|
||||
|
||||
private String id;
|
||||
private String applyToVersion;
|
||||
private int fixesFromSchema;
|
||||
private int fixesToSchema;
|
||||
private int targetSchema;
|
||||
private String description;
|
||||
/** a list of patches that this one depends on */
|
||||
private List<Patch> dependsOn;
|
||||
/** flag indicating if the patch was successfully applied */
|
||||
private boolean applied;
|
||||
/** the service to register ourselves with */
|
||||
private PatchService patchService;
|
||||
private TransactionService transactionService;
|
||||
|
||||
public AbstractPatch()
|
||||
{
|
||||
this.fixesFromSchema = -1;
|
||||
this.fixesToSchema = -1;
|
||||
this.targetSchema = -1;
|
||||
this.applied = false;
|
||||
this.dependsOn = Collections.emptyList();
|
||||
}
|
||||
@@ -57,15 +64,25 @@ public abstract class AbstractPatch implements Patch
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(56);
|
||||
StringBuilder sb = new StringBuilder(256);
|
||||
sb.append("Patch")
|
||||
.append("[id=").append(getId())
|
||||
.append(", after=").append(getApplyToVersion())
|
||||
.append(", description=").append(getDescription())
|
||||
.append("[ id=").append(id)
|
||||
.append(", description=").append(description)
|
||||
.append(", fixesFromSchema=").append(fixesFromSchema)
|
||||
.append(", fixesToSchema=").append(fixesToSchema)
|
||||
.append(", targetSchema=").append(targetSchema)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the service that this patch will register with for execution.
|
||||
*/
|
||||
public void setPatchService(PatchService patchService)
|
||||
{
|
||||
this.patchService = patchService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction provider so that each execution can be performed within a transaction
|
||||
*/
|
||||
@@ -73,7 +90,19 @@ public abstract class AbstractPatch implements Patch
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This ensures that this bean gets registered with the appropriate {@link PatchService service}.
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
if (patchService == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Mandatory property not set: patchService");
|
||||
}
|
||||
patchService.registerPatch(this);
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
@@ -88,18 +117,70 @@ public abstract class AbstractPatch implements Patch
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getApplyToVersion()
|
||||
public int getFixesFromSchema()
|
||||
{
|
||||
return applyToVersion;
|
||||
return fixesFromSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the smallest schema number that this patch may be applied to.
|
||||
*
|
||||
* @param applyAfterVersion the version of the repository after which this patch must be applied.
|
||||
* @param version a schema number not smaller than 0
|
||||
*/
|
||||
public void setApplyToVersion(String applyAfterVersion)
|
||||
public void setFixesFromSchema(int version)
|
||||
{
|
||||
this.applyToVersion = applyAfterVersion;
|
||||
if (version < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("The 'fixesFromSchema' property may not be less than 0");
|
||||
}
|
||||
this.fixesFromSchema = version;
|
||||
// auto-adjust the to version
|
||||
if (fixesToSchema < fixesFromSchema)
|
||||
{
|
||||
setFixesToSchema(this.fixesFromSchema);
|
||||
}
|
||||
}
|
||||
|
||||
public int getFixesToSchema()
|
||||
{
|
||||
return fixesToSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the largest schema version number that this patch may be applied to.
|
||||
*
|
||||
* @param version a schema version number not smaller than the
|
||||
* {@link #setFixesFromSchema(int) from version} number.
|
||||
*/
|
||||
public void setFixesToSchema(int version)
|
||||
{
|
||||
if (version < fixesFromSchema)
|
||||
{
|
||||
throw new IllegalArgumentException("'fixesToSchema' must be greater than or equal to 'fixesFromSchema'");
|
||||
}
|
||||
this.fixesToSchema = version;
|
||||
}
|
||||
|
||||
public int getTargetSchema()
|
||||
{
|
||||
return targetSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the schema version that this patch attempts to take the existing schema to.
|
||||
* This is for informational purposes only, acting as an indicator of intention rather
|
||||
* than having any specific effect.
|
||||
*
|
||||
* @param version a schema version number that must be greater than the
|
||||
* {@link #fixesToSchema max fix schema number}
|
||||
*/
|
||||
public void setTargetSchema(int version)
|
||||
{
|
||||
if (version <= fixesToSchema)
|
||||
{
|
||||
throw new IllegalArgumentException("'targetSchema' must be greater than 'fixesToSchema'");
|
||||
}
|
||||
this.targetSchema = version;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
@@ -130,6 +211,36 @@ public abstract class AbstractPatch implements Patch
|
||||
this.dependsOn = dependsOn;
|
||||
}
|
||||
|
||||
public boolean applies(int version)
|
||||
{
|
||||
return ((this.fixesFromSchema <= version) && (version <= fixesToSchema));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the schema version properties have been set appropriately
|
||||
*/
|
||||
private void checkProperties()
|
||||
{
|
||||
// check that the necessary properties have been set
|
||||
if (id == null || description == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"Patch properties 'id', 'fixesFromSchema' and 'description' have not all been set on this patch: \n" +
|
||||
" patch: " + this);
|
||||
}
|
||||
else if (fixesFromSchema == -1 || fixesToSchema == -1 || targetSchema == -1)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"Patch properties 'fixesFromSchema', 'fixesToSchema' and 'targetSchema' have not all been set on this patch: \n" +
|
||||
" patch: " + this);
|
||||
}
|
||||
else if (transactionService == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("'transactionService' property has not been set: \n" +
|
||||
" patch: " + this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the transaction and ensures thread-safety.
|
||||
*
|
||||
@@ -143,18 +254,8 @@ public abstract class AbstractPatch implements Patch
|
||||
throw new AlfrescoRuntimeException("The patch has already been executed: \n" +
|
||||
" patch: " + this);
|
||||
}
|
||||
// check that the necessary properties have been set
|
||||
if (id == null || applyToVersion == null || description == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"Patch properties 'id', 'applyToVersion' and 'description' have not all been set on this patch: \n" +
|
||||
" patch: " + this);
|
||||
}
|
||||
else if (transactionService == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("'transactionService' property has not been set: \n" +
|
||||
" patch: " + this);
|
||||
}
|
||||
// check properties
|
||||
checkProperties();
|
||||
// execute in a transaction
|
||||
try
|
||||
{
|
||||
|
@@ -40,11 +40,20 @@ public interface Patch
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* @see PatchService#applyOutstandingPatches()
|
||||
* @see AbstractPatch#setApplyToVersion(String)
|
||||
* @return Returns the smallest schema number that this patch may be applied to
|
||||
*/
|
||||
public String getApplyToVersion();
|
||||
public int getFixesFromSchema();
|
||||
|
||||
/**
|
||||
* @return Returns the largest schema number that this patch may be applied to
|
||||
*/
|
||||
public int getFixesToSchema();
|
||||
|
||||
/**
|
||||
* @return Returns the schema number that this patch attempts to bring the repo up to
|
||||
*/
|
||||
public int getTargetSchema();
|
||||
|
||||
/**
|
||||
* Get patches that this patch depends on
|
||||
*
|
||||
@@ -52,6 +61,14 @@ public interface Patch
|
||||
*/
|
||||
public List<Patch> getDependsOn();
|
||||
|
||||
/**
|
||||
* Check if the patch is applicable to a given schema version.
|
||||
*
|
||||
* @param version a schema version number
|
||||
* @return Returns <code>(fixesFromVersion <= version <= fixesToVersion)</code>
|
||||
*/
|
||||
public boolean applies(int version);
|
||||
|
||||
/**
|
||||
* Applies the patch. Typically this will be within the bounds of a new
|
||||
* transaction.
|
||||
|
@@ -16,10 +16,6 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.admin.PatchInfo;
|
||||
|
||||
/**
|
||||
* Manages patches applied against the repository.
|
||||
* <p>
|
||||
@@ -32,19 +28,11 @@ import org.alfresco.service.cmr.admin.PatchInfo;
|
||||
public interface PatchService
|
||||
{
|
||||
/**
|
||||
* Set the complete list of patches. All patch IDs must remain static for the duration their
|
||||
* existence. This allows us to recognise the
|
||||
* Registers a patch with the service that executes them.
|
||||
*
|
||||
* @param patches the complete list of patches (either applied or not)
|
||||
* @param patch the patch to register
|
||||
*/
|
||||
public void setPatches(List<Patch> patches);
|
||||
|
||||
/**
|
||||
* Get a list of all previously applied patches
|
||||
*
|
||||
* @return Returns a list of patch application information
|
||||
*/
|
||||
public List<PatchInfo> getAppliedPatches();
|
||||
public void registerPatch(Patch patch);
|
||||
|
||||
/**
|
||||
* Apply all outstanding patches that are relevant to the repo.
|
||||
|
@@ -21,12 +21,9 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.domain.AppliedPatch;
|
||||
import org.alfresco.service.cmr.admin.PatchException;
|
||||
import org.alfresco.service.cmr.admin.PatchInfo;
|
||||
import org.alfresco.service.descriptor.Descriptor;
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -50,6 +47,11 @@ public class PatchServiceImpl implements PatchService
|
||||
private PatchDaoService patchDaoService;
|
||||
private List<Patch> patches;
|
||||
|
||||
public PatchServiceImpl()
|
||||
{
|
||||
this.patches = new ArrayList<Patch>(10);
|
||||
}
|
||||
|
||||
public void setDescriptorService(DescriptorService descriptorService)
|
||||
{
|
||||
this.descriptorService = descriptorService;
|
||||
@@ -60,29 +62,11 @@ public class PatchServiceImpl implements PatchService
|
||||
this.patchDaoService = patchDaoService;
|
||||
}
|
||||
|
||||
public void setPatches(List<Patch> patches)
|
||||
public void registerPatch(Patch patch)
|
||||
{
|
||||
this.patches = patches;
|
||||
patches.add(patch);
|
||||
}
|
||||
|
||||
public List<PatchInfo> getAppliedPatches()
|
||||
{
|
||||
// get all the persisted patches
|
||||
List<AppliedPatch> appliedPatches = patchDaoService.getAppliedPatches();
|
||||
List<PatchInfo> patchInfos = new ArrayList<PatchInfo>(appliedPatches.size());
|
||||
for (AppliedPatch patch : appliedPatches)
|
||||
{
|
||||
PatchInfo patchInfo = new PatchInfo(patch);
|
||||
patchInfos.add(patchInfo);
|
||||
}
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Retrieved list of " + patchInfos.size() + " applied patches: \n");
|
||||
}
|
||||
return patchInfos;
|
||||
}
|
||||
|
||||
|
||||
public boolean applyOutstandingPatches()
|
||||
{
|
||||
// construct a map of all known patches by ID
|
||||
@@ -92,23 +76,18 @@ public class PatchServiceImpl implements PatchService
|
||||
allPatchesById.put(patch.getId(), patch);
|
||||
}
|
||||
// construct a list of executed patches by ID
|
||||
Map<String, PatchInfo> appliedPatchInfosById = new HashMap<String, PatchInfo>(23);
|
||||
List<PatchInfo> appliedPatches = getAppliedPatches();
|
||||
for (PatchInfo patchInfo : appliedPatches)
|
||||
Map<String, AppliedPatch> appliedPatchesById = new HashMap<String, AppliedPatch>(23);
|
||||
List<AppliedPatch> appliedPatches = patchDaoService.getAppliedPatches();
|
||||
for (AppliedPatch appliedPatch : appliedPatches)
|
||||
{
|
||||
// ignore unsuccessful attempts - we need to try them again
|
||||
if (!patchInfo.getSucceeded())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
appliedPatchInfosById.put(patchInfo.getId(), patchInfo);
|
||||
appliedPatchesById.put(appliedPatch.getId(), appliedPatch);
|
||||
}
|
||||
// go through all the patches and apply them where necessary
|
||||
boolean success = true;
|
||||
for (Patch patch : allPatchesById.values())
|
||||
{
|
||||
// apply the patch
|
||||
success = applyPatchAndDependencies(patch, appliedPatchInfosById);
|
||||
success = applyPatchAndDependencies(patch, appliedPatchesById);
|
||||
if (!success)
|
||||
{
|
||||
// we failed to apply a patch or one of its dependencies - terminate
|
||||
@@ -126,15 +105,15 @@ public class PatchServiceImpl implements PatchService
|
||||
* @param patchInfos all the executed patch data. If there was a failure, then this
|
||||
* is the list of successful executions only.
|
||||
* @param patch the patch (containing dependencies) to apply
|
||||
* @param appliedPatchInfosById already applied patches
|
||||
* @param appliedPatchesById already applied patches keyed by their ID
|
||||
* @return Returns true if the patch and all its dependencies were successfully applied.
|
||||
*/
|
||||
private boolean applyPatchAndDependencies(Patch patch, Map<String, PatchInfo> appliedPatchInfosById)
|
||||
private boolean applyPatchAndDependencies(Patch patch, Map<String, AppliedPatch> appliedPatchesById)
|
||||
{
|
||||
String id = patch.getId();
|
||||
// check if it has already been done
|
||||
PatchInfo patchInfo = appliedPatchInfosById.get(id);
|
||||
if (patchInfo != null && patchInfo.getSucceeded())
|
||||
AppliedPatch appliedPatch = appliedPatchesById.get(id);
|
||||
if (appliedPatch != null && appliedPatch.getSucceeded())
|
||||
{
|
||||
// this has already been done
|
||||
return true;
|
||||
@@ -144,7 +123,7 @@ public class PatchServiceImpl implements PatchService
|
||||
List<Patch> dependencies = patch.getDependsOn();
|
||||
for (Patch dependencyPatch : dependencies)
|
||||
{
|
||||
boolean success = applyPatchAndDependencies(dependencyPatch, appliedPatchInfosById);
|
||||
boolean success = applyPatchAndDependencies(dependencyPatch, appliedPatchesById);
|
||||
if (!success)
|
||||
{
|
||||
// a patch failed to be applied
|
||||
@@ -152,8 +131,8 @@ public class PatchServiceImpl implements PatchService
|
||||
}
|
||||
}
|
||||
// all the dependencies were successful
|
||||
patchInfo = applyPatch(patch);
|
||||
if (!patchInfo.getSucceeded())
|
||||
appliedPatch = applyPatch(patch);
|
||||
if (!appliedPatch.getSucceeded())
|
||||
{
|
||||
// this was a failure
|
||||
return false;
|
||||
@@ -161,26 +140,24 @@ public class PatchServiceImpl implements PatchService
|
||||
else
|
||||
{
|
||||
// it was successful - add it to the map of successful patches
|
||||
appliedPatchInfosById.put(id, patchInfo);
|
||||
appliedPatchesById.put(id, appliedPatch);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private PatchInfo applyPatch(Patch patch)
|
||||
private AppliedPatch applyPatch(Patch patch)
|
||||
{
|
||||
// get the patch from the DAO
|
||||
AppliedPatch appliedPatch = patchDaoService.getAppliedPatch(patch.getId());
|
||||
if (appliedPatch != null && appliedPatch.getSucceeded())
|
||||
{
|
||||
// it has already been applied
|
||||
PatchInfo patchInfo = new PatchInfo(appliedPatch);
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Patch was already successfully applied: \n" +
|
||||
" patch: " + patchInfo);
|
||||
" patch: " + appliedPatch);
|
||||
}
|
||||
return patchInfo;
|
||||
return appliedPatch;
|
||||
}
|
||||
// the execution report
|
||||
String report = null;
|
||||
@@ -211,28 +188,29 @@ public class PatchServiceImpl implements PatchService
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
// create a record for the execution
|
||||
appliedPatch = patchDaoService.newAppliedPatch(patch.getId());
|
||||
// fill in the record's details
|
||||
appliedPatch.setDescription(patch.getDescription());
|
||||
appliedPatch.setApplyToVersion(patch.getApplyToVersion());
|
||||
appliedPatch.setSucceeded(success);
|
||||
appliedPatch.setAppliedOnVersion(repoDescriptor.getVersion());
|
||||
appliedPatch.setAppliedOnDate(new Date());
|
||||
appliedPatch.setReport(report);
|
||||
// create the info for returning
|
||||
PatchInfo patchInfo = new PatchInfo(appliedPatch);
|
||||
appliedPatch.setFixesFromSchema(patch.getFixesFromSchema());
|
||||
appliedPatch.setFixesToSchema(patch.getFixesToSchema());
|
||||
appliedPatch.setTargetSchema(patch.getTargetSchema()); // the schema the server is expecting
|
||||
appliedPatch.setAppliedToSchema(repoDescriptor.getSchema()); // the old schema of the repo
|
||||
appliedPatch.setAppliedOnDate(new Date()); // the date applied
|
||||
appliedPatch.setSucceeded(success); // whether or not the patch succeeded
|
||||
appliedPatch.setReport(report); // additional, human-readable, status
|
||||
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Applied patch: \n" + patchInfo);
|
||||
logger.debug("Applied patch: \n" + appliedPatch);
|
||||
}
|
||||
return patchInfo;
|
||||
return appliedPatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not the patch should be applied to the repository, given the descriptor.
|
||||
* This helper is required to
|
||||
* Check whether the patch is applicable to the particular version of the repository.
|
||||
*
|
||||
* @param repoDescriptor contains the version details of the repository
|
||||
* @param patch the patch whos version must be checked
|
||||
@@ -240,76 +218,15 @@ public class PatchServiceImpl implements PatchService
|
||||
*/
|
||||
private boolean applies(Descriptor repoDescriptor, Patch patch)
|
||||
{
|
||||
// resolve the version numbers of the repo
|
||||
int[] repoVersions = new int[] {0, 0, 0};
|
||||
try
|
||||
{
|
||||
if (repoDescriptor.getVersionMajor() != null)
|
||||
{
|
||||
repoVersions[0] = Integer.parseInt(repoDescriptor.getVersionMajor());
|
||||
}
|
||||
if (repoDescriptor.getVersionMinor() != null)
|
||||
{
|
||||
repoVersions[1] = Integer.parseInt(repoDescriptor.getVersionMinor());
|
||||
}
|
||||
if (repoDescriptor.getVersionRevision() != null)
|
||||
{
|
||||
repoVersions[2] = Integer.parseInt(repoDescriptor.getVersionRevision());
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Non-numeric repository version are not allowed: " +
|
||||
repoDescriptor.getVersion());
|
||||
}
|
||||
|
||||
// by default, the patch won't apply. All the revision numbers will have to be greater
|
||||
// than that of the repo to apply
|
||||
int[] applyToVersions = new int[] {0, 0, 0};
|
||||
try
|
||||
{
|
||||
// break the patch version up
|
||||
String applyToVersion = patch.getApplyToVersion();
|
||||
StringTokenizer tokens = new StringTokenizer(applyToVersion, ".");
|
||||
for (int i = 0; i < 3 && tokens.hasMoreTokens(); i++)
|
||||
{
|
||||
String versionStr = tokens.nextToken();
|
||||
applyToVersions[i] = Integer.parseInt(versionStr);
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Non-numeric patch apply version: " + patch);
|
||||
}
|
||||
|
||||
// compare each version number
|
||||
// in the event of a match, we don't apply as the patch version is the
|
||||
boolean apply = true;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (repoVersions[i] < applyToVersions[i])
|
||||
{
|
||||
// repo is old and patch is newer - we definitely need to apply
|
||||
apply = true;
|
||||
break;
|
||||
}
|
||||
else if (repoVersions[i] > applyToVersions[i])
|
||||
{
|
||||
// the repo version number is high enough (repo is new enough) that patch doesn't apply
|
||||
apply = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// so far, the two match
|
||||
}
|
||||
}
|
||||
int repoSchema = repoDescriptor.getSchema();
|
||||
// does the patch apply?
|
||||
boolean apply = patch.applies(repoSchema);
|
||||
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Patch version number check against repo version: \n" +
|
||||
" repo version: " + repoDescriptor.getVersion() + "\n" +
|
||||
logger.debug("Patch schema version number check against repo version: \n" +
|
||||
" repo schema version: " + repoDescriptor.getVersion() + "\n" +
|
||||
" patch: " + patch);
|
||||
}
|
||||
return apply;
|
||||
|
@@ -16,14 +16,13 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.domain.AppliedPatch;
|
||||
import org.alfresco.service.cmr.admin.PatchException;
|
||||
import org.alfresco.service.cmr.admin.PatchInfo;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -41,7 +40,7 @@ public class PatchTest extends TestCase
|
||||
|
||||
private TransactionService transactionService;
|
||||
private PatchService patchService;
|
||||
private List<Patch> patches;
|
||||
private PatchDaoService patchDaoComponent;
|
||||
|
||||
public PatchTest(String name)
|
||||
{
|
||||
@@ -52,18 +51,18 @@ public class PatchTest extends TestCase
|
||||
{
|
||||
transactionService = (TransactionService) ctx.getBean("transactionComponent");
|
||||
patchService = (PatchService) ctx.getBean("PatchService");
|
||||
patchDaoComponent = (PatchDaoService) ctx.getBean("patchDaoComponent");
|
||||
|
||||
// get the patches to play with
|
||||
patches = new ArrayList<Patch>(2);
|
||||
patches.add((Patch)ctx.getBean("patch.sample.02"));
|
||||
patches.add((Patch)ctx.getBean("patch.sample.01"));
|
||||
patchService.setPatches(patches);
|
||||
patchService.registerPatch((Patch)ctx.getBean("patch.sample.02"));
|
||||
patchService.registerPatch((Patch)ctx.getBean("patch.sample.01"));
|
||||
}
|
||||
|
||||
public void testSetup() throws Exception
|
||||
{
|
||||
assertNotNull(transactionService);
|
||||
assertNotNull(patchService);
|
||||
assertNotNull(patchDaoComponent);
|
||||
}
|
||||
|
||||
public void testSimplePatchSuccess() throws Exception
|
||||
@@ -119,21 +118,21 @@ public class PatchTest extends TestCase
|
||||
boolean success = patchService.applyOutstandingPatches();
|
||||
assertTrue(success);
|
||||
// get applied patches
|
||||
List<PatchInfo> patchInfos = patchService.getAppliedPatches();
|
||||
List<AppliedPatch> appliedPatches = patchDaoComponent.getAppliedPatches();
|
||||
// check that the patch application was recorded
|
||||
boolean found01 = false;
|
||||
boolean found02 = false;
|
||||
for (PatchInfo patchInfo : patchInfos)
|
||||
for (AppliedPatch appliedPatch : appliedPatches)
|
||||
{
|
||||
if (patchInfo.getId().equals("Sample01"))
|
||||
if (appliedPatch.getId().equals("Sample01"))
|
||||
{
|
||||
found01 = true;
|
||||
assertTrue("Patch info didn't indicate success: " + patchInfo, patchInfo.getSucceeded());
|
||||
assertTrue("Patch info didn't indicate success: " + appliedPatch, appliedPatch.getSucceeded());
|
||||
}
|
||||
else if (patchInfo.getId().equals("Sample02"))
|
||||
else if (appliedPatch.getId().equals("Sample02"))
|
||||
{
|
||||
found02 = true;
|
||||
assertTrue("Patch info didn't indicate success: " + patchInfo, patchInfo.getSucceeded());
|
||||
assertTrue("Patch info didn't indicate success: " + appliedPatch, appliedPatch.getSucceeded());
|
||||
}
|
||||
}
|
||||
assertTrue("Sample 01 not in list of applied patches", found01);
|
||||
|
@@ -32,6 +32,14 @@ public class SamplePatch extends AbstractPatch
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the base class version to do nothing, i.e. it does not self-register
|
||||
*/
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper constructor for some tests. Default properties are set automatically.
|
||||
*
|
||||
@@ -43,7 +51,9 @@ public class SamplePatch extends AbstractPatch
|
||||
setTransactionService(transactionService);
|
||||
setId("SamplePatch");
|
||||
setDescription("This is a sample patch");
|
||||
setApplyToVersion("1.0.0");
|
||||
setFixesFromSchema(0);
|
||||
setFixesToSchema(1000);
|
||||
setTargetSchema(1001);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.importer.ImporterBootstrap;
|
||||
import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.service.cmr.repository.InvalidStoreRefException;
|
||||
@@ -71,7 +72,7 @@ public class DescriptorServiceImpl implements DescriptorService, ApplicationList
|
||||
* @param descriptorResource resource containing server descriptor meta-data
|
||||
* @throws IOException
|
||||
*/
|
||||
public void setServerDescriptor(Resource descriptorResource)
|
||||
public void setDescriptor(Resource descriptorResource)
|
||||
throws IOException
|
||||
{
|
||||
this.serverProperties = new Properties();
|
||||
@@ -121,7 +122,7 @@ public class DescriptorServiceImpl implements DescriptorService, ApplicationList
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.DescriptorService#getDescriptor()
|
||||
*/
|
||||
public Descriptor getDescriptor()
|
||||
public Descriptor getServerDescriptor()
|
||||
{
|
||||
return serverDescriptor;
|
||||
}
|
||||
@@ -187,7 +188,9 @@ public class DescriptorServiceImpl implements DescriptorService, ApplicationList
|
||||
String serverEdition = serverDescriptor.getEdition();
|
||||
String serverVersion = serverDescriptor.getVersion();
|
||||
String repoVersion = repoDescriptor.getVersion();
|
||||
logger.info(String.format("Alfresco started (%s) - v%s; repository v%s", serverEdition, serverVersion, repoVersion));
|
||||
int schemaVersion = repoDescriptor.getSchema();
|
||||
logger.info(String.format("Alfresco started (%s) - v%s; repository v%s; schema %d",
|
||||
serverEdition, serverVersion, repoVersion, schemaVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,6 +300,15 @@ public class DescriptorServiceImpl implements DescriptorService, ApplicationList
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.Descriptor#getSchema()
|
||||
*/
|
||||
public int getSchema()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.Descriptor#getDescriptorKeys()
|
||||
*/
|
||||
@@ -386,6 +398,32 @@ public class DescriptorServiceImpl implements DescriptorService, ApplicationList
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.Descriptor#getSchema()
|
||||
*/
|
||||
public int getSchema()
|
||||
{
|
||||
String schemaStr = getDescriptor("sys:versionSchema");
|
||||
if (schemaStr == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
int schema = Integer.parseInt(schemaStr);
|
||||
if (schema < 0)
|
||||
{
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("'version.schema' must be a positive integer");
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.Descriptor#getDescriptorKeys()
|
||||
*/
|
||||
@@ -470,7 +508,33 @@ public class DescriptorServiceImpl implements DescriptorService, ApplicationList
|
||||
{
|
||||
return serverProperties.getProperty("version.edition");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.Descriptor#getSchema()
|
||||
*/
|
||||
public int getSchema()
|
||||
{
|
||||
String schemaStr = serverProperties.getProperty("version.schema");
|
||||
if (schemaStr == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
int schema = Integer.parseInt(schemaStr);
|
||||
if (schema < 0)
|
||||
{
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("'version.schema' must be a positive integer");
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.descriptor.Descriptor#getDescriptorKeys()
|
||||
*/
|
||||
|
@@ -62,11 +62,11 @@ public class DescriptorServiceTest extends BaseSpringTest
|
||||
}
|
||||
|
||||
|
||||
public void testDescriptor()
|
||||
public void testServerDescriptor()
|
||||
{
|
||||
ServiceRegistry registry = (ServiceRegistry)applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
DescriptorService descriptor = registry.getDescriptorService();
|
||||
Descriptor serverDescriptor = descriptor.getDescriptor();
|
||||
DescriptorService descriptorService = registry.getDescriptorService();
|
||||
Descriptor serverDescriptor = descriptorService.getServerDescriptor();
|
||||
|
||||
String major = serverDescriptor.getVersionMajor();
|
||||
String minor = serverDescriptor.getVersionMinor();
|
||||
@@ -79,25 +79,31 @@ public class DescriptorServiceTest extends BaseSpringTest
|
||||
}
|
||||
|
||||
assertEquals(version, serverDescriptor.getVersion());
|
||||
|
||||
int schemaVersion = serverDescriptor.getSchema();
|
||||
assertTrue("Server schema version must be greater than 0", schemaVersion > 0);
|
||||
}
|
||||
|
||||
public void testRepositoryDescriptor()
|
||||
{
|
||||
ServiceRegistry registry = (ServiceRegistry)applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
DescriptorService descriptor = registry.getDescriptorService();
|
||||
Descriptor serverDescriptor = descriptor.getRepositoryDescriptor();
|
||||
DescriptorService descriptorService = registry.getDescriptorService();
|
||||
Descriptor repoDescriptor = descriptorService.getRepositoryDescriptor();
|
||||
|
||||
String major = serverDescriptor.getVersionMajor();
|
||||
String minor = serverDescriptor.getVersionMinor();
|
||||
String revision = serverDescriptor.getVersionRevision();
|
||||
String label = serverDescriptor.getVersionLabel();
|
||||
String major = repoDescriptor.getVersionMajor();
|
||||
String minor = repoDescriptor.getVersionMinor();
|
||||
String revision = repoDescriptor.getVersionRevision();
|
||||
String label = repoDescriptor.getVersionLabel();
|
||||
String version = major + "." + minor + "." + revision;
|
||||
if (label != null && label.length() > 0)
|
||||
{
|
||||
version += " (" + label + ")";
|
||||
}
|
||||
|
||||
assertEquals(version, serverDescriptor.getVersion());
|
||||
assertEquals(version, repoDescriptor.getVersion());
|
||||
|
||||
int schemaVersion = repoDescriptor.getSchema();
|
||||
assertTrue("Repository schema version must be greater than -1", schemaVersion > -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -31,18 +31,24 @@ public interface AppliedPatch
|
||||
public String getDescription();
|
||||
public void setDescription(String description);
|
||||
|
||||
public String getApplyToVersion();
|
||||
public void setApplyToVersion(String version);
|
||||
public int getFixesFromSchema();
|
||||
public void setFixesFromSchema(int version);
|
||||
|
||||
public boolean getSucceeded();
|
||||
public void setSucceeded(boolean succeeded);
|
||||
public int getFixesToSchema();
|
||||
public void setFixesToSchema(int version);
|
||||
|
||||
public String getAppliedOnVersion();
|
||||
public void setAppliedOnVersion(String version);
|
||||
public int getTargetSchema();
|
||||
public void setTargetSchema(int version);
|
||||
|
||||
public int getAppliedToSchema();
|
||||
public void setAppliedToSchema(int version);
|
||||
|
||||
public Date getAppliedOnDate();
|
||||
public void setAppliedOnDate(Date date);
|
||||
|
||||
public boolean getSucceeded();
|
||||
public void setSucceeded(boolean succeeded);
|
||||
|
||||
public String getReport();
|
||||
public void setReport(String report);
|
||||
}
|
||||
|
@@ -16,10 +16,12 @@
|
||||
optimistic-lock="version" >
|
||||
<id column="id" length="32" name="id" type="string" />
|
||||
<property name="description" column="description" type="string" length="1024" />
|
||||
<property name="applyToVersion" column="apply_to_version" type="string" length="10" />
|
||||
<property name="succeeded" column="succeeded" type="boolean" />
|
||||
<property name="appliedOnVersion" column="applied_on_version" type="string" length="10" />
|
||||
<property name="fixesFromSchema" column="fixes_from_schema" type="integer" />
|
||||
<property name="fixesToSchema" column="fixes_to_schema" type="integer" />
|
||||
<property name="appliedToSchema" column="applied_to_schema" type="integer" />
|
||||
<property name="targetSchema" column="target_schema" type="integer" />
|
||||
<property name="appliedOnDate" column="applied_on_date" type="timestamp" />
|
||||
<property name="succeeded" column="succeeded" type="boolean" />
|
||||
<property name="report" column="report" type="string" length="1024" />
|
||||
</class>
|
||||
|
||||
|
@@ -29,11 +29,36 @@ public class AppliedPatchImpl implements AppliedPatch
|
||||
{
|
||||
private String id;
|
||||
private String description;
|
||||
private String applyAfterVersion;
|
||||
private boolean succeeded;
|
||||
private String appliedOnVersion;
|
||||
private int fixesFromSchema;
|
||||
private int fixesToSchema;
|
||||
private int targetSchema;
|
||||
|
||||
private int appliedToSchema;
|
||||
private Date appliedOnDate;
|
||||
private boolean succeeded;
|
||||
private String report;
|
||||
|
||||
public AppliedPatchImpl()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(256);
|
||||
sb.append("AppliedPatch")
|
||||
.append("[ id=").append(id)
|
||||
.append(", description=").append(description)
|
||||
.append(", fixesFromSchema=").append(fixesFromSchema)
|
||||
.append(", fixesToSchema=").append(fixesToSchema)
|
||||
.append(", targetSchema=").append(targetSchema)
|
||||
.append(", appliedToSchema=").append(appliedToSchema)
|
||||
.append(", appliedOnDate=").append(appliedOnDate)
|
||||
.append(", succeeded=").append(succeeded)
|
||||
.append(", report=").append(report)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
@@ -57,14 +82,50 @@ public class AppliedPatchImpl implements AppliedPatch
|
||||
}
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getAppliedOnVersion()
|
||||
|
||||
public int getFixesFromSchema()
|
||||
{
|
||||
return appliedOnVersion;
|
||||
return fixesFromSchema;
|
||||
}
|
||||
public void setAppliedOnVersion(String appliedOnVersion)
|
||||
public void setFixesFromSchema(int version)
|
||||
{
|
||||
this.appliedOnVersion = appliedOnVersion;
|
||||
this.fixesFromSchema = version;
|
||||
}
|
||||
|
||||
public int getFixesToSchema()
|
||||
{
|
||||
return fixesToSchema;
|
||||
}
|
||||
public void setFixesToSchema(int version)
|
||||
{
|
||||
this.fixesToSchema = version;
|
||||
}
|
||||
|
||||
public int getTargetSchema()
|
||||
{
|
||||
return targetSchema;
|
||||
}
|
||||
public void setTargetSchema(int currentSchema)
|
||||
{
|
||||
this.targetSchema = currentSchema;
|
||||
}
|
||||
|
||||
public int getAppliedToSchema()
|
||||
{
|
||||
return appliedToSchema;
|
||||
}
|
||||
public void setAppliedToSchema(int version)
|
||||
{
|
||||
this.appliedToSchema = version;
|
||||
}
|
||||
|
||||
public Date getAppliedOnDate()
|
||||
{
|
||||
return appliedOnDate;
|
||||
}
|
||||
public void setAppliedOnDate(Date appliedOnDate)
|
||||
{
|
||||
this.appliedOnDate = appliedOnDate;
|
||||
}
|
||||
|
||||
public boolean getSucceeded()
|
||||
@@ -75,24 +136,6 @@ public class AppliedPatchImpl implements AppliedPatch
|
||||
{
|
||||
this.succeeded = succeeded;
|
||||
}
|
||||
|
||||
public String getApplyToVersion()
|
||||
{
|
||||
return applyAfterVersion;
|
||||
}
|
||||
public void setApplyToVersion(String applyAfterVersion)
|
||||
{
|
||||
this.applyAfterVersion = applyAfterVersion;
|
||||
}
|
||||
|
||||
public Date getAppliedOnDate()
|
||||
{
|
||||
return appliedOnDate;
|
||||
}
|
||||
public void setAppliedOnDate(Date appliedOnDate)
|
||||
{
|
||||
this.appliedOnDate = appliedOnDate;
|
||||
}
|
||||
|
||||
public String getReport()
|
||||
{
|
||||
|
@@ -517,7 +517,7 @@ public class ExporterComponent
|
||||
exportOf = getNodeRef(parameters.getExportFrom());
|
||||
|
||||
// get exporter version
|
||||
exporterVersion = descriptorService.getDescriptor().getVersion();
|
||||
exporterVersion = descriptorService.getServerDescriptor().getVersion();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@@ -26,5 +26,5 @@ import java.util.List;
|
||||
*/
|
||||
public interface AdminService
|
||||
{
|
||||
public List<PatchInfo> getPatches();
|
||||
// public List<PatchInfo> getPatches();
|
||||
}
|
||||
|
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.service.cmr.admin;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import org.alfresco.repo.domain.AppliedPatch;
|
||||
|
||||
/**
|
||||
* Provides information regarding an individual patch.
|
||||
*
|
||||
* @since 1.2
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class PatchInfo implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -8288217080763245510L;
|
||||
|
||||
private String id;
|
||||
private String description;
|
||||
private String applyToVersion;
|
||||
private boolean succeeded;
|
||||
private String appliedOnVersion;
|
||||
private Date appliedOnDate;
|
||||
private String report;
|
||||
|
||||
public PatchInfo(String id, String description, String applyAfterVersion)
|
||||
{
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.applyToVersion = applyAfterVersion;
|
||||
this.succeeded = false;
|
||||
}
|
||||
|
||||
public PatchInfo(AppliedPatch appliedPatch)
|
||||
{
|
||||
this.id = appliedPatch.getId();
|
||||
this.description = appliedPatch.getDescription();
|
||||
this.applyToVersion = appliedPatch.getApplyToVersion();
|
||||
|
||||
this.succeeded = appliedPatch.getSucceeded();
|
||||
this.appliedOnVersion = appliedPatch.getAppliedOnVersion();
|
||||
this.appliedOnDate = appliedPatch.getAppliedOnDate();
|
||||
this.report = appliedPatch.getReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the unique patch identifier
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns a description of the patch
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the version of the repository after which this patch must be applied
|
||||
*/
|
||||
public String getApplyToVersion()
|
||||
{
|
||||
return applyToVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns true if the patch has been successfully applied
|
||||
*/
|
||||
public boolean getSucceeded()
|
||||
{
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the repository version that the patch was applied on, or null if the patch
|
||||
* has not been applied
|
||||
*/
|
||||
public String getAppliedOnVersion()
|
||||
{
|
||||
return appliedOnVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the date that the patch was applied, or null if the patch has not been applied
|
||||
*/
|
||||
public Date getAppliedOnDate()
|
||||
{
|
||||
return appliedOnDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a report generated during the last attempted application. This will be an error report if
|
||||
* the last attempt failed. If the application of the patch was successful
|
||||
* ({@link #getAppliedOnDate() applied date} is not null) the it will be a message saying that it worked.
|
||||
*
|
||||
* @return Returns a report generated during application. This is only null if no attempt has been
|
||||
* made to apply the patch.
|
||||
*/
|
||||
public String getReport()
|
||||
{
|
||||
return report;
|
||||
}
|
||||
}
|
@@ -25,21 +25,21 @@ package org.alfresco.service.descriptor;
|
||||
public interface Descriptor
|
||||
{
|
||||
/**
|
||||
* Gets the major version number
|
||||
* Gets the major version number, e.g. <u>1</u>.2.3
|
||||
*
|
||||
* @return major version number
|
||||
*/
|
||||
public String getVersionMajor();
|
||||
|
||||
/**
|
||||
* Gets the minor version number
|
||||
* Gets the minor version number, e.g. 1.<u>2</u>.3
|
||||
*
|
||||
* @return minor version number
|
||||
*/
|
||||
public String getVersionMinor();
|
||||
|
||||
/**
|
||||
* Gets the version revision number
|
||||
* Gets the version revision number, e.g. 1.2.<u>3</u>
|
||||
*
|
||||
* @return revision number
|
||||
*/
|
||||
@@ -66,6 +66,13 @@ public interface Descriptor
|
||||
*/
|
||||
public String getEdition();
|
||||
|
||||
/**
|
||||
* Gets the schema number
|
||||
*
|
||||
* @return a positive integer
|
||||
*/
|
||||
public int getSchema();
|
||||
|
||||
/**
|
||||
* Gets the list available descriptors
|
||||
*
|
||||
|
@@ -30,7 +30,7 @@ public interface DescriptorService
|
||||
*
|
||||
* @return server descriptor
|
||||
*/
|
||||
public Descriptor getDescriptor();
|
||||
public Descriptor getServerDescriptor();
|
||||
|
||||
/**
|
||||
* Get descriptor for the repository
|
||||
|
Reference in New Issue
Block a user