/**
* Licensed to the zk1931 under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* The ASF licenses this file to you 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 com.github.zk1931.jzab;
import java.io.File;
import java.util.Iterator;
import com.github.zk1931.jzab.proto.ZabMessage.Message;
/**
* Abstract transport class. Used for communication between different
* Zab instances. It will handle connections to different peers underneath.
* When the transport is disconnected from a destination, it calls
* onDisconnected() callback, and it stops sending/receiving messages to/from
* the destination. Any subsequent send() call to the destination will simply be
* ignored. To tell the transport to reconnect to the destination, the caller
* needs to call clear() method. The purpose of the clear() method is for the
* caller to explicitly acknowledge the onDisconnected event.
*/
abstract class Transport {
protected Receiver receiver;
public Transport(Receiver r) {
this.receiver = r;
}
/**
* Sends a message to a specific server. The channel delivers
* the message in FIFO order. Transport establishes a connection to the
* destination implicitly the first time this method is called with a given
* destination.
*
* @param destination the id of the message destination
* @param message the message to be sent
*/
public abstract void send(String destination, Message message);
/**
* Sends a file to a specific server.
*
* @param destination the id of the message destination
* @param file the file to be sent
*/
public abstract void send(String destination, File file);
/**
* Clears the connection to the destination. If there is no connection to the
* destination, this method does nothing. This method clears any pending
* outgoing messages. Transport reestablishes the connection on the next
* send(). Note that Receiver.onDisconnected() callback will not be invoked
* when the caller clears the connection using this method.
*
* @param destination the id of the destination
*/
public abstract void clear(String destination);
/**
* Broadcasts a message to a set of peers.
*
* @param peers the set of destination peers.
* @param message the message to be broadcasted.
*/
public void broadcast(Iterator<String> peers, Message message) {
while (peers.hasNext()) {
send(peers.next(), message);
}
}
/**
* Shutdown the transport.
*
* @throws InterruptedException if it's interrupted.
*/
public abstract void shutdown() throws InterruptedException;
/**
* Interface of receiver class. Transport will notify the receiver of
* arrived messages.
*/
public interface Receiver {
/**
* Callback that will be called by Transport class once the message
* is arrived. The message is guaranteed to be received in FIFO order,
* which means if message m1 is sent before m2 from sender s, then m1
* is guaranteed to be received first.
*
* @param source the id of the server who sent the message
* @param message the message
*/
void onReceived(String source, Message message);
/**
* Callback that notifies that the transport has been disconnected from the
* destination. Once this callback is invoked, the transport stops sending/
* receiving messages to/from the destination. You need to call the clear()
* method to tell the transport it's ok to reconnect.
*
* @param destination the ID of the peer from which the transport got
* disconnected
*/
void onDisconnected(String destination);
}
}