Esempio n. 1
0
  @Override
  public void onStart(Application application) {

    tweetUrl = Play.application().configuration().getString("tweet.url");
    sentimentUrl = Play.application().configuration().getString("sentiment.url");

    if ((sentimentUrl == null) || (tweetUrl == null)) {
      throw new RuntimeException("Both sentiment.url and tweet.url configs must be specified");
    }

    usersActor = Akka.system().actorOf(new Props(UsersActor.class), "users");

    stockHolderActor = Akka.system().actorOf(new Props(StockHolderActor.class), "stocks");

    // fetch a new data point once every second
    Akka.system()
        .scheduler()
        .schedule(
            Duration.Zero(),
            Duration.create(50, TimeUnit.MILLISECONDS),
            stockHolderActor,
            FetchLatest.instance(),
            Akka.system().dispatcher());

    super.onStart(application);
  }
Esempio n. 2
0
  public static Promise<Result> editForm(final String datasetId) {
    // TODO
    Logger.debug("editForm");

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

    return from(database)
        .get(Dataset.class, datasetId)
        .query(listDatasetColumns(datasetId))
        .executeFlat(
            new Function2<Dataset, List<Column>, Promise<Result>>() {
              @Override
              public Promise<Result> apply(final Dataset ds, final List<Column> columns)
                  throws Throwable {
                return from(database)
                    .get(SourceDataset.class, ds.sourceDataset().id())
                    .executeFlat(
                        new Function<SourceDataset, Promise<Result>>() {
                          @Override
                          public Promise<Result> apply(final SourceDataset sds) throws Throwable {
                            final Form<DatasetForm> datasetForm =
                                Form.form(DatasetForm.class)
                                    .fill(new DatasetForm(ds, sds.dataSource().id(), columns));

                            Logger.debug("Edit datasetForm: " + datasetForm);
                            return renderEditForm(datasetForm);
                          }
                        });
              }
            });
    //		return Promise.pure ((Result) ok ());
  }
Esempio n. 3
0
  @Override
  public void onStart(Application app) {
    if (Play.application().configuration().getString("app.envirement").equals("dev")) {
      AppConfig.setupDevEnv();
    } else if (Play.application().configuration().getString("app.envirement").equals("test")) {
      AppConfig.setupTestEnv();
    } else if (Play.application().configuration().getString("app.envirement").equals("prod")) {
      AppConfig.setupProdEnv();
    }

    play.libs.Akka.system()
        .scheduler()
        .schedule(
            Duration.create(0, TimeUnit.MILLISECONDS),
            Duration.create(1, TimeUnit.DAYS),
            new Runnable() {
              public void run() {
                System.out.println("tick");
                File dir = new File(AppConfig.temporaryFilesDirectory);
                for (String fname : dir.list()) {
                  if (fname.equals(".") || fname.equals("..")) continue;
                  File tmp = new File(AppConfig.temporaryFilesDirectory + fname);
                  if (tmp.exists()
                      && tmp.isFile()
                      && (new Date().getTime() - tmp.lastModified()) > (30L * 86400L * 1000L)) {
                    tmp.delete();
                  }
                }
              }
            });

    super.onStart(app);
  }
Esempio n. 4
0
  public static Promise<Result> scheduleRefresh(String datasetId) {

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

    return from(database)
        .query(new RefreshDataset(datasetId))
        .execute(
            new Function<Boolean, Result>() {

              @Override
              public Result apply(Boolean b) throws Throwable {
                final ObjectNode result = Json.newObject();

                if (b) {
                  result.put("result", "ok");

                  return ok(result);
                } else {
                  result.put("result", "failed");

                  return internalServerError(result);
                }
              }
            });
  }
Esempio n. 5
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));
              }
            });
  }
Esempio n. 6
0
  public static Promise<Result> getDatasetJson(final String datasetId) {
    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    Logger.debug("getDatasetJson: " + datasetId);

    return from(database)
        .get(Dataset.class, datasetId)
        .execute(
            new Function<Dataset, Result>() {
              @Override
              public Result apply(final Dataset ds) throws Throwable {
                final ObjectNode result = Json.newObject();

                result.put("id", datasetId);

                if (ds == null) {
                  result.put("status", "notfound");
                  return ok(result);
                }

                result.put("status", "ok");
                result.put("dataset", Json.toJson(ds));

                return ok(result);
              }
            });
  }
 @Before
 public void setup() {
   super.setup();
   final Props props = Props.create(MockActor.class, new Object());
   final TestActorRef<TestActor> ref = TestActorRef.create(Akka.system(), props);
   testRef = ref;
   socketManager = new SocketManagerImpl();
 }
Esempio n. 8
0
  @Override
  public void onStart(Application app) {
    Logger.info("Global - onStart");
    super.onStart(app);
    /*
     * Sets the schedule for cleaning the media temp directory
     */
    Akka.system()
        .scheduler()
        .schedule(
            Duration.create(0, TimeUnit.MILLISECONDS),
            Duration.create(30, TimeUnit.MINUTES),
            new Runnable() {
              public void run() {
                MediaController.cleanUpTemp();
              }
            },
            Akka.system().dispatcher());

    InitialData.insert(app);
  }
Esempio n. 9
0
 @SuppressWarnings("serial")
 @Override
 public ActorRef get() {
   return Akka.system()
       .actorOf(
           new Props(
               new UntypedActorFactory() {
                 public T create() {
                   return injector.getInstance(Key.get(uta));
                 }
               }));
 }
  public void afterPropertiesSet() {
    final String configFile = System.getProperty("configFile");

    final String wsRequestPath = kikuyuLayoutWebserviceAddress + URL_MAPPINGS;

    Akka.system()
        .scheduler()
        .schedule(
            Duration.Zero(),
            Duration.create(reloadUrlMappingsFreqSecs, TimeUnit.SECONDS),
            new Runnable() {
              @Override
              public void run() {
                if (configFile == null) {
                  loadUrlMappingsFromWS(wsRequestPath);
                } else {
                  loadUrlMappingsFromFile(configFile);
                }
              }
            },
            Akka.system().dispatcher());
  }
Esempio n. 11
0
  public static Promise<Result> status(final String datasetId) {
    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    return from(database)
        .get(Dataset.class, datasetId)
        .execute(
            new Function<Dataset, Result>() {

              @Override
              public Result apply(final Dataset dataset) throws Throwable {
                return ok(status.render(dataset));
              }
            });
  }
Esempio n. 12
0
  /**
   * OnStart Event
   *
   * @param application
   */
  @Override
  public void onStart(Application application) {
    Akka.system()
        .scheduler()
        .schedule(
            Duration.create(0, TimeUnit.MILLISECONDS),
            Duration.create(10, TimeUnit.SECONDS),
            () -> {
              long start = System.currentTimeMillis();

              convertPictures();
              sendMails();

              long time = System.currentTimeMillis() - start;
              if (time > 1000) {
                CustomLogger.warn("Fast-Cron: " + time + "ms");
              }
            },
            Akka.system().dispatcher());
    Akka.system()
        .scheduler()
        .schedule(
            Duration.create(0, TimeUnit.MILLISECONDS),
            Duration.create(30, TimeUnit.MINUTES),
            () -> {
              long start = System.currentTimeMillis();

              deleteOldMails();
              deleteOldApiKeys();

              long time = System.currentTimeMillis() - start;
              if (time > 1000) {
                CustomLogger.warn("Slow-Cron: " + time + "ms");
              }
            },
            Akka.system().dispatcher());
  }
Esempio n. 13
0
public class Agents extends Controller {

  private static final Settings settings = SettingsProvider.SettingsProvider.get(Akka.system());
  private static final ObjectMapper mapper = new ObjectMapper();

  static {
    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"));
    mapper.configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true);
    mapper.setPropertyNamingStrategy(
        PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
  }

  public static Result index() {
    ActorRef scheduler = OnCueService.system().actorFor(settings.SCHEDULER_PATH);
    return async(
        Akka.asPromise(
                ask(scheduler, SimpleMessage.LIST_AGENTS, new Timeout(settings.SCHEDULER_TIMEOUT))
                    .recover(
                        new Recover<Object>() {
                          @Override
                          public Object recover(Throwable t) {
                            if (t instanceof AskTimeoutException) {
                              Logger.error(
                                  "Timeout waiting for scheduler to respond with the list of agents",
                                  t);
                              return internalServerError("Timeout");
                            } else {
                              Logger.error("Failed to request registered agents from scheduler", t);
                              return internalServerError(
                                  "Failed to request registered agents from scheduler");
                            }
                          }
                        },
                        OnCueService.system().dispatcher()))
            .map(
                new Function<Object, Result>() {
                  @Override
                  public Result apply(Object response) {
                    if (response instanceof Result) {
                      // Result objects are returned by the recover handler above
                      return (Result) response;
                    } else {
                      AgentSummary agentSummary = (AgentSummary) response;
                      return ok(mapper.valueToTree(agentSummary.getAgents()));
                    }
                  }
                }));
  }
}
Esempio n. 14
0
  public static Promise<Result> listColumnsAction(
      final String dataSourceId, final String sourceDatasetId) {

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

    return from(database)
        .query(new ListSourceDatasetColumns(dataSourceId, sourceDatasetId))
        .execute(
            new Function<List<Column>, Result>() {

              @Override
              public Result apply(List<Column> c) throws Throwable {
                return ok(columns.render(c, null, false));
              }
            });
  }
Esempio n. 15
0
  public static Promise<Result> show(final String datasetId) {
    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    return from(database)
        .get(Dataset.class, datasetId)
        .query(new ListDatasetColumnDiff(datasetId))
        .execute(
            new Function2<Dataset, List<ColumnDiff>, Result>() {

              @Override
              public Result apply(final Dataset dataset, final List<ColumnDiff> diffs)
                  throws Throwable {
                return ok(show.render(dataset, diffs));
              }
            });
  }
Esempio n. 16
0
  public static Promise<Result> get(String symbol) {
    ActorRef stockSentimentActor =
        ActorManagerExtension.ActorManagerExtensionProvider.get(Akka.system())
            .getStockSentimentProxy();
    Future<Object> futureStockSentiments =
        Patterns.ask(stockSentimentActor, new StockSentimentActor.GetSentiment(symbol), timeout);
    Promise<Object> promiseSentiments = Promise.wrap(futureStockSentiments);

    return promiseSentiments
        .<Result>map(
            obj -> {
              StockSentimentActor.SendSentiment sendSentiment =
                  (StockSentimentActor.SendSentiment) obj;
              return Results.ok(sendSentiment.getSentiment());
            })
        .recover(StockSentiment::errorResponse);
  }
Esempio n. 17
0
  private static Promise<Result> renderEditForm(final Form<DatasetForm> datasetForm) {
    // TODO
    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    return from(database)
        .list(DataSource.class)
        .list(Category.class)
        .query(
            listSourceDatasets(
                datasetForm.field("dataSourceId").value(), datasetForm.field("categoryId").value()))
        //			.query (listDatasetColumns (datasetForm.field ("id").value ()))
        .query(
            listSourceDatasetColumns(
                datasetForm.field("dataSourceId").value(),
                datasetForm.field("sourceDatasetId").value()))
        .execute(
            new Function4<
                Page<DataSource>,
                Page<Category>,
                Page<SourceDatasetStats>,
                List<Column>,
                Result>() {
              @Override
              public Result apply(
                  Page<DataSource> dataSources,
                  Page<Category> categories,
                  final Page<SourceDatasetStats> sourceDatasets,
                  final List<Column> columns)
                  throws Throwable {
                Logger.debug(
                    "Edit form: #datasources="
                        + dataSources.pageCount()
                        + ", #categories="
                        + categories.pageCount()
                        + ", #sourcedatasets="
                        + sourceDatasets.pageCount()
                        + ", #columns: "
                        + columns.size());
                return ok(
                    form.render(
                        dataSources, categories, sourceDatasets, columns, datasetForm, false));
              }
            });
  }
Esempio n. 18
0
  public static Promise<Result> delete(final String datasetId) {
    System.out.println("delete dataset " + datasetId);
    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    from(database)
        .delete(Dataset.class, datasetId)
        .execute(
            new Function<Response<?>, Result>() {

              @Override
              public Result apply(Response<?> a) throws Throwable {
                // TODO Auto-generated method stub
                System.out.println("apply delete: " + a);
                return null;
              }
            });

    return list(1);
  }
Esempio n. 19
0
 public static Result asyncResult() {
   return async(
       Akka.future(
               new Callable<String>() {
                 @Override
                 public String call() {
                   return "success";
                 }
               })
           .map(
               new Function<String, Result>() {
                 @Override
                 public Result apply(String a) {
                   response().setHeader("header_test", "header_val");
                   response().setCookie("cookie_test", "cookie_val");
                   session("session_test", "session_val");
                   flash("flash_test", "flash_val");
                   return ok(a);
                 };
               }));
 }
Esempio n. 20
0
  public static Promise<Result> listByCategoryAndMessages(
      final String categoryId, final boolean listWithMessages, final long page) {
    // Hack: force the database actor to be loaded:
    if (Database.instance == null) {
      throw new NullPointerException();
    }

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

    return from(database)
        .list(Category.class)
        .get(Category.class, categoryId)
        .executeFlat(
            new Function2<Page<Category>, Category, Promise<Result>>() {
              @Override
              public Promise<Result> apply(
                  final Page<Category> categories, final Category currentCategory)
                  throws Throwable {

                return from(database)
                    .query(new ListDatasets(currentCategory, page))
                    .execute(
                        new Function<Page<Dataset>, Result>() {
                          @Override
                          public Result apply(final Page<Dataset> datasets) throws Throwable {

                            //									return ok (list.render (listWithMessages));
                            return ok(
                                list.render(
                                    datasets,
                                    categories.values(),
                                    currentCategory,
                                    listWithMessages));
                          }
                        });
              }
            });
  }
Esempio n. 21
0
 public static Result index() {
   ActorRef scheduler = OnCueService.system().actorFor(settings.SCHEDULER_PATH);
   return async(
       Akka.asPromise(
               ask(scheduler, SimpleMessage.LIST_AGENTS, new Timeout(settings.SCHEDULER_TIMEOUT))
                   .recover(
                       new Recover<Object>() {
                         @Override
                         public Object recover(Throwable t) {
                           if (t instanceof AskTimeoutException) {
                             Logger.error(
                                 "Timeout waiting for scheduler to respond with the list of agents",
                                 t);
                             return internalServerError("Timeout");
                           } else {
                             Logger.error("Failed to request registered agents from scheduler", t);
                             return internalServerError(
                                 "Failed to request registered agents from scheduler");
                           }
                         }
                       },
                       OnCueService.system().dispatcher()))
           .map(
               new Function<Object, Result>() {
                 @Override
                 public Result apply(Object response) {
                   if (response instanceof Result) {
                     // Result objects are returned by the recover handler above
                     return (Result) response;
                   } else {
                     AgentSummary agentSummary = (AgentSummary) response;
                     return ok(mapper.valueToTree(agentSummary.getAgents()));
                   }
                 }
               }));
 }
Esempio n. 22
0
  public static Promise<Result> createFormForSourceDataset(final String sourceDatasetId) {
    final ActorSelection database = Akka.system().actorSelection(databaseRef);

    return from(database)
        .get(SourceDataset.class, sourceDatasetId)
        .executeFlat(
            new Function<SourceDataset, Promise<Result>>() {
              @Override
              public Promise<Result> apply(final SourceDataset sourceDataset) throws Throwable {
                if (sourceDataset == null) {
                  return Promise.pure((Result) notFound());
                }

                final DatasetForm form = new DatasetForm();

                form.setName(sourceDataset.name());
                form.setSourceDatasetId(sourceDatasetId);
                form.setDataSourceId(sourceDataset.dataSource().id());
                form.setCategoryId(sourceDataset.category().id());

                return renderCreateForm(Form.form(DatasetForm.class).fill(form));
              }
            });
  }
Esempio n. 23
0
 public static void InitializeInjector(Injector injector, String... namespaces) {
   Logger.debug("Initialize Injector");
   GuiceProvider.get(Akka.system()).initialize(injector);
   ActorScanner.ScheduleActors(namespaces);
   ActorScanner.ScheduleOnceActors(namespaces);
 }
Esempio n. 24
0
  public void onStart(Application app) {

    Logger.info("Application started");
    String uploadPath = Configuration.getUploadPath();
    File file = new File(uploadPath);
    if (!file.exists()) {
      try {
        if (!file.mkdir()) {
          System.out.println(file.getAbsolutePath());
        }
        ;
      } catch (Exception e) {
        e.printStackTrace();
        System.out.println(
            "Error while creating directory for server files, please check 'uploadPath' value in application.conf file");
        System.exit(-1);
      }
    } else {
      if (!file.canRead() || !file.canWrite()) {
        System.out.println(
            "Error: Server have no read and write access to "
                + uploadPath
                + ", please check 'uploadPath' value in application.conf file");
        System.exit(-1);
      }
    }

    // Checking existence of main directory
    String usersFilesDir = Configuration.getUploadPath();
    File applicationDir = new File(usersFilesDir + "/users/");
    if (!applicationDir.exists()) {
      Boolean createAppDir = applicationDir.mkdir();
      if (!createAppDir) {
        Logger.warn("Error while creating users directory");
        System.exit(-1);
      } else {
        Logger.info("Users directory created");
      }
    }

    if (Configuration.isApplyNewLimits()) {
      for (Account account : Account.findAll()) {
        account.setNewLimits();
      }
    }

    if (Configuration.isCreateDefaultUsers()) {
      UserService userService = new UserService(app);
      try {
        Integer nDefault = Configuration.getnDefaultUsers();
        String nameDefault = Configuration.getNameDefaultUser();
        for (int i = 1; i <= nDefault; i++) {
          String username = nameDefault + Integer.toString(i);
          String email = username + "@vdjviz.com";
          LocalUser localUser = LocalUser.find.byId(email);
          if (localUser == null) {
            Option<PasswordHasher> bcrypt = Registry.hashers().get("bcrypt");
            SocialUser socialUser =
                new SocialUser(
                    new IdentityId(email, "userpass"),
                    username,
                    username,
                    String.format("%s %s", username, username),
                    Option.apply(email),
                    null,
                    AuthenticationMethod.UserPassword(),
                    null,
                    null,
                    Some.apply(
                        new PasswordInfo(
                            "bcrypt", BCrypt.hashpw(username, BCrypt.gensalt()), null)));
            userService.doSave(socialUser);
          }
        }
      } catch (RuntimeException e) {
        Logger.error("Error while creating default users");
        e.printStackTrace();
      }
    }

    // Deleting empty files
    for (Account account : Account.findAll()) {
      for (UserFile userFile : account.getUserfiles()) {
        File fileDir = new File(userFile.getDirectoryPath());
        if (!fileDir.exists() || !userFile.checkExist()) {
          UserFile.deleteFile(userFile);
          Logger.of("user." + account.getUserName())
              .warn(
                  "Deleted empty file "
                      + userFile.getFileName()
                      + " for user : "******"user." + account.getUserName())
                              .info("File " + userFile.getFileName() + " was deleted");
                        }
                      }
                    }
                  }
                }
              },
              Akka.system().dispatcher());
    }
  }
Esempio n. 25
0
  public static Promise<Result> submitEdit(final String datasetId) {
    Logger.debug("submitEdit");

    final ActorSelection database = Akka.system().actorSelection(databaseRef);
    final Form<DatasetForm> datasetForm = Form.form(DatasetForm.class).bindFromRequest();

    if (datasetForm.hasErrors()) {
      return renderEditForm(datasetForm);
    }

    final DatasetForm dataset = datasetForm.get();

    return from(database)
        .get(DataSource.class, dataset.getDataSourceId())
        .get(Category.class, dataset.getCategoryId())
        .get(SourceDataset.class, dataset.getSourceDatasetId())
        .query(
            new ListSourceDatasetColumns(dataset.getDataSourceId(), dataset.getSourceDatasetId()))
        .executeFlat(
            new Function4<DataSource, Category, SourceDataset, List<Column>, Promise<Result>>() {
              @Override
              public Promise<Result> apply(
                  final DataSource dataSource,
                  final Category category,
                  final SourceDataset sourceDataset,
                  final List<Column> sourceColumns)
                  throws Throwable {
                Logger.debug("dataSource: " + dataSource);
                Logger.debug("category: " + category);
                Logger.debug("sourceDataset: " + sourceDataset);

                // TODO: Validate dataSource, category, sourceDataset!

                // Validate the columns used by the filter:
                if (!dataset.getFilterConditions().isValid(sourceColumns)) {
                  datasetForm.reject(
                      new ValidationError("filterConditions", "Het opgegeven filter is ongeldig"));
                  return renderEditForm(datasetForm);
                }

                // Create the list of selected columns:
                final List<Column> columns = new ArrayList<>();
                for (final Column column : sourceColumns) {
                  if (dataset.getColumns().containsKey(column.getName())) {
                    columns.add(column);
                  }
                }

                final PutDataset putDataset =
                    new PutDataset(
                        CrudOperation.UPDATE,
                        dataset.getId(),
                        dataset.getName(),
                        sourceDataset.id(),
                        columns,
                        dataset.getFilterConditions());

                Logger.debug("update dataset " + putDataset);

                return from(database)
                    .put(putDataset)
                    .executeFlat(
                        new Function<Response<?>, Promise<Result>>() {
                          @Override
                          public Promise<Result> apply(final Response<?> response)
                              throws Throwable {
                            if (CrudResponse.NOK.equals(response.getOperationresponse())) {
                              datasetForm.reject(
                                  "dataset kon niet worden geupdate: " + dataset.getName());
                              return renderEditForm(datasetForm);
                            }

                            flash("success", "Dataset " + dataset.getName() + " is aangepast.");

                            return Promise.pure(redirect(routes.Datasets.list(0)));
                          }
                        });
              }
            });
  }
Esempio n. 26
0
/** Created by kareypowell on 5/31/14. */
@Entity
public class Proposal extends Model {

  @Id public Long id;

  @Required public String title;

  @Required
  @MinLength(value = 10)
  @MaxLength(value = 1000)
  @Column(length = 1000)
  public String content;

  @Required public SessionType type = SessionType.OneHourTalk;

  @Required public Boolean isApproved = false;

  public String keywords;

  @Valid
  @OneToOne(cascade = CascadeType.ALL)
  public Speaker speaker;

  public DateTime createdAt = new DateTime();

  public DateTime updatedAt = new DateTime();

  private static Finder<Long, Proposal> find =
      new Finder<Long, Proposal>(Long.class, Proposal.class);

  private static ExecutionContext ctx = Akka.system().dispatchers().lookup("akka.db-dispatcher");

  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 Promise<Void> asyncSave() {
    return Promise.promise(
        new Function0<Void>() {
          @Override
          public Void apply() throws Throwable {
            save();
            return null;
          }
        },
        ctx);
  }

  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);
  }
}