/**
* Copyright (c) 2011-2014, OpenIoT
*
* This file is part of OpenIoT.
*
* OpenIoT is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* OpenIoT is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenIoT. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: OpenIoT mailto: info@openiot.eu
*/
package org.openiot.cupus.entity.broker;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.UUID;
import org.openiot.cupus.entity.NetworkEntity;
import org.openiot.cupus.message.Message;
import org.openiot.cupus.message.external.SubscribeMessage;
import org.openiot.cupus.message.external.SubscriberDisconnectMessage;
import org.openiot.cupus.message.external.SubscriberUnregisterMessage;
/**
* This class is a representation of a subscriber connected with a broker on the
* broker it is connected with. It is used for communication with the subscriber
* and identification of the subscriber on the broker (via UUID).
*
* @author Eugen
*
*/
public class SubscriberForBroker extends NetworkEntity implements Runnable {
protected UUID subID;
protected MessageReceiver broker;
protected Socket socket;
ObjectInputStream inFromClient;
ObjectOutputStream outToClient;
private Message message;
private boolean isRunning = false;
/**
* Constructor
*
* @param myName Name of subscriber it represents
* @param subscriberOriginalID original UUID of connected subscriber
* @param myIP IP address of connected subscriber
* @param myPort Port number of connected subscriber
*/
public SubscriberForBroker(String myName, String myIP, int myPort,
UUID subscriberOriginalID, MessageReceiver myBroker) {
super(myName, myIP, myPort);
this.subID = subscriberOriginalID;
this.broker = myBroker;
}
@Override
public void run() {
if (isRunning || !broker.isRunning) {
return;
}
isRunning = true;
while (isRunning) {
Object objIn = null;
try {
objIn = inFromClient.readObject();
} catch (Exception e) {
terminateConnection();
broker.sendInternalMessage(
new SubscriberDisconnectMessage(myName, getId()));
return;
}
if (!(objIn instanceof Message)) {
//TODO send some sort of NACK
continue;
} else {
message = (Message) objIn;
}
if (message instanceof SubscriberDisconnectMessage) {
terminateConnection();
broker.sendInternalMessage(message);
//TODO send some sort of ACK
return;
} else if (message instanceof SubscriberUnregisterMessage) {
terminateConnection();
broker.removeSubscriber((SubscriberUnregisterMessage) message);
//TODO send some sort of ACK
return;
} else if (message instanceof SubscribeMessage) {
broker.subscribe(subID, (SubscribeMessage) message);
//TODO send some sort of ACK
}
}
terminateConnection(); //just in case
}
/**
* Used for terminating the connection to the subscriber
*/
public void terminateConnection() {
if (!isRunning && socket == null) {
return;
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
//ignoring...
}
socket = null;
this.isRunning = false;
}
/**
* Used for (re)connecting a previously registered subscriber...
*
* @param socket
*/
public boolean setSocketAndStreams(Socket socket,
ObjectInputStream in, ObjectOutputStream out) {
if (isRunning) {
return false;
}
this.socket = socket;
this.inFromClient = in;
this.outToClient = out;
return true;
}
public boolean isRunning() {
return isRunning;
}
public UUID getSubID() {
return subID;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((subID == null) ? 0 : subID.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof SubscriberForBroker)) {
return false;
}
SubscriberForBroker other = (SubscriberForBroker) obj;
if (subID == null) {
if (other.subID != null) {
return false;
}
} else if (!subID.equals(other.subID)) {
return false;
}
return true;
}
}