Get body of error response with Spring Reactive Elasticsearch Client - spring-data-elasticsearch

I'm using Spring Data Elasticsearch to get some aggregations, and I'm trying to use the ReactiveElasticsearchClient. I'm getting a 500 error from Elasticsearch, but can't figure out how to get the body of the response so that I can debug what's wrong with my request. Here's what I have so far:
final Flux<Aggregation> resp = client.aggregate(request -> {
final SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.queryStringQuery(query)).size(0)
.aggregation(AggregationBuilders.composite("report", compositeValueBuilders));
request.indices(index).source(sourceBuilder);
});
resp.doOnError(throwable -> {
throwable.printStackTrace();
}).log().doOnEach(signal -> {
if (signal.hasError()) {
signal.getThrowable().printStackTrace();
} else {
final Aggregation agg = signal.get();
System.out.println(agg.getType());
System.out.println(agg.getClass());
System.out.println(agg.getName());
}
}).blockLast();
With trace logging enabled for org.springframework.data.elasticsearch.client.WIRE, the request body is logged, but the log line for the response is just this:
2020-06-09 14:12:46.625 TRACE 19999 --- [or-http-epoll-1] o.s.data.elasticsearch.client.WIRE : [4ed5a037] Received raw response: 500 INTERNAL_SERVER_ERROR
I'm getting the following stack trace. I can see the ElasticsearchStatusException, but I don't see anything I can do with the Signal object to get the response body.
org.elasticsearch.ElasticsearchStatusException: POST request to /<index name>/_search returned error code 500.
at org.springframework.data.elasticsearch.client.reactive.DefaultReactiveElasticsearchClient.handleServerError(DefaultReactiveElasticsearchClient.java:809) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.data.elasticsearch.client.reactive.DefaultReactiveElasticsearchClient.readResponseBody(DefaultReactiveElasticsearchClient.java:760) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at org.springframework.data.elasticsearch.client.reactive.DefaultReactiveElasticsearchClient.lambda$sendRequest$22(DefaultReactiveElasticsearchClient.java:680) ~[spring-data-elasticsearch-4.0.0.RELEASE.jar:4.0.0.RELEASE]
at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:156) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1755) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:73) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:385) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:173) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:213) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:845) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:845) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2317) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribeInner(MonoFlatMapMany.java:143) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:182) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.FluxRetryPredicate$RetryPredicateSubscriber.onNext(FluxRetryPredicate.java:82) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:156) ~[reactor-core-3.3.5.RELEASE.jar:3.3.5.RELEASE]
at reactor.netty.http.client.HttpClientConnect$HttpIOHandlerObserver.onStateChange(HttpClientConnect.java:428) ~[reactor-netty-0.9.7.RELEASE.jar:0.9.7.RELEASE]
at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:514) ~[reactor-netty-0.9.7.RELEASE.jar:0.9.7.RELEASE]
at reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.onStateChange(PooledConnectionProvider.java:536) ~[reactor-netty-0.9.7.RELEASE.jar:0.9.7.RELEASE]
at reactor.netty.resources.PooledConnectionProvider$PooledConnection.onStateChange(PooledConnectionProvider.java:427) ~[reactor-netty-0.9.7.RELEASE.jar:0.9.7.RELEASE]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:562) ~[reactor-netty-0.9.7.RELEASE.jar:0.9.7.RELEASE]
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96) ~[reactor-netty-0.9.7.RELEASE.jar:0.9.7.RELEASE]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) ~[netty-handler-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.49.Final.jar:4.1.49.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311) ~[netty-codec-4.1.49.Final.jar:4.1.49.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:425) ~[netty-codec-4.1.49.Final.jar:4.1.49.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.49.Final.jar:4.1.49.Final]
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:792) ~[netty-transport-native-epoll-4.1.49.Final-linux-x86_64.jar:4.1.49.Final]
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:475) ~[netty-transport-native-epoll-4.1.49.Final-linux-x86_64.jar:4.1.49.Final]
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378) ~[netty-transport-native-epoll-4.1.49.Final-linux-x86_64.jar:4.1.49.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.49.Final.jar:4.1.49.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.49.Final.jar:4.1.49.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.49.Final.jar:4.1.49.Final]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Tl;dr: How do I get the response body of an error response when using the Spring ReactiveElasticsearchClient?

You should activate the logging by setting the logging level of
org.springframework.data.elasticsearch.client.WIRE
to trace level. This logs what is sent and received, especially in the case of errors (excerpt from the implementation):
private <T> Publisher<? extends T> readResponseBody(String logId, Request request, ClientResponse response,
Class<T> responseType) {
// ...
if (response.statusCode().is5xxServerError()) {
ClientLogger.logRawResponse(logId, response.statusCode());
return handleServerError(request, response);
}
if (response.statusCode().is4xxClientError()) {
ClientLogger.logRawResponse(logId, response.statusCode());
return handleClientError(logId, request, response, responseType);
}
// ...
}
Edit:
sorry, my fault, should have seen that the response body is not logged.
What you could do is use an intercepting proxy that monitors the traffic between your application and Elasticsearch. There's the OWASP ZAP proxy and the Burp Suite Community edition. Both applications start as a proxy on port 8080, so you either need to configure your application to listen on a different port (server.port in the application properties, I use for example 9090 for my test app) or change the proxy port. Besides that you need to configure the proxy in your app, I have the following configuration:
#Configuration
public class ReactiveRestClientConfig extends AbstractReactiveElasticsearchConfiguration {
#Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
.connectedTo("localhost:9200") //
.withProxy("localhost:8080")
.build();
return ReactiveRestClients.create(clientConfiguration);
}
}
The when accessing you application, the traffic to Elasticsearch goes through the proxy where you can see the requests and responses.

Related

i am have an issue with post request in the chatbot ap using watson assistant

while sending a post request on postman after session id is generated, it goes to catch block, and it shows error
Error: Missing required parameters: sessionId
at Object.getMissingParams (E:\Projects\ChatBot App\node_modules\ibm-cloud-sdk-core\lib\helper.js:116:11)
at AssistantV2.message (E:\Projects\ChatBot App\node_modules\ibm-watson\assistant\v2.js:217:50)
at E:\Projects\ChatBot App\routes\api\watson.js:44:41
at Layer.handle [as handle_request] (E:\Projects\ChatBot App\node_modules\express\lib\router\layer.js:95:5)
at next (E:\Projects\ChatBot App\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (E:\Projects\ChatBot App\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (E:\Projects\ChatBot App\node_modules\express\lib\router\layer.js:95:5)
at E:\Projects\ChatBot App\node_modules\express\lib\router\index.js:281:22
at Function.process_params (E:\Projects\ChatBot App\node_modules\express\lib\router\index.js:335:12)
at next (E:\Projects\ChatBot App\node_modules\express\lib\router\index.js:275:10)
the code is:
router.post('/message', async (req, res) => {
payload = {
assistantId: process.env.WA_ASSISTANT_ID,
sessionId: req.headers.session_id,
input: {
message_type: "text",
text: req.body.input,
},
};
try {
const message = await assistant.message(payload);
res.json(message["result"]);
} catch (err) {
res.send("There was an error processing your request.");
console.log(err);
}
});
Your screenshot of Postman shows that you added session_id as URL parameters. That would be for a GET request. You need to transfer the assistantId and session_id as payload of the POST request, i.e., as data in the request body. Then it should work.
This is not related to IBM Watson Assistant, but how http requests work.

Vert.x TemplateHandler (with ThymeleafTemplateEngine) usage problem

I have problem of using vert.x's TemplateHandler (with Thymeleaf) to render html on server side. I follow the vertx document on 'https://vertx.io/docs/vertx-web/java/#_templates', but still don't know how to solve it.
Following is verticle code :
TemplateEngine engine = ThymeleafTemplateEngine.create(vertx);
TemplateHandler handler = TemplateHandler.create(engine);
Router router = Router.router(vertx);
router.route().handler(handler);
router.errorHandler(500, rc -> {
System.err.println("Handling failure");
Throwable failure = rc.failure();
if (failure != null) {
failure.printStackTrace();
}
});
Following is html code :
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:text="${context.request().params().get('param1')}">hello</h1>
</body>
</html>
Following is exception stack :
Handling failure
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating OGNL expression: "context.request().params().get('param1')" (template: "templates/index.html" - line 8, col 5)
at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.evaluate(OGNLVariableExpressionEvaluator.java:191)
at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.evaluate(OGNLVariableExpressionEvaluator.java:95)
at org.thymeleaf.standard.expression.VariableExpression.executeVariableExpression(VariableExpression.java:166)
at org.thymeleaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:66)
at org.thymeleaf.standard.expression.Expression.execute(Expression.java:109)
at org.thymeleaf.standard.expression.Expression.execute(Expression.java:138)
at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess(AbstractStandardExpressionAttributeTagProcessor.java:144)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)
at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205)
at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136)
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:661)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1067)
at io.vertx.ext.web.templ.thymeleaf.impl.ThymeleafTemplateEngineImpl.render(ThymeleafTemplateEngineImpl.java:93)
at io.vertx.ext.web.common.template.TemplateEngine.render(TemplateEngine.java:52)
at io.vertx.ext.web.handler.impl.TemplateHandlerImpl.handle(TemplateHandlerImpl.java:72)
at io.vertx.ext.web.handler.impl.TemplateHandlerImpl.handle(TemplateHandlerImpl.java:32)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1104)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:151)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:131)
at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:55)
at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:37)
at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:67)
at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:30)
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:52)
at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:194)
at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:140)
at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:151)
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:144)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:101)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.vertx.core.http.impl.Http1xUpgradeToH2CHandler.channelRead(Http1xUpgradeToH2CHandler.java:115)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61)
at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: target is null for method request
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1613)
at ognl.ASTMethod.getValueBody(ASTMethod.java:91)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.ASTChain.getValueBody(ASTChain.java:141)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:467)
at ognl.Ognl.getValue(Ognl.java:431)
at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.executeExpression(OGNLVariableExpressionEvaluator.java:316)
at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.evaluate(OGNLVariableExpressionEvaluator.java:170)
... 66 more
Help !!!.

Getting NPE while receiving the reply message using RabbitTemplate

I have two microservices. one contains the REST controller which has the Get method which receives the message when sent to specific queue. other microservice just sends the reply message to same queue so that processed message can be seen in the browser when hit the REST API
however, getting NPE while receiving the message.
below is the complete stack-trace:
2018-05-19 15:46:13.409 INFO 30104 --- [nio-8097-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/unit] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-05-19 15:46:13.409 INFO 30104 --- [nio-8097-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-05-19 15:46:13.443 INFO 30104 --- [nio-8097-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 34 ms 2018-05-19 15:46:13.533 INFO 30104 --- [nio-8097-exec-1] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [35.154.27.134:5672] 2018-05-19 15:46:13.593 INFO 30104 --- [nio-8097-exec-1] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#5b2b49d6:0/SimpleConnection#3e4f13fa [delegate=amqp://guest#35.154.27.134:5672/, localPort= 58742] 2018-05-19 15:46:18.681 ERROR 30104 --- [nio-8097-exec-1] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/unit] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.infy.ci.unitamqpservice.UnitAmqpRestController.getAggregatedDataForSectionOfNightlyBuild(UnitAmqpRestController.java:83) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_151]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_151]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.27.jar!/:8.5.27]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]
further, when hitting the REST API in the web browser, getting following log on the console
2018-05-19 15:45:22.328 INFO 30023 --- [ main]
o.s.j.e.a.AnnotationMBeanExporter : Located managed bean
'rabbitConnectionFactory': registering with JMX server as MBean
[org.springframework.amqp.rabbit.connection:name=rabbitConnectionFactory,type=CachingConnectionFactory]
2018-05-19 15:45:22.423 INFO 30023 --- [ main]
o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase
2147483647 2018-05-19 15:45:22.445 INFO 30023 --- [cTaskExecutor-1]
o.s.a.r.c.CachingConnectionFactory : Attempting to connect to:
[35.154.27.134:5672] 2018-05-19 15:45:22.471 INFO 30023 ---
[cTaskExecutor-1] o.s.a.r.c.CachingConnectionFactory : Created
new connection:
rabbitConnectionFactory#325fc787:0/SimpleConnection#38a7acf7
[delegate=amqp://guest#35.154.27.134:5672/, localPort= 58736]
2018-05-19 15:45:22.875 INFO 30023 --- [ main]
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s):
8099 (http) 2018-05-19 15:45:22.902 INFO 30023 --- [ main]
com.infy.ci.unitdbamqpservice.RPCServer : Started RPCServer in 7.517
seconds (JVM running for 8.286) Sat May 19 15:45:23 UTC 2018 WARN:
Establishing SSL connection without server's identity verification is
not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+
requirements SSL connection must be established by default if explicit
option isn't set. For compliance with existing applications not using
SSL the verifyServerCertificate property is set to 'false'. You need
either to explicitly disable SSL by setting useSSL=false, or set
useSSL=true and provide truststore for server certificate
verification. Sat May 19 15:46:13 UTC 2018 WARN: Establishing SSL
connection without server's identity verification is not recommended.
According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL
connection must be established by default if explicit option isn't
set. For compliance with existing applications not using SSL the
verifyServerCertificate property is set to 'false'. You need either to
explicitly disable SSL by setting useSSL=false, or set useSSL=true and
provide truststore for server certificate verification.
can this be the reason for NPE ? i have already included following in the JDBC code but still no luck.
prop.setProperty("useSSL", "false");
prop.setProperty("autoReconnect", "true");
both the services are checked-in at github:
https://github.com/irfanjs/unitamqpservice
https://github.com/irfanjs/unitdbamqpservice
return rabbitTemplate.convertSendAndReceive("myExchange", requestQueueName, message).toString();
You are unconditionally calling toString() on the reply.
The reply will be null if the template's replyTimeout is exceeded before the reply is received (the timeout defaults to 5 seconds).
You must check for null result before calling toString().
just sends the reply message to same queue
You can't send the reply to the same queue - it must go to the replyTo header in the request.
If you use a #RabbitListener or MessageListenerAdapter on the server side, it will be taken care of for you.
This has nothing to do with SSL
WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set.
That warning is about MySQL.
EDIT
I just hacked your applications down to the bare minimum and they work fine for me...
#Controller
#Configuration
#PropertySource("classpath:/application.properties")
#RequestMapping("/unittestdata")
public class UnitAmqpRestController {
private final String requestQueueName = "rpc_queue1";
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
private final Logger logger = LoggerFactory.getLogger(UnitAmqpRestController.class);
private final RabbitTemplate rabbitTemplate;
#Autowired
public UnitAmqpRestController(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setReplyTimeout(15_000L);
}
#RequestMapping(value = "/{projectid}/ut/aggregate",
method = RequestMethod.GET,
produces = MediaType.TEXT_HTML_VALUE)
public #ResponseBody String getAggregatedDataForSectionOfNightlyBuild(#PathVariable("projectid") int projectid,
#RequestParam("buildtype") String buildtype, #RequestParam("build") String build) throws Exception {
if (build.toLowerCase().equals("latest") && buildtype.equals("nightly")) {
String message = String.format("aggregate");
logger.info("Sending: " + message);
Object returned = rabbitTemplate.convertSendAndReceive("", requestQueueName, message);
logger.info("Reply: " + returned);
if (returned == null) {
throw new RuntimeException("failed to get a response");
}
return returned.toString();
}
else {
return null;
}
}
}
and
#Configuration
#SpringBootApplication
#PropertySource("classpath:/application.properties")
public class RPCServer {
private static final Logger logger = LoggerFactory.getLogger(RPCServer.class);
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
SpringApplication.run(RPCServer.class, args);
}
private static final String RPC_QUEUE_NAME = "rpc_queue1";
#Bean
public Queue queue() {
return new Queue(RPC_QUEUE_NAME);
}
#Component
public static class RpcListener {
#RabbitListener(queues = RPC_QUEUE_NAME)
public String reply(String request) throws IOException, TimeoutException, ClassNotFoundException, SQLException {
logger.info(request);
return request.toUpperCase();
}
}
}
and
2018-05-20 12:46:00.298 INFO 13369 --- [nio-8097-exec-1] c.i.c.u.UnitAmqpRestController : Sending: aggregate
...
o.s.amqp.rabbit.core.RabbitTemplate : Publishing message on exchange [], routingKey = [rpc_queue1]
2018-05-20 12:46:00.554 DEBUG 13369 --- [nio-8097-exec-1] o.s.amqp.rabbit.core.RabbitTemplate : Reply: (Body:'AGGREGATE' MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=amq.rabbitmq.reply-to.g2dkABByYWJiaXRAbG9jYWxob3N0AAAHFAAAAAAC.3M1LyvOdR9dHQehSV4l67A==, receivedDelay=null, deliveryTag=1, messageCount=null, consumerTag=null, consumerQueue=null])
2018-05-20 12:46:00.561 INFO 13369 --- [nio-8097-exec-1] c.i.c.u.UnitAmqpRestController : Reply: AGGREGATE

Unable to use Response.Status.METHOD_NOT_ALLOWED in Neo4J 2.3.1

I am creating a REST api with a dynamic path like this:
#DELETE
#Path("/{path: .+}")
#Produces(MediaType.APPLICATION_JSON)
public void delete() {
...
}
When I do not find a single node by the path I would like to return a 405 "Method not allowed" response. To do this I tried this:
return Response.status(Response.Status.METHOD_NOT_ALLOWED).build();
This result in an exception and the server gives a 500 "Server Error" response. This is what I get:
java.lang.NoSuchFieldError: METHOD_NOT_ALLOWED
... my boring classes...
at com.sun.jersey.spi.container.ContainerResponse.mapException(ContainerResponse.java:480)
at com.sun.jersey.spi.container.ContainerResponse.mapMappableContainerException(ContainerResponse.java:417)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1477)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.neo4j.server.rest.web.CollectUserAgentFilter.doFilter(CollectUserAgentFilter.java:69)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:540)
at java.lang.Thread.run(Thread.java:745)
Any ideas? :)
METHOD_NOT_ALLOWED should just be int 405. So william-lyon's response should be the correct one:
return Response.status(405).build();
But it looks like we should request neo4j 3.0 upgrade jax-rs to 2 from 1.1.
Can you please create raise an issue on github? https://github.com/neo4j/neo4j/issues

iOS + gtm-oauth2 library: Getting a 401 invalid request

I have a Ruby on Rails application which is an OAuth 2.0 provider thanks to the Doorkeeper gem and has an API. I am building an iPhone client that will interact with the API; it uses the gtm-oauth2 library for the authentication process.
I finished the OAuth authentication part, so a user can add an account to the iPhone app. Now I need to retrieve the authorization from the iPhone (or iPhone Simulator) keychain to interact with the private API of my main application. Here is the code that I have:
GTMOAuth2Authentication *auth = [_db catapultAuthenticaiton];
[GTMOAuth2ViewControllerTouch authorizeFromKeychainForName:kCatapultKeychainItemName
authentication:auth];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://api.lvh.me:3000/api/clients/%#", accountName]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
[fetcher setAuthorizer:auth];
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
if (error != nil) {
#if DEBUG
NSLog(#"Error fetching client: %#", error);
#endif
}
}];
In the fetcher completion handler I am getting a 401 invalid_request error when trying to retrieve an existing authorization from the keychain and doing an API call to the server:
2013-04-02 11:08:55.546 Catapult for iOS[31776:c07] Error Error Domain=com.google.HTTPStatus Code=401 "The operation couldn’t be completed. (com.google.HTTPStatus error 401.)" UserInfo=0x7248010 {data=<7b226572 726f7222 3a22696e 76616c69 645f7265 71756573 74222c22 6572726f 725f6465 73637269 7074696f 6e223a22 54686520 72657175 65737420 6973206d 69737369 6e672061 20726571 75697265 64207061 72616d65 7465722c 20696e63 6c756465 7320616e 20756e73 7570706f 72746564 20706172 616d6574 65722076 616c7565 2c206f72 20697320 6f746865 72776973 65206d61 6c666f72 6d65642e 227d>}
Error data:
{
error = "invalid_request";
"error_description" = "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.";
}
2013-04-02 11:08:55.546 Catapult for iOS[31776:c07] Error fetching client: Error Domain=com.google.HTTPStatus Code=401 "The operation couldn’t be completed. (com.google.HTTPStatus error 401.)" UserInfo=0x725bf00 {data=<7b226572 726f7222 3a22696e 76616c69 645f7265 71756573 74222c22 6572726f 725f6465 73637269 7074696f 6e223a22 54686520 72657175 65737420 6973206d 69737369 6e672061 20726571 75697265 64207061 72616d65 7465722c 20696e63 6c756465 7320616e 20756e73 7570706f 72746564 20706172 616d6574 65722076 616c7565 2c206f72 20697320 6f746865 72776973 65206d61 6c666f72 6d65642e 227d>, json={
error = "invalid_request";
"error_description" = "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.";
}}
I used GTMHTTPFetcherLogging to log the HTTP request made and here is what was logged:
refresh token for oauth.lvh.me
2013-04-02 10:08:55 +0000
Request: POST https://oauth.lvh.me:3000/oauth/token
Request headers:
Content-Type: application/x-www-form-urlencoded
User-Agent: gtm-oauth2 com.catapult.Catapult-for-iOS/1.0
Request body: (257 bytes)
client_id=b29a572c2caa218b8591011e1cc67f0f3536ffe4c449ab7b806dd4d363681401&client_secret=_snip_&grant_type=refresh_token&refresh_token=_snip_
Response: status 401
Response headers:
Cache-Control: no-store
Connection: close
Content-Type: application/json; charset=utf-8
Pragma: no-cache
Server: thin 1.5.1 codename Straight Razor
Strict-Transport-Security: max-age=31536000
X-Request-Id: 65b11f0a4fc06fa5562332252fd6cdcd
X-Runtime: 0.212716
X-UA-Compatible: IE=Edge
Response body: (162 bytes)
{
"error_description" : "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.",
"error" : "invalid_request"
}
-----------------------------------------------------------
And here are the server's logs:
Started POST "/oauth/token" for 127.0.0.1 at 2013-04-02 11:08:55 +0100
Doorkeeper::AccessToken Load (0.2ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."refresh_token" = 'ddb0a1bd3256e351ff7081300dc7ac73035e897ea93d36053b7fb87843015a51' LIMIT 1
Doorkeeper::Application Load (0.1ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."uid" = 'b29a572c2caa218b8591011e1cc67f0f3536ffe4c449ab7b806dd4d363681401' AND "oauth_applications"."secret" = 'b0de316c20112708d04284f6867f5bb51c1d20c72415642b38f09a8faca966cd' LIMIT 1
When the request works, here is how the server's logs look like:
Started POST "/oauth/token" for 127.0.0.1 at 2013-04-02 11:19:19 +0100
Doorkeeper::AccessGrant Load (0.2ms) SELECT "oauth_access_grants".* FROM "oauth_access_grants" WHERE "oauth_access_grants"."token" = '4391e187a0df16c56d1e6b16bf51340af8d677dbf625c495f50a249678e0502e' LIMIT 1
Doorkeeper::Application Load (0.1ms) SELECT "oauth_applications".* FROM "oauth_applications" WHERE "oauth_applications"."uid" = 'b29a572c2caa218b8591011e1cc67f0f3536ffe4c449ab7b806dd4d363681401' AND "oauth_applications"."secret" = 'b0de316c20112708d04284f6867f5bb51c1d20c72415642b38f09a8faca966cd' LIMIT 1
SQL (1.0ms) UPDATE "oauth_access_grants" SET "revoked_at" = '2013-04-02 10:19:19' WHERE "oauth_access_grants"."id" = 7
Doorkeeper::AccessToken Load (0.2ms) SELECT "oauth_access_tokens".* FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."application_id" = 1 AND "oauth_access_tokens"."resource_owner_id" = 266 AND "oauth_access_tokens"."revoked_at" IS NULL ORDER BY created_at desc LIMIT 1
So there is clearly something wrong here... I don't know if the problem comes from the server or the iOS client, but my guts tell me it comes from the client.
Any clues on what is happening please?

Resources