@ApiOperation(value = "Add data-source", authorizations = @Authorization(value = "master_key")) @Path("/add/database") @JsonRequest public SuccessMessage addDatabase(@Named("project") RequestContext context, @BodyParam CustomDataSource hook) { return service.addDatabase(context.project, hook); }
@ApiOperation(value = "Test database", authorizations = @Authorization(value = "master_key")) @Path("/test/file") @JsonRequest public SuccessMessage testFile(@Named("project") RequestContext context, @BodyParam CustomDataSourceService.DiscoverableRemoteTable hook) { return service.testFile(context.project, hook); } }
@JsonRequest @ApiOperation(value = "Update report", authorizations = @Authorization(value = "master_key")) @Path("/update") public ABTestingReport update(@Named("project") RequestContext context, @BodyParam ABTestingReport report) { return metadata.update(context.project, report); } }
@ApiOperation(value = "Create Pre-computed table", authorizations = @Authorization(value = "master_key") ) @JsonRequest @Path("/pre_calculate") public CompletableFuture<AbstractEventExplorer.PrecalculatedTable> createPrecomputedTable(@Named("project") RequestContext context, @BodyParam OLAPTable table) { return eventExplorer.create(context, table); }
@ApiOperation(value = "Create Report", authorizations = @Authorization(value = "read_key")) @Path("/create") @POST @ProtectEndpoint(writeOperation = true) public SuccessMessage create(@Named("user_id") Project project, @BodyParam Report report) { metadata.save(project.userId, project.project, report); return SuccessMessage.success(); }
@Path("/save") @POST @JsonRequest @ProtectEndpoint(writeOperation = true) @ApiOperation(value = "Save Report", authorizations = @Authorization(value = "read_key"), response = SuccessMessage.class, request = CustomPageDatabase.Page.class) public SuccessMessage save( @Named("user_id") UIPermissionParameterProvider.Project project, @BodyParam CustomPageDatabase.Page report) { database.get().save(project.userId, project.project, report); return SuccessMessage.success(); }
@ApiOperation(value = "Add scenario", authorizations = @Authorization(value = "master_key") ) @JsonRequest @Path("/add") public SuccessMessage addRule(@Named("project") RequestContext context, @BodyParam AutomationRule rule) { service.add(context.project, rule); return SuccessMessage.success(); }
@JsonRequest @ApiOperation(value = "Create test", authorizations = @Authorization(value = "master_key")) @Path("/create") public SuccessMessage create(@Named("project") RequestContext context, @BodyParam ABTestingReport report) { metadata.save(context.project, report); return SuccessMessage.success(); }
@ApiOperation(value = "Get project stats") @JsonRequest @Path("/stats") public Map<String, Metastore.Stats> getStats(@BodyParam List<String> apiKeys) { Map<String, String> keys = new LinkedHashMap<>(); for (String apiKey : apiKeys) { String project; try { project = apiKeyService.getProjectOfApiKey(apiKey, READ_KEY); } catch (RakamException e) { if (e.getStatusCode() == FORBIDDEN) { continue; } throw e; } keys.put(project, apiKey); } Map<String, Metastore.Stats> stats = metastore.getStats(keys.keySet()); if (stats == null) { return ImmutableMap.of(); } return stats.entrySet().stream() .collect(Collectors.toMap(e -> keys.get(e.getKey()), e -> e.getValue())); }
@ApiOperation(value = "Perform simple query on event data", authorizations = @Authorization(value = "read_key") ) @JsonRequest @Path("/analyze") public CompletableFuture<QueryResult> analyzeEvents(@Named("project") RequestContext context, @QueryParam("read_key") String readKey, @BodyParam AnalyzeRequest analyzeRequest) { checkArgument(!analyzeRequest.collections.isEmpty(), "collections array is empty"); return eventExplorer.analyze(context, analyzeRequest.collections, analyzeRequest.measure, analyzeRequest.grouping, analyzeRequest.segment, analyzeRequest.filterExpression, analyzeRequest.startDate, analyzeRequest.endDate, Optional.ofNullable(analyzeRequest.timezone).orElse(ZoneOffset.UTC)).getResult(); }
@ApiOperation(value = "Update report", authorizations = @Authorization(value = "read_key")) @POST @Path("/update") @JsonRequest @ProtectEndpoint(writeOperation = true) public SuccessMessage update(@Named("user_id") Project project, @BodyParam Report report) { metadata.update(project.userId, project.project, report); return SuccessMessage.success(); } }
/** * Creates a new materialized view for specified SQL query. * materialized views allow you to execute batch queries over the data-set. * Rakam caches the materialized view result and serve the cached data when you request. * You can also trigger an update using using '/view/update' endpoint. * This feature is similar to MATERIALIZED VIEWS in RDBMSs. * <p> * curl 'http://localhost:9999/materialized-view/create' -H 'Content-Type: text/event-stream;charset=UTF-8' --data-binary '{"project": "projectId", "name": "Yearly Visits", "query": "SELECT year(time), count(1) from visits GROUP BY 1"}' * * @param query materialized view query * @return the status */ @JsonRequest @ApiOperation(value = "Create view", authorizations = @Authorization(value = "master_key")) @Path("/create") public CompletableFuture<SuccessMessage> createView(@Named("project") RequestContext context, @BodyParam MaterializedView query) { return service.create(context, query).thenApply(res -> SuccessMessage.success()); }
@ApiOperation(value = "Create reports", tags = "rakam-ui", authorizations = @Authorization(value = "read_key"), response = SuccessMessage.class, request = CustomReport.class) @JsonRequest @ProtectEndpoint(writeOperation = true) @Path("/create") public SuccessMessage create(@Named("user_id") Project project, @BodyParam CustomReport report) { metadata.save(project.userId, project.project, report); return SuccessMessage.success(); }
@JsonRequest @ApiOperation(value = "Update project configurations") @Path("/project-configuration") public SuccessMessage updateProjectPreferences(@Named("user_id") Project project, @BodyParam ProjectConfiguration configuration) { if (!service.hasMasterAccess(project.project, project.userId)) { throw new RakamException("You don't have master access", UNAUTHORIZED); } service.updateProjectConfigurations(project.project, configuration); return SuccessMessage.success(); }
/** * Creates real-time report using continuous queries. * This module adds a new attribute called 'time' to events, it's simply a unix epoch that represents the seconds the event is occurred. * Continuous query continuously aggregates 'time' column and * real-time module executes queries on continuous query table similar to 'select count from stream_count where time > now() - interval 5 second' * <p> * curl 'http://localhost:9999/realtime/create' -H 'Content-Type: application/json;charset=UTF-8' --data-binary '{"project": "projectId", "name": "Events by collection", "aggregation": "COUNT"}' * * @param report real-time report * @return a future that contains the operation status */ @JsonRequest @ApiOperation(value = "Create report", authorizations = @Authorization(value = "master_key")) @Path("/create") public CompletableFuture<SuccessMessage> createTable(@Named("project") RequestContext context, @BodyParam RealTimeReport report) { return realtimeService.create(context.project, report).thenApply(error -> { if (error == null) { return SuccessMessage.success(); } return SuccessMessage.success(error.message); }); }
@ApiOperation(value = "Execute query", authorizations = @Authorization(value = "read_key") ) @POST @JsonRequest @Path("/analyze") public CompletableFuture<QueryResult> analyzeRetention(@Named("project") RequestContext context, @BodyParam RetentionQuery query) { CompletableFuture<QueryResult> result = retentionQueryExecutor.query(context, Optional.ofNullable(query.firstAction), Optional.ofNullable(query.returningAction), query.dateUnit, Optional.ofNullable(query.dimension), Optional.ofNullable(query.period), query.startDate, query.endDate, query.timezone, query.approximate).getResult(); result.thenAccept(data -> { if (data.isFailed()) { LOGGER.error(new RuntimeException(JsonHelper.encode(query) + " : " + data.getError().toString()), "Error running retention query"); } }); return result; }
@ApiOperation(value = "Execute query", request = FunnelQuery.class, authorizations = @Authorization(value = "read_key") ) @POST @JsonRequest @Path("/analyze") public CompletableFuture<QueryResult> analyzeFunnel(@Named("project") RequestContext context, @BodyParam FunnelQuery query) { CompletableFuture<QueryResult> result = funnelQueryExecutor.query(context, query.steps, Optional.ofNullable(query.dimension), Optional.ofNullable(query.segment), query.startDate, query.endDate, Optional.ofNullable(query.window), query.timezone, Optional.ofNullable(query.connectors), getFunnelType(query)).getResult(); result.thenAccept(data -> { if (data.isFailed()) { LOGGER.error(new RuntimeException(JsonHelper.encode(query) + " : " + data.getError().toString()), "Error running funnel query"); } }); return result; }
@JsonRequest @Path("/update") @ProtectEndpoint(writeOperation = true) @ApiOperation(value = "Update reports", tags = "rakam-ui", authorizations = @Authorization(value = "read_key")) public SuccessMessage update(@Named("user_id") Project project, @BodyParam CustomReport report) { CustomReport customReport = metadata.get(report.reportType, project.project, report.name); if (customReport.getUser() != null && customReport.getUser() != project.userId) { int id = userService.getProjectOwner(project.project).id; if (id != project.userId) { throw new RakamException("The owner of the custom report can update the report", UNAUTHORIZED); } } metadata.update(project.project, report); return SuccessMessage.success(); }
@JsonRequest @ApiOperation(value = "Merge user with anonymous id", authorizations = @Authorization(value = "write_key")) @ApiResponses(value = {@ApiResponse(code = 404, message = "User does not exist.")}) @Path("/merge") @IgnoreApi @AllowCookie public void mergeUser(RakamHttpRequest request, @BodyParam MergeRequest mergeRequest) { // TODO: what if a user sends real user ids instead of its previous anonymous id? if (!config.getEnableUserMapping()) { throw new RakamException("The feature is not supported", PRECONDITION_FAILED); } Object anonymousId = mergeRequest.anonymousId; DefaultFullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, wrappedBuffer(OK_MESSAGE)); setBrowser(request, response); if (anonymousId == null) { throw new RakamException("Anonymous id is required", BAD_REQUEST); } String project = apiKeyService.getProjectOfApiKey(mergeRequest.api.apiKey, WRITE_KEY); service.merge(project, mergeRequest.id, anonymousId, Instant.ofEpochMilli(mergeRequest.createdAt), Instant.ofEpochMilli(mergeRequest.mergedAt)); request.response(response).end(); }
@ApiOperation(value = "Create custom event mapper", authorizations = @Authorization(value = "master_key") ) @Path("/update") @JsonRequest public SuccessMessage update(@Named("project") RequestContext context, @BodyParam JSEventMapperCode mapper) { try (Handle handle = dbi.open()) { int execute = handle.createStatement("UPDATE custom_event_mappers SET script = :script, parameters = :parameters, image = :image " + "WHERE id = :id AND project = :project") .bind("project", context.project) .bind("id", mapper.id) .bind("image", mapper.image) .bind("parameters", JsonHelper.encode(mapper.parameters)) .bind("script", mapper.script).execute(); if (execute == 0) { throw new RakamException(NOT_FOUND); } return SuccessMessage.success(); } }