/*
* Copyright (c) 2014.
*
* BaasBox - info@baasbox.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baasbox.controllers;
import com.baasbox.BBConfiguration;
import com.baasbox.controllers.actions.filters.ConnectToDBFilter;
import com.baasbox.controllers.actions.filters.ExtractQueryParameters;
import com.baasbox.controllers.actions.filters.UserOrAnonymousCredentialsFilter;
import com.baasbox.dao.exception.ScriptException;
import com.baasbox.db.DbHelper;
import com.baasbox.service.scripting.ScriptingService;
import com.baasbox.service.scripting.base.ScriptCall;
import com.baasbox.service.scripting.base.ScriptEvalException;
import com.baasbox.service.scripting.base.ScriptResult;
import com.baasbox.service.scripting.js.Json;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.orientechnologies.orient.core.record.impl.ODocument;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import com.baasbox.service.logging.BaasBoxLogger;
import play.libs.EventSource;
import play.libs.F;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Result;
import play.mvc.With;
import play.data.DynamicForm;
import play.data.Form;
import views.html.admin.main_.content_.dbmanager_.dbmanager;
import java.util.Map;
/**
* Invokes a script through restful api
*
* Created by Andrea Tortorella on 10/06/14.
*/
public class ScriptInvoker extends Controller{
@With({UserOrAnonymousCredentialsFilter.class,
ConnectToDBFilter.class,
ExtractQueryParameters.class})
public static Result invoke(String name,String path){
ODocument serv = null;
if(request().body().asText()!=null && request().body().isMaxSizeExceeded())//fixes issue_561
return badRequest("Too much data! The maximum is " + ObjectUtils.toString(BBConfiguration.configuration.getString("parsers.text.maxLength"),"128KB"));
try {
serv = ScriptingService.get(name, true,true);
} catch (ScriptException e) {
return status(503,"Script is in an invalid state");
}
if (serv == null){
return notFound("Script does not exists");
}
JsonNode reqAsJson = serializeRequest(path, request());
try {
ScriptResult result =ScriptingService.invoke(ScriptCall.rest(serv, reqAsJson));
return status(result.status(),result.content());
} catch (ScriptEvalException e) {
if (DbHelper.getConnection()!=null && !DbHelper.getConnection().isClosed() && DbHelper.isInTransaction())
DbHelper.rollbackTransaction();
BaasBoxLogger.error("Error evaluating script",e);
return status(CustomHttpCode.PLUGIN_INTERNAL_ERROR.getBbCode(),ExceptionUtils.getFullStackTrace(e));
// return internalServerError(ExceptionUtils.getFullStackTrace(e));
}
// catch (IllegalStateException e){
// return internalServerError("script returned invalid json response");
// }
}
public static JsonNode serializeRequest(String path,Http.Request request){
Http.RequestBody body = request.body();
Map<String, String[]> headers = request.headers();
String method = request.method();
Map<String, String[]> query = request.queryString();
path=path==null?"/":path;
ObjectNode reqJson = Json.mapper().createObjectNode();
reqJson.put("method",method);
reqJson.put("path",path);
reqJson.put("remote",request.remoteAddress());
if (!StringUtils.containsIgnoreCase(request.getHeader(CONTENT_TYPE), "application/json")) {
String textBody = body == null ? null : body.asText();
if (textBody == null) {
//fixes issue 627
Map<String, String> params = BodyHelper.requestData(request);
JsonNode jsonBody = Json.mapper().valueToTree(params);
reqJson.put("body", jsonBody);
} else {
reqJson.put("body", textBody);
}
} else {
reqJson.put("body", body.asJson());
}
JsonNode queryJson = Json.mapper().valueToTree(query);
reqJson.put("queryString",queryJson);
JsonNode headersJson = Json.mapper().valueToTree(headers);
reqJson.put("headers",headersJson);
BaasBoxLogger.debug("Serialized request to pass to the script: ");
BaasBoxLogger.debug(reqJson.toString());
return reqJson;
}
}