All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.plugin.tools.server.DomainManager Maven / Gradle / Ivy

The newest version!
/*
 * Copyright The WildFly Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package org.wildfly.plugin.tools.server;

import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.client.helpers.ClientConstants;
import org.jboss.as.controller.client.helpers.Operations;
import org.jboss.as.controller.client.helpers.domain.DomainClient;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.logging.Logger;
import org.wildfly.plugin.tools.OperationExecutionException;

/**
 * A utility for executing management operations on domain servers.
 *
 * @author James R. Perkins
 */
@SuppressWarnings("unused")
public class DomainManager extends AbstractServerManager {
    private static final Logger LOGGER = Logger.getLogger(DomainManager.class);

    DomainManager(final ProcessHandle process, final DomainClient client,
            final boolean shutdownOnClose) {
        super(process, client, shutdownOnClose);
    }

    @Override
    public String serverState() {
        try {
            return executeOperation(Operations.createReadAttributeOperation(determineHostAddress(), "host-state"))
                    .asString();
        } catch (OperationExecutionException e) {
            LOGGER.debugf("Checking the server state has failed: %s", Operations.getFailureDescription(e.getExecutionResult()));
        } catch (RuntimeException | IOException e) {
            LOGGER.tracef("Interrupted determining the server state", e);
        }
        return "failed";
    }

    /**
     * Determines the address for the host being used.
     *
     * @return the address of the host
     *
     * @throws IOException                 if an error occurs communicating with the server
     * @throws OperationExecutionException if the operation used to determine the host name fails
     */
    public ModelNode determineHostAddress() throws OperationExecutionException, IOException {
        return CommonOperations.determineHostAddress(client());
    }

    /**
     * Checks to see if the domain is running. If the server is not in admin only mode each servers running state is
     * checked. If any server is not in a started state the domain is not considered to be running.
     *
     * @return {@code true} if the server is in a running state, otherwise {@code false}
     */
    @Override
    public boolean isRunning() {
        if (process != null) {
            return process.isAlive() && CommonOperations.isDomainRunning(client(), false);
        }
        return CommonOperations.isDomainRunning(client(), false);
    }

    @Override
    public void executeReload() throws IOException, OperationExecutionException {
        executeReload(Operations.createOperation("reload-servers"));
    }

    @Override
    public void reloadIfRequired() throws IOException {
        reloadIfRequired(10L, TimeUnit.SECONDS);
    }

    @Override
    public void reloadIfRequired(final long timeout, final TimeUnit unit) throws IOException {
        final String launchType = launchType();
        if ("DOMAIN".equalsIgnoreCase(launchType)) {
            final Map steps = new HashMap<>();
            Operations.CompositeOperationBuilder builder = Operations.CompositeOperationBuilder.create();
            int stepCounter = 1;
            final ModelNode hostAddress = determineHostAddress();
            for (var entry : client.getServerStatuses().entrySet()) {
                final ModelNode address = hostAddress.clone().add("server", entry.getKey().getServerName());
                final ModelNode op = Operations.createReadAttributeOperation(address, "server-state");
                builder.addStep(op);
                // We will simply record the step and address to have a mapping for the reload commands
                steps.put("step-" + stepCounter++, address);
            }

            // Execute the operation
            final ModelNode result = executeOperation(builder.build());
            // Create a new builder for each reload operation
            builder = Operations.CompositeOperationBuilder.create();
            for (Property serverResult : result.asPropertyList()) {
                if (ClientConstants.CONTROLLER_PROCESS_STATE_RELOAD_REQUIRED
                        .equals(Operations.readResult(serverResult.getValue())
                                .asString())) {
                    final ModelNode address = steps.get(serverResult.getName());
                    builder.addStep(Operations.createOperation("reload", address));
                }
            }
            executeOperation(builder.build());
            try {
                if (!waitFor(timeout, unit)) {
                    throw new RuntimeException(String.format("Failed to reload servers within %d %s.", timeout, unit.name()
                            .toLowerCase(Locale.ROOT)));
                }
            } catch (InterruptedException e) {
                throw new RuntimeException("Failed to reload the servers.", e);
            }
        } else {
            LOGGER.warnf("Cannot reload and wait for the server to start with a server type of %s.", launchType);
        }
    }

    @Override
    void internalShutdown(final ModelControllerClient client, final long timeout) throws IOException {
        // Note the following two operations used to shutdown a domain don't seem to work well in a composite operation.
        // The operation occasionally sees a java.util.concurrent.CancellationException because the operation client
        // is likely closed before the AsyncFuture.get() is complete. Using a non-composite operation doesn't seem to
        // have this issue.
        // First shutdown the servers
        final ModelNode stopServersOp = Operations.createOperation("stop-servers");
        stopServersOp.get("blocking").set(true);
        stopServersOp.get("timeout").set(timeout);
        executeOperation(client, stopServersOp);

        // Now shutdown the host
        final ModelNode address = CommonOperations.determineHostAddress(client);
        final ModelNode shutdownOp = Operations.createOperation("shutdown", address);
        executeOperation(client, shutdownOp);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy