use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class Select method handledAllServersResponded.
// If all the servers have sent us a response we're done.
private static void handledAllServersResponded(InternalRequestHeader header, SelectResponsePacket packet, NSSelectInfo info, GNSApplicationInterface<String> replica) throws JSONException, ClientException, IOException, InternalRequestException {
// must be done before the notify below
// we're done processing this select query
QUERIES_IN_PROGRESS.remove(packet.getNsQueryId());
Set<JSONObject> allRecords = info.getResponsesAsSet();
// Todo - clean up this use of guids further below in the group code
Set<String> guids = extractGuidsFromRecords(allRecords);
LOGGER.log(Level.FINE, "NS{0} guids:{1}", new Object[] { replica.getNodeID(), guids });
SelectResponsePacket response;
// If projection is null we return guids (old-style).
if (info.getProjection() == null) {
response = SelectResponsePacket.makeSuccessPacketForGuidsOnly(packet.getId(), null, -1, null, new JSONArray(guids));
// Otherwise we return a list of records.
} else {
List<JSONObject> records = filterAndMassageRecords(allRecords);
LOGGER.log(Level.FINE, "NS{0} record:{1}", new Object[] { replica.getNodeID(), records });
response = SelectResponsePacket.makeSuccessPacketForFullRecords(packet.getId(), null, -1, -1, null, new JSONArray(records));
}
// Put the result where the coordinator can see it.
QUERY_RESULT.put(packet.getNsQueryId(), response);
// and let the coordinator know the value is there
if (GNSApp.DELEGATE_CLIENT_MESSAGING) {
synchronized (QUERIES_IN_PROGRESS) {
QUERIES_IN_PROGRESS.notify();
}
}
// Now we update any group guid stuff
if (info.getGroupBehavior().equals(SelectGroupBehavior.GROUP_SETUP)) {
LOGGER.log(Level.FINE, "NS{0} storing query string and other info", replica.getNodeID());
// for setup we need to squirrel away the query for later lookups
NSGroupAccess.updateQueryString(header, info.getGuid(), info.getQuery(), info.getProjection(), replica.getRequestHandler());
NSGroupAccess.updateMinRefresh(header, info.getGuid(), info.getMinRefreshInterval(), replica.getRequestHandler());
}
if (info.getGroupBehavior().equals(SelectGroupBehavior.GROUP_SETUP) || info.getGroupBehavior().equals(SelectGroupBehavior.GROUP_LOOKUP)) {
String guid = info.getGuid();
LOGGER.log(Level.FINE, "NS{0} updating group members", replica.getNodeID());
GroupAccess.addToGroup(header, guid, new ResultValue(guids), null, null, null, null, replica.getRequestHandler());
//NSGroupAccess.updateMembers(header, guid, guids, replica.getRequestHandler());
//NSGroupAccess.updateRecords(guid, processResponsesIntoJSONArray(info.getResponsesAsMap()), replica);
NSGroupAccess.updateLastUpdate(header, guid, new Date(), replica.getRequestHandler());
}
}
use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class Select method handleSelectRequestFromClient.
/**
* Handle a select request from a client.
* This node is the broadcaster and selector.
*
* @param header
* @param packet
* @param app
* @return a select response packet
* @throws JSONException
* @throws UnknownHostException
* @throws FailedDBOperationException
* @throws InternalRequestException
*/
@SuppressWarnings("unchecked")
public static SelectResponsePacket handleSelectRequestFromClient(InternalRequestHeader header, SelectRequestPacket packet, GNSApplicationInterface<String> app) throws JSONException, UnknownHostException, FailedDBOperationException, InternalRequestException {
// If sufficient time hasn't passed we just send the current value back
if (packet.getGroupBehavior().equals(SelectGroupBehavior.GROUP_LOOKUP)) {
// grab the timing parameters that we squirreled away from the SETUP
Date lastUpdate = NSGroupAccess.getLastUpdate(header, packet.getGuid(), app.getRequestHandler());
int minRefreshInterval = NSGroupAccess.getMinRefresh(header, packet.getGuid(), app.getRequestHandler());
if (lastUpdate != null) {
LOGGER.log(Level.FINE, "GROUP_LOOKUP Request: {0} - {1} <= {2}", new Object[] { new Date().getTime(), lastUpdate.getTime(), minRefreshInterval });
// if not enough time has passed we just return the current value of the group
if (new Date().getTime() - lastUpdate.getTime() <= minRefreshInterval) {
LOGGER.log(Level.FINE, "GROUP_LOOKUP Request: Time has not elapsed. Returning current group value for {0}", packet.getGuid());
ResultValue result = NSGroupAccess.lookupMembers(header, packet.getGuid(), true, app.getRequestHandler());
return SelectResponsePacket.makeSuccessPacketForGuidsOnly(packet.getId(), null, -1, null, new JSONArray(result.toStringSet()));
}
} else {
LOGGER.fine("GROUP_LOOKUP Request: No Last Update Info ");
}
}
// the code below executes for regular selects and also for GROUP SETUP and GROUP LOOKUP but for lookup
// only if enough time has elapsed since last lookup (see above)
// OR in the anamolous situation where the update info could not be found
LOGGER.fine(packet.getSelectOperation().toString() + " Request: Forwarding request for " + packet.getGuid() != null ? packet.getGuid() : "non-guid select");
// If it's not a group lookup or is but enough time has passed we do the usual thing
// and send the request out to all the servers. We'll receive a response sent on the flipside.
Set<InetSocketAddress> serverAddresses = new HashSet<>(PaxosConfig.getActives().values());
//Set<String> serverIds = app.getGNSNodeConfig().getActiveReplicas();
// store the info for later
int queryId = addQueryInfo(serverAddresses, packet.getSelectOperation(), packet.getGroupBehavior(), packet.getQuery(), packet.getProjection(), packet.getMinRefreshInterval(), packet.getGuid());
if (packet.getGroupBehavior().equals(SelectGroupBehavior.GROUP_LOOKUP)) {
// the query string is supplied with a lookup so we stuff in it there. It was saved from the SETUP operation.
packet.setQuery(NSGroupAccess.getQueryString(header, packet.getGuid(), app.getRequestHandler()));
packet.setProjection(NSGroupAccess.getProjection(header, packet.getGuid(), app.getRequestHandler()));
}
InetSocketAddress returnAddress = new InetSocketAddress(app.getNodeAddress().getAddress(), ReconfigurationConfig.getClientFacingPort(app.getNodeAddress().getPort()));
packet.setNSReturnAddress(returnAddress);
//packet.setNameServerID(app.getNodeID());
// Note: this also tells handleSelectRequest that it should go to NS now
packet.setNsQueryId(queryId);
JSONObject outgoingJSON = packet.toJSONObject();
try {
LOGGER.log(Level.FINER, "addresses: {0} node address: {1}", new Object[] { serverAddresses, app.getNodeAddress() });
// Forward to all but self because...
for (InetSocketAddress address : serverAddresses) {
if (!address.equals(app.getNodeAddress())) {
InetSocketAddress offsetAddress = new InetSocketAddress(address.getAddress(), ReconfigurationConfig.getClientFacingPort(address.getPort()));
LOGGER.log(Level.INFO, "NS {0} sending select {1} to {2} ({3})", new Object[] { app.getNodeID(), outgoingJSON, offsetAddress, address });
app.sendToAddress(offsetAddress, outgoingJSON);
}
}
// we handle our self by locally getting self-select records
handleSelectResponse(getMySelectedRecords(packet, app), app);
// Wait for responses, otherwise you are violating Replicable.execute(.)'s semantics.
synchronized (QUERIES_IN_PROGRESS) {
while (QUERIES_IN_PROGRESS.containsKey(queryId)) {
try {
QUERIES_IN_PROGRESS.wait(SELECT_REQUEST_TIMEOUT);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (QUERY_RESULT.containsKey(queryId)) {
return QUERY_RESULT.remove(queryId);
}
} catch (IOException | ClientException e) {
LOGGER.log(Level.SEVERE, "Exception while sending select request: {0}", e);
}
return null;
}
use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class RemoveMembersFromGroup method execute.
@Override
public CommandResponse execute(InternalRequestHeader header, CommandPacket commandPacket, ClientRequestHandlerInterface handler) throws InvalidKeyException, InvalidKeySpecException, JSONException, NoSuchAlgorithmException, SignatureException, ParseException {
JSONObject json = commandPacket.getCommand();
String guid = json.getString(GNSProtocol.GUID.toString());
String members = json.getString(GNSProtocol.MEMBERS.toString());
// writer might be same as guid
String writer = json.optString(GNSProtocol.WRITER.toString(), guid);
// signature and message can be empty for unsigned cases
String signature = json.optString(GNSProtocol.SIGNATURE.toString(), null);
String message = json.optString(GNSProtocol.SIGNATUREFULLMESSAGE.toString(), null);
Date timestamp = json.has(GNSProtocol.TIMESTAMP.toString()) ? Format.parseDateISO8601UTC(json.getString(GNSProtocol.TIMESTAMP.toString())) : // can be null on older client
null;
ResponseCode responseCode;
try {
if (!(responseCode = GroupAccess.removeFromGroup(header, commandPacket, guid, new ResultValue(members), writer, signature, message, timestamp, handler)).isExceptionOrError()) {
return new CommandResponse(ResponseCode.NO_ERROR, GNSProtocol.OK_RESPONSE.toString());
} else {
return new CommandResponse(responseCode, GNSProtocol.BAD_RESPONSE.toString() + " " + responseCode.getProtocolCode());
}
} catch (ClientException | IOException | InternalRequestException e) {
return new CommandResponse(ResponseCode.UNSPECIFIED_ERROR, GNSProtocol.BAD_RESPONSE.toString() + " " + GNSProtocol.UNSPECIFIED_ERROR.toString() + " " + e.getMessage());
}
}
use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class NSFieldAccess method lookupListFieldAnywhere.
/**
* Looks up the value of an old-style list field in the guid.
* If allowQueryToOtherNSs is true and guid doesn't exists on this Name Server,
* sends a read query from this Name Server to a Local Name Server.
* Returns the value of a field in a GNSProtocol.GUID.toString() as a ResultValue.
*
* @param guid
* @param field
* @param allowRemoteLookup
* @param handler
* @return ResultValue containing the value of the field or an empty ResultValue if field cannot be found
* @throws edu.umass.cs.gnscommon.exceptions.server.FailedDBOperationException
*/
public static ResultValue lookupListFieldAnywhere(InternalRequestHeader header, String guid, String field, boolean allowRemoteLookup, ClientRequestHandlerInterface handler) throws FailedDBOperationException {
ResultValue result = lookupListFieldLocallySafe(guid, field, handler.getApp().getDB());
// and we're allowed then send a query to another server
if (result.isEmpty() && !handler.getApp().getDB().containsName(guid) && allowRemoteLookup) {
try {
String stringResult = handler.getInternalClient().execute(GNSCommandInternal.fieldRead(guid, field, header)).getResultString();
result = new ResultValue(stringResult);
} catch (Exception e) {
ClientSupportConfig.getLogger().log(Level.SEVERE, "Problem getting record from remote server: {0}", e);
}
if (!result.isEmpty()) {
ClientSupportConfig.getLogger().log(Level.FINE, "@@@@@@ Field {0} in {1}" + " not found on this server but was found thru remote query. " + "Returning {2}", new Object[] { field, guid, result.toString() });
}
}
return result;
}
use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class AddMembersToGroup method execute.
@Override
public CommandResponse execute(InternalRequestHeader header, CommandPacket commandPacket, ClientRequestHandlerInterface handler) throws InvalidKeyException, InvalidKeySpecException, JSONException, NoSuchAlgorithmException, SignatureException, ParseException {
JSONObject json = commandPacket.getCommand();
String guid = json.getString(GNSProtocol.GUID.toString());
String members = json.getString(GNSProtocol.MEMBERS.toString());
// writer might be same as guid
String writer = json.optString(GNSProtocol.WRITER.toString(), guid);
// signature and message can be empty for unsigned cases
String signature = json.optString(GNSProtocol.SIGNATURE.toString(), null);
String message = json.optString(GNSProtocol.SIGNATUREFULLMESSAGE.toString(), null);
Date timestamp = json.has(GNSProtocol.TIMESTAMP.toString()) ? Format.parseDateISO8601UTC(json.getString(GNSProtocol.TIMESTAMP.toString())) : // can be null on older client
null;
ResponseCode responseCode;
try {
if (!(responseCode = GroupAccess.addToGroup(header, guid, new ResultValue(members), writer, signature, message, timestamp, handler)).isExceptionOrError()) {
return new CommandResponse(ResponseCode.NO_ERROR, GNSProtocol.OK_RESPONSE.toString());
} else {
return new CommandResponse(responseCode, GNSProtocol.BAD_RESPONSE.toString() + " " + responseCode.getProtocolCode());
}
} catch (ClientException | IOException | InternalRequestException e) {
return new CommandResponse(ResponseCode.UNSPECIFIED_ERROR, GNSProtocol.BAD_RESPONSE.toString() + " " + GNSProtocol.UNSPECIFIED_ERROR.toString() + " " + e.getMessage());
}
}
Aggregations