Package org.jboss.as.domain.controller.mgmt

Source Code of org.jboss.as.domain.controller.mgmt.DomainControllerOperationHandler$UnregisterOperation

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

import java.io.DataOutput;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import org.jboss.as.domain.controller.DomainController;
import org.jboss.as.domain.controller.FileRepository;
import org.jboss.as.domain.controller.ServerManagerClient;
import org.jboss.as.model.DeploymentUnitElement;
import org.jboss.as.protocol.ProtocolUtils;
import org.jboss.as.protocol.mgmt.AbstractMessageHandler;
import org.jboss.as.protocol.ByteDataInput;
import org.jboss.as.protocol.ByteDataOutput;
import org.jboss.as.protocol.Connection;
import org.jboss.as.protocol.mgmt.ManagementOperationHandler;
import org.jboss.as.protocol.mgmt.ManagementProtocol;
import org.jboss.as.protocol.mgmt.ManagementResponse;
import org.jboss.as.protocol.SimpleByteDataInput;
import org.jboss.as.protocol.SimpleByteDataOutput;
import org.jboss.as.protocol.StreamUtils;
import static org.jboss.as.protocol.StreamUtils.readUTFZBytes;
import static org.jboss.as.protocol.StreamUtils.safeClose;

import static org.jboss.as.protocol.ProtocolUtils.expectHeader;
import org.jboss.logging.Logger;
import org.jboss.marshalling.Marshaller;
import static org.jboss.marshalling.Marshalling.createByteOutput;
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;

/**
* {@link org.jboss.as.protocol.mgmt.ManagementOperationHandler} implementation used to handle request
* intended for the domain controller.
*
* @author John Bailey
*/
public class  DomainControllerOperationHandler extends AbstractMessageHandler implements ManagementOperationHandler, Service<DomainControllerOperationHandler> {
    private static final Logger log = Logger.getLogger("org.jboss.as.management");
    public static final ServiceName SERVICE_NAME = DomainController.SERVICE_NAME.append("operation", "handler");

    private final InjectedValue<DomainController> domainControllerValue = new InjectedValue<DomainController>();
    private final InjectedValue<ScheduledExecutorService> executorServiceValue = new InjectedValue<ScheduledExecutorService>();
    private final InjectedValue<ThreadFactory> threadFactoryValue = new InjectedValue<ThreadFactory>();
    private final InjectedValue<FileRepository> localFileRepositoryValue = new InjectedValue<FileRepository>();

    private DomainController domainController;
    private ScheduledExecutorService executorService;
    private ThreadFactory threadFactory;
    private FileRepository localFileRepository;

    /** {@inheritDoc} */
    public final byte getIdentifier() {
        return DomainControllerProtocol.DOMAIN_CONTROLLER_REQUEST;
    }

    /** {@inheritDoc} */
    public synchronized void start(StartContext context) throws StartException {
        try {
            domainController = domainControllerValue.getValue();
            executorService = executorServiceValue.getValue();
            localFileRepository = localFileRepositoryValue.getValue();
            this.threadFactory = threadFactoryValue.getValue();
        } catch (IllegalStateException e) {
            throw new StartException(e);
        }
    }

    /** {@inheritDoc} */
    public synchronized void stop(StopContext context) {
        domainController = null;
        executorService = null;
        localFileRepository = null;
    }

    /** {@inheritDoc} */
    public synchronized DomainControllerOperationHandler getValue() throws IllegalStateException {
        return this;
    }

    public Injector<DomainController> getDomainControllerInjector() {
        return domainControllerValue;
    }

    public Injector<ScheduledExecutorService> getExecutorServiceInjector() {
        return executorServiceValue;
    }

    public Injector<FileRepository> getLocalFileRepositoryInjector() {
        return localFileRepositoryValue;
    }

    public Injector<ThreadFactory> getThreadFactoryInjector() {
        return threadFactoryValue;
    }

    /**
     * Handles the request.  Reads the requested command byte. Once the command is available it will get the
     * appropriate operation and execute it.
     *
     * @param connection  The connection
     * @param input The connection input
     * @throws IOException If any problems occur performing the operation
     */
    @Override
    public void handle(final Connection connection, final InputStream input) throws IOException {
        final byte commandCode;
        expectHeader(input, ManagementProtocol.REQUEST_OPERATION);
        commandCode = StreamUtils.readByte(input);

        final AbstractMessageHandler operation = operationFor(commandCode);
        if (operation == null) {
            throw new IOException("Invalid command code " + commandCode + " received from server manager");
        }
        log.debugf("Received DomainController operation [%s]", operation);

        operation.handle(connection, input);
    }

    private AbstractMessageHandler operationFor(final byte commandByte) {
        switch (commandByte) {
            case DomainControllerProtocol.REGISTER_REQUEST:
                return new RegisterOperation();
            case DomainControllerProtocol.SYNC_FILE_REQUEST:
                return new GetFileOperation();
            case DomainControllerProtocol.UNREGISTER_REQUEST:
                return new UnregisterOperation();
            default: {
                return null;
            }
        }
    }

    private abstract class DomainControllerOperation extends ManagementResponse {
        @Override
        protected void readRequest(final InputStream input) throws IOException {
            super.readRequest(input);
            final String serverManagerId;
            expectHeader(input, DomainControllerProtocol.PARAM_SERVER_MANAGER_ID);
            serverManagerId = readUTFZBytes(input);
            readRequest(serverManagerId, input);
        }

        protected abstract void readRequest(final String serverManagerId, final InputStream input) throws IOException;
    }

    private class RegisterOperation extends DomainControllerOperation {
        @Override
        protected final byte getResponseCode() {
            return DomainControllerProtocol.REGISTER_RESPONSE;
        }

        @Override
        protected final void readRequest(final String serverManagerId, final InputStream inputStream) throws IOException {
            ByteDataInput input = null;
            try {
                input = new SimpleByteDataInput(inputStream);
                expectHeader(input, DomainControllerProtocol.PARAM_SERVER_MANAGER_HOST);
                final int addressSize = input.readInt();
                byte[] addressBytes = new byte[addressSize];
                input.readFully(addressBytes);
                expectHeader(input, DomainControllerProtocol.PARAM_SERVER_MANAGER_PORT);
                final int port = input.readInt();
                final InetAddress address = InetAddress.getByAddress(addressBytes);
                final ServerManagerClient client = new RemoteDomainControllerClient(serverManagerId, address, port, executorService, threadFactory);
                domainController.addClient(client);
                log.infof("Server manager registered [%s]", client);
            } finally {
                safeClose(input);
            }
        }

        @Override
        protected final void sendResponse(final OutputStream output) throws IOException {
            final Marshaller marshaller = getMarshaller();
            marshaller.start(createByteOutput(output));
            marshaller.writeByte(DomainControllerProtocol.PARAM_DOMAIN_MODEL);
            marshaller.writeObject(domainController.getDomainModel());
            marshaller.finish();
        }
    }

    private class UnregisterOperation extends DomainControllerOperation {
        @Override
        protected final byte getResponseCode() {
            return DomainControllerProtocol.UNREGISTER_RESPONSE;
        }

        @Override
        protected final void readRequest(final String serverManagerId, final InputStream input) throws IOException {
            log.infof("Server manager unregistered [%s]", serverManagerId);
            domainController.removeClient(serverManagerId);
        }
    }

    private class GetFileOperation extends DomainControllerOperation {
        private File localPath;

        @Override
        protected final byte getResponseCode() {
            return DomainControllerProtocol.SYNC_FILE_RESPONSE;
        }

        @Override
        protected final void readRequest(final String serverManagerId, final InputStream inputStream) throws IOException {
            final byte rootId;
            final String filePath;
            ByteDataInput input = null;
            try {
                input = new SimpleByteDataInput(inputStream);
                expectHeader(input, DomainControllerProtocol.PARAM_ROOT_ID);
                rootId = input.readByte();
                expectHeader(input, DomainControllerProtocol.PARAM_FILE_PATH);
                filePath = input.readUTF();

                log.debugf("Server manager [%s] requested file [%s] from root [%d]", serverManagerId, filePath, rootId);
                switch (rootId) {
                    case (byte)DomainControllerProtocol.PARAM_ROOT_ID_FILE: {
                        localPath = localFileRepository.getFile(filePath);
                        break;
                    }
                    case (byte)DomainControllerProtocol.PARAM_ROOT_ID_CONFIGURATION: {
                        localPath = localFileRepository.getConfigurationFile(filePath);
                        break;
                    }
                    case (byte)DomainControllerProtocol.PARAM_ROOT_ID_DEPLOYMENT: {
                        byte[] hash = DeploymentUnitElement.hexStringToBytes(filePath);
                        localPath = localFileRepository.getDeploymentRoot(hash);
                        break;
                    }
                    default: {
                        throw new IOException(String.format("Invalid root id [%d]", rootId));
                    }
                }
            } finally {
                safeClose(input);
            }
        }

        @Override
        protected void sendResponse(final OutputStream outputStream) throws IOException {
            ByteDataOutput output = null;
            try {
                output = new SimpleByteDataOutput(outputStream);
                output.writeByte(DomainControllerProtocol.PARAM_NUM_FILES);
                if (localPath == null || !localPath.exists()) {
                    output.writeInt(-1);
                } else if (localPath.isFile()) {
                    output.writeInt(1);
                    writeFile(localPath, output);
                } else {
                    final List<File> childFiles = getChildFiles(localPath);
                    output.writeInt(childFiles.size());
                    for (File child : childFiles) {
                        writeFile(child, output);
                    }
                }
                output.close();
            } finally {
                safeClose(output);
            }
        }

        private List<File> getChildFiles(final File base) {
            final List<File> childFiles = new ArrayList<File>();
            getChildFiles(base, childFiles);
            return childFiles;
        }

        private void getChildFiles(final File base, final List<File> childFiles) {
            for (File child : base.listFiles()) {
                if (child.isFile()) {
                    childFiles.add(child);
                } else {
                    getChildFiles(child, childFiles);
                }
            }
        }

        private String getRelativePath(final File parent, final File child) {
            return child.getAbsolutePath().substring(parent.getAbsolutePath().length());
        }

        private void writeFile(final File file, final DataOutput output) throws IOException {
            output.writeByte(DomainControllerProtocol.FILE_START);
            output.writeByte(DomainControllerProtocol.PARAM_FILE_PATH);
            output.writeUTF(getRelativePath(localPath, file));
            output.writeByte(DomainControllerProtocol.PARAM_FILE_SIZE);
            output.writeLong(file.length());
            InputStream inputStream = null;
            try {
                inputStream = new FileInputStream(file);
                byte[] buffer = new byte[8192];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    output.write(buffer, 0, len);
                }
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException ignored) {
                    }
                }
            }
            output.writeByte(DomainControllerProtocol.FILE_END);
            log.infof("Wrote file [%s]", file);
        }
    }

    private static Marshaller getMarshaller() throws IOException {
        return ProtocolUtils.getMarshaller(ProtocolUtils.MODULAR_CONFIG);
    }
}
TOP

Related Classes of org.jboss.as.domain.controller.mgmt.DomainControllerOperationHandler$UnregisterOperation

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.