All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.bitsensor.plugins.java.blocking.BlockingManagerImpl Maven / Gradle / Ivy

The newest version!
package io.bitsensor.plugins.java.blocking;

import io.bitsensor.plugins.shaded.com.fasterxml.jackson.core.type.TypeReference;
import io.bitsensor.plugins.shaded.com.fasterxml.jackson.databind.ObjectMapper;
import io.bitsensor.lib.entity.proto.Block;
import io.bitsensor.lib.entity.util.ProtoUtils;
import io.bitsensor.plugins.java.blocking.BlockingEvent.Type;
import io.bitsensor.plugins.java.core.BitSensorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.bitsensor.plugins.shaded.io.bitsensor.plugins.shaded.org.springframework.amqp.rabbit.AsyncRabbitTemplate;
import io.bitsensor.plugins.shaded.io.bitsensor.plugins.shaded.org.springframework.amqp.rabbit.annotation.RabbitListener;
import io.bitsensor.plugins.shaded.org.springframework.beans.factory.annotation.Autowired;
import io.bitsensor.plugins.shaded.org.springframework.context.ApplicationEventPublisher;
import io.bitsensor.plugins.shaded.org.springframework.context.ApplicationListener;
import io.bitsensor.plugins.shaded.org.springframework.context.event.ContextRefreshedEvent;
import io.bitsensor.plugins.shaded.org.springframework.stereotype.Component;
import io.bitsensor.plugins.shaded.org.springframework.util.concurrent.ListenableFutureCallback;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;


/**
 * A simple blocking manager implementation that fetches blacklist from Bitbrain rabbitmq instance and subscribes to
 * blacklist changes.
 */
@Component
public class BlockingManagerImpl implements BlockingManager, ApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(BlockingManagerImpl.class);

    private final ApplicationEventPublisher publisher;
    private final AsyncRabbitTemplate asyncTemplate;
    private List blocks = new CopyOnWriteArrayList<>();
    private ObjectMapper mapper = ProtoUtils.objectMapper();

    @Autowired
    public BlockingManagerImpl(ApplicationEventPublisher publisher, AsyncRabbitTemplate asyncTemplate) {
        this.publisher = publisher;
        this.asyncTemplate = asyncTemplate;
    }

    @Override
    public List getBlacklist() {
        return blocks;
    }

    @Override
    public void fetchBlacklist() {
        doFetchBlacklist().addCallback(new ListenableFutureCallback() {
            @Override
            public void onFailure(Throwable ex) {
                LOGGER.error("Failed fetching blacklist from BitSensor", ex);
                publisher.publishEvent(new BlockingEvent(this, Type.FETCH, false));
            }

            @Override
            public void onSuccess(Object result) {
                if (result == null) {
                    onFailure(new BitSensorException("Blacklist fetch returns null."));
                    return;
                }

                blocks = new CopyOnWriteArrayList<>(mapper.>convertValue(result,
                        new TypeReference>() {
                        }));

                LOGGER.info("Fetched {} blocked attackers", blocks.size());
                publisher.publishEvent(new BlockingEvent(this, Type.FETCH, blocks));
            }
        });
    }

    /**
     * Returns a list of {@link Block} being fetched from BitSensor.
     */
    private AsyncRabbitTemplate.RabbitConverterFuture doFetchBlacklist() {
        String message = "getAll";

        return asyncTemplate.convertSendAndReceive(
                BlockingConfig.RPC_EXCHANGE,
                BlockingConfig.RPC_ROUTING_KEY,
                message);
    }


    @RabbitListener(queues = "#{blacklistAddQueue.name}")
    public void receiveAdd(Block block) {
        blocks.add(block);

        LOGGER.info("Added block {}", block.getId());
        publisher.publishEvent(new BlockingEvent(this, Type.ADD, block));
    }


    @RabbitListener(queues = "#{blacklistUpdateQueue.name}")
    public void receiveUpdate(Block block) {
        blocks.add(block);

        LOGGER.info("Updated block {}", block.getId());
        publisher.publishEvent(new BlockingEvent(this, Type.UPDATE, block));
    }

    @RabbitListener(queues = "#{blacklistDeleteQueue.name}")
    public void receiveDelete(String id) {
        if (id == null)
            return;

        for (Iterator blockIterator = blocks.iterator(); blockIterator.hasNext(); ) {
            Block block = blockIterator.next();

            if (block.getId().equals(id)) {
                blocks.remove(block);
                LOGGER.info("Deleted block {}", id);
                publisher.publishEvent(new BlockingEvent(this, Type.DELETE, id));
                return;
            }
        }
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        fetchBlacklist();
    }
}