Package org.graylog2.shared.inputs

Source Code of org.graylog2.shared.inputs.InputRegistry

/**
* This file is part of Graylog2.
*
* Graylog2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog2.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.shared.inputs;


import com.codahale.metrics.InstrumentedExecutorService;
import com.codahale.metrics.InstrumentedThreadFactory;
import com.codahale.metrics.MetricRegistry;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.graylog2.plugin.configuration.Configuration;
import org.graylog2.plugin.inputs.InputState;
import org.graylog2.plugin.inputs.MessageInput;
import org.graylog2.shared.buffers.ProcessBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public abstract class InputRegistry {
    private static final Logger LOG = LoggerFactory.getLogger(InputRegistry.class);
    protected final Set<InputState> inputStates = new HashSet<>();
    protected final ExecutorService executor;
    private final MessageInputFactory messageInputFactory;
    private final ProcessBuffer processBuffer;

    protected abstract void finishedLaunch(InputState state);

    protected abstract void finishedTermination(InputState state);

    protected abstract void finishedStop(InputState inputState);

    protected abstract List<MessageInput> getAllPersisted();

    public abstract void cleanInput(MessageInput input);

    public InputRegistry(MessageInputFactory messageInputFactory,
                         ProcessBuffer processBuffer,
                         MetricRegistry metricRegistry) {
        this.messageInputFactory = messageInputFactory;
        this.processBuffer = processBuffer;
        this.executor = executorService(metricRegistry);
    }

    private ExecutorService executorService(final MetricRegistry metricRegistry) {
        return new InstrumentedExecutorService(
                Executors.newCachedThreadPool(threadFactory(metricRegistry)), metricRegistry);
    }

    private ThreadFactory threadFactory(final MetricRegistry metricRegistry) {
        return new InstrumentedThreadFactory(
                new ThreadFactoryBuilder().setNameFormat("inputs-%d").build(),
                metricRegistry);
    }

    public MessageInput create(String inputClass, Configuration configuration) throws NoSuchInputTypeException {
        return messageInputFactory.create(inputClass, configuration);
    }

    public InputState launch(final MessageInput input, String id) {
        return launch(input, id, false);
    }

    public InputState launch(final MessageInput input, String id, boolean register) {
        final InputState inputState = new InputState(input, id);
        inputStates.add(inputState);

        return launch(input, inputState, register);
    }

    protected InputState launch(final MessageInput input, final InputState inputState, final boolean register) {
        if (input == null)
            throw new IllegalArgumentException("InputState has no MessageInput!");

        if (!inputState.getMessageInput().equals(input))
            throw new IllegalArgumentException("Supplied InputState already has Input which is not the one supplied.");

        if (inputState.getMessageInput() == null)
            inputState.setMessageInput(input);

        executor.submit(new Runnable() {
            @Override
            public void run() {
                LOG.info("Starting [{}] input with ID <{}>", input.getClass().getCanonicalName(), input.getId());
                try {
                    input.checkConfiguration();
                    inputState.setState(InputState.InputStateType.STARTING);
                    input.launch(processBuffer);
                    inputState.setState(InputState.InputStateType.RUNNING);
                    String msg = "Completed starting [" + input.getClass().getCanonicalName() + "] input with ID <" + input.getId() + ">";
                    LOG.info(msg);
                } catch (Exception e) {
                    handleLaunchException(e, input, inputState);
                } finally {
                    finishedLaunch(inputState);
                }
            }
        });

        return inputState;
    }

    protected void handleLaunchException(Throwable e, MessageInput input, InputState inputState) {
        StringBuilder msg = new StringBuilder("The [" + input.getClass().getCanonicalName() + "] input with ID <" + input.getId() + "> misfired. Reason: ");

        String causeMsg = extractMessageCause(e);

        msg.append(causeMsg);

        LOG.error(msg.toString(), e);

        // Clean up.
        //cleanInput(input);

        inputState.setState(InputState.InputStateType.FAILED);
        inputState.setDetailedMessage(causeMsg);
    }

    private String extractMessageCause(Throwable e) {
        StringBuilder causeMsg = new StringBuilder(e.getMessage());

        // Go down the whole cause chain to build a message that provides as much information as possible.
        int maxLevel = 7; // ;)
        Throwable cause = e.getCause();
        for (int i = 0; i < maxLevel; i++) {
            if (cause == null) {
                break;
            }

            causeMsg.append(", ").append(cause.getMessage());
            cause = cause.getCause();
        }
        return causeMsg.toString();
    }

    public InputState launch(final MessageInput input) {
        return launch(input, UUID.randomUUID().toString());
    }

    public InputState launch(final InputState inputState) {
        final MessageInput input = inputState.getMessageInput();

        return launch(input, inputState, false);
    }

    public Set<InputState> getInputStates() {
        return ImmutableSet.copyOf(inputStates);
    }

    public InputState getInputState(String inputId) {
        for (InputState inputState : inputStates) {
            if (inputState.getMessageInput().getPersistId().equals(inputId))
                return inputState;
        }

        return null;
    }

    public Set<InputState> getRunningInputs() {
        Set<InputState> runningInputs = new HashSet<>();
        for (InputState inputState : inputStates) {
            if (inputState.getState() == InputState.InputStateType.RUNNING)
                runningInputs.add(inputState);
        }
        return ImmutableSet.copyOf(runningInputs);
    }

    public boolean hasTypeRunning(Class klazz) {
        for (InputState inputState : inputStates) {
            if (inputState.getMessageInput().getClass().equals(klazz)) {
                return true;
            }
        }

        return false;
    }

    public Map<String, InputDescription> getAvailableInputs() {
        return messageInputFactory.getAvailableInputs();
    }

    public int runningCount() {
        return getRunningInputs().size();
    }

    public void removeFromRunning(InputState inputState) {
        inputStates.remove(inputState);
    }

    public InputState launchPersisted(MessageInput input) {
        return launch(input);
    }

    public void launchAllPersisted() {
        for (MessageInput input : getAllPersisted()) {
            input.initialize();
            launchPersisted(input);
        }
    }

    public InputState terminate(MessageInput input) {
        InputState inputState = stop(input);

        if (inputState != null) {
            inputState.setState(InputState.InputStateType.TERMINATED);
            finishedTermination(inputState);
        }

        return inputState;
    }

    public InputState stop(MessageInput input) {
        InputState inputState = getRunningInputState(input.getId());

        if (inputState != null) {
            try {
                input.stop();
            } catch (Exception e) {
                LOG.warn("Stopping input <{}> failed, removing anyway: {}", input.getId(), e);
            }
            inputState.setState(InputState.InputStateType.STOPPED);
            finishedStop(inputState);
        }

        return inputState;
    }

    public MessageInput getRunningInput(String inputId) {
        for (InputState inputState : inputStates) {
            if (inputState.getMessageInput().getId().equals(inputId))
                return inputState.getMessageInput();
        }

        return null;
    }

    public InputState getRunningInputState(String inputStateId) {
        for (InputState inputState : inputStates) {
            if (inputState.getMessageInput().getId().equals(inputStateId))
                return inputState;
        }

        return null;
    }

    public MessageInput getPersisted(String inputId) {
        for (MessageInput input : getAllPersisted()) {
            if (input.getId().equals(inputId))
                return input;
        }

        return null;
    }
}
TOP

Related Classes of org.graylog2.shared.inputs.InputRegistry

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.