Skip to content

Commit

Permalink
Merge pull request #116 from MobilityFirst/sanity_check_config
Browse files Browse the repository at this point in the history
Configurable sanity check before request update
  • Loading branch information
v-arun authored Jun 18, 2017
2 parents ca9b891 + a568501 commit b176a7c
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 12 deletions.
4 changes: 2 additions & 2 deletions build.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Sat, 18 Feb 2017 17:11:23 -0500
#Sun, 28 May 2017 23:06:01 +0530
build.major.number=1
build.minor.number=19
build.revision.number=13
build.revision.number=15
7 changes: 6 additions & 1 deletion src/edu/umass/cs/gnscommon/GNSProtocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,12 @@ public enum GNSProtocol {
/**
* Whether an internal request was previously coordinated (at most once).
*/
COORD1("COORD1"),;
COORD1("COORD1"),
/**
* Indicates that sanity check failed
* See {@link edu.umass.cs.gnscommon.ResponseCode#SANITY_CHECK_ERROR}.
*/
SANITY_CHECK_ERROR("+SANITY_CHECK_ERROR+"),;

final String label;

Expand Down
6 changes: 5 additions & 1 deletion src/edu/umass/cs/gnscommon/ResponseCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,11 @@ public enum ResponseCode implements Serializable {
* IO exception incurred either by the client or by an induced remote query.
*/
IO_EXCEPTION(412, IOException.class.getSimpleName(),
ResponseCodeType.EXCEPTION)
ResponseCodeType.EXCEPTION),
/*
* Sanity check on a record failed.
*/
SANITY_CHECK_ERROR(413, GNSProtocol.SANITY_CHECK_ERROR.toString(), ResponseCodeType.ERROR)

;

Expand Down
24 changes: 17 additions & 7 deletions src/edu/umass/cs/gnsserver/database/DiskMapRecords.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import com.mongodb.BulkWriteException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
Expand Down Expand Up @@ -361,45 +362,54 @@ record = lookupEntireRecord(collection, name);

@Override
public AbstractRecordCursor getAllRowsIterator(String collection) throws FailedDBOperationException {
getMap(collection).commit();
commit(collection);
return getMongoRecords(collection).getAllRowsIterator(MongoRecords.DBNAMERECORD);
}

@Override
public AbstractRecordCursor selectRecords(String collection, ColumnField valuesMapField, String key, Object value) throws FailedDBOperationException {
getMap(collection).commit();
commit(collection);
return getMongoRecords(collection).selectRecords(MongoRecords.DBNAMERECORD, valuesMapField, key, value);
}

@Override
public AbstractRecordCursor selectRecordsWithin(String collection, ColumnField valuesMapField, String key, String value) throws FailedDBOperationException {
getMap(collection).commit();
commit(collection);
return getMongoRecords(collection).selectRecordsWithin(MongoRecords.DBNAMERECORD, valuesMapField, key, value);
}

@Override
public AbstractRecordCursor selectRecordsNear(String collection, ColumnField valuesMapField, String key, String value, Double maxDistance) throws FailedDBOperationException {
getMap(collection).commit();
commit(collection);
return getMongoRecords(collection).selectRecordsNear(MongoRecords.DBNAMERECORD, valuesMapField, key, value, maxDistance);
}

@Override
public AbstractRecordCursor selectRecordsQuery(String collection, ColumnField valuesMapField,
String query, List<String> projection) throws FailedDBOperationException {
getMap(collection).commit();
commit(collection);
return getMongoRecords(collection).selectRecordsQuery(MongoRecords.DBNAMERECORD, valuesMapField,
query, projection);
}

@Override
public void createIndex(String collection, String field, String index) {
getMap(collection).commit();
commit(collection);
getMongoRecords(collection).createIndex(MongoRecords.DBNAMERECORD, field, index);
}

@Override
public void printAllEntries(String collection) throws FailedDBOperationException {
getMap(collection).commit();
commit(collection);
getMongoRecords(collection).printAllEntries(MongoRecords.DBNAMERECORD);
}

private void commit(String collection) {
try{
getMap(collection).commit();
} catch (BulkWriteException e) {
LOGGER.log(Level.WARNING, "Caught {e}, ignoring and proceeding: {1}", new Object[]{e.getClass().getSimpleName(), e.getMessage()});
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
*
* Copyright (c) 2015 University of Massachusetts
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Initial developer(s): Karthik A.
*
*/

package edu.umass.cs.gnsserver.extensions.sanitycheck;

import edu.umass.cs.gigapaxos.interfaces.Request;
import edu.umass.cs.reconfiguration.reconfigurationutils.RequestParseException;

public abstract class AbstractSanityCheck {

public abstract void check(Request request) throws RequestParseException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
*
* Copyright (c) 2015 University of Massachusetts
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Initial developer(s): Karthik A.
*
*/

package edu.umass.cs.gnsserver.extensions.sanitycheck;

import edu.umass.cs.gigapaxos.interfaces.Request;
import edu.umass.cs.gnscommon.CommandType;
import edu.umass.cs.gnscommon.GNSProtocol;
import edu.umass.cs.reconfiguration.reconfigurationutils.RequestParseException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/* This is an implementation of sanity checker */
public class GeoSanityCheck extends AbstractSanityCheck {

@Override
public void check(Request request) throws RequestParseException {

try {
JSONObject requestJSON = new JSONObject(request.toString());
JSONObject commandQuery = requestJSON.getJSONObject(GNSProtocol.COMMAND_QUERY.toString());

if (commandQuery.has(GNSProtocol.COMMAND_INT.toString()) &&
commandQuery.getInt(GNSProtocol.COMMAND_INT.toString()) == CommandType.ReplaceUserJSON.getInt()) {
JSONObject userJSON = new JSONObject(commandQuery.getString(GNSProtocol.USER_JSON.toString()));
if (userJSON.has(GNSProtocol.LOCATION_FIELD_NAME_2D_SPHERE.toString())) {
JSONObject geoLocCurrent = userJSON.getJSONObject(GNSProtocol.LOCATION_FIELD_NAME_2D_SPHERE.toString());
if (geoLocCurrent.has("coordinates")) {
JSONArray coordinates = geoLocCurrent.getJSONArray("coordinates");
if(coordinates.get(0).getClass().equals(String.class) || coordinates.get(1).getClass().equals(String.class)) {
throw new RequestParseException(new Exception("Numeric value expected for location coordinates, string provided"));
}
}
}
}

} catch (JSONException e) {
//Pass
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
*
* Copyright (c) 2015 University of Massachusetts
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Initial developer(s): Karthik A.
*
*/

package edu.umass.cs.gnsserver.extensions.sanitycheck;

import edu.umass.cs.gigapaxos.interfaces.Request;
import edu.umass.cs.reconfiguration.reconfigurationutils.RequestParseException;

public class NullSanityCheck extends AbstractSanityCheck {

public void check(Request request) throws RequestParseException {

}

}
32 changes: 32 additions & 0 deletions src/edu/umass/cs/gnsserver/gnsapp/GNSApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import edu.umass.cs.gigapaxos.interfaces.Replicable;
import edu.umass.cs.gigapaxos.interfaces.Request;
import edu.umass.cs.gigapaxos.interfaces.RequestIdentifier;
import edu.umass.cs.gnscommon.GNSProtocol;
import edu.umass.cs.gnscommon.ResponseCode;
import edu.umass.cs.gnscommon.exceptions.client.ClientException;
import edu.umass.cs.gnsserver.activecode.ActiveCodeHandler;
import edu.umass.cs.gnsserver.database.ColumnField;
Expand All @@ -36,6 +38,7 @@
import edu.umass.cs.gnscommon.packets.CommandPacket;
import edu.umass.cs.gnscommon.packets.ResponsePacket;
import edu.umass.cs.gnsserver.database.NoSQLRecords;
import edu.umass.cs.gnsserver.extensions.sanitycheck.AbstractSanityCheck;
import edu.umass.cs.gnsserver.main.GNSConfig;
import edu.umass.cs.gnsserver.gnsapp.clientCommandProcessor.ClientRequestHandlerInterface;

Expand Down Expand Up @@ -170,6 +173,17 @@ private static boolean enqueueCommand() {
*/
private AppAdminServer appAdminServer = null;

private static AbstractSanityCheck sanityCheck;

static {
try {
sanityCheck = (AbstractSanityCheck) Class.forName(Config.getGlobalString(GNSConfig.GNSC.SANITY_CHECKER)).newInstance();
} catch (ClassNotFoundException|InstantiationException|IllegalAccessException e) {
GNSConfig.getLogger().log(Level.SEVERE, "Error instantiating sanity checker class: {0}", e.getMessage());
}

}

/**
* Constructor invoked via reflection by gigapaxos.
*
Expand Down Expand Up @@ -283,6 +297,24 @@ public boolean execute(Request request, boolean doNotReplyToClient) {
+ RequestIdentifier.class;
}

try {
if (sanityCheck != null) {
sanityCheck.check(request);
} else {
GNSConfig.getLogger().log(Level.FINE, "Sanity checker has not been instantiated, skipping check");
}
} catch (RequestParseException e) {
//Malformed request, log and skip execution returning an error
GNSConfig.getLogger().log(Level.WARNING, "Sanity check caught malformed request: {0}", e.getMessage());
((BasicPacketWithClientAddress) request)
.setResponse(new ResponsePacket(request.getServiceName(),
((RequestIdentifier) request).getRequestID(),
ResponseCode.SANITY_CHECK_ERROR,
GNSProtocol.BAD_RESPONSE.toString() + " " + GNSProtocol.SANITY_CHECK_ERROR + " " + e.getMessage()));
return true;
}


switch (packetType) {
case SELECT_REQUEST:
Select.handleSelectRequest((SelectRequestPacket) request, this);
Expand Down
9 changes: 8 additions & 1 deletion src/edu/umass/cs/gnsserver/main/GNSConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.logging.Logger;

import edu.umass.cs.gnsclient.client.GNSClientConfig;
import edu.umass.cs.gnsserver.extensions.sanitycheck.NullSanityCheck;
import edu.umass.cs.utils.Config;

/**
Expand Down Expand Up @@ -248,7 +249,13 @@ public static enum GNSC implements Config.ConfigurableEnum,
* Turn off active code handling. Default is true.
* Temporary - The use of this will go away at some point.
*/
DISABLE_ACTIVE_CODE(true);
DISABLE_ACTIVE_CODE(true),
/**
* The class name to use for doing sanity checks while updating GNS
* record. Must extend {@link edu.umass.cs.gnsserver.extensions.sanitycheck.AbstractSanityCheck}
*/
SANITY_CHECKER(NullSanityCheck.class.getName())
;

final Object defaultValue;
final boolean unsafeTestingOnly;
Expand Down

0 comments on commit b176a7c

Please sign in to comment.