Skip to content

Commit eb35818

Browse files
author
jmarkerink
committed
feat: introduce enum for Commands wrapped in DatabaseCommand value object
1 parent ac36af6 commit eb35818

13 files changed

Lines changed: 370 additions & 213 deletions

File tree

core/src/main/java/de/bwaldvogel/mongo/MongoBackend.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.Collection;
55
import java.util.List;
66

7+
import de.bwaldvogel.mongo.backend.DatabaseCommand;
78
import de.bwaldvogel.mongo.backend.QueryResult;
89
import de.bwaldvogel.mongo.bson.Document;
910
import de.bwaldvogel.mongo.wire.message.MongoMessage;
@@ -14,7 +15,7 @@ public interface MongoBackend {
1415

1516
void handleClose(Channel channel);
1617

17-
Document handleCommand(Channel channel, String database, String command, Document query);
18+
Document handleCommand(Channel channel, String database, DatabaseCommand command, Document query);
1819

1920
QueryResult handleQuery(MongoQuery query);
2021

core/src/main/java/de/bwaldvogel/mongo/MongoDatabase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.bwaldvogel.mongo;
22

33
import de.bwaldvogel.mongo.backend.CollectionOptions;
4+
import de.bwaldvogel.mongo.backend.DatabaseCommand;
45
import de.bwaldvogel.mongo.backend.DatabaseResolver;
56
import de.bwaldvogel.mongo.backend.QueryResult;
67
import de.bwaldvogel.mongo.bson.Document;
@@ -14,7 +15,7 @@ public interface MongoDatabase {
1415

1516
void handleClose(Channel channel);
1617

17-
Document handleCommand(Channel channel, String command, Document query, DatabaseResolver databaseResolver, Oplog oplog);
18+
Document handleCommand(Channel channel, DatabaseCommand command, Document query, DatabaseResolver databaseResolver, Oplog oplog);
1819

1920
QueryResult handleQuery(MongoQuery query);
2021

core/src/main/java/de/bwaldvogel/mongo/backend/AbstractMongoBackend.java

Lines changed: 103 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import java.util.Map;
1515
import java.util.Set;
1616
import java.util.concurrent.ConcurrentHashMap;
17-
import java.util.stream.Collectors;
1817

1918
import org.slf4j.Logger;
2019
import org.slf4j.LoggerFactory;
@@ -152,57 +151,69 @@ private Document getLog(String argument) {
152151
return response;
153152
}
154153

155-
private Document handleAdminCommand(String command, Document query) {
156-
if (command.equalsIgnoreCase("listdatabases")) {
157-
List<Document> databases = listDatabaseNames().stream()
158-
.sorted()
159-
.map(databaseName -> {
160-
MongoDatabase database = openOrCreateDatabase(databaseName);
161-
Document dbObj = new Document("name", database.getDatabaseName());
162-
dbObj.put("empty", Boolean.valueOf(database.isEmpty()));
163-
return dbObj;
164-
})
165-
.collect(Collectors.toList());
166-
Document response = new Document();
167-
response.put("databases", databases);
168-
Utils.markOkay(response);
169-
return response;
170-
} else if (command.equalsIgnoreCase("find")) {
171-
String collectionName = (String) query.get(command);
172-
if (collectionName.equals("$cmd.sys.inprog")) {
173-
return Utils.firstBatchCursorResponse(collectionName, new Document("inprog", Collections.emptyList()));
174-
} else {
175-
throw new NoSuchCommandException(new Document(command, collectionName).toString());
154+
private Document handleAdminCommand(DatabaseCommand command, Document query) {
155+
switch (command.getCommand()) {
156+
case LIST_DATABASES: {
157+
List<Document> databases = listDatabaseNames().stream()
158+
.sorted()
159+
.map(databaseName -> {
160+
MongoDatabase database = openOrCreateDatabase(databaseName);
161+
Document dbObj = new Document("name", database.getDatabaseName());
162+
dbObj.put("empty", Boolean.valueOf(database.isEmpty()));
163+
return dbObj;
164+
})
165+
.toList();
166+
Document response = new Document();
167+
response.put("databases", databases);
168+
Utils.markOkay(response);
169+
return response;
170+
}
171+
case FIND: {
172+
String collectionName = query.get(command.getQueryValue()).toString();
173+
if (collectionName.equals("$cmd.sys.inprog")) {
174+
return Utils.firstBatchCursorResponse(collectionName, new Document("inprog", Collections.emptyList()));
175+
} else {
176+
throw new NoSuchCommandException(new Document(command.getQueryValue(), collectionName).toString());
177+
}
178+
}
179+
case REPL_SET_GET_STATUS: {
180+
throw new NoReplicationEnabledException();
181+
}
182+
case GET_LOG: {
183+
final Object argument = query.get(command.getQueryValue());
184+
return getLog(argument == null ? null : argument.toString());
185+
}
186+
case RENAME_COLLECTION: {
187+
return handleRenameCollection(command.getQueryValue(), query);
188+
}
189+
case GET_LAST_ERROR: {
190+
log.debug("getLastError on admin database");
191+
return successResponse();
192+
}
193+
case CONNECTION_STATUS: {
194+
Document response = new Document();
195+
response.append("authInfo", new Document()
196+
.append("authenticatedUsers", Collections.emptyList())
197+
.append("authenticatedUserRoles", Collections.emptyList())
198+
);
199+
Utils.markOkay(response);
200+
return response;
201+
}
202+
case HOST_INFO: {
203+
return handleHostInfo();
204+
}
205+
case GET_CMD_LINE_OPTS: {
206+
return handleGetCmdLineOpts();
207+
}
208+
case GET_FREE_MONITORING_STATUS: {
209+
return handleGetFreeMonitoringStatus();
176210
}
177-
} else if (command.equalsIgnoreCase("replSetGetStatus")) {
178-
throw new NoReplicationEnabledException();
179-
} else if (command.equalsIgnoreCase("getLog")) {
180-
final Object argument = query.get(command);
181-
return getLog(argument == null ? null : argument.toString());
182-
} else if (command.equalsIgnoreCase("renameCollection")) {
183-
return handleRenameCollection(command, query);
184-
} else if (command.equalsIgnoreCase("getLastError")) {
185-
log.debug("getLastError on admin database");
186-
return successResponse();
187-
} else if (command.equalsIgnoreCase("connectionStatus")) {
188-
Document response = new Document();
189-
response.append("authInfo", new Document()
190-
.append("authenticatedUsers", Collections.emptyList())
191-
.append("authenticatedUserRoles", Collections.emptyList())
192-
);
193-
Utils.markOkay(response);
194-
return response;
195-
} else if (command.equalsIgnoreCase("hostInfo")) {
196-
return handleHostInfo();
197-
} else if (command.equalsIgnoreCase("getCmdLineOpts")) {
198-
return handleGetCmdLineOpts();
199-
} else if (command.equalsIgnoreCase("getFreeMonitoringStatus")) {
200-
return handleGetFreeMonitoringStatus();
201-
} else if (command.equalsIgnoreCase("endSessions")) {
202-
log.debug("endSessions on admin database");
203-
return successResponse();
204-
} else {
205-
throw new NoSuchCommandException(command);
211+
case END_SESSIONS: {
212+
log.debug("endSessions on admin database");
213+
return successResponse();
214+
}
215+
default:
216+
throw new NoSuchCommandException(command.getQueryValue());
206217
}
207218
}
208219

@@ -299,45 +310,46 @@ private MongoCollection<?> resolveCollection(String namespace) {
299310
protected abstract MongoDatabase openOrCreateDatabase(String databaseName);
300311

301312
@Override
302-
public Document handleCommand(Channel channel, String databaseName, String command, Document query) {
303-
if (command.equalsIgnoreCase("whatsmyuri")) {
304-
Document response = new Document();
305-
InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();
306-
response.put("you", remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort());
307-
Utils.markOkay(response);
308-
return response;
309-
} else if (command.equalsIgnoreCase("ismaster")) {
310-
Document response = new Document("ismaster", Boolean.TRUE);
311-
response.put("maxBsonObjectSize", Integer.valueOf(BsonConstants.MAX_BSON_OBJECT_SIZE));
312-
response.put("maxWriteBatchSize", Integer.valueOf(MongoWireProtocolHandler.MAX_WRITE_BATCH_SIZE));
313-
response.put("maxMessageSizeBytes", Integer.valueOf(MongoWireProtocolHandler.MAX_MESSAGE_SIZE_BYTES));
314-
response.put("maxWireVersion", Integer.valueOf(version.getWireVersion()));
315-
response.put("minWireVersion", Integer.valueOf(0));
316-
response.put("localTime", Instant.now(clock));
317-
Utils.markOkay(response);
318-
return response;
319-
} else if (command.equalsIgnoreCase("buildinfo")) {
320-
Document response = new Document("version", version.toVersionString());
321-
response.put("versionArray", version.getVersionArray());
322-
response.put("maxBsonObjectSize", Integer.valueOf(BsonConstants.MAX_BSON_OBJECT_SIZE));
323-
Utils.markOkay(response);
324-
return response;
325-
} else if (command.equalsIgnoreCase("dropDatabase")) {
326-
return handleDropDatabase(databaseName);
327-
} else if (command.equalsIgnoreCase("getMore")) {
328-
return handleGetMore(databaseName, command, query);
329-
} else if (command.equalsIgnoreCase("killCursors")) {
330-
return handleKillCursors(query);
331-
} else if (command.equalsIgnoreCase("ping")) {
332-
return successResponse();
333-
} else if (command.equalsIgnoreCase("serverStatus")) {
334-
return getServerStatus();
335-
} else if (databaseName.equals(ADMIN_DB_NAME)) {
336-
return handleAdminCommand(command, query);
337-
}
338-
339-
MongoDatabase mongoDatabase = resolveDatabase(databaseName);
340-
return mongoDatabase.handleCommand(channel, command, query, this::resolveDatabase, oplog);
313+
public Document handleCommand(Channel channel, String databaseName, DatabaseCommand command, Document query) {
314+
return switch (command.getCommand()) {
315+
case WHATS_MY_URI -> {
316+
Document response = new Document();
317+
InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();
318+
response.put("you", remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort());
319+
Utils.markOkay(response);
320+
yield response;
321+
}
322+
case IS_MASTER -> {
323+
Document response = new Document("ismaster", Boolean.TRUE);
324+
response.put("maxBsonObjectSize", Integer.valueOf(BsonConstants.MAX_BSON_OBJECT_SIZE));
325+
response.put("maxWriteBatchSize", Integer.valueOf(MongoWireProtocolHandler.MAX_WRITE_BATCH_SIZE));
326+
response.put("maxMessageSizeBytes", Integer.valueOf(MongoWireProtocolHandler.MAX_MESSAGE_SIZE_BYTES));
327+
response.put("maxWireVersion", Integer.valueOf(version.getWireVersion()));
328+
response.put("minWireVersion", Integer.valueOf(0));
329+
response.put("localTime", Instant.now(clock));
330+
Utils.markOkay(response);
331+
yield response;
332+
}
333+
case BUILD_INFO -> {
334+
Document response = new Document("version", version.toVersionString());
335+
response.put("versionArray", version.getVersionArray());
336+
response.put("maxBsonObjectSize", Integer.valueOf(BsonConstants.MAX_BSON_OBJECT_SIZE));
337+
Utils.markOkay(response);
338+
yield response;
339+
}
340+
case DROP_DATABASE -> handleDropDatabase(databaseName);
341+
case GET_MORE -> handleGetMore(databaseName, command.getQueryValue(), query);
342+
case KILL_CURSORS -> handleKillCursors(query);
343+
case PING -> successResponse();
344+
case SERVER_STATUS -> getServerStatus();
345+
default -> {
346+
if (databaseName.equals(ADMIN_DB_NAME)) {
347+
yield handleAdminCommand(command, query);
348+
}
349+
MongoDatabase mongoDatabase = resolveDatabase(databaseName);
350+
yield mongoDatabase.handleCommand(channel, command, query, this::resolveDatabase, oplog);
351+
}
352+
};
341353
}
342354

343355
@Override
@@ -409,7 +421,7 @@ public Document handleMessage(MongoMessage message) {
409421
Channel channel = message.getChannel();
410422
String databaseName = message.getDatabaseName();
411423
Document query = message.getDocument();
412-
String command = query.keySet().iterator().next();
424+
DatabaseCommand command = DatabaseCommand.of(query.keySet().iterator().next());
413425
return handleCommand(channel, databaseName, command, query);
414426
}
415427

0 commit comments

Comments
 (0)