Skip to content

Commit

Permalink
Feature/dubbo3.2 resteasy response context result support (apache#12854)
Browse files Browse the repository at this point in the history
* resteasy response context result support

* some detail

---------

Co-authored-by: suncr <suncairong@moresec.cn>
  • Loading branch information
suncairong163 and suncr committed Aug 7, 2023
1 parent b39a1e8 commit e7fa74b
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.protocol.rest.extension.resteasy.filter;

import org.jboss.resteasy.specimpl.BuiltResponse;

/**
* wrapper resteasy BuiltResponse
*/
public class DubboBuiltResponse extends BuiltResponse {

// user reset entity
private boolean resetEntity;

public DubboBuiltResponse(Object entity, int status, Class<?> entityClass) {

this.entity = entity;
this.entityClass = entityClass;
this.status = status;
}


@Override
public void setEntity(Object entity) {
if (entity == null) {
return;
}

if (entity.equals(this.entity)) {
return;
}
// reset entity true
this.resetEntity = true;
super.setEntity(entity);
}

public boolean isResetEntity() {
return resetEntity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.apache.dubbo.rpc.protocol.rest.filter.context.RestFilterContext;
import org.apache.dubbo.rpc.protocol.rest.netty.NettyHttpResponse;
import org.apache.dubbo.rpc.protocol.rest.request.RequestFacade;
import org.jboss.resteasy.specimpl.BuiltResponse;
import org.jboss.resteasy.spi.HttpResponse;

import javax.ws.rs.container.ContainerResponseFilter;
Expand All @@ -50,16 +49,18 @@ public void filter(RestFilterContext restFilterContext) throws Exception {
// response filter entity first


// empty jaxrsResponse
BuiltResponse jaxrsResponse = new BuiltResponse();
// build jaxrsResponse from rest netty response
DubboBuiltResponse dubboBuiltResponse = new DubboBuiltResponse(response.getResponseBody(), response.getStatus(), response.getEntityClass());
// NettyHttpResponse wrapper
HttpResponse httpResponse = new ResteasyNettyHttpResponse(response);
DubboContainerResponseContextImpl containerResponseContext = createContainerResponseContext(requestFacade, httpResponse, jaxrsResponse, containerRequestFilters.toArray(new ContainerResponseFilter[0]));
DubboContainerResponseContextImpl containerResponseContext = createContainerResponseContext(requestFacade, httpResponse, dubboBuiltResponse, containerRequestFilters.toArray(new ContainerResponseFilter[0]));
containerResponseContext.filter();
if (jaxrsResponse.getEntity() != null) {

// user reset entity
if (dubboBuiltResponse.hasEntity() && dubboBuiltResponse.isResetEntity()) {
// clean output stream data
restOutputStream(response);
writeResteasyResponse(url, requestFacade, response, jaxrsResponse);
writeResteasyResponse(url, requestFacade, response, dubboBuiltResponse);
}
addResponseHeaders(response, httpResponse.getOutputHeaders());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ private void doHandler(HttpRequest nettyHttpRequest,
// execute business method invoke
Result result = invoker.invoke(rpcInvocation);

// set raw response
nettyHttpResponse.setResponseBody(result.getValue());

if (result.hasException()) {
Throwable exception = result.getException();
logger.error("", exception.getMessage(), "", "dubbo rest protocol provider Invoker invoke error", exception);
Expand Down Expand Up @@ -150,7 +153,8 @@ public static void writeResult(NettyHttpResponse nettyHttpResponse, RequestFacad

public static void writeResult(NettyHttpResponse nettyHttpResponse, URL url, Object value, Class<?> returnType, MediaType mediaType) throws Exception {
MessageCodecResultPair booleanMediaTypePair = HttpMessageCodecManager.httpMessageEncode(nettyHttpResponse.getOutputStream(), value, url, mediaType, returnType);

// reset raw response result
nettyHttpResponse.setResponseBody(value);
nettyHttpResponse.addOutputHeaders(RestHeaderEnum.CONTENT_TYPE.getHeader(), booleanMediaTypePair.getMediaType().value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void handle(NettyRequestFacade requestFacade, NettyHttpResponse nettyHttp


/**
* execute response filters
* execute rest filters
*
* @param url
* @param requestFacade
Expand All @@ -123,8 +123,8 @@ public void handle(NettyRequestFacade requestFacade, NettyHttpResponse nettyHttp
public void executeFilters(URL url, RequestFacade requestFacade, NettyHttpResponse nettyHttpResponse, ServiceDeployer serviceDeployer, List<RestFilter> restFilters) throws Exception {
RestFilterContext restFilterContext = new RestFilterContext(url, requestFacade, nettyHttpResponse, serviceDeployer);

for (RestFilter restResponseFilter : restFilters) {
restResponseFilter.filter(restFilterContext);
for (RestFilter restFilter : restFilters) {
restFilter.filter(restFilterContext);
if (restFilterContext.complete()) {
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public class NettyHttpResponse implements HttpResponse {
private boolean committed;
private boolean keepAlive;
private HttpMethod method;
// raw response body
private Object responseBody;
// raw response class
private Class<?> entityClass;

public NettyHttpResponse(final ChannelHandlerContext ctx, final boolean keepAlive) {
this(ctx, keepAlive, null);
Expand Down Expand Up @@ -105,6 +109,7 @@ public void sendError(int status) throws IOException {
@Override
public void sendError(int status, String message) throws IOException {
setStatus(status);
setResponseBody(message);
if (message != null) {
getOutputStream().write(message.getBytes(StandardCharsets.UTF_8));
}
Expand Down Expand Up @@ -211,4 +216,21 @@ public static void transformHeaders(NettyHttpResponse nettyResponse, io.netty.ha
}

}

public Object getResponseBody() {
return responseBody;
}

public void setResponseBody(Object responseBody) {

this.responseBody = responseBody;

if (responseBody != null) {
this.entityClass = responseBody.getClass();
}
}

public Class<?> getEntityClass() {
return entityClass;
}
}

0 comments on commit e7fa74b

Please sign in to comment.