From b906fd0ea39066bac1396357475b60e816d8ace4 Mon Sep 17 00:00:00 2001 From: Harald Pehl Date: Fri, 5 Jan 2024 14:23:01 +0100 Subject: [PATCH] HAL-1951: wip --- .../installer/RevertUsingArchivesWizard.java | 107 ++++++++++++++ .../hal/client/installer/UpdateColumn.java | 19 ++- .../installer/UploadAndPrepareStep.java | 137 ++++++++++++++++++ pom.xml | 6 +- 4 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/jboss/hal/client/installer/RevertUsingArchivesWizard.java create mode 100644 app/src/main/java/org/jboss/hal/client/installer/UploadAndPrepareStep.java diff --git a/app/src/main/java/org/jboss/hal/client/installer/RevertUsingArchivesWizard.java b/app/src/main/java/org/jboss/hal/client/installer/RevertUsingArchivesWizard.java new file mode 100644 index 0000000000..90eb06996e --- /dev/null +++ b/app/src/main/java/org/jboss/hal/client/installer/RevertUsingArchivesWizard.java @@ -0,0 +1,107 @@ +/* + * Copyright 2022 Red Hat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * 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.jboss.hal.client.installer; + +import java.util.List; + +import org.jboss.hal.ballroom.wizard.Wizard; +import org.jboss.hal.dmr.ModelNode; +import org.jboss.hal.dmr.dispatch.Dispatcher; +import org.jboss.hal.meta.StatementContext; +import org.jboss.hal.resources.Resources; + +import com.google.web.bindery.event.shared.EventBus; + +import static org.jboss.hal.client.installer.RevertState.APPLY_REVERT; +import static org.jboss.hal.client.installer.RevertState.LIST_UPDATES; +import static org.jboss.hal.client.installer.RevertState.PREPARE_SERVER; +import static org.jboss.hal.core.finder.FinderColumn.RefreshMode.RESTORE_SELECTION; + +class RevertUsingArchivesWizard { + + private final EventBus eventBus; + private final Dispatcher dispatcher; + private final StatementContext statementContext; + private final Resources resources; + private final UpdateManagerContext context; + + RevertUsingArchivesWizard(EventBus eventBus, Dispatcher dispatcher, StatementContext statementContext, Resources resources, + UpdateItem updateItem, List updates) { + this.eventBus = eventBus; + this.statementContext = statementContext; + this.dispatcher = dispatcher; + this.resources = resources; + this.context = new UpdateManagerContext(updates, updateItem); + } + + void show(UpdateColumn column) { + Wizard.Builder builder = new Wizard.Builder<>( + resources.constants().revertUpdatePreviousState(), context); + + builder.stayOpenAfterFinish() + .addStep(LIST_UPDATES, new ListUpdatesStep( + resources.constants().listComponents(), + resources.messages().revertComponentsList(), + resources.messages().revertComponentsDescription( + resources.constants().listComponents(), + resources.constants().prepareServerCandidate(), + resources.constants().applyUpdates()))) + .addStep(PREPARE_SERVER, + new UploadAndPrepareStep(eventBus, dispatcher, statementContext, resources)) + .addStep(APPLY_REVERT, new ApplyStep( + resources.constants().applyUpdates(), + resources.constants().applyingUpdates(), + resources.messages().applyUpdatesPending(), + resources.constants().applyUpdatesSuccess(), + resources.messages().revertUpdatesSuccess(), + resources.messages().revertUpdatesError(), + dispatcher, statementContext, resources)); + + builder.onBack((ctx, currentState) -> { + RevertState previous = null; + switch (currentState) { + case LIST_UPDATES: + break; + case PREPARE_SERVER: + previous = LIST_UPDATES; + break; + case APPLY_REVERT: + previous = ctx.prepared ? LIST_UPDATES : PREPARE_SERVER; + break; + } + return previous; + }); + + builder.onNext((ctx, currentState) -> { + RevertState next = null; + switch (currentState) { + case LIST_UPDATES: + next = ctx.prepared ? APPLY_REVERT : PREPARE_SERVER; + break; + case PREPARE_SERVER: + next = APPLY_REVERT; + break; + case APPLY_REVERT: + break; + } + return next; + }); + + builder.onFinish((wizard, ctx) -> column.refresh(RESTORE_SELECTION)); + + builder.build().show(); + } +} diff --git a/app/src/main/java/org/jboss/hal/client/installer/UpdateColumn.java b/app/src/main/java/org/jboss/hal/client/installer/UpdateColumn.java index f850f739d8..ac503f6e1e 100644 --- a/app/src/main/java/org/jboss/hal/client/installer/UpdateColumn.java +++ b/app/src/main/java/org/jboss/hal/client/installer/UpdateColumn.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.function.Consumer; import javax.inject.Inject; @@ -169,6 +170,11 @@ public List> actions() { .handler(itm -> revert(itm)) .constraint(Constraint.executable(INSTALLER_TEMPLATE, PREPARE_REVERT)) .build()); + actions.add(new ItemAction.Builder() + .title("Revert using archives") // TODO i18n + .handler(itm -> revertUsingArchives(itm)) + .constraint(Constraint.executable(INSTALLER_TEMPLATE, PREPARE_REVERT)) + .build()); } return actions; } @@ -240,6 +246,17 @@ private void clean() { } private void revert(UpdateItem updateItem) { + internalRevert(updateItem, + updates -> new RevertWizard(eventBus, dispatcher, statementContext, resources, updateItem, updates).show(this)); + } + + private void revertUsingArchives(UpdateItem updateItem) { + internalRevert(updateItem, + updates -> new RevertUsingArchivesWizard(eventBus, dispatcher, statementContext, resources, updateItem, updates) + .show(this)); + } + + private void internalRevert(UpdateItem updateItem, Consumer> updatesConsumer) { Operation operation = new Operation.Builder(AddressTemplates.INSTALLER_TEMPLATE.resolve(statementContext), HISTORY_FROM_REVISION) .param(REVISION, updateItem.getName()) @@ -256,7 +273,7 @@ private void revert(UpdateItem updateItem) { .build(); dialog.show(); } else { - new RevertWizard(eventBus, dispatcher, statementContext, resources, updateItem, updates).show(this); + updatesConsumer.accept(updates); } }, (op, error) -> MessageEvent.fire(eventBus, Message.error(resources.messages().lastOperationFailed()))); } diff --git a/app/src/main/java/org/jboss/hal/client/installer/UploadAndPrepareStep.java b/app/src/main/java/org/jboss/hal/client/installer/UploadAndPrepareStep.java new file mode 100644 index 0000000000..f77f3c01ed --- /dev/null +++ b/app/src/main/java/org/jboss/hal/client/installer/UploadAndPrepareStep.java @@ -0,0 +1,137 @@ +/* + * Copyright 2022 Red Hat + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * 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.jboss.hal.client.installer; + +import java.util.List; + +import org.jboss.hal.ballroom.wizard.AsyncStep; +import org.jboss.hal.ballroom.wizard.WizardStep; +import org.jboss.hal.ballroom.wizard.WorkflowCallback; +import org.jboss.hal.client.shared.uploadwizard.UploadElement; +import org.jboss.hal.dmr.ModelNode; +import org.jboss.hal.dmr.Operation; +import org.jboss.hal.dmr.dispatch.Dispatcher; +import org.jboss.hal.flow.FlowContext; +import org.jboss.hal.flow.Progress; +import org.jboss.hal.flow.Task; +import org.jboss.hal.meta.StatementContext; +import org.jboss.hal.resources.Resources; +import org.jboss.hal.spi.Message; +import org.jboss.hal.spi.MessageEvent; + +import com.google.web.bindery.event.shared.EventBus; + +import elemental2.dom.HTMLElement; +import elemental2.promise.Promise; + +import static java.util.Collections.singletonList; + +import static org.jboss.elemento.Elements.div; +import static org.jboss.hal.client.installer.AddressTemplates.INSTALLER_TEMPLATE; +import static org.jboss.hal.dmr.ModelDescriptionConstants.CLEAN; +import static org.jboss.hal.dmr.ModelDescriptionConstants.MAVEN_REPO_FILES; +import static org.jboss.hal.dmr.ModelDescriptionConstants.PREPARE_REVERT; +import static org.jboss.hal.dmr.ModelDescriptionConstants.REVISION; +import static org.jboss.hal.flow.Flow.sequential; + +class UploadAndPrepareStep> extends WizardStep + implements AsyncStep { + + private final EventBus eventBus; + private final Dispatcher dispatcher; + private final StatementContext statementContext; + private final Resources resources; + private final HTMLElement root; + private final UploadElement uploadElement; + + UploadAndPrepareStep(final EventBus eventBus, + final Dispatcher dispatcher, + final StatementContext statementContext, + final Resources resources) { + super(resources.constants().prepareServerCandidate(), true); + this.eventBus = eventBus; + this.statementContext = statementContext; + this.dispatcher = dispatcher; + this.resources = resources; + + root = div() + .add(uploadElement = new UploadElement(false, resources.messages().noContent())) + .element(); + } + + @Override + public HTMLElement element() { + return root; + } + + @Override + protected void onShow(UpdateManagerContext context) { + uploadElement.reset(); + } + + @Override + public void onNext(UpdateManagerContext context, WorkflowCallback callback) { + wizard().showProgress(resources.constants().preparingServerCandidate(), + resources.messages().prepareServerCandidatePending()); + + ModelNode mavenRepoFiles = new ModelNode(); + for (int i = 0; i < uploadElement.getFiles().length; i++) { + mavenRepoFiles.add(i); + } + Operation operation = new Operation.Builder(INSTALLER_TEMPLATE.resolve(statementContext), PREPARE_REVERT) + .param(REVISION, context.updateItem.getName()) + .param(MAVEN_REPO_FILES, mavenRepoFiles) + .build(); + List> tasks = singletonList( + flowContext -> dispatcher.upload(uploadElement.getFiles(), operation) + .then(result -> Promise.resolve(flowContext))); + sequential(new FlowContext(Progress.NOOP), tasks) + .timeout(Timeouts.UPLOAD * 1_000) + .then(flowContext -> { + context.prepared = true; + wizard().showSuccess(resources.constants().prepareServerCandidateSuccess(), + resources.messages().prepareServerCandidateSuccessDescription(), false); + callback.proceed(); + return Promise.resolve(context); + }) + .catch_(failure -> { + if (FlowContext.timeout(failure)) { + wizard().showError(resources.constants().timeout(), resources.messages().operationTimeout(), false); + } else { + wizard().showError(resources.constants().error(), resources.messages().prepareServerCandidateError(), + String.valueOf(failure), false); + } + return Promise.reject(failure); + }); + } + + @Override + public void onCancel(final UpdateManagerContext context, final WorkflowCallback callback) { + if (context.prepared) { + Operation operation = new Operation.Builder(INSTALLER_TEMPLATE.resolve(statementContext), CLEAN).build(); + dispatcher.execute(operation, + modelNode -> { + callback.proceed(); + MessageEvent.fire(eventBus, Message.success(resources.messages().serverCandidateCleanupSuccess())); + }, (op, error) -> { + callback.proceed(); + MessageEvent.fire(eventBus, Message.error(resources.messages().serverCandidateCleanupError())); + }); + } else { + callback.proceed(); + } + } +} diff --git a/pom.xml b/pom.xml index ea8fecc1a0..7ea3eaa5ef 100644 --- a/pom.xml +++ b/pom.xml @@ -107,8 +107,8 @@ 2.0.2 4.13.2 5.8.0 - v16.14.0 - 8.18.0 + v21.3.0 + 10.2.4 2.0.3 1.7.7.1 1.0.0.GA @@ -129,7 +129,7 @@ quarkus-bom io.quarkus.platform - 3.6.0 + 3.5.3 git@github.com:hal/console.git