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 NSFieldAccess method lookupListFieldLocallyNoAuth.
/**
* Looks up the value of an old-style list field
* in the guid in the local replica.
* Returns the value of a field in a GNSProtocol.GUID.toString() as a ResultValue or
* an empty ResultValue if field cannot be found.
*
* @param guid
* @param field
* @param database
* @return ResultValue
* @throws edu.umass.cs.gnscommon.exceptions.server.FailedDBOperationException
* @throws edu.umass.cs.gnscommon.exceptions.server.FieldNotFoundException
* @throws edu.umass.cs.gnscommon.exceptions.server.RecordNotFoundException
*/
public static ResultValue lookupListFieldLocallyNoAuth(String guid, String field, BasicRecordMap database) throws FailedDBOperationException, FieldNotFoundException, RecordNotFoundException {
NameRecord nameRecord = NameRecord.getNameRecordMultiUserFields(database, guid, ColumnFieldType.LIST_STRING, field);
ClientSupportConfig.getLogger().log(Level.FINE, "LOOKUPFIELDONTHISSERVER: {0} : {1} -> {2}", new Object[] { guid, field, nameRecord });
ResultValue result = nameRecord.getUserKeyAsArray(field);
if (result != null) {
return result;
} else {
return new ResultValue();
}
}
use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class CreateList 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 field = json.getString(GNSProtocol.FIELD.toString());
String value = json.getString(GNSProtocol.VALUE.toString());
// the opt hair below is for the subclasses... cute, huh?
// writer might be same as guid
String writer = json.optString(GNSProtocol.WRITER.toString(), guid);
String signature = json.getString(GNSProtocol.SIGNATURE.toString());
String message = json.getString(GNSProtocol.SIGNATUREFULLMESSAGE.toString());
Date timestamp;
if (json.has(GNSProtocol.TIMESTAMP.toString())) {
// can be null on older client
timestamp = json.has(GNSProtocol.TIMESTAMP.toString()) ? Format.parseDateISO8601UTC(json.getString(GNSProtocol.TIMESTAMP.toString())) : null;
} else {
timestamp = null;
}
ResponseCode responseCode;
if (!(responseCode = FieldAccess.createField(header, commandPacket, guid, field, new ResultValue(value), 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());
}
}
use of edu.umass.cs.gnsserver.utils.ResultValue in project GNS by MobilityFirst.
the class FieldMetaData method lookup.
/**
* Grabs the metadata indexed by type from the field from the guid.
*
* @param header
* @param commandPacket
* @param type
* @param guid
* @param key
* @param reader
* @param signature
* @param message
* @param timestamp
* @param handler
* @return a set of strings
*/
public static Set<String> lookup(InternalRequestHeader header, CommandPacket commandPacket, MetaDataTypeName type, String guid, String key, String reader, String signature, String message, Date timestamp, ClientRequestHandlerInterface handler) {
String field = makeFieldMetaDataKey(type, key);
ResponseCode errorCode = FieldAccess.signatureAndACLCheckForRead(header, commandPacket, guid, field, //fields
null, reader, signature, message, timestamp, handler.getApp());
if (errorCode.isExceptionOrError()) {
return new HashSet<>();
}
ResultValue result = NSFieldAccess.lookupListFieldLocallySafe(guid, field, handler.getApp().getDB());
return new HashSet<>(result.toStringSet());
}
Aggregations