@BeforeSuite public void setUp() throws Exception { FieldDependencyBuilder.FieldDependency fieldDependency = new FieldDependencyBuilder().build(); apiKeyService = new InMemoryApiKeyService(); metastore = new InMemoryMetastore(apiKeyService); SchemaChecker schemaChecker = new SchemaChecker(metastore, fieldDependency); eventDeserializer = new JsonEventDeserializer( metastore, apiKeyService, new TestingConfigManager(), schemaChecker, fieldDependency); EventListDeserializer eventListDeserializer = new EventListDeserializer(apiKeyService, eventDeserializer); mapper = JsonHelper.getMapper(); mapper.registerModule( new SimpleModule() .addDeserializer(Event.class, eventDeserializer) .addDeserializer(EventList.class, eventListDeserializer)); eventBuilder = new EventBuilder("test", metastore); }
@GET @ApiOperation( value = "Subscribe Event Stream", consumes = "text/event-stream", produces = "text/event-stream", authorizations = @Authorization(value = "read_key"), notes = "Subscribes the event stream.") @ApiResponses(value = {@ApiResponse(code = 400, message = "Project does not exist.")}) @Path("/subscribe") @IgnorePermissionCheck @IgnoreApi public void subscribe(RakamHttpRequest request) { if (!Objects.equals(request.headers().get(HttpHeaders.Names.ACCEPT), "text/event-stream")) { request .response( "the response should accept text/event-stream", HttpResponseStatus.NOT_ACCEPTABLE) .end(); return; } RakamHttpRequest.StreamResponse response = request.streamResponse(); List<String> data = request.params().get("data"); if (data == null || data.isEmpty()) { response .send( "result", encode( errorMessage("data query parameter is required", HttpResponseStatus.BAD_REQUEST))) .end(); return; } StreamQuery query; try { query = JsonHelper.readSafe(data.get(0), StreamQuery.class); } catch (IOException e) { response .send( "result", encode(errorMessage("json couldn't parsed", HttpResponseStatus.BAD_REQUEST))) .end(); return; } List<String> api_key = request.params().get("api_key"); if (api_key == null || api_key.isEmpty() || !metastore.checkPermission( query.project, Metastore.AccessKeyType.READ_KEY, api_key.get(0))) { response.send("result", HttpResponseStatus.UNAUTHORIZED.reasonPhrase()).end(); return; } List<CollectionStreamQuery> collect; try { collect = query .collections .stream() .map( collection -> { Expression expression = null; try { expression = collection.filter == null ? null : sqlParser.createExpression(collection.filter); } catch (ParsingException e) { ObjectNode obj = errorMessage( format( "Couldn't parse %s: %s", collection.filter, e.getErrorMessage()), HttpResponseStatus.BAD_REQUEST); request.response(encode(obj)).end(); throw e; } return new CollectionStreamQuery( collection.name, expression == null ? null : expression.toString()); }) .collect(Collectors.toList()); } catch (ParsingException e) { return; } EventStream.EventStreamer subscribe = stream.subscribe( query.project, collect, query.columns, new StreamResponseAdapter(response)); eventLoopGroup.schedule( new Runnable() { @Override public void run() { if (response.isClosed()) { subscribe.shutdown(); } else { subscribe.sync(); eventLoopGroup.schedule(this, 3, TimeUnit.SECONDS); } } }, 3, TimeUnit.SECONDS); }