Skip to content

Commit

Permalink
Merge pull request #4 from safetrax/mongoException
Browse files Browse the repository at this point in the history
Upgrade Jetty
  • Loading branch information
Vignesh committed Jan 21, 2016
2 parents b198d74 + 565824b commit bf2c44a
Show file tree
Hide file tree
Showing 17 changed files with 124 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: java
jdk:
- oraclejdk7
- oraclejdk8
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ext {
ext.libraries = [
javaxServlet: 'javax.servlet:javax.servlet-api:3.0.1',
gson: 'com.google.code.gson:gson:2.4',
mongoDriver: 'org.mongodb:mongo-java-driver:2.7.3',
mongoDriver: 'org.mongodb:mongo-java-driver:3.2.1',
mongoapi: project(':mongoapi'),
mongoser: project(':mongoser'),
googleTruth: 'com.google.truth:truth:0.27',
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP=in.mtap.iincube
VERSION_NAME=0.1.2
VERSION_NAME=0.2.1

POM_DESCRIPTION=MongoDB REST API
POM_URL=https://github.com/safetrax/mongorest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static void assertNotNull(Object object, String message) {
error(message);
}

/** @throw IllegalArgument exception */
/** @throws IllegalArgumentException exception */
public static void error(String msg) {
throw new IllegalArgumentException(msg);
}
Expand Down
5 changes: 2 additions & 3 deletions mongoser/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ dependencies {
compile libraries.javaxServlet
compile libraries.apacheCommons

compile 'org.eclipse.jetty.orbit:javax.servlet:3.0.0.v201112011016'
compile 'org.eclipse.jetty:jetty-server:8.1.2.v20120308'
compile 'org.eclipse.jetty:jetty-servlet:8.1.2.v20120308'
compile 'org.eclipse.jetty:jetty-server:9.3.6.v20151106'
compile 'org.eclipse.jetty:jetty-servlet:9.3.6.v20151106'

testCompile libraries.junit
testCompile libraries.googleTruth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ public class Mongoser {
}

public void start() throws Exception {
server.setSendServerVersion(false);

server.setConnectors(serverConfig.getConnectors());
server.setConnectors(serverConfig.getConnectors(server));
ErrorPageErrorHandler errorHandler = new MongoserErrorHandler();
errorHandler.addErrorPage(400, 599, "/error");
errorHandler.setShowStacks(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@

package in.mtap.iincube.mongoser;

import com.mongodb.MongoException;
import in.mtap.iincube.mongoser.model.Status;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
Expand All @@ -42,7 +40,15 @@ public MongoserErrorHandler() {
@Override public void handle(String target, Request baseRequest,
HttpServletRequest req, HttpServletResponse res) throws IOException {
Class<?> exceptionClass = (Class<?>) req.getAttribute(Dispatcher.ERROR_EXCEPTION_TYPE);
LOG.fine("handling error type: " + exceptionClass.getSimpleName());
Throwable throwable = (Throwable) req.getAttribute(Dispatcher.ERROR_EXCEPTION);

if (exceptionClass == null) {
LOG.warning("Unknown state for request " + req.toString());
writeMongoError("Unknown error", baseRequest, res);
return;
}

LOG.info("handling error type: " + exceptionClass.getSimpleName());
if (MongoserException.class.equals(exceptionClass)) {
MongoserException exception = (MongoserException) req.getAttribute(Dispatcher.ERROR_EXCEPTION);

Expand All @@ -56,30 +62,15 @@ public MongoserErrorHandler() {
PrintWriter w = res.getWriter();
w.println(st.toJson());
w.flush();
AbstractHttpConnection.getCurrentConnection().getRequest().setHandled(true);
return;
} else if (MongoException.Network.class.equals(exceptionClass)) {
writeMongoError("Mongodb server down or can not be reached", res);
return;
} else if (MongoException.CursorNotFound.class.equals(exceptionClass)) {
writeMongoError("Mongodb: cursor not found", res);
return;
} else if (MongoException.DuplicateKey.class.equals(exceptionClass)) {
writeMongoError("Mongodb: duplicate key", res);
return;
} else if (exceptionClass != null
&& "com.mongodb.CommandResult$CommandFailure".equals(exceptionClass.getName())) {
Exception exc = (Exception) req.getAttribute(Dispatcher.ERROR_EXCEPTION);
writeMongoError("Mongodb: " + exc.getMessage(), res);
baseRequest.setHandled(true);
return;
} else {
writeMongoError("Unhandled exception", res);
writeMongoError(throwable.getMessage(), baseRequest, res);
return;
}
// super.handle(target, baseRequest, req, res);
}

private void writeMongoError(String msg, HttpServletResponse res)
private void writeMongoError(String msg, Request baseRequest, HttpServletResponse res)
throws IOException {
res.setContentType("application/json;charset=UTF-8");
res.setStatus(SC_BAD_REQUEST);
Expand All @@ -89,7 +80,6 @@ private void writeMongoError(String msg, HttpServletResponse res)
PrintWriter w = res.getWriter();
w.println(st.toJson());
w.flush();
AbstractHttpConnection.getCurrentConnection().getRequest().setHandled(true);
baseRequest.setHandled(true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class MongoserException extends RuntimeException {
private final Status status;

public MongoserException(int code, Status status) {
super("Error code [" + code + "] " + status.getMessage());
this.code = code;
this.status = status;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ private void closeDecoders() {
*/
public Result<List<DBObject>> readResultDbObject() {
try {
Result<List<DBObject>> result = new Result<List<DBObject>>(decodeAsDBObject(), true,
Result<List<DBObject>> result = new Result<>(decodeAsDBObject(), true,
requestBody.toString());
requestBody.setLength(0);
return result;
} catch (Exception e) {
return new Result<List<DBObject>>(null, false);
return new Result<>(null, false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
package in.mtap.iincube.mongoser.config;

import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import in.mtap.iincube.mongoapi.MongoClient;

Expand Down Expand Up @@ -71,16 +71,16 @@ private Mongo getMongo() {
return mongo;
try {
List<ServerAddress> serverAddresses = toAddress(servers);
MongoOptions opts = new MongoOptions();
opts.autoConnectRetry = true;
MongoClientOptions.Builder opts = new MongoClientOptions.Builder();

if (threadNo < 100) {
opts.connectionsPerHost = threadNo;
opts.connectionsPerHost(threadNo);
} else {
opts.connectionsPerHost = 100;
opts.connectionsPerHost(100);
}
opts.threadsAllowedToBlockForConnectionMultiplier = 10;
opts.maxWaitTime = 10000;
mongo = new Mongo(serverAddresses, opts);
opts.threadsAllowedToBlockForConnectionMultiplier(10);
opts.maxWaitTime(10000);
mongo = new com.mongodb.MongoClient(serverAddresses, opts.build());
return mongo;
} catch (UnknownHostException e) {
throw new IllegalArgumentException("Unknown host : " + servers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@
package in.mtap.iincube.mongoser.config;

import in.mtap.iincube.mongoser.utils.Utility;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

Expand All @@ -46,27 +51,28 @@ public ServerConfig(String serverAddr, int port, int noOfThreads, boolean ssl,
threadPool = new QueuedThreadPool(noOfThreads);
}

public Connector[] getConnectors() {
private ConnectionFactory getConnectionFactory() {
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSendServerVersion(false);
httpConfig.setSecurePort(port);
httpConfig.setSendDateHeader(true);
ConnectionFactory result;
if (ssl) {
SslSelectChannelConnector sslConnector = new SslSelectChannelConnector();
sslConnector.setStatsOn(false);
sslConnector.setHost(serverAddr);
sslConnector.setPort(port);
sslConnector.setThreadPool(threadPool);
sslConnector.setName("Simple Mongoser SSL Connector");
SslContextFactory sslContextFactory = sslConnector.getSslContextFactory();
sslContextFactory.setKeyStorePath(sslKeystore);
sslContextFactory.setKeyManagerPassword(sslPassword);
return new Connector[]{sslConnector};
SslContextFactory contextFactory = new SslContextFactory();
contextFactory.setKeyStorePath(sslKeystore);
contextFactory.setKeyManagerPassword(sslPassword);
result = new SslConnectionFactory(contextFactory, HttpVersion.HTTP_1_1.asString());
} else {
SelectChannelConnector connector = new SelectChannelConnector();
connector.setStatsOn(false);
connector.setHost(serverAddr);
connector.setPort(port);
connector.setThreadPool(threadPool);
connector.setName("SimpleMongodb connector");
return new Connector[]{connector};
result = new HttpConnectionFactory(httpConfig);
}
return result;
}

public Connector[] getConnectors(Server server) {
ServerConnector connector = new ServerConnector(server, getConnectionFactory());
connector.setHost(serverAddr);
connector.setPort(port);
return new Connector[] {connector};
}

public static ServerConfig extractFrom(Properties properties) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,16 @@
public class ReadRequestHandler {
static final String INVALID_LIMIT_SKIP = "skip or limit param is invalid";
private final DocumentClient documentClient;
private final ReadProxy readProxy;
private final JsonEncoder jsonEncoder = new JsonEncoder();

public ReadRequestHandler(DocumentClient documentClient) {
this(documentClient, ReadProxy.NONE);
}

public ReadRequestHandler(DocumentClient documentClient, ReadProxy readProxy) {
this.documentClient = documentClient;
this.readProxy = readProxy;
}

/**
Expand All @@ -55,6 +61,12 @@ public void process(RequestReader requestReader, Response responseWriter)
Status.get(MISSING_DB_COL_PARAMS).toJsonTree());
return;
}

if (!readProxy.isNamespaceAllowed(requestReader.getDbName(), requestReader.getDbName())) {
responseWriter.send(SC_BAD_REQUEST,
Status.get("Not allowed to read this namespace").toJsonTree());
return;
}
int skip = -1;
int limit = -1;
try {
Expand Down Expand Up @@ -93,12 +105,21 @@ public void process(RequestReader requestReader, Response responseWriter)
if (queryData.size() > 1)
mongoReader.sort(queryData.get(1));
try {
responseWriter.send(SC_OK, mongoReader.query(jsonEncoder));
responseWriter.send(SC_OK, mongoReader.execute(jsonEncoder));
} catch (IllegalArgumentException e) {
throw new MongoserException(400,
Status.get(" Error message: " + e.getMessage()
+ " Invalid request " + resultData.getPlainBody()));
}
}

public interface ReadProxy {
boolean isNamespaceAllowed(String dbname, String colname);

ReadProxy NONE = new ReadProxy() {
@Override public boolean isNamespaceAllowed(String dbname, String colname) {
return true;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public static Status get(String status) {
return new Status(status);
}

public String getMessage() {
return status;
}

public String toJson() {
return GSON.toJson(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.io.StringWriter;

import static com.google.common.truth.Truth.assertThat;
Expand Down Expand Up @@ -83,6 +84,16 @@ public class JsonArrayDecoderTest {
}
}

@Test public void readRegexInput() throws IOException {
StringWriter out = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(out);
jsonWriter.beginObject().name("firstName").beginObject()
.name("$regex").value("hello").endObject().endObject();
jsonArrayDecoder.addData(out.toString());
jsonArrayDecoder.getAsDBObject();
assertThat(jsonArrayDecoder.isValid()).isTrue();
}

@Test public void invalidWhenNoData() {
assertThat(jsonArrayDecoder.isValid()).isFalse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import in.mtap.iincube.mongoser.codec.Result;
import org.junit.Test;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
Expand Down Expand Up @@ -149,5 +150,17 @@ public MockServletInputStream(InputStream inputStream) {
@Override public int read() throws IOException {
return source.read();
}

@Override public boolean isFinished() {
return false;
}

@Override public boolean isReady() {
return false;
}

@Override public void setReadListener(ReadListener readListener) {

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ public class ReadRequestHandlerTest {
verifyNoMoreInteractions(response);
}

@Test public void errorIfReadProxyDidNotAllow() throws Exception {
when(reader.getCollectionName()).thenReturn("colname");
when(reader.getDbName()).thenReturn("dbname");
ReadRequestHandler readRequestHandler = new ReadRequestHandler(null,
new ReadRequestHandler.ReadProxy() {
@Override public boolean isNamespaceAllowed(String dbname, String colname) {
return false;
}
});
readRequestHandler.process(reader, response);

verify(response).send(HttpServletResponse.SC_BAD_REQUEST,
Status.get("Not allowed to read this namespace").toJsonTree());
verifyNoMoreInteractions(response);
}

@Test public void parseErrorOnInputStream() throws Exception {
when(reader.getCollectionName()).thenReturn("colname");
when(reader.getDbName()).thenReturn("dbname");
Expand Down
2 changes: 1 addition & 1 deletion restrunner/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apply plugin: 'application'

mainClassName = 'in.mtap.iincube.restrunner.RestServer'

sourceCompatibility = 1.7
sourceCompatibility = 1.8
version = '1.0'

repositories {
Expand Down

0 comments on commit bf2c44a

Please sign in to comment.