Skip to content

Commit

Permalink
Issue-111: Is adminCommand really connected to the admin DB?
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandru-slobodcicov committed Mar 14, 2021
1 parent 5907e9c commit d5de32b
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 17 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ Liquibase turned to be the most feasible tool to extend as it allows to define c
<a name="release-notes"></a>
## Release Notes

#### 4.3.1.1
* Upgrade Mongo Java Driver from 4.2.1 to 4.2.2
* Fixed [Issue-111: Is adminCommand really connected to the admin DB?](https://github.com/liquibase/liquibase-mongodb/issues/111)

#### 4.3.1
* Support for Liquibase 4.3.1
* This an important release build with 4.2.0 mongo-driver-sync and is compatible with mongo-driver 3.x.x if provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

import com.mongodb.MongoException;
import com.mongodb.client.MongoDatabase;
import liquibase.ext.mongodb.database.MongoLiquibaseDatabase;
import liquibase.nosql.statement.NoSqlExecuteStatement;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -51,7 +52,11 @@ public void execute(final MongoLiquibaseDatabase database) {
}

public Document run(final MongoLiquibaseDatabase database) {
final Document response = database.getMongoDatabase().runCommand(command);
return run(database.getMongoDatabase());
}

public Document run(final MongoDatabase mongoDatabase) {
final Document response = mongoDatabase.runCommand(command);
checkResponse(response);
return response;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* #L%
*/

import liquibase.ext.mongodb.database.MongoConnection;
import liquibase.ext.mongodb.database.MongoLiquibaseDatabase;
import lombok.EqualsAndHashCode;
import lombok.Getter;
Expand All @@ -46,7 +47,8 @@ public String getCommandName() {

@Override
public Document run(final MongoLiquibaseDatabase database) {
return database.getMongoDatabase().runCommand(command);
return super.run(((MongoConnection) database.getConnection()).getMongoClient()
.getDatabase(database.getSystemSchema()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
* Finds and updates a single document via the database runCommand method
* NOTE: This does not return the original document,
* instead returns 1 if a document was updated, else 0
*
* <p>
* For a list of supported options see the reference page:
* @see <a href="https://docs.mongodb.com/manual/reference/command/findAndModify//">findAndModify</a>
*
* @see <a href="https://docs.mongodb.com/manual/reference/command/findAndModify//">findAndModify</a>
*/
@Getter
@EqualsAndHashCode(callSuper = true)
Expand All @@ -55,7 +55,7 @@ public FindOneAndUpdateStatement(final String collectionName, final Bson filter,
this(collectionName, combine(filter, document, sort));
}

public FindOneAndUpdateStatement(final String collectionName, Document options) {
public FindOneAndUpdateStatement(final String collectionName, final Document options) {
super(toCommand(RUN_COMMAND_NAME, collectionName, options));
}

Expand All @@ -66,19 +66,24 @@ public String getRunCommandName() {

private static Document combine(final Bson filter, final Bson document, final Bson sort) {
final Document combined = new Document(QUERY, filter);
if(nonNull(document)) { combined.put(UPDATE, document); }
if(nonNull(sort)) { combined.put(SORT, sort); }
if (nonNull(document)) {
combined.put(UPDATE, document);
}
if (nonNull(sort)) {
combined.put(SORT, sort);
}
return combined;
}

/**
* Executes the findAndModify operation
*
* @param database the database to run against
* @return 1 if a document was modified else 0
*/
@Override
public int update(final MongoLiquibaseDatabase database) {
Document response = super.run(database);
final Document response = super.run(database);
return isNull(response.get(VALUE)) ? 0 : 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* #L%
*/

import liquibase.change.CheckSum;
import liquibase.changelog.ChangeSet;
import liquibase.ext.mongodb.statement.AdminCommandStatement;
import liquibase.statement.SqlStatement;
Expand All @@ -31,6 +32,7 @@
import static liquibase.ext.mongodb.TestUtils.BUILD_INFO_1;
import static liquibase.ext.mongodb.TestUtils.getChangesets;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;

class AdminCommandChangeTest extends AbstractMongoChangeTest {

Expand All @@ -44,19 +46,45 @@ void getConfirmationMessage() {
void generateStatements() {
final List<ChangeSet> changeSets = getChangesets("liquibase/ext/changelog.admin-command.test.xml", database);

assertThat(changeSets).hasSize(1).first()
.returns("8:e17342ecb217a7588eb1d33af4fadff4", s -> s.generateCheckSum().toString());
assertThat(changeSets).hasSize(2).extracting(ChangeSet::getAuthor, ChangeSet::getId, ChangeSet::generateCheckSum)
.containsExactly(
tuple("alex", "1", CheckSum.parse("8:e17342ecb217a7588eb1d33af4fadff4")),
tuple("alex", "2", CheckSum.parse("8:b961faf376a802b74abeba3a54b34045"))
);

assertThat(changeSets.get(0).getChanges())
.hasSize(1)
.hasOnlyElementsOfTypes(AdminCommandChange.class);

final AdminCommandChange ch2 = (AdminCommandChange) changeSets.get(0).getChanges().get(0);
assertThat(ch2.getCommand()).isEqualTo(BUILD_INFO_1);
final AdminCommandChange change1 = (AdminCommandChange) changeSets.get(0).getChanges().get(0);
assertThat(change1.getCommand()).isEqualTo(BUILD_INFO_1);

final SqlStatement[] sqlStatements2 = ch2.generateStatements(database);
assertThat(sqlStatements2).hasSize(1);
assertThat(sqlStatements2).hasOnlyElementsOfType(AdminCommandStatement.class);
assertThat(((AdminCommandStatement) sqlStatements2[0]).getCommand()).containsEntry("buildInfo", 1);
final SqlStatement[] statements1 = change1.generateStatements(database);
assertThat(statements1).hasSize(1)
.hasOnlyElementsOfType(AdminCommandStatement.class);
final AdminCommandStatement statement1 = (AdminCommandStatement) statements1[0];
assertThat(statement1.getCommand()).containsEntry("buildInfo", 1);
assertThat(statement1.toJs())
.isEqualTo(statement1.toString())
.isEqualTo("db.adminCommand({\"buildInfo\": 1});");
assertThat(statement1.getCommandName())
.isEqualTo(AdminCommandStatement.COMMAND_NAME)
.isEqualTo("adminCommand");

assertThat(changeSets.get(1).getChanges())
.hasSize(1)
.hasOnlyElementsOfTypes(AdminCommandChange.class);

final AdminCommandChange change2 = (AdminCommandChange) changeSets.get(1).getChanges().get(0);
assertThat(change2.getCommand()).isEqualTo("{ shardCollection: \"db1.player_info_static\", key: {location: 1, _id: 1}, unique: true}");

final SqlStatement[] statements2 = change2.generateStatements(database);
assertThat(statements2).hasSize(1)
.hasOnlyElementsOfType(AdminCommandStatement.class);
final AdminCommandStatement statement2 = (AdminCommandStatement) statements2[0];
assertThat(statement2.getCommand()).containsEntry("shardCollection", "db1.player_info_static");
assertThat(statement2.toJs())
.isEqualTo(statement2.toString())
.isEqualTo("db.adminCommand({\"shardCollection\": \"db1.player_info_static\", \"key\": {\"location\": 1, \"_id\": 1}, \"unique\": true});");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package liquibase.ext.mongodb.statement;

import com.mongodb.MongoCommandException;
import liquibase.ext.AbstractMongoIntegrationTest;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

class AdminCommandStatementIT extends AbstractMongoIntegrationTest {

@Test
void executeStatement() {

new CreateCollectionStatement("orders").execute(database);

assertThat(new CountCollectionByNameStatement("orders").queryForLong(database)).isEqualTo(1L);

final AdminCommandStatement statement1 = new AdminCommandStatement("{\n" +
" renameCollection: \"" + mongoDatabase.getName() + ".orders\",\n" +
" to: \"" + mongoDatabase.getName() + ".orders-2016\"\n" +
" }");
statement1.execute(database);

assertThat(new CountCollectionByNameStatement("orders").queryForLong(database)).isEqualTo(0L);
assertThat(new CountCollectionByNameStatement("orders-2016").queryForLong(database)).isEqualTo(1L);

final RunCommandStatement statement2 = new RunCommandStatement(statement1.getCommand());
assertThatExceptionOfType(MongoCommandException.class).isThrownBy(() -> statement2.execute(database))
.withMessageContaining("renameCollection may only be run against the admin database");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

<changeSet id="2" author="alex">
<property name="database.name" value="db1"/>

<changeSet id="1" author="alex">

<ext:adminCommand>

Expand All @@ -36,4 +38,16 @@

</changeSet>

<changeSet id="2" author="alex">

<ext:adminCommand>

<ext:command>
{ shardCollection: "${database.name}.player_info_static", key: {location: 1, _id: 1}, unique: true}
</ext:command>

</ext:adminCommand>

</changeSet>

</databaseChangeLog>

0 comments on commit d5de32b

Please sign in to comment.