Pool.java
package emissary.server.api;
import emissary.client.EmissaryClient;
import emissary.client.response.MapResponseEntity;
import emissary.core.EmissaryException;
import emissary.core.Namespace;
import emissary.core.NamespaceException;
import emissary.directory.EmissaryNode;
import emissary.pool.AgentPool;
import emissary.pool.MobileAgentFactory;
import emissary.server.EmissaryServer;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static emissary.server.api.ApiUtils.lookupPeers;
import static emissary.server.api.ApiUtils.stripPeerString;
/**
* The agents Emissary API endpoint. Currently contains the local (/api/pool) call and cluster (/api/clusterPool) calls.
*/
@Path("")
// context is /api and is set in EmissaryServer.java
public class Pool {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String POOL_ENDPOINT = "api/pool";
public static final String POOL_CLUSTER_ENDPOINT = "api/cluster/pool";
@GET
@Path("/pool")
@Produces(MediaType.APPLICATION_JSON)
public Response pool() {
return Response.ok().entity(this.lookupPool()).build();
}
@GET
@Path("/cluster/pool")
@Produces(MediaType.APPLICATION_JSON)
public Response clusterPool() {
MapResponseEntity entity = new MapResponseEntity();
try {
// Get our local mobile agents
entity.append(this.lookupPool());
// Get all of our peers agents
EmissaryClient client = new EmissaryClient();
for (String peer : lookupPeers()) {
String remoteEndPoint = stripPeerString(peer) + "api/pool";
MapResponseEntity remoteEntity = client.send(new HttpGet(remoteEndPoint)).getContent(MapResponseEntity.class);
entity.append(remoteEntity);
}
return Response.ok().entity(entity).build();
} catch (EmissaryException e) {
// This should never happen since we already saw if it exists
return Response.serverError().entity(e.getMessage()).build();
}
}
private MapResponseEntity lookupPool() {
MapResponseEntity entity = new MapResponseEntity();
// Get the server so we can be ready to talk to ourself then the peers
try {
EmissaryServer emissaryServer = (EmissaryServer) Namespace.lookup("EmissaryServer");
EmissaryNode localNode = emissaryServer.getNode();
String nodeName = localNode.getNodeName() + ":" + localNode.getNodePort();
int active = 0;
int idle = 0;
try {
for (int i = 0; i < AgentPool.lookup().getMaxTotal(); i++) {
String agentKey = MobileAgentFactory.AGENT_NAME + "-" + String.format("%02d", i);
if (Namespace.exists(agentKey)) {
if (Namespace.lookup(agentKey).toString().startsWith("Idle")) {
idle++;
} else {
active++;
}
} else {
// TODO Handle this any better?
logger.error("Missing an agent in the Namespace: {}", agentKey);
entity.addError("Missing an agent in the Namespace: " + agentKey);
idle++;
}
}
entity.addKeyValue(nodeName, "Poolsize active/idle: " + active + "/" + idle);
} catch (EmissaryException e) {
// TODO Figure out what we really want to do here in the event a node crashes
logger.error("Problem when looking up the pool", e);
entity.addError("Problem when looking up the pool on " + localNode + ": " + e.getMessage());
}
} catch (NamespaceException e) {
// should never happen
logger.error("Problem finding the emissary server in the namespace, something is majorly wrong", e);
entity.addError("Problem finding the emissary server in the namespace: " + e.getMessage());
}
return entity;
}
}