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

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

There is a newer version: 4.0.3
Show 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.BlockedAttacker;
import io.bitsensor.lib.entity.Identifiable;
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.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 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 Map blockedAttackerMap = new ConcurrentHashMap<>();
    private ObjectMapper mapper = ProtoUtils.objectMapper();

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

    @Override
    public Map getBlacklist() {
        return blockedAttackerMap;
    }

    @Override
    public BlockedAttacker getBlocking(String id) {
        return blockedAttackerMap.get(id);
    }

    @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;
                }

                List> res = mapper.convertValue(result,
                        new TypeReference>>() {
                        });

                blockedAttackerMap.clear();
                res.forEach(i -> blockedAttackerMap.put(i.getIdentifier(), i.getIdentifiable()));

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

    /**
     * Returns a list of {@link BlockedAttacker} 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(Identifiable attacker) {
        blockedAttackerMap.put(attacker.getIdentifier(), attacker.getIdentifiable());

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


    @RabbitListener(queues = "#{blacklistUpdateQueue.name}")
    public void receiveUpdate(Identifiable attacker) {
        blockedAttackerMap.put(attacker.getIdentifier(), attacker.getIdentifiable());

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

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

        blockedAttackerMap.remove(id);

        LOGGER.info("Deleted block {}", id);
        publisher.publishEvent(new BlockingEvent(this, Type.DELETE, id));
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

        // Fetch blacklist when application initialized or refreshed.
        fetchBlacklist();
    }
}