use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.
the class IdentityPatchRunner method loadRollbackInformation.
static RollbackPatch loadRollbackInformation(final String patchId, final InstalledImage installedImage) throws PatchingException, IOException, XMLStreamException {
final File historyDir = installedImage.getPatchHistoryDir(patchId);
final File patchXml = new File(historyDir, Constants.ROLLBACK_XML);
return (RollbackPatch) PatchXml.parse(patchXml).resolvePatch(null, null);
}
use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.
the class IdentityPatchRunner method reenableNotOverridenModules.
void reenableNotOverridenModules(final RollbackPatch patch, IdentityPatchContext context) throws PatchingException, IOException, XMLStreamException {
assert patch.getIdentity().getPatchType() == Patch.PatchType.CUMULATIVE;
final Iterator historyIterator = context.getHistory().iterator(patch.getIdentityState().getIdentity().loadTargetInfo());
if (!historyIterator.hasNext()) {
return;
}
final List<PatchElement> elements = patch.getElements();
final Map<String, List<PatchElement>> layerPatches = new HashMap<String, List<PatchElement>>(elements.size());
final Map<String, List<PatchElement>> addonPatches = new HashMap<String, List<PatchElement>>(elements.size());
for (PatchElement e : elements) {
if (e.getProvider().isAddOn()) {
addonPatches.put(e.getProvider().getName(), Collections.<PatchElement>emptyList());
} else {
layerPatches.put(e.getProvider().getName(), Collections.<PatchElement>emptyList());
}
}
Patch prevCP = null;
while (historyIterator.hasNext()) {
final Entry entry = historyIterator.next();
if (entry.getType() == PatchType.CUMULATIVE) {
prevCP = entry.getMetadata();
break;
}
final Patch oneOff = entry.getMetadata();
for (PatchElement oneOffElement : oneOff.getElements()) {
final Map<String, List<PatchElement>> providerPatches;
if (oneOffElement.getProvider().isAddOn()) {
providerPatches = addonPatches;
} else {
providerPatches = layerPatches;
}
List<PatchElement> patches = providerPatches.get(oneOffElement.getProvider().getName());
if (patches != null) {
switch(patches.size()) {
case 0:
providerPatches.put(oneOffElement.getProvider().getName(), Collections.singletonList(oneOffElement));
break;
case 1:
patches = new ArrayList<PatchElement>(patches);
providerPatches.put(oneOffElement.getProvider().getName(), patches);
default:
patches.add(oneOffElement);
}
}
}
}
Set<ModuleItem> cpElementModules;
Set<ModuleItem> reenabledModules = Collections.emptySet();
for (PatchElement e : elements) {
final List<PatchElement> patches;
if (e.getProvider().isAddOn()) {
patches = addonPatches.get(e.getProvider().getName());
} else {
patches = layerPatches.get(e.getProvider().getName());
}
if (patches.isEmpty()) {
continue;
}
cpElementModules = null;
final PatchEntry rollbackEntry = context.resolveForElement(e);
for (PatchElement oneOff : patches) {
for (ContentModification mod : oneOff.getModifications()) {
if (mod.getItem().getContentType() != ContentType.MODULE) {
continue;
}
final ModuleItem module = (ModuleItem) mod.getItem();
if (rollbackEntry.get(new Location(module)) != null) {
continue;
}
if (reenabledModules.contains(module)) {
continue;
}
final File modulePath = PatchContentLoader.getModulePath(rollbackEntry.getDirectoryStructure().getModulePatchDirectory(oneOff.getId()), module);
rollbackEntry.invalidateRoot(modulePath);
if (reenabledModules.isEmpty()) {
reenabledModules = new HashSet<ModuleItem>();
}
reenabledModules.add(module);
if (prevCP == null) {
rollbackEntry.disableBaseModule(module);
} else {
if (cpElementModules == null) {
for (PatchElement cpE : prevCP.getElements()) {
if (cpE.getProvider().getName().equals(e.getProvider().getName()) && cpE.getProvider().getLayerType().equals(e.getProvider().getLayerType())) {
cpElementModules = new HashSet<ModuleItem>(cpE.getModifications().size());
for (ContentModification cpMod : cpE.getModifications()) {
if (cpMod.getItem().getContentType() == ContentType.MODULE) {
cpElementModules.add(cpMod.getItem(ModuleItem.class));
}
}
break;
}
}
}
if (cpElementModules != null && !cpElementModules.contains(module)) {
rollbackEntry.disableBaseModule(module);
}
}
}
}
}
}
use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.
the class IdentityPatchContext method finalize.
/**
* Finalize the patch.
*
* @param callback the finalize callback
* @return the result
* @throws Exception
*/
protected PatchingResult finalize(final FinalizeCallback callback) throws Exception {
assert state == State.NEW;
final Patch original = callback.getPatch();
final Patch.PatchType patchType = original.getIdentity().getPatchType();
final String patchId;
if (patchType == Patch.PatchType.CUMULATIVE) {
patchId = modification.getCumulativePatchID();
} else {
patchId = original.getPatchId();
}
try {
// The processed patch, based on the recorded changes
final Patch processedPatch = createProcessedPatch(original);
// The rollback containing all the recorded rollback actions
final RollbackPatch rollbackPatch = createRollbackPatch(patchId, patchType);
callback.finishPatch(processedPatch, rollbackPatch, this);
} catch (Exception e) {
if (undoChanges()) {
callback.operationCancelled(this);
}
throw e;
}
state = State.PREPARED;
return new PatchingResult() {
@Override
public String getPatchId() {
return original.getPatchId();
}
@Override
public PatchInfo getPatchInfo() {
return new PatchInfo() {
@Override
public String getVersion() {
return identityEntry.getResultingVersion();
}
@Override
public String getCumulativePatchID() {
return identityEntry.delegate.getModifiedState().getCumulativePatchID();
}
@Override
public List<String> getPatchIDs() {
return identityEntry.delegate.getModifiedState().getPatchIDs();
}
};
}
@Override
public void commit() {
if (state == State.PREPARED) {
complete(modification, callback);
} else {
undoChanges();
throw new IllegalStateException();
}
}
@Override
public void rollback() {
if (undoChanges()) {
try {
callback.operationCancelled(IdentityPatchContext.this);
} finally {
modification.cancel();
}
}
}
};
}
use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.
the class IdentityPatchRunner method rollback.
/**
* Rollback a patch.
*
* @param patchID the patch id
* @param context the patch context
* @throws PatchingException
*/
private void rollback(final String patchID, final IdentityPatchContext context) throws PatchingException {
try {
// Load the patch history
final PatchingTaskContext.Mode mode = context.getMode();
final Patch originalPatch = loadPatchInformation(patchID, installedImage);
final RollbackPatch rollbackPatch = loadRollbackInformation(patchID, installedImage);
final Patch.PatchType patchType = rollbackPatch.getIdentity().getPatchType();
final InstalledIdentity history = rollbackPatch.getIdentityState();
// Process originals by type first
final LinkedHashMap<String, PatchElement> originalLayers = new LinkedHashMap<String, PatchElement>();
final LinkedHashMap<String, PatchElement> originalAddOns = new LinkedHashMap<String, PatchElement>();
for (final PatchElement patchElement : originalPatch.getElements()) {
final PatchElementProvider provider = patchElement.getProvider();
final String layerName = provider.getName();
final LayerType layerType = provider.getLayerType();
final Map<String, PatchElement> originals;
switch(layerType) {
case Layer:
originals = originalLayers;
break;
case AddOn:
originals = originalAddOns;
break;
default:
throw new IllegalStateException();
}
if (!originals.containsKey(layerName)) {
originals.put(layerName, patchElement);
} else {
throw PatchLogger.ROOT_LOGGER.installationDuplicateLayer(layerType.toString(), layerName);
}
}
// Process the rollback xml
for (final PatchElement patchElement : rollbackPatch.getElements()) {
final String elementPatchId = patchElement.getId();
final PatchElementProvider provider = patchElement.getProvider();
final String layerName = provider.getName();
final LayerType layerType = provider.getLayerType();
final LinkedHashMap<String, PatchElement> originals;
switch(layerType) {
case Layer:
originals = originalLayers;
break;
case AddOn:
originals = originalAddOns;
break;
default:
throw new IllegalStateException();
}
final PatchElement original = originals.remove(layerName);
if (original == null) {
throw PatchLogger.ROOT_LOGGER.noSuchLayer(layerName);
}
final IdentityPatchContext.PatchEntry entry = context.resolveForElement(patchElement);
// Create the rollback
PatchingTasks.rollback(elementPatchId, original.getModifications(), patchElement.getModifications(), entry, ContentItemFilter.ALL_BUT_MISC, mode);
entry.rollback(original.getId());
// We need to restore the previous state
final Patch.PatchType elementPatchType = provider.getPatchType();
final PatchableTarget.TargetInfo info;
if (layerType == LayerType.AddOn) {
info = history.getAddOn(layerName).loadTargetInfo();
} else {
info = history.getLayer(layerName).loadTargetInfo();
}
if (mode == ROLLBACK) {
restoreFromHistory(entry, elementPatchId, elementPatchType, info);
}
}
if (!originalLayers.isEmpty() || !originalAddOns.isEmpty()) {
throw PatchLogger.ROOT_LOGGER.invalidRollbackInformation();
}
// Rollback the patch
final IdentityPatchContext.PatchEntry identity = context.getIdentityEntry();
PatchingTasks.rollback(patchID, originalPatch.getModifications(), rollbackPatch.getModifications(), identity, ContentItemFilter.MISC_ONLY, mode);
identity.rollback(patchID);
// Restore previous state
if (mode == ROLLBACK) {
final PatchableTarget.TargetInfo identityHistory = history.getIdentity().loadTargetInfo();
restoreFromHistory(identity, rollbackPatch.getPatchId(), patchType, identityHistory);
if (patchType == Patch.PatchType.CUMULATIVE) {
reenableNotOverridenModules(rollbackPatch, context);
}
}
if (patchType == Patch.PatchType.CUMULATIVE) {
final Identity.IdentityUpgrade upgrade = rollbackPatch.getIdentity().forType(Patch.PatchType.CUMULATIVE, Identity.IdentityUpgrade.class);
identity.setResultingVersion(upgrade.getResultingVersion());
}
} catch (Exception e) {
throw rethrowException(e);
}
}
use of org.jboss.as.patching.metadata.RollbackPatch in project wildfly-core by wildfly.
the class RollbackTargetArtifact method process.
@Override
public boolean process(PatchingXmlArtifact.XmlArtifactState<RollbackPatch> parent, PatchingArtifactProcessor processor) {
final RollbackPatch patch = parent.getPatch();
final PatchingArtifacts.PatchID patchID = processor.getParentArtifact(PatchingArtifacts.HISTORY_RECORD);
final InstalledIdentity identity = patch.getIdentityState();
processor.getValidationContext().setCurrentPatchIdentity(identity);
final State state = new State(identity, patchID);
if (identity == null) {
processor.getValidationContext().getErrorHandler().addMissing(PatchingArtifacts.ROLLBACK_TARGET, state);
return false;
} else {
return processor.process(this, state);
}
}
Aggregations