Esempio n. 1
0
 public static JsonNode postAPI(String apiString, JsonNode jsonData) {
   System.out.println("apiString: " + apiString);
   System.out.println("jsonData: " + jsonData.get("purpose"));
   Promise<WSResponse> responsePromise = WS.url(apiString).post(jsonData);
   final Promise<JsonNode> bodyPromise =
       responsePromise.map(
           new Function<WSResponse, JsonNode>() {
             public JsonNode apply(WSResponse response) throws Throwable {
               if ((response.getStatus() == 201 || response.getStatus() == 200)) {
                 try {
                   return response.asJson();
                 } catch (Exception e) {
                   // If response is in Json format, return as json, otherwise just plain success
                   return createResponse(ResponseType.SUCCESS);
                 }
               } else { // other response status from the server
                 return createResponse(ResponseType.SAVEERROR);
               }
             }
           });
   try {
     return bodyPromise.get(10000L);
   } catch (Exception e) {
     return createResponse(ResponseType.TIMEOUT);
   }
 }
  @Override
  public Promise<Result> call(Context ctx) throws Throwable {
    String accessToken = ctx.request().getHeader("x-access-token");
    if (accessToken != null) {
      // Check RateLimit
      Logger.debug("Checking for token RateLimit. token:" + accessToken);
      if (!RateLimitAgent.isRateOverLimit(accessToken)) {
        return Promise.<Result>pure(badRequest("Over RateLimit. Account temporaly suspended"));
      }
    } else {
      return Promise.<Result>pure(badRequest("Authentication need"));
    }

    return delegate.call(ctx);
  }
Esempio n. 3
0
 // #async
 public static Promise<SimpleResult> index() {
   Promise<Integer> promiseOfInt =
       Promise.promise(
           new Function0<Integer>() {
             public Integer apply() {
               return intensiveComputation();
             }
           });
   return promiseOfInt.map(
       new Function<Integer, SimpleResult>() {
         public SimpleResult apply(Integer i) {
           return ok("Got result: " + i);
         }
       });
 }
Esempio n. 4
0
 public static Promise<Proposal> findKeynote() {
   return Promise.promise(
           new Function0<Proposal>() {
             @Override
             public Proposal apply() throws Throwable {
               return find.where().eq("type", SessionType.Keynote).findUnique();
             }
           },
           ctx)
       .recover(
           new Function<Throwable, Proposal>() {
             @Override
             public Proposal apply(Throwable throwable) throws Throwable {
               Logger.error("Failed to fetch keynote information", throwable);
               Proposal proposal = new Proposal();
               proposal.title = "COMING SOON!";
               proposal.content = "";
               Speaker speaker = new Speaker();
               speaker.name = "";
               speaker.pictureUrl = "";
               speaker.twitterId = "";
               proposal.speaker = speaker;
               return proposal;
             }
           },
           ctx);
 }
  public static void quotes() throws DOMException, InterruptedException, ExecutionException {
    Promise<HttpResponse> promise2 =
        WS.url("http://www.iheartquotes.com/api/v1/random?format=json").getAsync();
    Promise<HttpResponse> promise1 =
        WS.url("http://jamocreations.com/widgets/travel-quotes/get.php").getAsync();
    Map map = new HashMap<String, String>();

    // code here, preferably long running like db queries...
    List<HttpResponse> resps = Promise.waitAll(promise1, promise2).get();
    if (resps.get(0) != null) {
      map.put(
          "first",
          resps
              .get(0)
              .getXml()
              .getElementsByTagName("quote")
              .item(0)
              .getChildNodes()
              .item(1)
              .getTextContent());
    }
    if (resps.get(1) != null) {
      map.put("second", ((JsonObject) resps.get(1).getJson()).get("quote").getAsString());
    }
    renderJSON(map);
  }
Esempio n. 6
0
  public static Promise<Result> setNotificationResult(
      final String datasetId, final String notificationId) {
    final String[] resultString = request().body().asFormUrlEncoded().get("result");
    if (resultString == null || resultString.length != 1 || resultString[0] == null) {
      return Promise.pure((Result) redirect(controllers.routes.Datasets.show(datasetId)));
    }

    final ConfirmNotificationResult result = ConfirmNotificationResult.valueOf(resultString[0]);

    Logger.debug("Conform notification: " + notificationId + ", " + result);

    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    return from(database)
        .query(new PutNotificationResult(notificationId, result))
        .execute(
            new Function<Response<?>, Result>() {
              @Override
              public Result apply(final Response<?> response) throws Throwable {
                if (response.getOperationresponse().equals(CrudResponse.OK)) {
                  flash("success", "Resultaat van de structuurwijziging is opgeslagen");
                } else {
                  flash("danger", "Resultaat van de structuurwijziging kon niet worden opgeslagen");
                }
                return redirect(controllers.routes.Datasets.show(datasetId));
              }
            });
  }
  /**
   * Action Read a single model.
   *
   * @param leftId The id of the parent model.
   * @param rightId The id of the child model.
   * @param fields Fields to retrieve off the model. If not provided, retrieves all.
   * @param fetches Get any 1to1 relationships off the model. By default, it returns only the id off
   *     the relationships.
   * @return A promise containing the results
   */
  public Promise<Result> read(
      final Long leftId, final Long rightId, final String fields, final String fetches) {
    return Promise.promise(
        new Function0<Result>() {
          public Result apply() {
            L left = createLeftQuery(new ServiceParams()).where().eq("id", leftId).findUnique();
            if (left == null) {
              return CrudResults.notFoundError(leftClass, leftId);
            }

            ServiceParams rightParams = new ServiceParams(fields, fetches);
            ServiceParams params = new ServiceParams(fields, fetches, rightFieldName + ".");
            Query<J> query = createJunctionQuery(params);

            handleFieldsAndFetches(query, junctionClass, params);
            List<J> junctions = applyJunctionFiltering(leftId, rightId, query);
            List<R> rights = getChildObjects(junctions, rightParams);

            if (rights.size() == 0) {
              return CrudResults.notFoundError(getBaseModelClass(), rightId);
            }

            List<? extends Model> returnList = rights;
            return CrudResults.success(returnList.get(0));
          }
        });
  }
  /**
   * Implements a bulk delete method
   *
   * @param leftId The id of the parent object
   * @return
   */
  @play.db.ebean.Transactional
  public Promise<Result> deleteBulk(final Long leftId) {
    return Promise.promise(
        new Function0<Result>() {
          public Result apply() {
            L left = createLeftQuery(new ServiceParams()).where().eq("id", leftId).findUnique();
            if (left == null) {
              return CrudResults.notFoundError(leftClass, leftId);
            }

            List<Long> items = getItemsFromRequest();

            if (items != null) {
              // TODO: Ebean doesn't support deletes based off a where clause.
              // We should switch this to raw sql to reduce it to 1 db call instead of 2. V
              List<J> junks = applyJunctionFiltering(leftId, items, null);
              if (junks.size() == items.size()) {
                // modelMediator.beforeModelDelete(junks);
                Ebean.delete(junks);
                // modelMediator.afterModelDelete(junks);
                return noContent();
              } else {
                return CrudResults.notFoundError(junctionClass, "");
              }
            } else {
              return CrudResults.error("Array of objects with ids required");
            }
          }
        });
  }
  /**
   * Implements a delete method
   *
   * @param leftId The id of the parent model
   * @param rightId The id of the child model
   * @return
   */
  public Promise<Result> delete(final Long leftId, final Long rightId) {
    return Promise.promise(
        new Function0<Result>() {
          public Result apply() {
            L left = createLeftQuery(new ServiceParams()).where().eq("id", leftId).findUnique();
            if (left == null) {
              return CrudResults.notFoundError(leftClass, leftId);
            }

            List<? extends Model> junctions;

            junctions = applyJunctionFiltering(leftId, rightId, null);

            List<? extends Model> rights = getChildObjects(junctions, new ServiceParams());
            List<? extends Model> toDelete = junctions;

            if (rights.size() == 0) {
              return CrudResults.notFoundError(getBaseModelClass(), rightId);
            }
            // Can we not just do, createJunctionQuery().eq(leftId).eq(rightId).findList()?

            for (Model m : toDelete) {
              m.delete();
            }
            return noContent();
          }
        });
  }
 /**
  * Create a new SysAdminUtilsImpl
  *
  * @param lifecycle the play application lifecycle listener
  * @param configuration the play application configuration
  * @param databaseDependencyService the service which secure the availability of the database
  * @param actorSystem the Akka actor system
  */
 @Inject
 public SysAdminUtilsImpl(
     ApplicationLifecycle lifecycle,
     Configuration configuration,
     IDatabaseDependencyService databaseDependencyService,
     ActorSystem actorSystem) {
   log.info("SERVICE>>> SysAdminUtilsImpl starting...");
   this.actorSystem = actorSystem;
   this.configuration = configuration;
   initAutomatedSystemStatus();
   lifecycle.addStopHook(
       () -> {
         log.info("SERVICE>>> SysAdminUtilsImpl stopping...");
         if (automaticSystemStatus != null) {
           try {
             getAutomaticSystemStatus().cancel();
           } catch (Exception e) {
             log.error("Unable to stop the automatic system status", e);
           }
         }
         log.info("SERVICE>>> SysAdminUtilsImpl stopped");
         return Promise.pure(null);
       });
   log.info("SERVICE>>> SysAdminUtilsImpl started");
 }
  /**
   * Action Query a list of models.
   *
   * @param leftId The id of the parent model
   * @param offset An offset from the first item to start filtering from. Used for paging.
   * @param count The total count to query. This is the length of items to query after the offset.
   *     Used for paging.
   * @param orderBy Order the queried models in order by the given properties of the model.
   * @param fields The fields, or properties, of the models to retrieve.
   * @param fetches If the model has 1to1 relationships, use this to retrieve those relationships.
   *     By default, returns the id of each relationship.
   * @param queryString Filter the models with a comma-delimited query string in the format of
   *     "property:value".
   * @return A promise containing the results
   */
  public Promise<Result> list(
      final Long leftId,
      final Integer offset,
      final Integer count,
      final String orderBy,
      final String fields,
      final String fetches,
      final String queryString) {
    return Promise.promise(
        new Function0<Result>() {
          public Result apply() {
            L left = createLeftQuery(new ServiceParams()).where().eq("id", leftId).findUnique();
            if (left == null) {
              return CrudResults.notFoundError(leftClass, leftId);
            }

            ServiceParams rightParams =
                new ServiceParams(offset, count, orderBy, fields, fetches, queryString);
            ServiceParams params =
                new ServiceParams(
                    offset, count, orderBy, fields, fetches, queryString, rightFieldName + ".");

            Query<J> query = createJunctionQuery(params);

            // turn query into like statements, with everything or'd
            // ?q=name:%bri%,location:seattle%
            if (queryString != null) {
              handleSearchQuery(query, getJunctionClass(), params);
            }

            String appendedOrderBy = "";
            // ?orderBy=name asc
            if (orderBy != null && !orderBy.isEmpty()) {
              appendedOrderBy = formatOrderBy(params.orderBy, junctionClass);
              query.orderBy(appendedOrderBy);
            }

            handleFieldsAndFetches(query, junctionClass, params);

            query.where().eq(getTableName(leftClass, leftFieldName) + "_id", leftId);

            query.setFirstRow(offset);
            Integer actualCount =
                count == null
                    ? Play.application().configuration().getInt("crud.defaultCount")
                    : count;
            query.setMaxRows(actualCount == null ? 100 : count);

            if (count == null) {
              Logger.warn("No count specified on request: " + request().uri());
            }

            List<J> junctions = junctions = query.findList();
            return CrudResults.successCount(
                query.findRowCount(), junctions.size(), getChildObjects(junctions, rightParams));
          }
        });
  }
Esempio n. 12
0
 private static Result wrapScalaResult(
     scala.concurrent.Future<play.api.mvc.Result> result, long timeout) {
   if (result == null) {
     return null;
   } else {
     final play.api.mvc.Result scalaResult = Promise.wrap(result).get(timeout);
     return scalaResult.asJava();
   }
 }
Esempio n. 13
0
 public static <V> void waitFor(Future<V> task, final Invocation invocation) {
   if (task instanceof Promise) {
     Promise<V> smartFuture = (Promise<V>) task;
     smartFuture.onRedeem(
         new F.Action<F.Promise<V>>() {
           public void invoke(Promise<V> result) {
             executor.submit(invocation);
           }
         });
   } else {
     synchronized (WaitForTasksCompletion.class) {
       if (instance == null) {
         instance = new WaitForTasksCompletion();
         Logger.warn("Start WaitForTasksCompletion");
         instance.start();
       }
       instance.queue.put(task, invocation);
     }
   }
 }
Esempio n. 14
0
 public static JsonNode putAPI(String apiString, JsonNode jsonData) {
   Promise<WSResponse> responsePromise = WS.url(apiString).put(jsonData);
   final Promise<JsonNode> bodyPromise =
       responsePromise.map(
           new Function<WSResponse, JsonNode>() {
             public JsonNode apply(WSResponse response) throws Throwable {
               if ((response.getStatus() == 201 || response.getStatus() == 200)
                   && !response.getBody().contains("not")) {
                 return createResponse(ResponseType.SUCCESS);
               } else { // other response status from the server
                 return createResponse(ResponseType.SAVEERROR);
               }
             }
           });
   try {
     return bodyPromise.get(10000L);
   } catch (Exception e) {
     return createResponse(ResponseType.TIMEOUT);
   }
 }
 /**
  * Return the byte stream for the captcha image to be displayed.
  *
  * @param uuid the unique captcha id
  */
 public Promise<Result> getCaptchaImage(final String uuid) {
   return Promise.promise(
       new Function0<Result>() {
         @Override
         public Result apply() throws Throwable {
           String decodedUuid = new String(Base64.decodeBase64(uuid));
           response().setContentType("image/png");
           return ok(CaptchaManager.createCaptcha(decodedUuid));
         }
       });
 }
Esempio n. 16
0
 public Promise<Void> asyncSave() {
   return Promise.promise(
       new Function0<Void>() {
         @Override
         public Void apply() throws Throwable {
           save();
           return null;
         }
       },
       ctx);
 }
Esempio n. 17
0
  public static void checkJobStatus(int jobId) {
    Authentication.requireAdmin();

    // Check the status of the currently running job
    if (runningJob == null) {
      renderText("No job is currently running.");
    } else if (runningJob.isDone()) {
      try {
        // Return the message
        String message = runningJob.get().message;
        runningJob = null;
        renderText(message);
      } catch (InterruptedException e) {
        renderText("The job that was running has been halted.");
      } catch (ExecutionException e) {
        renderText("The job that was running has failed with an exception.");
      }
    } else {
      ok();
    }
  }
Esempio n. 18
0
 public static Promise<Proposal> selectRandomTalk() {
   return Promise.promise(
       new Function0<Proposal>() {
         @Override
         public Proposal apply() throws Throwable {
           // randomly select one if the first
           Long randomId = (long) (1 + Math.random() * (5 - 1));
           return Proposal.find.byId(randomId);
         }
       },
       ctx);
 }
Esempio n. 19
0
 public static JsonNode deleteAPI(String apiString) {
   Promise<WSResponse> responsePromise =
       WS.url(apiString.replace("+", "%20")).setContentType("text/html").delete();
   final Promise<JsonNode> bodyPromise =
       responsePromise.map(
           new Function<WSResponse, JsonNode>() {
             public JsonNode apply(WSResponse response) throws Throwable {
               if ((response.getStatus() == 200 || response.getStatus() == 201)
                   && !response.getBody().contains("not")) {
                 return createResponse(ResponseType.SUCCESS);
               } else { // no response from the server
                 return createResponse(ResponseType.DELETEERROR);
               }
             }
           });
   try {
     return bodyPromise.get(10000L);
   } catch (Exception e) {
     return createResponse(ResponseType.TIMEOUT);
   }
 }
Esempio n. 20
0
  public static JsonNode getAPI(String apiString) {
    Logger.info(apiString);
    Promise<WSResponse> responsePromise = WS.url(apiString).get();
    final Promise<JsonNode> bodyPromise =
        responsePromise.map(
            new Function<WSResponse, JsonNode>() {
              public JsonNode apply(WSResponse response) {
                if (response.getStatus() == 200 || response.getStatus() == 201) {
                  return response.asJson();
                } else { // no response from the server
                  Logger.info("" + response.getStatus());
                  return createResponse(ResponseType.GETERROR);
                }
              }
            });

    try {
      return bodyPromise.get(10000L);
    } catch (Exception e) {
      return createResponse(ResponseType.TIMEOUT);
    }
  }
Esempio n. 21
0
 public static Promise<Response> createCacheableUrlFetchPromise(
     String getUrl, Map<String, String> getParams) {
   final String key =
       "http-cache-" + getUrl + ":" + new TreeMap<String, String>(getParams).toString();
   final Response cached = (Response) Cache.get(key);
   if (cached == null) {
     WSRequestHolder holder = WS.url(getUrl);
     for (String k : getParams.keySet()) holder.setQueryParameter(k, getParams.get(k));
     Promise<Response> promise = holder.get();
     return promise.map(
         new Function<Response, Response>() {
           @Override
           public Response apply(Response res) throws Throwable {
             Cache.set(key, res);
             synchronized (cachedSet) {
               cachedSet.insert(key);
             }
             return res;
           }
         });
   } else {
     return Promise.pure(cached);
   }
 }
 /**
  * Gets a list of associations for the base model object
  *
  * @return
  */
 @Override
 public Promise<Result> associations(Long leftId) {
   return Promise.promise(
       new Function0<Result>() {
         public Result apply() {
           List<Class<? extends Model>> associations = new ArrayList<Class<? extends Model>>();
           associations.addAll(AssociationFinder.findClassAssociations(junctionClass));
           List<String> simpleAssociations = new ArrayList<String>();
           for (Class<? extends Model> assoc : associations) {
             simpleAssociations.add(assoc.getSimpleName());
           }
           return CrudResults.successCount(
               simpleAssociations.size(), simpleAssociations.size(), simpleAssociations);
         }
       });
 }
Esempio n. 23
0
  @Override
  public Promise<SimpleResult> call(Context ctx) throws Throwable {

    Promise<SimpleResult> ret = null;

    // redirect if it's not secure
    if (!isHttpsRequest(ctx.request())) {
      String url = redirectHostHttps(ctx) + ctx.request().uri();
      ret = Promise.pure(redirect(url));
    } else {
      // Let request proceed.
      ret = delegate.call(ctx);
    }

    return ret;
  }
  /**
   * Generates the error json required for ajax calls calls when the user is not authorized to
   * execute the action
   *
   * @return
   */
  protected static Promise<Result> notAuthorizedResult(Http.Context ctx) {
    Http.Request req = ctx.request();
    Result result;

    if (req.accepts("text/html")) {
      result = forbidden(notAuthorizedPage(ctx));
    } else if (req.accepts("application/json")) {
      ObjectNode node = Json.newObject();
      node.put("error", "Not authorized");
      result = forbidden(node);
    } else {
      result = forbidden("Not authorized");
    }

    return Promise.pure(result);
  }
  /**
   * Generates the error json required for ajax calls calls when the user is not authenticated
   *
   * @return
   */
  protected static Promise<Result> notAuthenticatedResult(Http.Context ctx) {
    Http.Request req = ctx.request();
    Result result;

    if (req.accepts("text/html")) {
      ctx.flash().put("error", play.i18n.Messages.get("securesocial.loginRequired"));
      ctx.session().put(ORIGINAL_URL, ctx.request().uri());
      result = redirect(env().routes().loginPageUrl(ctx._requestHeader()));
    } else if (req.accepts("application/json")) {
      ObjectNode node = Json.newObject();
      node.put("error", "Credentials required");
      result = unauthorized(node);
    } else {
      result = unauthorized("Credentials required");
    }
    return Promise.pure(result);
  }
  /**
   * Implements a update method
   *
   * @param leftId The id of the parent model
   * @param rightId The id of the child model
   * @return
   */
  @BodyParser.Of(BodyParser.Json.class)
  public Promise<Result> update(final Long leftId, final Long rightId) {
    return Promise.promise(
        new Function0<Result>() {
          public Result apply() {
            J model =
                createJunctionQuery(new ServiceParams())
                    .where()
                    .eq(getTableName(rightClass, rightFieldName) + "_id", rightId)
                    .eq(getTableName(leftClass, leftFieldName) + "_id", leftId)
                    .findUnique();

            // You can only update rights that we have a junction for
            if (model == null) {
              return CrudResults.notFoundError(junctionClass, "");
            }

            return ManyToManyCrudController.super.update(rightId).get(5000);
          }
        });
  }
Esempio n. 27
0
 public Promise<Result> onHandlerNotFound(RequestHeader request) {
   return Promise.<Result>pure(notFound(views.html.notFoundPage.render(request.uri())));
 }
  /**
   * When a StartJobMessage is received, the corresponding Job is extracted and the unprocessed
   * instances are sent and received one at a time to the solver. Every time a text annotation is
   * processed, JobProcessingActor notifies its parent, the MasterActor, of its progress.
   */
  @Override
  public void onReceive(Object message) throws Exception {
    if (message instanceof SetUpJobMessage) {
      ActorRef master = getSender();
      SetUpJobMessage jobInfo = (SetUpJobMessage) message;
      this.conf_id = jobInfo.getConf_id();
      this.record_id = jobInfo.getRecord_id();
      this.url = jobInfo.getUrl();
      LearnerSettings learnerSettings = jobInfo.getLearnerSettings();
      Job job = Core.setUpJob(conf_id, url, record_id);
      ClassificationTester eval = new ClassificationTester();
      Evaluator evaluator;
      String viewName;
      try {
        evaluator = Core.getEvaluator(conf_id);
        viewName = Core.getEvaluatorView(conf_id);
      } catch (Exception e) {
        master.tell(
            new StatusUpdate(0, 0, 0, record_id, eval, "Error receiving evaluator from database"),
            getSelf());
        Core.storeResultsOfRunInDatabase(eval, record_id, false);
        return;
      }
      if (job.getError() != null) {
        master.tell(new StatusUpdate(0, 0, 0, record_id, eval, job.getError()), getSelf());
        Core.storeResultsOfRunInDatabase(eval, record_id, false);
        return;
      }
      List<TextAnnotation> unprocessedInstances = job.getUnprocessedInstances();
      List<TextAnnotation> goldInstances = job.getGoldInstances();
      completed = 0;
      skipped = 0;
      total = unprocessedInstances.size();
      master.tell(new StatusUpdate(completed, skipped, total, record_id, eval, null), getSelf());

      System.out.println("Created Job Processor Worker");
      System.out.println("Sending and recieving annotations:");
      try {
        int maxBatchSize = learnerSettings.maxNumInstancesAccepted;
        for (int startIndex = 0;
            startIndex < unprocessedInstances.size();
            startIndex += maxBatchSize) {
          int batchSize = Math.min(maxBatchSize, unprocessedInstances.size() - startIndex);
          List<TextAnnotation> batch = makeBatch(unprocessedInstances, startIndex, batchSize);
          Promise<LearnerInstancesResponse> response = job.sendAndReceiveRequestsFromSolver(batch);

          int batchStartIndex = startIndex;
          response.onRedeem(
              new F.Callback<LearnerInstancesResponse>() {
                @Override
                public void invoke(LearnerInstancesResponse learnerInstancesResponse)
                    throws Throwable {
                  for (int batchIndex = 0; batchIndex < batchSize; batchIndex++) {
                    if (learnerInstancesResponse.textAnnotations[batchIndex] != null) {
                      TextAnnotation goldInstance = goldInstances.get(batchStartIndex + batchIndex);
                      try {
                        Core.evaluate(
                            evaluator,
                            eval,
                            goldInstance,
                            learnerInstancesResponse.textAnnotations[batchIndex],
                            viewName);
                      } catch (Exception e) {
                        Core.storeResultsOfRunInDatabase(eval, record_id, false);
                        master.tell(
                            new StatusUpdate(
                                completed,
                                skipped,
                                total,
                                record_id,
                                eval,
                                "Error in evaluator. Please check your returned View: " + viewName),
                            getSelf());
                        master.tell(new StopRunMessage(record_id), master);
                        return;
                      }
                      completed++;
                    } else {
                      skipped++;
                    }
                  }

                  if (completed + skipped < total)
                    Core.storeResultsOfRunInDatabase(eval, record_id, true);
                  else Core.storeResultsOfRunInDatabase(eval, record_id, false);

                  master.tell(
                      new StatusUpdate(completed, skipped, total, record_id, eval, null),
                      getSelf());
                  System.out.println(String.format("Completed batch of size %s", batchSize));
                }
              });
          response.get(learnerTimeout);
          if (killCommandHasBeenSent()) {
            System.out.println("Exiting");
            Core.storeResultsOfRunInDatabase(eval, record_id, false);
            break;
          }
        }
      } catch (Exception ex) {
        System.out.println("Err sending and receiving text annotations" + ex.getMessage());
        master.tell(
            new StatusUpdate(
                completed,
                skipped,
                total,
                record_id,
                eval,
                "Error receiving and sending text annotations"),
            getSelf());
        Core.storeResultsOfRunInDatabase(eval, record_id, false);
        ex.printStackTrace();
      }
      System.out.println("Done");
    } else unhandled(message);
  }
  /**
   * Create a new entity with the json body of the request. If the body is an array, it will bulk
   * create.
   *
   * @param leftId The id of the parent object
   * @return Result object with the created entities
   */
  @BodyParser.Of(BodyParser.Json.class)
  public Promise<Result> create(final Long leftId) {
    return Promise.promise(
        new Function0<Result>() {
          public Result apply() {
            L left = createLeftQuery(new ServiceParams()).where().eq("id", leftId).findUnique();
            if (left == null) {
              return CrudResults.notFoundError(leftClass, leftId);
            }

            List<R> rightList = new ArrayList<R>();
            List<J> junctionList = new ArrayList<J>();

            // if id is sent get existing model, otherwise create it
            JsonNode reqBody = request().body().asJson();
            JsonNode array;

            // convert the request into an array if it's not. Reduces logic.
            if (!reqBody.isArray()) {
              ArrayNode a = new ArrayNode(JsonNodeFactory.instance);
              a.add(reqBody);
              array = a;
            } else {
              array = reqBody;
            }

            for (final JsonNode node : array) {
              JsonNode rightNode = node;
              R right;
              if (rightNode != null) {
                JsonNode idNode = rightNode.get("id");
                if (idNode != null && !idNode.asText().equals("null")) {
                  Long rightId = idNode.asLong(); // TODO: Slow
                  right = createQuery(new ServiceParams()).where().eq("id", rightId).findUnique();
                  if (right != null) {
                    rightList.add(right);
                  } else {
                    return CrudResults.notFoundError(getBaseModelClass(), rightId);
                  }
                } else {
                  right = Json.fromJson(rightNode, getBaseModelClass());
                  ResultOrValue<R> rov = isModelValid(right);
                  if (rov.result != null) {
                    return rov.result;
                  } else {
                    rightList.add(right);
                  }
                }
              } else {
                return CrudResults.error("No right object found on junction.");
              }
            }

            for (R right : rightList) {
              // save junction - this can be cleaned up
              J junction = null;
              try {
                Constructor<J> ctor = junctionClass.getConstructor();
                junction = ctor.newInstance();
              } catch (NoSuchMethodException e) {
                e.printStackTrace();
              } catch (InstantiationException e) {
                e.printStackTrace();
              } catch (IllegalAccessException e) {
                e.printStackTrace();
              } catch (InvocationTargetException e) {
                e.printStackTrace();
              }

              setSubObject(junction, left, leftFieldName);
              setSubObject(junction, right, rightFieldName);
              junctionList.add(junction);
            }

            Ebean.save(rightList);
            Ebean.save(junctionList);

            // return an array if the request was originally an array
            List<? extends Model> returnList = rightList;
            if (reqBody.isArray()) {
              return CrudResults.successCreate(returnList);
            } else {
              return CrudResults.successCreate(returnList.get(0));
            }
          }
        });
  }