@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if (msg instanceof ResourceResponse && !(msg instanceof ResourceErrorResponse)) { ResourceResponse response = (ResourceResponse) msg; Runnable action = () -> { encode(ctx, response, promise); }; if (response.resource() instanceof BlockingResource) { this.workerPool.execute(action); } else { action.run(); } } else { super.write(ctx, msg, promise); } }
private void sendError(Subscription subscription, HttpResponseStatus status, ResourceResponse origResourceResponse) throws Exception { ResourceState state = new DefaultResourceState(origResourceResponse.resource().id()); state.putProperty("error", "New resource subscribed, but you can't see it due to error: " + status.reasonPhrase()); subscription.sendAuthzError(state, origResourceResponse.resource(), status.code()); }
@Override public void resourceUpdated(ResourceResponse resourceResponse) { ResourcePath path = resourcePathOf(resourceResponse.resource()); this.subscriptionsTree.objects(path).forEach((subscription) -> subscribeResourceUpdated(path, subscription, resourceResponse)); }
@Override public void resourceDeleted(ResourceResponse resourceResponse) { ResourcePath path = resourcePathOf(resourceResponse.resource()); this.subscriptionsTree.objects(path).forEach((subscription) -> subscribeResourceDeleted(path, subscription, resourceResponse)); this.subscriptionsTree.objects(path.parent()).forEach((subscription) -> subscribeResourceDeleted(path.parent(), subscription, resourceResponse)); }
@Override public void resourceCreated(ResourceResponse resourceResponse) { ResourcePath path = resourcePathOf(resourceResponse.resource()); this.subscriptionsTree.objects(path).forEach((subscription) -> subscribeResourceCreated(path, subscription, resourceResponse)); this.subscriptionsTree.objects(path.parent()).forEach((subscription) -> subscribeResourceCreated(path.parent(), subscription, resourceResponse)); }
public EncodingResult encode(RequestContext ctx, MediaTypeMatcher mediaTypeMatcher, ResourceResponse response) throws Exception { Resource resource = response.resource(); if (resource instanceof BinaryResource) { MediaType match = mediaTypeMatcher.findBestMatch(Collections.singletonList(((BinaryResource) resource).mediaType())); if (match != null) { return new EncodingResult(match, null); } else { throw new IncompatibleMediaTypeException(mediaTypeMatcher, (BinaryResource) resource); } } MediaType bestMatch = mediaTypeMatcher.findBestMatch(this.codecs.stream().map((e) -> { return e.mediaType; }).collect(Collectors.toList())); // if we don't have a match and the response isn't already an error response, then return a error response if (bestMatch == null && !(response instanceof ResourceErrorResponse)) { throw new UnsupportedMediaTypeException(mediaTypeMatcher); } ResourceCodec codec = getResourceCodec(bestMatch); if (codec == null) { codec = getResourceCodec(MediaType.JSON); bestMatch = MediaType.JSON; } if (!codec.hasEncoder()) { log.trace("This media is not supported: " + mediaTypeMatcher + " (codecs: " + codecs + ")"); throw new UnsupportedMediaTypeException(mediaTypeMatcher); } return new EncodingResult(bestMatch, codec.encode(ctx, response.state())); }
@Override public void resourceUpdated(ResourceResponse resourceResponse) throws Exception { URI uri = destinationUri(resourceResponse.resource()); HttpClientRequest request = this.httpClient.put(uri.getPath(), (response) -> { }); request.setChunked(true); RequestContext requestContext = new RequestContext.Builder().build(); ByteBuf encoded = codec.encode(requestContext, resourceResponse.state()); request.write(new Buffer(encoded)); request.end(); }
@Override public void resourceDeleted(ResourceResponse resourceResponse) throws Exception { URI uri = destinationUri(resourceResponse.resource()); HttpClientRequest request = this.httpClient.delete(uri.getPath(), (response) -> { }); request.setChunked(true); RequestContext requestContext = new RequestContext.Builder().build(); ByteBuf encoded = codec.encode(requestContext, resourceResponse.state()); request.write(new Buffer(encoded)); request.end(); }
/** * Encode (for some cheap value of 'encode') a resulting resource into a ResourceState. * * @param ctx * @param response The response to encode. * @throws Exception */ protected void encode(ChannelHandlerContext ctx, ResourceResponse response, ChannelPromise promise) { final ClientResourceResponse.ResponseType responseType = ClientResourceResponse.ResponseType.OK; if (response.resource() == null) { ctx.writeAndFlush(new ClientResourceResponseImpl(response.inReplyTo(), responseType, response.inReplyTo().resourcePath().toString(), null)); ctx.fireUserEventTriggered(new RequestCompleteEvent(response.requestId())); return; } final ResourceStateEncoder encoder = new ResourceStateEncoder(); RootEncodingDriver driver = new RootEncodingDriver(response.inReplyTo().requestContext(), encoder, response.resource(), () -> { ResourceState state = encoder.root(); response.setState(state); ctx.writeAndFlush(response, promise).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE).addListener(ChannelFutureListener.CLOSE_ON_FAILURE); }, t -> handleError(ctx, response.inReplyTo(), t)); try { driver.encode(); } catch (Throwable e) { handleError(ctx, response.inReplyTo(), e); } }
@Override public void onOutbound(OutboundInterceptorContext context) throws Exception { ResourceResponse response = context.response(); if (context.request().requestType() == RequestType.READ && response.responseType() == ResourceResponse.ResponseType.READ && response.state() != null) { ResourcePath resourcePath = new ResourcePath(response.resource().uri().toString()); SecurityContext securityContext = context.request().requestContext().securityContext(); // Process just members of response.state() and not the state itself as resource has been already authorized at onInbound processMembers(resourcePath, response.state(), securityContext, new Consumer<ResourceState>() { @Override public void accept(ResourceState authorizedState) { response.setState(authorizedState); context.forward(); } }); } else { super.onOutbound(context); } }
/** * Encode (for some cheap value of 'encode') a resulting resource into a ResourceState. * * @param ctx * @param response The response to encode. * @throws Exception */ protected void encode(ChannelHandlerContext ctx, ResourceResponse response) { final ClientResourceResponse.ResponseType responseType = ClientResourceResponse.ResponseType.OK; if (response.resource() == null) { ctx.writeAndFlush(new ClientResourceResponseImpl(response.inReplyTo(), responseType, response.inReplyTo().resourcePath().toString(), null)); ctx.fireUserEventTriggered(new RequestCompleteEvent(response.requestId())); return; } ctx.writeAndFlush(new ClientResourceResponseImpl(response.inReplyTo(), responseType, response.inReplyTo().resourcePath().toString(), response.state())); ctx.fireUserEventTriggered(new RequestCompleteEvent(response.requestId())); }
protected StompMessage createMessage(String action, int status, ResourceResponse resourceResponse) throws Exception { Resource resource = resourceResponse.resource(); StompMessage message = new DefaultStompMessage(); message.headers().put(Headers.SUBSCRIPTION, this.subscriptionId); message.headers().put(Headers.CONTENT_TYPE, this.mediaType.toString()); message.headers().put("action", action); message.headers().put("status", "" + status); message.headers().put("location", resource.uri().toString()); RequestContext requestContext = new RequestContext.Builder().build(); message.content(this.codec.encode(requestContext, resourceResponse.state())); return message; }