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

org.cometd.oort.OortComet Maven / Gradle / Ivy

There is a newer version: 8.0.6
Show newest version
/*
 * Copyright (c) 2008-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cometd.oort;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;

import org.cometd.bayeux.client.ClientSession;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.client.BayeuxClient;
import org.cometd.client.transport.ClientTransport;

/**
 * 

The Oort comet client connects a local Oort comet server to a remote Oort comet server.

*/ public class OortComet extends BayeuxClient { private final ConcurrentMap _subscriptions = new ConcurrentHashMap<>(); private final Oort _oort; private final String _cometURL; private volatile boolean _subscriptionsAllowed; public OortComet(Oort oort, String cometURL, ScheduledExecutorService scheduler, ClientTransport transport, ClientTransport... transports) { super(cometURL, scheduler, transport, transports); _oort = oort; _cometURL = cometURL; } protected void subscribe(Set observedChannels) { // Guard against concurrent subscription clearing from the handshake callback if (!_subscriptionsAllowed) { return; } for (String channel : observedChannels) { if (_subscriptions.containsKey(channel)) { continue; } ClientSessionChannel.MessageListener listener = (c, message) -> { if (logger.isDebugEnabled()) { logger.debug("Republishing message {} from {}", message, _cometURL); } // BayeuxServer may sweep channels, so calling bayeux.getChannel(...) // may return null, and therefore we use the client to send the message. _oort.getOortSession().getChannel(message.getChannel()).publish(message); }; ClientSessionChannel.MessageListener existing = _subscriptions.putIfAbsent(channel, listener); if (existing == null) { if (logger.isDebugEnabled()) { logger.debug("Subscribing to messages on {} from {}", channel, _cometURL); } getChannel(channel).subscribe(listener); } } if (logger.isDebugEnabled()) { logger.debug("Subscriptions to messages on {} from {}", _subscriptions, _cometURL); } } protected void unsubscribe(String channel) { ClientSessionChannel.MessageListener listener = _subscriptions.remove(channel); if (listener != null) { if (logger.isDebugEnabled()) { logger.debug("Unsubscribing to messages on {} from {}", channel, _cometURL); } getChannel(channel).unsubscribe(listener); } } protected void clearSubscriptions() { for (String channel : _oort.getObservedChannels()) { unsubscribe(channel); } } void open(final ClientSession.MessageListener callback) { batch(() -> { // Subscribe to cloud notifications getChannel(Oort.OORT_CLOUD_CHANNEL).subscribe((channel, message) -> { if (message.isSuccessful()) { _oort.joinComets(message); } }); // It is possible that a call to Oort.observeChannel() (which triggers // the call to subscribe()) is performed concurrently with the handshake // of this OortComet with a remote comet. // For example, Seti calls Oort.observeChannel() on startup and this may // be called while the Oort cloud is connecting all the comets together. // In this case, below we will clear existing subscriptions, but we will // subscribe them again just afterwards, ensuring only one subscriber // (and not multiple ones) is subscribed. clearSubscriptions(); _subscriptionsAllowed = true; Set channels = _oort.getObservedChannels(); if (logger.isDebugEnabled()) { logger.debug("Observing channels {}", channels); } subscribe(channels); // Advertise our own network. getChannel(Oort.OORT_CLOUD_CHANNEL).publish(new ArrayList<>(_oort.getKnownComets())); // Advertise the remote node that we have joined. Map data = new HashMap<>(2); data.put(Oort.EXT_OORT_ID_FIELD, _oort.getId()); data.put(Oort.EXT_OORT_URL_FIELD, _oort.getURL()); if (logger.isDebugEnabled()) { logger.debug("Sending join data {}", data); } getChannel(Oort.OORT_SERVICE_CHANNEL).publish(data, callback); }); } @Override public String toString() { return String.format("%s[%s]", super.toString(), _cometURL); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy