|
14 | 14 | import java.util.Map; |
15 | 15 | import java.util.Set; |
16 | 16 | import java.util.concurrent.ConcurrentHashMap; |
17 | | -import java.util.stream.Collectors; |
18 | 17 |
|
19 | 18 | import org.slf4j.Logger; |
20 | 19 | import org.slf4j.LoggerFactory; |
@@ -152,57 +151,69 @@ private Document getLog(String argument) { |
152 | 151 | return response; |
153 | 152 | } |
154 | 153 |
|
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(); |
176 | 210 | } |
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()); |
206 | 217 | } |
207 | 218 | } |
208 | 219 |
|
@@ -299,45 +310,46 @@ private MongoCollection<?> resolveCollection(String namespace) { |
299 | 310 | protected abstract MongoDatabase openOrCreateDatabase(String databaseName); |
300 | 311 |
|
301 | 312 | @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 | + }; |
341 | 353 | } |
342 | 354 |
|
343 | 355 | @Override |
@@ -409,7 +421,7 @@ public Document handleMessage(MongoMessage message) { |
409 | 421 | Channel channel = message.getChannel(); |
410 | 422 | String databaseName = message.getDatabaseName(); |
411 | 423 | Document query = message.getDocument(); |
412 | | - String command = query.keySet().iterator().next(); |
| 424 | + DatabaseCommand command = DatabaseCommand.of(query.keySet().iterator().next()); |
413 | 425 | return handleCommand(channel, databaseName, command, query); |
414 | 426 | } |
415 | 427 |
|
|
0 commit comments