org.graylog2.messageprocessors.OrderedMessageProcessors Maven / Gradle / Ivy
/**
* This file is part of Graylog.
*
* Graylog 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.
*
* Graylog 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 Graylog. If not, see .
*/
package org.graylog2.messageprocessors;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import org.graylog2.cluster.ClusterConfigChangedEvent;
import org.graylog2.plugin.cluster.ClusterConfigService;
import org.graylog2.plugin.messageprocessors.MessageProcessor;
import org.graylog2.utilities.LenientExplicitOrdering;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
* Represents the current MessageProcessor ordering in the system.
*
* The order is configurable by writing a new MessageProcessorOrder into the ClusterConfig
*/
public class OrderedMessageProcessors implements Iterable {
private static final Logger LOG = LoggerFactory.getLogger(OrderedMessageProcessors.class);
private final Set processors;
private final ClusterConfigService clusterConfigService;
private final AtomicReference> sortedProcessors =
new AtomicReference<>(Collections.emptyList());
private Ordering classNameOrdering;
@Inject
public OrderedMessageProcessors(Set processors,
ClusterConfigService clusterConfigService,
EventBus eventBus) {
this.processors = processors;
this.clusterConfigService = clusterConfigService;
eventBus.register(this);
// TODO by default sort on class name this is probably not the best idea, but for now works.
this.classNameOrdering = Ordering.from(String.CASE_INSENSITIVE_ORDER);
// Initial sort.
sortProcessorChain();
}
private void sortProcessorChain() {
final MessageProcessorsConfig config = clusterConfigService.get(MessageProcessorsConfig.class);
if (config != null) {
// if we have an explicit ordering use that (unknown last, partial ordering over the given list)
classNameOrdering = new LenientExplicitOrdering<>(config.processorOrder());
}
final ImmutableList sortedCopy =
classNameOrdering.onResultOf(mp -> mp.getClass().getCanonicalName()).immutableSortedCopy(processors);
final Collection enabledMessageProcessors =
Collections2.filter(sortedCopy,
mp -> config == null || !config.disabledProcessors().contains(mp.getClass().getCanonicalName()));
LOG.debug("New active message processors: {}", enabledMessageProcessors);
sortedProcessors.set(ImmutableList.copyOf(enabledMessageProcessors));
}
@Subscribe
public void handleOrderingUpdate(ClusterConfigChangedEvent event) {
if (!MessageProcessorsConfig.class.getCanonicalName().equals(event.type())) {
return;
}
sortProcessorChain();
}
@Override
public Iterator iterator() {
return sortedProcessors.get().iterator();
}
}