Package org.jboss.as.server.manager

Source Code of org.jboss.as.server.manager.ModelManager

/*
* 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.server.manager;

import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.stream.XMLInputFactory;

import org.jboss.as.domain.client.api.ServerIdentity;
import org.jboss.as.domain.controller.FileRepository;
import org.jboss.as.domain.client.impl.HostUpdateApplierResponse;
import org.jboss.as.model.AbstractDomainModelUpdate;
import org.jboss.as.model.AbstractHostModelUpdate;
import org.jboss.as.model.DomainModel;
import org.jboss.as.model.HostModel;
import org.jboss.as.model.NewRepositoryContentUpdate;
import org.jboss.as.model.ServerElement;
import org.jboss.as.model.UpdateFailedException;
import org.jboss.logging.Logger;
import org.jboss.staxmapper.XMLMapper;

/**
* {@link ServerManager} component that is responsible for managing the ServerManager's
* {@link HostModel} and its copy of the {@link DomainModel}.
*
* @author Brian Stansberry
*/
public class ModelManager {
    private static final Logger log = Logger.getLogger("org.jboss.as.server.manager");

    private final HostConfigurationPersister configPersister;
    private DomainModel domainModel;
    private volatile HostModel hostModel;

    private final StandardElementReaderRegistrar extensionRegistrar;
    private FileRepository repository;

    ModelManager(final ServerManagerEnvironment environment, final StandardElementReaderRegistrar extensionRegistrar) {
        this(new HostConfigurationPersisterImpl(environment.getDomainConfigurationDir()), extensionRegistrar);
    }

    ModelManager(final HostConfigurationPersister configPersister, final StandardElementReaderRegistrar extensionRegistrar) {

        assert configPersister != null : "configPersister is null";
        assert extensionRegistrar != null : "extensionRegistrar is null";
        this.configPersister = configPersister;
        this.extensionRegistrar = extensionRegistrar;
    }


    public void start() {
        getHostModel();
    }

    public HostModel getHostModel() {
        if (hostModel == null) {
            synchronized (configPersister) {
                if (hostModel == null) {
                    hostModel = parseHostXml();
                }
            }
        }
        return hostModel;
    }

    public DomainModel getDomainModel() {
        return domainModel;
    }

    void setDomainModel(final DomainModel model) {
        assert model != null : "model is null";
        this.domainModel = model;
    }

    void setFileRepository(final FileRepository repository) {
        this.repository = repository;
    }

    public List<ServerIdentity> applyDomainModelUpdate(AbstractDomainModelUpdate<?> update, boolean applyToDomain) throws UpdateFailedException {

        log.debugf("Received update %s", update.getClass().getSimpleName());
        if (applyToDomain) {
            try {
                // Force a sync if our repository falls back to a remote
                if (update instanceof NewRepositoryContentUpdate && repository != null)
                    repository.getDeploymentFiles(((NewRepositoryContentUpdate) update).getHash());

                domainModel.update(update);
            }
            catch (UpdateFailedException e) {
                // TODO mark ourself in a state where we require
                // correction by the DC.
                throw e;
            }
        }


        List<String> serverNames = update.getAffectedServers(domainModel, getHostModel());
        log.debugf("Servers affected by %s: %s", update.getClass().getSimpleName(), serverNames);

        if (serverNames.size() == 0) {
            return Collections.emptyList();
        }
        List<ServerIdentity> ids = new ArrayList<ServerIdentity>(serverNames.size());
        String hostName = hostModel.getName();
        for (String server : serverNames) {
            ServerElement se = hostModel.getServer(server);
            ids.add(new ServerIdentity(hostName, se.getServerGroup(), server));
        }
        return ids;
    }


    public List<HostUpdateApplierResponse> applyHostModelUpdates(List<AbstractHostModelUpdate<?>> updates) {


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

        // First we apply updates to our local model copy
        boolean ok = true;
        List<AbstractHostModelUpdate<?>> rollbacks = new ArrayList<AbstractHostModelUpdate<?>>();
        for (AbstractHostModelUpdate<?> update : updates) {
            if (ok) {
                try {
                    AbstractHostModelUpdate<?> rollback = update.getCompensatingUpdate(hostModel);
                    hostModel.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 host update faiure triggers a rollback or will get replaced with
                    // the final result if we apply to servers
                    result.add(new HostUpdateApplierResponse(false));
                }
                catch (UpdateFailedException e) {
                    ok = false;
                    result.add(new HostUpdateApplierResponse(e));
                }
            } else {
                // Add a cancellation response
                result.add(new HostUpdateApplierResponse(true));
            }
        }

        if (!ok) {
            // Apply compensating updates to fix our local model
            for (int i = 0; i < rollbacks.size(); i++) {
                AbstractHostModelUpdate<?> rollback = rollbacks.get(i);
                try {
                    hostModel.update(rollback);
                }
                catch (UpdateFailedException e) {
                    // TODO uh oh. Reload from the file?
                }
            }
        }
        else {
            // Persist model
            configPersister.persistConfiguration(hostModel);

            result.clear();

            for (AbstractHostModelUpdate<?> update : updates) {
                result.add(new HostUpdateApplierResponse(getAffectedServers(update)));
            }
        }

        return result;
    }

    public List<ServerIdentity> applyHostModelUpdate(AbstractHostModelUpdate<?> update) throws UpdateFailedException {

        List<HostUpdateApplierResponse> rsps = applyHostModelUpdates(Collections.<AbstractHostModelUpdate<?>>singletonList(update));
        HostUpdateApplierResponse rsp = rsps.get(0);
        if (rsp.getHostFailure() != null) {
            throw rsp.getHostFailure();
        }
        else {
            return rsp.getServers();
        }
    }


    private List<ServerIdentity> getAffectedServers(AbstractHostModelUpdate<?> update) {
        List<String> serverNames = update.getAffectedServers(hostModel);
        if (serverNames.size() == 0) {
            return Collections.emptyList();
        }
        List<ServerIdentity> ids = new ArrayList<ServerIdentity>(serverNames.size());
        String hostName = hostModel.getName();
        for (String server : serverNames) {
            ServerElement se = hostModel.getServer(server);
            ids.add(new ServerIdentity(hostName, se.getServerGroup(), server));
        }
        return ids;
    }

    private HostModel parseHostXml() {

        try {
            final List<AbstractHostModelUpdate<?>> hostUpdates = new ArrayList<AbstractHostModelUpdate<?>>();
            final XMLMapper mapper = XMLMapper.Factory.create();
            extensionRegistrar.registerStandardHostReaders(mapper);
            mapper.parseDocument(hostUpdates, XMLInputFactory.newInstance().createXMLStreamReader(new BufferedInputStream(configPersister.getConfigurationInputStream())));
            final HostModel hostModel = new HostModel();
            for(final AbstractHostModelUpdate<?> update : hostUpdates) {
                hostModel.update(update);
            }
            return hostModel;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("Caught exception during processing of host.xml", e);
        }
    }
}
TOP

Related Classes of org.jboss.as.server.manager.ModelManager

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.