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

com.ibm.cp4waiops.connectors.sdk.CloudEventConsumer Maven / Gradle / Ivy

There is a newer version: 2.2.8
Show newest version
package com.ibm.cp4waiops.connectors.sdk;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.ibm.aiops.connectors.bridge.ConnectorBridgeGrpc.ConnectorBridgeStub;

import io.cloudevents.CloudEvent;
import io.micrometer.core.instrument.MeterRegistry;

/**
 * Manages GRPCCloudEventConsumeChannel instances, creating and destroying them as needed
 */
class CloudEventConsumer {
    private static final Logger logger = Logger.getLogger(CloudEventConsumer.class.getName());

    private static class ChannelEntry {
        public CloudEvent requestTemplate;
        public GRPCCloudEventConsumeChannel channel;
    }

    static class CloudEventEntry {
        String channelName;
        CloudEvent event;
    }

    private ConnectorBridgeStub _stub;
    private BlockingQueue _actionQueue;
    private HashMap _channels;

    protected MeterRegistry _meterRegistry;

    /**
     * Constructs an instance
     * 
     * @param stub
     *            the interface used communicate with the bridge server
     * @param actionQueue
     *            where consumed events are placed
     * @param meterRegistry
     *            a registry for channel metrics
     */
    CloudEventConsumer(ConnectorBridgeStub stub, BlockingQueue actionQueue,
            MeterRegistry meterRegistry) {
        _stub = stub;
        _actionQueue = actionQueue;
        _channels = new HashMap<>();
        _meterRegistry = meterRegistry;
    }

    /**
     * Creates the target channel if it does not exist
     * 
     * @param name
     *            the channel name that will be sent to the server, most likely the name of the kafka topic
     * @param requestTemplate
     *            a template for information sent to the server when starting the channel
     */
    void setupChannel(String name, CloudEvent requestTemplate) {
        // Reuse existing stream if no change is needed
        ChannelEntry existing = _channels.get(name);
        if (existing != null && existing.requestTemplate.equals(requestTemplate)) {
            return;
        }
        // Terminate existing channel
        if (existing != null) {
            logger.log(Level.INFO, "channel request template changed, restarting: name=" + name);
            existing.channel.close();
        }
        // Start new channel
        ChannelEntry entry = new ChannelEntry();
        entry.requestTemplate = requestTemplate;
        entry.channel = new GRPCCloudEventConsumeChannel(name, _stub, requestTemplate, _actionQueue, _meterRegistry);
        entry.channel.startChannel();
        _channels.put(name, entry);
    }

    /**
     * Closes all active consume channels except those listed
     * 
     * @param excludedNames
     */
    void closeAllChannelsExcept(List excludedNames) {
        ArrayList toRemove = new ArrayList<>();
        for (var entry : _channels.entrySet()) {
            if (excludedNames.contains(entry.getKey())) {
                continue;
            }
            logger.log(Level.INFO, "channel no longer requested, closing: name=" + entry.getKey());
            toRemove.add(entry.getKey());
            entry.getValue().channel.close();
        }
        for (String name : toRemove) {
            _channels.remove(name);
        }
    }

    /**
     * Closes all active consume channels
     */
    void closeAllChannels() {
        closeAllChannelsExcept(new ArrayList<>());
    }

    /**
     * Restarts any channel that have stopped due to connection errors
     */
    void fixChannels() {
        for (var entry : _channels.entrySet()) {
            entry.getValue().channel.fixChannelIfStopped();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy