Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [server side change only] convert Mongo's form data to raw / native query #10058

Merged
merged 11 commits into from
Apr 1, 2022
Next Next commit
test with find command
  • Loading branch information
sumitsum committed Dec 28, 2021
commit a9b0a42ed97f31a5c813d0e4982921ec7f66e01d
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,8 @@ default Mono<Tuple2<Set<String>, Set<String>>> getHintMessages(ActionConfigurati
default Mono<TriggerResultDTO> trigger(TriggerRequestDTO request) {
return Mono.empty();
}

default ActionConfiguration extractAndSetNativeQueryFromFormData(ActionConfiguration actionConfiguration) {
return actionConfiguration;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.appsmith.external.plugins.BasePlugin;
import com.appsmith.external.plugins.PluginExecutor;
import com.appsmith.external.plugins.SmartSubstitutionInterface;
import com.external.plugins.commands.MongoCommand;
import com.external.plugins.utils.MongoErrorUtils;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
Expand Down Expand Up @@ -70,6 +71,7 @@
import static com.external.plugins.utils.MongoPluginUtils.generateTemplatesAndStructureForACollection;
import static com.external.plugins.utils.MongoPluginUtils.getDatabaseName;
import static com.appsmith.external.helpers.PluginUtils.getValueSafelyFromFormData;
import static com.external.plugins.utils.MongoPluginUtils.getRawQuery;
import static com.external.plugins.utils.MongoPluginUtils.isRawCommand;
import static com.appsmith.external.helpers.PluginUtils.setValueSafelyInFormData;
import static com.external.plugins.utils.MongoPluginUtils.urlEncode;
Expand All @@ -86,6 +88,7 @@
import static com.external.plugins.constants.FieldName.UPDATE_QUERY;
import static com.external.plugins.constants.FieldName.UPDATE_OPERATION;
import static java.lang.Boolean.TRUE;
import static org.apache.logging.log4j.util.Strings.isBlank;

public class MongoPlugin extends BasePlugin {

Expand Down Expand Up @@ -958,6 +961,24 @@ public Mono<ActionExecutionResult> execute(MongoClient mongoClient,
// Unused function
return Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation"));
}

@Override
public ActionConfiguration extractAndSetNativeQueryFromFormData(ActionConfiguration actionConfiguration) {
Map<String, Object> formData = actionConfiguration.getFormData();
if (formData != null && !formData.isEmpty()) {
// If it is not raw command, then it must be one of the mongo form commands
if (!isRawCommand(formData)) {
if (isBlank(actionConfiguration.getBody())) {
String rawQuery = getRawQuery(actionConfiguration);
if (rawQuery != null) {
setValueSafelyInFormData(formData, "formToNativeQuery", rawQuery); // TODO: magic string
}
}
}
}

return actionConfiguration;
}
}

private static Object cleanUp(Object object) {
Expand Down Expand Up @@ -1008,5 +1029,4 @@ private static boolean isAuthenticated(DBAuth authentication, String mongoUri) {
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.minidev.json.JSONObject;
import org.bson.Document;
import org.pf4j.util.StringUtils;

Expand Down Expand Up @@ -167,4 +168,32 @@ private DatasourceStructure.Template generateFindByIdTemplate(String collectionN
configMap
);
}

@Override
public String getRawQuery() {
JSONObject query = new JSONObject();
query.put("find", this.collection);

if (!StringUtils.isNullOrEmpty(this.query)) {
query.put("filter", this.query);
}

if (!StringUtils.isNullOrEmpty(this.sort)) {
query.put("sort", this.sort);
}

// Default to returning 10 documents if not mentioned
int limit = 10;
if (!StringUtils.isNullOrEmpty(this.limit)) {
limit = Integer.parseInt(this.limit);
}
query.put("limit", limit);
query.put("batchSize", limit);

if (!StringUtils.isNullOrEmpty(this.skip)) {
query.put("skip", this.skip);
}

return query.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,17 @@ public Boolean isValid() {
}

public Document parseCommand() {
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation : All mongo commands must implement parseCommand");
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation : All mongo " +
"commands must implement parseCommand");
}

public List<DatasourceStructure.Template> generateTemplate(Map<String, Object> templateConfiguration) {
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation : All mongo commands must implement generateTemplate");
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation : All mongo " +
"commands must implement generateTemplate");
}

public String getRawQuery() {
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Unsupported Operation : All mongo " +
"commands must implement getRawQuery");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,7 @@ public static String convertMongoFormInputToRawCommand(ActionConfiguration actio
if (!isRawCommand(formData)) {

// Parse the commands into raw appropriately
MongoCommand command = null;
switch ((String) formData.getOrDefault(COMMAND, "")) {
case "INSERT":
command = new Insert(actionConfiguration);
break;
case "FIND":
command = new Find(actionConfiguration);
break;
case "UPDATE":
command = new UpdateMany(actionConfiguration);
break;
case "DELETE":
command = new Delete(actionConfiguration);
break;
case "COUNT":
command = new Count(actionConfiguration);
break;
case "DISTINCT":
command = new Distinct(actionConfiguration);
break;
case "AGGREGATE":
command = new Aggregate(actionConfiguration);
break;
default:
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, "No valid mongo command found. Please select a command from the \"Command\" dropdown and try again");
}
MongoCommand command = getMongoCommand(actionConfiguration);
if (!command.isValid()) {
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR, "Try again after configuring the fields : " + command.getFieldNamesWithNoConfiguration());
}
Expand All @@ -95,6 +70,41 @@ public static String convertMongoFormInputToRawCommand(ActionConfiguration actio
return actionConfiguration.getBody();
}

// TODO: add comment
private static MongoCommand getMongoCommand(ActionConfiguration actionConfiguration) throws AppsmithPluginException {
Map<String, Object> formData = actionConfiguration.getFormData();
MongoCommand command;
switch ((String) formData.getOrDefault(COMMAND, "")) {
case "INSERT":
command = new Insert(actionConfiguration);
break;
case "FIND":
command = new Find(actionConfiguration);
break;
case "UPDATE":
command = new UpdateMany(actionConfiguration);
break;
case "DELETE":
command = new Delete(actionConfiguration);
break;
case "COUNT":
command = new Count(actionConfiguration);
break;
case "DISTINCT":
command = new Distinct(actionConfiguration);
break;
case "AGGREGATE":
command = new Aggregate(actionConfiguration);
break;
default:
throw new AppsmithPluginException(AppsmithPluginError.PLUGIN_EXECUTE_ARGUMENT_ERROR,
"No valid mongo command found. Please select a command from the \"Command\" dropdown and try " +
"again");
}

return command;
}

public static String getDatabaseName(DatasourceConfiguration datasourceConfiguration) {
// Explicitly set default database.
String databaseName = datasourceConfiguration.getConnection().getDefaultDatabaseName();
Expand Down Expand Up @@ -191,4 +201,9 @@ public static String urlEncode(String text) {
return URLEncoder.encode(text, StandardCharsets.UTF_8);
}

public static String getRawQuery(ActionConfiguration actionConfiguration) {
MongoCommand command = getMongoCommand(actionConfiguration);
return command.getRawQuery(); // TODO: fix it
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ public Mono<ActionDTO> updateUnpublishedAction(String id, ActionDTO action) {
copyNewFieldValuesIntoOldObject(action, dbAction.getUnpublishedAction());
return dbAction;
})
.flatMap(this::extractAndSetNativeQueryFromFormData)
.cache();

Mono<ActionDTO> savedUpdatedActionMono = updatedActionMono
Expand All @@ -523,6 +524,19 @@ public Mono<ActionDTO> updateUnpublishedAction(String id, ActionDTO action) {
.then(savedUpdatedActionMono);
}

private Mono<NewAction> extractAndSetNativeQueryFromFormData(NewAction action) {
Mono<Plugin> pluginMono = pluginService.getById(action.getPluginId());
Mono<PluginExecutor> pluginExecutorMono = pluginExecutorHelper.getPluginExecutor(pluginMono);

return pluginExecutorMono
.flatMap(pluginExecutor -> {
action.getUnpublishedAction().setActionConfiguration(pluginExecutor
.extractAndSetNativeQueryFromFormData(action.getUnpublishedAction().getActionConfiguration()));

return Mono.just(action);
});
}

@Override
public Mono<ActionExecutionResult> executeAction(ExecuteActionDTO executeActionDTO) {
// 1. Validate input parameters which are required for mustache replacements
Expand Down