package com.workshare.msnos.core.payloads;
import java.util.HashSet;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.workshare.msnos.core.Agent;
import com.workshare.msnos.core.Cloud;
import com.workshare.msnos.core.Iden;
import com.workshare.msnos.core.LocalAgent;
import com.workshare.msnos.core.Message;
import com.workshare.msnos.core.Message.Payload;
import com.workshare.msnos.core.MsnosException;
import com.workshare.msnos.core.RemoteAgent;
import com.workshare.msnos.core.protocols.ip.Endpoint;
import com.workshare.msnos.core.protocols.ip.HttpEndpoint;
import com.workshare.msnos.soup.json.Json;
public class Presence implements Message.Payload {
private static Logger log = LoggerFactory.getLogger(Presence.class);
private final boolean present;
private final Set<Endpoint> endpoints;
public Presence(boolean present, Set<Endpoint> endpoints) {
this.present = present;
this.endpoints = endpoints;
log.trace(present ? "Presence message created: {}" : "Absence message created: {}", this);
}
public Presence(boolean present, Agent agent) throws MsnosException {
this(present, present ? agent.getEndpoints() : new HashSet<Endpoint>());
}
public boolean isPresent() {
return present;
}
public Set<Endpoint> getEndpoints() {
return endpoints;
}
@Override
public String toString() {
return Json.toJsonString(this);
}
@Override
public Message.Payload[] split() {
Set<Endpoint> netOne = new HashSet<Endpoint>();
Set<Endpoint> netTwo = new HashSet<Endpoint>();
int i = 0;
for (Endpoint ep : endpoints) {
if (i++ % 2 == 0)
netOne.add(ep);
else
netTwo.add(ep);
}
return new Payload[]{
new Presence(present, netOne),
new Presence(present, netTwo)
};
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + endpoints.hashCode();
result = prime * result + (present ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj) {
try {
Presence other = (Presence) obj;
return endpoints.equals(other.endpoints) && present == other.present;
} catch (Exception any) {
return false;
}
}
@Override
public boolean process(Message message, Cloud.Internal internal) {
Iden from = message.getFrom();
if (isPresent()) {
RemoteAgent agent = new RemoteAgent(from.getUUID(), internal.cloud(), extractEndpoints(from));
log.debug("Discovered new agent from network: {}", agent.toString());
internal.remoteAgents().add(agent);
} else {
log.debug("Agent from network leaving: {}", from);
internal.remoteAgents().remove(from);
}
return true;
}
// FIXME this method is NOT tested - patch - need to be refactored and tested please
private Set<Endpoint> extractEndpoints(Iden from) {
final Set<Endpoint> all = getEndpoints();
final Set<Endpoint> res = new HashSet<Endpoint>();
for (Endpoint endpoint : all) {
if (endpoint instanceof HttpEndpoint) {
HttpEndpoint http = (HttpEndpoint)endpoint;
endpoint = http.withTarget(from);
}
res.add(endpoint);
}
return res;
}
public static Presence on(LocalAgent agent) {
return new Presence(true, agent.getEndpoints());
}
}