Package org.jboss.as.domain.controller

Source Code of org.jboss.as.domain.controller.DomainController

/*
* JBoss, Home of Professional Open Source.
* Copyright 2010, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.domain.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.xml.stream.XMLInputFactory;

import org.jboss.as.domain.client.api.DomainUpdateResult;
import org.jboss.as.domain.client.api.HostUpdateResult;
import org.jboss.as.domain.client.api.ServerIdentity;
import org.jboss.as.domain.client.api.ServerStatus;
import org.jboss.as.domain.client.api.deployment.DeploymentPlan;
import org.jboss.as.domain.client.impl.DomainUpdateApplierResponse;
import org.jboss.as.model.AbstractDomainModelUpdate;
import org.jboss.as.model.AbstractHostModelUpdate;
import org.jboss.as.model.AbstractServerModelUpdate;
import org.jboss.as.model.DomainModel;
import org.jboss.as.model.HostModel;
import org.jboss.as.model.ServerModel;
import org.jboss.as.model.UpdateFailedException;
import org.jboss.as.model.UpdateResultHandlerResponse;
import org.jboss.logging.Logger;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
import org.jboss.staxmapper.XMLMapper;

/**
* A Domain controller instance.
*
* @author John Bailey
*/
public class DomainController implements Service<DomainController> {
    private static final Logger log = Logger.getLogger("org.jboss.as.domain.controller");
    public static final ServiceName SERVICE_NAME = ServiceName.JBOSS.append("domain", "controller");
    private DomainModel domainModel;
    private final ConcurrentMap<String, ServerManagerClient> clients = new ConcurrentHashMap<String, ServerManagerClient>();
    private final InjectedValue<XMLMapper> xmlMapper = new InjectedValue<XMLMapper>();
    private final InjectedValue<File> domainConfigDir = new InjectedValue<File>();
    private final InjectedValue<File> domainDeploymentsDir = new InjectedValue<File>();
    private final InjectedValue<ScheduledExecutorService> scheduledExecutorService = new InjectedValue<ScheduledExecutorService>();
    private volatile DomainConfigurationPersister configPersister;
    private ScheduledFuture<?> pollingFuture;
    private DomainDeploymentHandler deploymentPlanHandler;
    private DomainDeploymentRepository deploymentRepository;

    public DomainController() {
    }

    /**
     * For use in testing.
     * @param configPersister
     */
    public DomainController(final DomainConfigurationPersister configPersister, final DomainDeploymentRepository deploymentRepository) {
        assert configPersister != null : "configPersister is null";
        assert deploymentRepository != null : "deploymentRepository is null";
        this.configPersister = configPersister;
        this.deploymentRepository = deploymentRepository;
    }

    // ---------------------------------------------------------------  Service

    /**
     * Start the domain controller with configuration.  This will launch required service for the domain controller.
     */
    @Override
    public synchronized void start(final StartContext context) throws StartException {

        try {
            log.info("Starting Domain Controller");

            if (configPersister == null) {
                configPersister = new DomainConfigurationPersisterImpl(getDomainConfigDir());
            }
            if (deploymentRepository == null) {
                deploymentRepository = new DomainDeploymentRepository(getDomainDeploymentsDir());
            }

            log.info("Parsing Domain Configuration");
            domainModel = parseDomain(xmlMapper.getValue());

            deploymentPlanHandler = new DomainDeploymentHandler(this, scheduledExecutorService.getValue());
            pollingFuture = scheduledExecutorService.getValue().scheduleAtFixedRate(new Runnable() {
                public void run() {
                    for(ServerManagerClient client : clients.values()) {
                        if(!client.isActive()) {
                            log.warnf("Registered Server Manager [%s] is no longer active", client.getId());
                        }
                    }
                }
            }, 30L, 30L, TimeUnit.SECONDS);
        } catch (IllegalStateException e) {
            throw new StartException("Failed to start " + getClass().getSimpleName(), e);
        }
    }

    /**
     * Stop the domain controller
     */
    @Override
    public synchronized void stop(final StopContext stopContext) {
        log.info("Stopping Domain Controller");
        domainModel = null;
        if(pollingFuture != null) {
            pollingFuture.cancel(true);
        }
    }

    @Override
    public DomainController getValue() throws IllegalStateException {
        return this;
    }

    // ----------------------------------  Operations invoked by Server Manager

    public void addClient(final ServerManagerClient domainControllerClient) {
        if(clients.putIfAbsent(domainControllerClient.getId(), domainControllerClient) != null) {
            // TODO: Handle duplicate client
        }
    }

    public void removeClient(final String id) {
        if(clients.remove(id) == null) {
            // TODO: Handle non-existent client
        }
    }

    // -----------------------------------  Operations invoked by DomainClient

    public synchronized DomainModel getDomainModel() {
        return domainModel;
    }

    public Set<String> getServerManagerNames() {
        return Collections.unmodifiableSet(clients.keySet());
    }

    public HostModel getHostModel(final String serverManagerName) {

        ServerManagerClient client = clients.get(serverManagerName);
        if (client == null) {
            return null;
        }
        else {
            return client.getHostModel();
        }
    }

    public Map<ServerIdentity, ServerStatus> getServerStatuses() {
        Map<ServerIdentity, ServerStatus> result = new HashMap<ServerIdentity, ServerStatus>();
        Map<String, Future<Map<ServerIdentity, ServerStatus>>> futures = new HashMap<String, Future<Map<ServerIdentity, ServerStatus>>>();
        for (Map.Entry<String, ServerManagerClient> entry : clients.entrySet()) {
            final ServerManagerClient client = entry.getValue();
            Callable<Map<ServerIdentity, ServerStatus>> callable = new Callable<Map<ServerIdentity, ServerStatus>>() {

                @Override
                public Map<ServerIdentity, ServerStatus> call() {
                    return client.getServerStatuses();
                }

            };
            futures.put(entry.getKey(), scheduledExecutorService.getValue().submit(callable));
        }

        for (Map.Entry<String, Future<Map<ServerIdentity, ServerStatus>>> entry : futures.entrySet()) {
            try {
                Map<ServerIdentity, ServerStatus> map = entry.getValue().get();
                if (map != null) {
                    result.putAll(map);
                }
            } catch (InterruptedException e) {
                log.errorf("Interrupted while reading server statuses from server manager %s -- aborting", entry.getKey());
                Thread.currentThread().interrupt();
                break;
            } catch (ExecutionException e) {
                log.errorf(e, "Caught exception while reading server statuses from server manager %s -- ignoring that server manager", entry.getKey());
            }
        }
        return result;
    }

    public ServerModel getServerModel(final String serverManagerName, final String serverName) {

        ServerManagerClient client = clients.get(serverManagerName);
        if (client == null) {
            log.debugf("Received getServerModel request for unknown server manager %s", serverManagerName);
            return null;
        }
        else {
            return client.getServerModel(serverName);
        }
    }

    public ServerStatus startServer(final String serverManagerName, final String serverName) {

        ServerManagerClient client = clients.get(serverManagerName);
        if (client == null) {
            log.debugf("Received startServer request for unknown server manager %s", serverManagerName);
            return ServerStatus.UNKNOWN;
        }
        else {
            return client.startServer(serverName);
        }
    }

    public ServerStatus stopServer(final String serverManagerName, final String serverName, final long gracefulTimeout) {

        ServerManagerClient client = clients.get(serverManagerName);
        if (client == null) {
            log.debugf("Received stopServer request for unknown server manager %s", serverManagerName);
            return ServerStatus.UNKNOWN;
        }
        else {
            return client.stopServer(serverName, gracefulTimeout);
        }
    }

    public ServerStatus restartServer(final String serverManagerName, final String serverName, final long gracefulTimeout) {

        ServerManagerClient client = clients.get(serverManagerName);
        if (client == null) {
            log.debugf("Received restartServer request for unknown server manager %s", serverManagerName);
            return ServerStatus.UNKNOWN;
        }
        else {
            return client.restartServer(serverName, gracefulTimeout);
        }
    }

    private DomainModel parseDomain(final XMLMapper mapper) {
        try {
            InputStream reader = configPersister.getConfigurationInputStream();
            final List<AbstractDomainModelUpdate<?>> domainUpdates = new ArrayList<AbstractDomainModelUpdate<?>>();
            mapper.parseDocument(domainUpdates, XMLInputFactory.newInstance().createXMLStreamReader(new BufferedInputStream(reader)));
            final DomainModel domainModel = new DomainModel();
            for(final AbstractDomainModelUpdate<?> update : domainUpdates) {
                domainModel.update(update);
            }
            return domainModel;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("Caught exception during processing of domain.xml", e);
        }
    }

    public Injector<XMLMapper> getXmlMapperInjector() {
        return xmlMapper;
    }

    File getDomainConfigDir() {
        return domainConfigDir.getValue();
    }

    File getDomainDeploymentsDir() {
        return domainDeploymentsDir.getValue();
    }

    public Injector<File> getDomainConfigDirInjector() {
        return domainConfigDir;
    }

    public Injector<File> getDomainDeploymentsDirInjector() {
        return domainDeploymentsDir;
    }

    public Injector<ScheduledExecutorService> getScheduledExecutorServiceInjector() {
        return scheduledExecutorService;
    }

    public List<DomainUpdateResult<?>> applyUpdates(List<AbstractDomainModelUpdate<?>> updates) {
        if (updates == null || updates.size() == 0) {
            throw new IllegalArgumentException("updates is " + (updates == null ? "null" : "empty"));
        }
        List<DomainUpdateResult<?>> result;

        List<DomainUpdateApplierResponse> domainResults = applyUpdatesToModel(updates);

        // Check the last update to verify overall success
        DomainUpdateApplierResponse last = domainResults.get(domainResults.size() - 1);
        if (last.isCancelled() || last.isRolledBack() || last.getDomainFailure() != null || last.getHostFailures().size() > 0) {
            // Something failed; don't push to servers
            result = new ArrayList<DomainUpdateResult<?>>();
            for (DomainUpdateApplierResponse duar : domainResults) {
                if (duar.isCancelled()) {
                    result.add(new DomainUpdateResult<Object>(true));
                }
                else if (duar.isRolledBack()) {
                    result.add(new DomainUpdateResult<Object>(false));
                }
                else if (duar.getDomainFailure() != null) {
                    result.add(new DomainUpdateResult<Object>(duar.getDomainFailure()));
                }
                else {
                    result.add(new DomainUpdateResult<Object>(duar.getHostFailures()));
                }
            }
        }
        else {
            // Push to servers
            result = applyUpdatesToServers(updates, domainResults, false);
        }

        return result;
    }

    public <T> DomainUpdateResult<T> applyUpdate(AbstractDomainModelUpdate<T> update) {

        @SuppressWarnings("unchecked")
        DomainUpdateResult<T> result = (DomainUpdateResult<T>) applyUpdates(Collections.<AbstractDomainModelUpdate<?>>singletonList(update)).get(0);
        return result;
    }

    public DomainUpdateApplierResponse applyUpdateToModel(AbstractDomainModelUpdate<?> update) {
        List<DomainUpdateApplierResponse> responses = applyUpdatesToModel(Collections.<AbstractDomainModelUpdate<?>>singletonList(update));
        return responses.get(0);
    }

    public List<DomainUpdateApplierResponse> applyUpdatesToModel(final List<AbstractDomainModelUpdate<?>> updates) {

        int updateCount = updates.size();
        log.debugf("Applying %s domain updates", updateCount);

        List<DomainUpdateApplierResponse> result = new ArrayList<DomainUpdateApplierResponse>(updateCount);

        // First we apply updates to our local model copy
        boolean ok = true;
        List<AbstractDomainModelUpdate<?>> rollbacks = new ArrayList<AbstractDomainModelUpdate<?>>();
        for (AbstractDomainModelUpdate<?> update : updates) {
            if (ok) {
                try {
                    AbstractDomainModelUpdate<?> rollback = update.getCompensatingUpdate(domainModel);
                    domainModel.update(update);
                    // Add the rollback after success so we don't rollback
                    // the failed update -- which should not have changed anything
                    rollbacks.add(0, rollback);
                    // Stick in a placeholder result that will survive if
                    // a domain update faiure triggers a rollback or will get replaced with
                    // the final result if we apply to servers
                    result.add(new DomainUpdateApplierResponse(false));
                }
                catch (UpdateFailedException e) {
                    log.debugf(e, "Failed applying %s", update);
                    ok = false;
                    result.add(new DomainUpdateApplierResponse(e));
                }
            } else {
                // Add a cancellation response
                result.add(new DomainUpdateApplierResponse(true));
            }
        }

        if (!ok) {
            // Apply compensating updates to fix our local model
            for (int i = 0; i < rollbacks.size(); i++) {
                AbstractDomainModelUpdate<?> rollback = rollbacks.get(i);
                try {
                    domainModel.update(rollback);
                }
                catch (UpdateFailedException e) {
                    // TODO uh oh. Reload from the file?
                }
            }
        }
        else {
            log.debug("Domain updates applied successfully locally; pushing to server managers");
            // Persist model
            configPersister.persistConfiguration(domainModel);
            // Move on to server managers.
            result = applyUpdatesToServerManagers(updates, rollbacks);
        }

        return result;
    }

    public List<UpdateResultHandlerResponse<?>> applyUpdatesToServer(final ServerIdentity server, final List<AbstractServerModelUpdate<?>> updates, final boolean allowOverallRollback) {

        ServerManagerClient client = clients.get(server.getHostName());
        List<UpdateResultHandlerResponse<?>> responses;

        if (client == null) {
            log.debugf("Unknown server manager %s", server.getHostName());
            // TODO better handle disappearance of host
            responses = new ArrayList<UpdateResultHandlerResponse<?>>();
            UpdateResultHandlerResponse<?> failure = UpdateResultHandlerResponse.createFailureResponse(new IllegalStateException("unknown host " + server.getHostName()));
            for (int i = 0; i < updates.size(); i++) {
                responses.add(failure);
            }
        }
        else {
            responses = client.updateServerModel(server.getServerName(), updates, allowOverallRollback);
        }
        return responses;
    }

    public void executeDeploymentPlan(DeploymentPlan plan, BlockingQueue<List<StreamedResponse>> responseQueue) {
        deploymentPlanHandler.executeDeploymentPlan(plan, responseQueue);
    }

    public DomainDeploymentRepository getDomainDeploymentRepository() {
        if (deploymentRepository == null) {
            throw new IllegalStateException("Must call start before requesting " + DomainDeploymentRepository.class.getSimpleName());
        }
        return deploymentRepository;
    }

    public boolean isDeploymentNameUnique(String deploymentName) {
        return (domainModel.getDeployment(deploymentName) == null);
    }

    private List<DomainUpdateApplierResponse> applyUpdatesToServerManagers(final List<AbstractDomainModelUpdate<?>> updates,
            List<AbstractDomainModelUpdate<?>> rollbacks) {

        List<DomainUpdateApplierResponse> result = new ArrayList<DomainUpdateApplierResponse>(updates.size());

        // We update server managers concurrently
        Map<String, Future<List<ModelUpdateResponse<List<ServerIdentity>>>>> futures = new HashMap<String, Future<List<ModelUpdateResponse<List<ServerIdentity>>>>>();
        for (Map.Entry<String, ServerManagerClient> entry : clients.entrySet()) {
            final ServerManagerClient client = entry.getValue();
            final Callable<List<ModelUpdateResponse<List<ServerIdentity>>>> callable = new Callable<List<ModelUpdateResponse<List<ServerIdentity>>>>() {

                @Override
                public List<ModelUpdateResponse<List<ServerIdentity>>> call() throws Exception {
                    return client.updateDomainModel(updates);
                }

            };

            futures.put(entry.getKey(), scheduledExecutorService.getValue().submit(callable));
        }

        log.debugf("Domain updates pushed to %s server manager(s)", futures.size());

        // Collate the results for each update
        boolean ok = true;
        for (int i = 0; i < updates.size(); i++) {

            Map<String, UpdateFailedException> hostFailures = new HashMap<String, UpdateFailedException>();
            List<ServerIdentity> servers = new ArrayList<ServerIdentity>();

            for (Map.Entry<String, Future<List<ModelUpdateResponse<List<ServerIdentity>>>>> entry : futures.entrySet()) {
                try {
                    List<ModelUpdateResponse<List<ServerIdentity>>> list = entry.getValue().get();
                    if (list.size() > i) {
                        ModelUpdateResponse<List<ServerIdentity>> hostResponse = list.get(i);
                        if (hostResponse.isSuccess()) {
                            servers.addAll(hostResponse.getResult());
                        }
                        else {
                            hostFailures.put(entry.getKey(), hostResponse.getUpdateException());
                        }
                    }
                    // else this host didn't get this far
                } catch (InterruptedException e) {
                    log.debug("Interrupted reading server manager response");
                    Thread.currentThread().interrupt();
                    hostFailures.put(entry.getKey(), new UpdateFailedException(e));
                } catch (ExecutionException e) {
                    log.debug("Execution exception reading server manager response", e);
                    hostFailures.put(entry.getKey(), new UpdateFailedException(e));
                }
            }
            if (hostFailures.size() == 0) {
                log.debugf("%s servers affected by update %s", servers.size(), i);
                result.add(new DomainUpdateApplierResponse(servers));
            }
            else {
                log.debugf("%s server managers failed on update %s", hostFailures.size(), i);
                result.add(new DomainUpdateApplierResponse(hostFailures));
                ok = false;
                // No point processing other updates, as we are going to roll them back.
                // Act as if we did the whole thing one update at a time and this
                // failure stopped us doing the rest
                break;
            }
        }

        if (!ok) {

            // Some server manager failed, so we gotta roll 'em all back

            log.warn("One or more updates failed on some server managers; rolling back");

            // Apply compensating updates to fix our local model
            for (int i = 0; i < rollbacks.size(); i++) {
                AbstractDomainModelUpdate<?> rollback = rollbacks.get(i);
                try {
                    domainModel.update(rollback);
                }
                catch (UpdateFailedException e) {
                    // TODO uh oh. Reload from the file?
                }
            }

            // List of servers we fail to successfully roll back
            Set<String> outOfSync = new HashSet<String>();

            Map<String, Future<Boolean>> rollbackFutures = new HashMap<String, Future<Boolean>>(futures.size());
            for (Map.Entry<String, Future<List<ModelUpdateResponse<List<ServerIdentity>>>>> entry : futures.entrySet()) {
                try {
                    // For this host figure out how many updates need to be rolled back
                    List<ModelUpdateResponse<List<ServerIdentity>>> rspList = entry.getValue().get();
                    int idx = rspList.size() - 1;
                    if (idx >= 0 && !rspList.get(idx).isSuccess()) {
                        idx--; // !isSuccess one shouldn't have affected model state so no rollback of it
                    }
                    if (idx < 0) {
                        // This host didn't apply anything
                        continue;
                    }

                    // Set up the rollback list
                    final List<AbstractDomainModelUpdate<?>> serverManagerRollbacks =
                        (idx == rollbacks.size() -1) ? rollbacks : new ArrayList<AbstractDomainModelUpdate<?>>(idx + 1);
                    if (serverManagerRollbacks != rollbacks) {
                        // Rollbacks are in reverse order from updates. We take
                        // the last X=idx items from the rollback list since
                        // those correspond to the updates that didn't fail and need rollback
                        for (int j = rollbacks.size() - 1 - idx; j < rollbacks.size(); j++) {
                            serverManagerRollbacks.add(rollbacks.get(j));
                        }
                    }
                    // Tell the host to roll back
                    final ServerManagerClient client = clients.get(entry.getKey());
                    Callable<Boolean> callable = new Callable<Boolean>() {
                        @Override
                        public Boolean call() throws Exception {
                            List<ModelUpdateResponse<List<ServerIdentity>>> rsp = client.updateDomainModel(serverManagerRollbacks);
                            return Boolean.valueOf(rsp.size() == serverManagerRollbacks.size() && rsp.get(rsp.size() - 1).isSuccess());
                        }
                    };
                    rollbackFutures.put(entry.getKey(), scheduledExecutorService.getValue().submit(callable));

                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    outOfSync.add(entry.getKey());
                } catch (ExecutionException e) {
                    outOfSync.add(entry.getKey());
                }
            }

            // Wait until rollbacks complete
            for (Map.Entry<String, Future<Boolean>> entry : rollbackFutures.entrySet()) {
                try {
                    if (!entry.getValue().get()) {
                        outOfSync.add(entry.getKey());
                    }
                }  catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    outOfSync.add(entry.getKey());
                } catch (ExecutionException e) {
                    outOfSync.add(entry.getKey());
                }
            }

            for (String host : outOfSync) {
                // Rollback failed; need to push the whole model
                ServerManagerClient client = clients.get(host);
                client.updateDomainModel(domainModel);
            }

            // Update the result list to record the rollbacks
            for (int i = 0; i < result.size(); i++) {
                DomainUpdateApplierResponse rsp = result.get(i);
                if (rsp.getHostFailures().size() < 0) {
                    result.set(i, new DomainUpdateApplierResponse(false));
                }
            }
        }

        return result;
    }

    private List<DomainUpdateResult<?>> applyUpdatesToServers(final List<AbstractDomainModelUpdate<?>> updates,
                                                              final List<DomainUpdateApplierResponse> domainResults,
                                                              final boolean allowOverallRollback) {
        List<DomainUpdateResult<?>> result;
        Map<AbstractDomainModelUpdate<?>, AbstractServerModelUpdate<?>> serverByDomain =
            new HashMap<AbstractDomainModelUpdate<?>, AbstractServerModelUpdate<?>>();
        Map<AbstractServerModelUpdate<?>, DomainUpdateResult<Object>> resultsByUpdate = new HashMap<AbstractServerModelUpdate<?>, DomainUpdateResult<Object>>();
        for (int i = 0; i < updates.size(); i++) {
            AbstractDomainModelUpdate<?> domainUpdate = updates.get(i);
            AbstractServerModelUpdate<?> serverUpdate = domainUpdate.getServerModelUpdate();
            if (serverUpdate != null) {
                serverByDomain.put(domainUpdate, serverUpdate);
                resultsByUpdate.put(serverUpdate, new DomainUpdateResult<Object>());
            }
        }
        Map<ServerIdentity, List<AbstractServerModelUpdate<?>>> updatesByServer = getUpdatesByServer(updates, domainResults, serverByDomain);

        log.debugf("updates affect %s", updatesByServer.keySet());

        // TODO Add param to configure pushing out concurrently
        for (Map.Entry<ServerIdentity, List<AbstractServerModelUpdate<?>>> entry : updatesByServer.entrySet()) {
            ServerIdentity server = entry.getKey();
            List<AbstractServerModelUpdate<?>> serverUpdates = entry.getValue();
            // Push them out
            List<UpdateResultHandlerResponse<?>> rsps = applyUpdatesToServer(server, serverUpdates, allowOverallRollback);
            for (int i = 0; i < serverUpdates.size(); i++) {
                UpdateResultHandlerResponse<?> rsp = rsps.get(i);
                AbstractServerModelUpdate<?> serverUpdate = entry.getValue().get(i);
                DomainUpdateResult<Object> dur = resultsByUpdate.get(serverUpdate);

                if (rsp.isCancelled()) {
                    dur = dur.newWithAddedCancellation(server);
                }
                else if (rsp.isTimedOut()) {
                    dur = dur.newWithAddedTimeout(server);
                }
                else if (rsp.isRolledBack()) {
                    dur = dur.newWithAddedRollback(server);
                }
                else if (rsp.getFailureResult() != null) {
                    dur = dur.newWithAddedFailure(server, rsp.getFailureResult());
                }
                else {
                    dur = dur.newWithAddedResult(server, rsp.getSuccessResult());
                }
                resultsByUpdate.put(serverUpdate, dur);
            }
        }

        result = new ArrayList<DomainUpdateResult<?>>();
        for (AbstractDomainModelUpdate<?> domainUpdate : updates) {
            AbstractServerModelUpdate<?> serverUpdate = serverByDomain.get(domainUpdate);
            DomainUpdateResult<?> dur = resultsByUpdate.get(serverUpdate);
            if (dur == null) {
                // Update did not impact servers
                dur = new DomainUpdateResult<Object>();
            }
            result.add(dur);
        }
        return result;
    }

    private Map<ServerIdentity, List<AbstractServerModelUpdate<?>>> getUpdatesByServer(
            final List<AbstractDomainModelUpdate<?>> domainUpdates,
            final List<DomainUpdateApplierResponse> domainResults,
            final Map<AbstractDomainModelUpdate<?>, AbstractServerModelUpdate<?>> serverByDomain) {

        Map<ServerIdentity, List<AbstractServerModelUpdate<?>>> result = new HashMap<ServerIdentity, List<AbstractServerModelUpdate<?>>>();

        for (int i = 0; i < domainResults.size(); i++) {
            DomainUpdateApplierResponse domainResult = domainResults.get(i);
            AbstractDomainModelUpdate<?> domainUpdate = domainUpdates.get(i);
            AbstractServerModelUpdate<?> serverUpdate = serverByDomain.get(domainUpdate);
            for (ServerIdentity server : domainResult.getServers()) {
                List<AbstractServerModelUpdate<?>> serverList = result.get(server);
                if (serverList == null) {
                    serverList = new ArrayList<AbstractServerModelUpdate<?>>();
                    result.put(server, serverList);
                }
                serverList.add(serverUpdate);
            }
        }
        return result;
    }

    UpdateResultHandlerResponse<?> restartServer(ServerIdentity server, long gracefulTimeout) {
        ServerStatus status = restartServer(server.getHostName(), server.getServerName(), gracefulTimeout);
        switch (status) {
            case STARTED:
            case STARTING:
                return UpdateResultHandlerResponse.createRestartResponse();
            default: {
                UpdateFailedException ufe = new UpdateFailedException("Server " + server + " did not restart. Server status is " + status);
                return UpdateResultHandlerResponse.createFailureResponse(ufe);
            }

        }
    }

    public List<HostUpdateResult<?>> applyHostUpdates(String serverManagerName, List<AbstractHostModelUpdate<?>> updates) {

        List<HostUpdateResult<?>> result;
        ServerManagerClient client = clients.get(serverManagerName);
        if (client == null) {
            result = new ArrayList<HostUpdateResult<?>>(updates.size());
            HostUpdateResult<Object> hur = new HostUpdateResult<Object>(new UpdateFailedException("Host " + serverManagerName + " is unknown"));
            for (int i = 0; i < updates.size(); i++) {
                result.add(hur);
            }
        }
        else {
            result = client.updateHostModel(updates);
        }
        return result;
    }
}
TOP

Related Classes of org.jboss.as.domain.controller.DomainController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.