Search in sources :

Example 1 with ValuesMap

use of edu.umass.cs.gnsserver.utils.ValuesMap in project GNS by MobilityFirst.

the class ActiveCodeHandler method main.

/**
   * *************************** TEST CODE ********************
   */
/**
   * @param args
   * @throws InterruptedException
   * @throws ExecutionException
   * @throws IOException
   * @throws JSONException
   * @throws InternalRequestException
   */
public static void main(String[] args) throws InterruptedException, ExecutionException, IOException, JSONException, InternalRequestException {
    new ActiveCodeHandler("Test");
    // initialize the parameters used in the test 
    JSONObject obj = new JSONObject();
    obj.put("testGuid", "success");
    ValuesMap valuesMap = new ValuesMap(obj);
    final String guid1 = "guid";
    final String field1 = "testGuid";
    final String read_action = "read";
    String noop_code = new String(Files.readAllBytes(Paths.get("./scripts/activeCode/noop.js")));
    String noop_code64 = Base64.encodeToString(noop_code.getBytes("utf-8"), true);
    ActiveCodeHandler.runCode(null, noop_code64, guid1, field1, read_action, valuesMap, 100);
    int n = 1000000;
    long t = System.currentTimeMillis();
    for (int i = 0; i < n; i++) {
        ActiveCodeHandler.runCode(null, noop_code64, guid1, field1, read_action, valuesMap, 100);
    }
    long elapsed = System.currentTimeMillis() - t;
    System.out.println(String.format("it takes %d ms, avg_latency = %f us", elapsed, elapsed * 1000.0 / n));
}
Also used : JSONObject(org.json.JSONObject) ValuesMap(edu.umass.cs.gnsserver.utils.ValuesMap)

Example 2 with ValuesMap

use of edu.umass.cs.gnsserver.utils.ValuesMap in project GNS by MobilityFirst.

the class ActiveCodeHandler method handleActiveCode.

/**
   * This interface is used for the class out of activecode package to trigger active code.
   * It requires the parameters for running active code such as guid, field, and value.
   * It runs the requests and returns the processed result to the caller.
   *
   *
   * @param header header is needed for depth query
   * @param guid
   * @param field
   * @param action the actions in {@code ActiveCode}
   * @param value
   * @param db db is needed for fetching active code to run
   * @return the processed result as an JSONObject, the original value is returned if there is an error with code execution
   * @throws InternalRequestException
   */
public static JSONObject handleActiveCode(InternalRequestHeader header, String guid, String field, String action, JSONObject value, BasicRecordMap db) throws InternalRequestException {
    if (Config.getGlobalBoolean(GNSConfig.GNSC.DISABLE_ACTIVE_CODE)) {
        return value;
    }
    if (header != null) {
        // this is a depth query, and we do not call the code again, as it will form a infinite loop if not.
        if (guid.equals(header.getOriginatingGUID()) && header.getTTL() < InternalRequestHeader.DEFAULT_TTL) {
            return value;
        }
    } else {
        // without a header, the code can misbehave without any regulation, therefore we return the value immediately if no header presents
        return value;
    }
    long t = System.nanoTime();
    ActiveCodeHandler.getLogger().log(DEBUG_LEVEL, "OOOOOOOOOOOOO handles:[guid:{0},field:{1},action:{2},value:{3},header:{4}]", new Object[] { guid, field, action, value, header });
    /**
     * Only execute active code for user field
     * FIXME:
     * <p>
     * Read can be a single-field read or multi-field read.
     * If it's a single-field read, then the field can not be a internal field.
     * If it's a multi-field read, then there may be some field is internal.
     * <p>
     * Write has no field value, but if there should not be an internal
     * field in the JSONObject value.
     */
    if ((action.equals(ActiveCode.READ_ACTION) && field != null && InternalField.isInternalField(field)) || (action.equals(ActiveCode.WRITE_ACTION) && ((value != null && containInternalField(value)) || (field != null && InternalField.isInternalField(field))))) {
        ActiveCodeHandler.getLogger().log(DEBUG_LEVEL, "OOOOOOOOOOOOO no need to handle:[guid:{0},field:{1},action:{2},value:{3},header:{4}]", new Object[] { guid, field, action, value, header });
        return value;
    }
    JSONObject newResult = value;
    if (field == null || !InternalField.isInternalField(field)) {
        //FIXME: Seems like this field lookup all could be replaced by something 
        // like NSFieldAccess.lookupJSONFieldLocalNoAuth
        NameRecord activeCodeNameRecord = null;
        try {
            activeCodeNameRecord = NameRecord.getNameRecordMultiUserFields(db, guid, ColumnFieldType.USER_JSON, ActiveCode.getCodeField(action));
        } catch (RecordNotFoundException | FailedDBOperationException | IllegalArgumentException e) {
            e.printStackTrace();
            return value;
        }
        ValuesMap codeMap = null;
        try {
            codeMap = activeCodeNameRecord.getValuesMap();
        } catch (FieldNotFoundException e) {
            e.printStackTrace();
            return value;
        }
        if (codeMap != null && value != null) {
            String code;
            try {
                code = codeMap.getString(ActiveCode.getCodeField(action));
            } catch (JSONException | IllegalArgumentException e) {
                return value;
            }
            // Prepare values for query
            String accessorGuid = header == null ? guid : header.getOriginatingGUID();
            if (header.getSourceAddress() != null) {
                try {
                    value.put(SOURCE_IP_FIELD, header.getSourceAddress());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            // Run code
            newResult = runCode(header, code, guid, accessorGuid, action, value, header.getTTL());
            // Strip the appended fields
            if (newResult.has(SOURCE_IP_FIELD)) {
                newResult.remove(SOURCE_IP_FIELD);
            }
        } else if (codeMap == null) {
            ActiveCodeHandler.getLogger().log(DEBUG_LEVEL, "OOOOOOOOOOOOO no code to run:[guid:{0},field:{1},action:{2},value:{3},header:{4}]", new Object[] { guid, field, action, value, header });
        }
    }
    ActiveCodeHandler.getLogger().log(DEBUG_LEVEL, "OOOOOOOOOOOOO The result after executing active code is {0}", new Object[] { newResult });
    DelayProfiler.updateDelayNano("activeTotal", t);
    return newResult;
}
Also used : ValuesMap(edu.umass.cs.gnsserver.utils.ValuesMap) FieldNotFoundException(edu.umass.cs.gnscommon.exceptions.server.FieldNotFoundException) JSONException(org.json.JSONException) FailedDBOperationException(edu.umass.cs.gnscommon.exceptions.server.FailedDBOperationException) RecordNotFoundException(edu.umass.cs.gnscommon.exceptions.server.RecordNotFoundException) NameRecord(edu.umass.cs.gnsserver.gnsapp.recordmap.NameRecord) JSONObject(org.json.JSONObject) JSONObject(org.json.JSONObject)

Example 3 with ValuesMap

use of edu.umass.cs.gnsserver.utils.ValuesMap in project GNS by MobilityFirst.

the class NameRecord method updateNameRecord.

/**
   * Updates the value of the field associated with the key.
   *
   * @param recordKey
   * @param newValues
   * @param oldValues
   * @param argument
   * @param operation
   * @param userJSON
   * @return True if the updateEntireValuesMap does anything, false otherwise.
   * @throws edu.umass.cs.gnscommon.exceptions.server.FieldNotFoundException
   * @throws edu.umass.cs.gnscommon.exceptions.server.FailedDBOperationException
   */
public boolean updateNameRecord(String recordKey, ResultValue newValues, ResultValue oldValues, int argument, ValuesMap userJSON, UpdateOperation operation) throws FieldNotFoundException, FailedDBOperationException {
    // whose purpose is to remove the field with name = key from values map.
    if (operation.equals(UpdateOperation.SINGLE_FIELD_REMOVE_FIELD)) {
        ArrayList<ColumnField> keys = new ArrayList<>();
        keys.add(new ColumnField(recordKey, ColumnFieldType.LIST_STRING));
        GNSConfig.getLogger().log(Level.FINE, "<============>REMOVE {0} from {1}<============>", new Object[] { recordKey, getName() });
        recordMap.removeMapKeys(getName(), VALUES_MAP, keys);
        return true;
    }
    /*
     * Some updateEntireValuesMap operations require that record is first read from DB, modified, and then written.
     * That is 1 DB read + 1 DB write. Others do not require record to be read, but we can directly do a write.
     * This saves us a database read.
     *
     * To implement this, we changed both ClientRequestWorker.updateAdddressNS and NameRecord.updateNameRecord.
     * There could be other operations like SINGLE_FIELD_REPLACE_ALL which could proceed without DB read,
     * and should be handled similar to SINGLE_FIELD_REPLACE_ALL. In my experiments, I was using SINGLE_FIELD_REPLACE_ALL so I have
     * included it as a special case for it.
     */
    ValuesMap valuesMap;
    if (operation.isAbleToSkipRead()) {
        valuesMap = new ValuesMap();
        hashMap.put(VALUES_MAP, valuesMap);
    } else {
        // this will throw an exception if field is not read.
        valuesMap = getValuesMap();
    }
    // FIXME: might want to handle this without a special case at some point
    boolean updated = UpdateOperation.USER_JSON_REPLACE.equals(operation) || UpdateOperation.USER_JSON_REPLACE_OR_CREATE.equals(operation) ? true : UpdateOperation.updateValuesMap(valuesMap, recordKey, newValues, oldValues, argument, userJSON, operation);
    if (updated) {
        // commit updateEntireValuesMap to database
        ArrayList<ColumnField> updatedFields = new ArrayList<>();
        ArrayList<Object> updatedValues = new ArrayList<>();
        if (userJSON != null) {
            // full userJSON (new style) updateEntireValuesMap
            Iterator<?> keyIter = userJSON.keys();
            while (keyIter.hasNext()) {
                String key = (String) keyIter.next();
                try {
                    updatedFields.add(new ColumnField(key, ColumnFieldType.USER_JSON));
                    updatedValues.add(userJSON.get(key));
                } catch (JSONException e) {
                    GNSConfig.getLogger().log(Level.SEVERE, "Unable to get {0} from userJSON:{1}", new Object[] { key, e });
                }
            }
        } else {
            // single field updateEntireValuesMap
            updatedFields.add(new ColumnField(recordKey, ColumnFieldType.LIST_STRING));
            updatedValues.add(valuesMap.getAsArray(recordKey));
        }
        recordMap.updateIndividualFields(getName(), updatedFields, updatedValues);
    }
    return updated;
}
Also used : ValuesMap(edu.umass.cs.gnsserver.utils.ValuesMap) ColumnField(edu.umass.cs.gnsserver.database.ColumnField) ArrayList(java.util.ArrayList) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject)

Example 4 with ValuesMap

use of edu.umass.cs.gnsserver.utils.ValuesMap in project GNS by MobilityFirst.

the class NSUpdateSupport method updateNameRecord.

private static void updateNameRecord(InternalRequestHeader header, NameRecord nameRecord, String guid, String field, UpdateOperation operation, ResultValue updateValue, ResultValue oldValue, int argument, ValuesMap userJSON, BasicRecordMap db, ActiveCodeHandler activeCodeHandler) throws FailedDBOperationException, FieldNotFoundException, InternalRequestException {
    ValuesMap newValue = userJSON;
    if (activeCodeHandler != null) {
        JSONObject result = ActiveCodeHandler.handleActiveCode(header, guid, field, ActiveCode.WRITE_ACTION, userJSON, db);
        newValue = result != null ? new ValuesMap(result) : null;
    }
    // END ACTIVE CODE HANDLING
    if (field != null) {
        ClientSupportConfig.getLogger().log(Level.FINE, "field={0}, operation={1}, value={2}, name_record={3}", new Object[] { field, operation, updateValue, nameRecord.getSummary() });
    }
    // Apply updateEntireValuesMap to record in the database
    nameRecord.updateNameRecord(field, updateValue, oldValue, argument, newValue, operation);
    // This is for MOB-893 - logging updates
    writeUpdateLog(guid, field, updateValue, newValue, operation);
}
Also used : JSONObject(org.json.JSONObject) ValuesMap(edu.umass.cs.gnsserver.utils.ValuesMap)

Example 5 with ValuesMap

use of edu.umass.cs.gnsserver.utils.ValuesMap in project GNS by MobilityFirst.

the class NSFieldAccess method lookupFieldsLocalNoAuth.

/**
   *
   * @param header
   * @param guid
   * @param fields
   * @param returnFormat
   * @param handler
   * @return a values map
   * @throws FailedDBOperationException
   */
public static ValuesMap lookupFieldsLocalNoAuth(InternalRequestHeader header, String guid, List<String> fields, ColumnFieldType returnFormat, ClientRequestHandlerInterface handler) throws FailedDBOperationException {
    // Try to look up the value in the database
    try {
        ClientSupportConfig.getLogger().log(Level.FINE, "Fields={0} Format={1}", new Object[] { fields, returnFormat });
        String[] fieldArray = new String[fields.size()];
        fieldArray = fields.toArray(fieldArray);
        // Grab the fields the user wanted
        NameRecord nameRecord = NameRecord.getNameRecordMultiUserFields(handler.getApp().getDB(), guid, returnFormat, fieldArray);
        if (nameRecord != null) {
            // active code handling
            ValuesMap valuesMap = nameRecord.getValuesMap();
            //if (!Config.getGlobalBoolean(GNSConfig.GNSC.DISABLE_ACTIVE_CODE)) {
            try {
                JSONObject result = ActiveCodeHandler.handleActiveCode(header, guid, null, ActiveCode.READ_ACTION, valuesMap, handler.getApp().getDB());
                valuesMap = result != null ? new ValuesMap(result) : valuesMap;
            } catch (InternalRequestException e) {
                e.printStackTrace();
            }
            //}
            return valuesMap;
        }
    } catch (RecordNotFoundException e) {
        ClientSupportConfig.getLogger().log(Level.FINE, "Record not found for name: {0}", guid);
    } catch (FieldNotFoundException e) {
        ClientSupportConfig.getLogger().log(Level.FINE, "Field not found for {0} : {1}", new Object[] { guid, e });
    }
    return null;
}
Also used : RecordNotFoundException(edu.umass.cs.gnscommon.exceptions.server.RecordNotFoundException) NameRecord(edu.umass.cs.gnsserver.gnsapp.recordmap.NameRecord) JSONObject(org.json.JSONObject) InternalRequestException(edu.umass.cs.gnscommon.exceptions.server.InternalRequestException) ValuesMap(edu.umass.cs.gnsserver.utils.ValuesMap) FieldNotFoundException(edu.umass.cs.gnscommon.exceptions.server.FieldNotFoundException) JSONObject(org.json.JSONObject)

Aggregations

ValuesMap (edu.umass.cs.gnsserver.utils.ValuesMap)35 JSONException (org.json.JSONException)25 JSONObject (org.json.JSONObject)24 FailedDBOperationException (edu.umass.cs.gnscommon.exceptions.server.FailedDBOperationException)20 RecordNotFoundException (edu.umass.cs.gnscommon.exceptions.server.RecordNotFoundException)9 IOException (java.io.IOException)8 Test (org.junit.Test)8 InternalRequestException (edu.umass.cs.gnscommon.exceptions.server.InternalRequestException)7 NameRecord (edu.umass.cs.gnsserver.gnsapp.recordmap.NameRecord)6 ResponseCode (edu.umass.cs.gnscommon.ResponseCode)5 ClientException (edu.umass.cs.gnscommon.exceptions.client.ClientException)5 RandomString (edu.umass.cs.gnscommon.utils.RandomString)4 ArrayList (java.util.ArrayList)4 FieldNotFoundException (edu.umass.cs.gnscommon.exceptions.server.FieldNotFoundException)3 RecordExistsException (edu.umass.cs.gnscommon.exceptions.server.RecordExistsException)3 HashMap (java.util.HashMap)3 JSONArray (org.json.JSONArray)3 ParseException (java.text.ParseException)2 Future (java.util.concurrent.Future)2 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)2