Package org.jboss.as.domain.controller

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

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, 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 static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_HEADERS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ROLLBACK_ON_RUNTIME_FAILURE;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;

import org.jboss.as.controller.ResultHandler;
import org.jboss.as.controller.client.OperationBuilder;
import org.jboss.as.controller.persistence.ConfigurationPersistenceException;
import org.jboss.as.controller.persistence.ExtensibleConfigurationPersister;
import org.jboss.as.process.CommandLineConstants;
import org.jboss.as.protocol.StreamUtils;
import org.jboss.as.server.deployment.api.DeploymentRepository;
import org.jboss.as.server.services.net.NetworkInterfaceBinding;
import org.jboss.dmr.ModelNode;
import org.jboss.logging.Logger;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;

/**
* @author Emanuel Muckenhuber
*/
public final class DomainControllerService implements Service<DomainController> {

    private static final Logger log = Logger.getLogger("org.jboss.as.domain.controller");
    private final ExtensibleConfigurationPersister configurationPersister;
    private final DeploymentRepository deploymentRepository;
    private final FileRepository localFileRepository;
    private final InjectedValue<ScheduledExecutorService> scheduledExecutorService = new InjectedValue<ScheduledExecutorService>();
    private final InjectedValue<MasterDomainControllerClient> masterDomainControllerClient = new InjectedValue<MasterDomainControllerClient>();
    private final InjectedValue<LocalHostModel> hostController = new InjectedValue<LocalHostModel>();
    private final InjectedValue<NetworkInterfaceBinding> mgmtInterface = new InjectedValue<NetworkInterfaceBinding>();
    private final InjectedValue<HostRegistryService> hostRegistry = new InjectedValue<HostRegistryService>();
    private final String localHostName;
    private final boolean backupDomainFiles;
    private final boolean useCachedDc;
    private final int mgmtPort;
    private final DomainModelImpl domainModel;
    private DomainController controller;

    public DomainControllerService(final ExtensibleConfigurationPersister configurationPersister, final String localHostName, final int mgmtPort,
                                   final DeploymentRepository deploymentRepository, final FileRepository localFileRepository, final boolean backupDomainFiles,
                                   final boolean useCachedDc, final DomainModelImpl domainModel) {
        this.configurationPersister = configurationPersister;
        this.localHostName = localHostName;
        this.mgmtPort = mgmtPort;
        this.deploymentRepository = deploymentRepository;
        this.localFileRepository = localFileRepository;
        this.backupDomainFiles = backupDomainFiles;
        this.useCachedDc = useCachedDc;
        this.domainModel = domainModel;
    }

    /** {@inheritDoc} */
    @Override
    public synchronized void start(final StartContext context) throws StartException {
        MasterDomainControllerClient masterClient = masterDomainControllerClient.getOptionalValue();
        this.controller = masterClient == null ? startMasterDomainController() : startSlaveDomainController(masterClient);
        backupDomainFiles();
        hostController.getValue().startServers(controller);
        try {
            configurationPersister.successfulBoot();
        } catch (ConfigurationPersistenceException e) {
            throw new StartException(e);
        }
    }

    /** {@inheritDoc} */
    @Override
    public synchronized void stop(final StopContext context) {
        hostController.getValue().stopServers();
        MasterDomainControllerClient masterClient = masterDomainControllerClient.getOptionalValue();
        if (masterClient != null) {
            masterClient.unregister();
        }
        this.controller = null;
    }

    /** {@inheritDoc} */
    @Override
    public synchronized DomainController getValue() throws IllegalStateException, IllegalArgumentException {
        final DomainController controller = this.controller;
        if(controller == null) {
            throw new IllegalStateException();
        }
        return controller;
    }

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

    public Injector<LocalHostModel> getHostControllerServiceInjector() {
        return hostController;
    }

    public Injector<MasterDomainControllerClient> getMasterDomainControllerClientInjector() {
        return masterDomainControllerClient;
    }

    public Injector<NetworkInterfaceBinding> getInterfaceInjector() {
        return mgmtInterface;
    }

    public InjectedValue<HostRegistryService> getHostRegistryInjector() {
        return hostRegistry;
    }

    private DomainController startMasterDomainController() throws StartException {
        log.info("Starting Domain Controller");
        loadLocalDomainModel();
        return new DomainControllerImpl(scheduledExecutorService.getValue(), domainModel, localHostName, localFileRepository, deploymentRepository, hostRegistry.getValue());
    }

    private DomainController startSlaveDomainController(MasterDomainControllerClient masterClient) throws StartException {
        DomainController remoteController = startRemoteSlaveDomainController(masterClient);
        if (remoteController != null) {
            return remoteController;
        }
        if (useCachedDc) {
            return startLocalCopySlaveDomainController(masterClient);
        } else {
            throw new StartException("Could not contact master domain controller. No attempt to was made to start up from the cached domain controller since "
                    + CommandLineConstants.CACHED_DC + " was not passed in on the command line");
        }
    }

    private DomainController startRemoteSlaveDomainController(MasterDomainControllerClient masterClient) throws StartException {
        // By having a remote repo as a secondary content will be synced only if needed
        FallbackRepository fileRepository = new FallbackRepository(localFileRepository, masterClient.getRemoteFileRepository());
        domainModel.initialiseAsSlaveDC(configurationPersister, deploymentRepository, fileRepository, hostRegistry.getValue());
        final DomainControllerImpl controller = new DomainControllerImpl(scheduledExecutorService.getValue(), domainModel, localHostName, localFileRepository, masterClient, hostRegistry.getValue());
        try {
            masterClient.register(hostController.getValue().getName(), mgmtInterface.getValue().getAddress(), mgmtPort, controller);
        } catch (IllegalStateException e) {
            return null;
        }

        try {
            configurationPersister.store(domainModel.getDomainModel());
        } catch (ConfigurationPersistenceException e) {
            log.error("Could not cache domain model", e);
        }

        return controller;
    }

    private DomainController startLocalCopySlaveDomainController(MasterDomainControllerClient masterClient) throws StartException {
        loadLocalDomainModel();
        return new DomainControllerImpl(scheduledExecutorService.getValue(), domainModel, localHostName, localFileRepository, masterClient, hostRegistry.getValue());
    }

    private void loadLocalDomainModel() throws StartException {
        domainModel.initialiseAsMasterDC(configurationPersister, deploymentRepository, localFileRepository, hostRegistry.getValue());

        final List<ModelNode> updates;
        try {
             updates = configurationPersister.load();
        } catch (final Exception e) {
            log.error("failed to start domain controller", e);
            throw new StartException(e);
        }

        final AtomicInteger count = new AtomicInteger(1);
        final ResultHandler resultHandler = new ResultHandler() {
            @Override
            public void handleResultFragment(final String[] location, final ModelNode result) {
            }

            @Override
            public void handleResultComplete() {
                if (count.decrementAndGet() == 0) {
                    // some action
                }
            }

            @Override
            public void handleFailed(final ModelNode failureDescription) {
                if (count.decrementAndGet() == 0) {
                    // some action
                }
            }

            @Override
            public void handleCancellation() {
                if (count.decrementAndGet() == 0) {
                    // some action
                }
            }
        };
        for (ModelNode update : updates) {
            count.incrementAndGet();
            update.get(OPERATION_HEADERS, ROLLBACK_ON_RUNTIME_FAILURE).set(false);
            domainModel.execute(OperationBuilder.Factory.create(update).build(), resultHandler);
        }
        if (count.decrementAndGet() == 0) {
            // some action?
        }
    }

    private void backupDomainFiles() {
        if (!backupDomainFiles) {
            return;
        }
        if (masterDomainControllerClient.getOptionalValue() == null) {
            log.warn(CommandLineConstants.BACKUP_DC + " is ignored so no backup of the domain controller files will happen, since the domain controller is running locally");
            return;
        }
        log.debug("Backing up the remote domain controller files");

        //Copy the original host since it will be overwritten by the copy from the domain
        final File originalHost = localFileRepository.getConfigurationFile("host.xml");
        File hostBackup;
        try {
            hostBackup = File.createTempFile("host", "xml", originalHost.getParentFile());
        } catch (IOException e1) {
            throw new RuntimeException(e1);
        }
        try {
            copyFile(originalHost, hostBackup);
        } catch (IOException e) {
            throw new RuntimeException("Error backing up " + originalHost + " to " + hostBackup, e);
        }

        //Get the DC files, this will be handled for us by these calls on the client
        FileRepository remote = masterDomainControllerClient.getValue().getRemoteFileRepository();
        remote.getFile("");
        remote.getConfigurationFile("");
        remote.getDeploymentFiles(null);

        //We pulled the remote host which overwrote our host.xml, copy that to somewhere else and restore the backup
        final File remoteHost = new File(originalHost.getParent(), "remoteHost.xml");
        try {
            copyFile(originalHost, remoteHost);
            copyFile(hostBackup, originalHost);
        } catch (IOException e) {
            // AutoGenerated
            throw new RuntimeException("An error happened copying the remote domain controller files. " + originalHost + " has been overwritten. The original can be found at" + hostBackup);
        }
        hostBackup.delete();
    }

    private void copyFile(File src, File dest) throws IOException {
        if (dest.exists()) {
            dest.delete();
        }
        final InputStream in = new BufferedInputStream(new FileInputStream(src));
        try {
            final OutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
            try {
                int i = in.read();
                while (i != -1) {
                    out.write(i);
                    i = in.read();
                }
            } finally {
                StreamUtils.safeClose(out);
            }
        } finally {
            StreamUtils.safeClose(in);
        }
    }
}
TOP

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

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.