Camel Rest-DSL (api-doc) - Potential bug - rest

I've been using Rest-DSL (Camel v2.18.1) and trying to set up my own RestOperationResponseMsgDefinition so as to have a useful API doc. By setting a class to the responseModel to tell which object will be returned in case of success, its structure is properly shown in the API doc. However, if I create a class that has that object within, all endpoints which mention it as their outputType/responseModel stop showing the correct structure in the API doc and put "string" instead. Like this:
My outputType/responseModel:
class Address {
private Integer id;
private String descr;
}
API-doc snippet:
"/addresses" : {
"get" : {
"produces" : [ "application/json" ],
"responses" : {
"200" : {
"description" : "Success.",
"schema" : {
"$ref" : "#/definitions/Address"
}
}
...
In Swagger-UI, the response example value is shown as:
{
"id": "string",
"descr": "string"
}
Everything is alright till I create any class having an Address object within! For instance:
class Store {
private Integer id;
private String name;
private Address address;
}
Now, for the same endpoint mentioned before, I get...
"/addresses" : {
"get" : {
"produces" : [ "application/json" ],
"responses" : {
"200" : {
"description" : "Success.",
"schema" : {
"type" : "string",
"format" : "com.mycompany.integration.domain.Address"
}
}
...
And the following in Swagger-UI as example value:
"string"
Has anybody ever passed through and solved this? This seems a bug, though...

Related

How to use swagger-akka-http annotations for classes containing scala traits?

The naive approach of using swagger-akka-http to annotate a case class containing traits would be
#Schema(description = "identifier of data value")
trait Identifier {
val id: String
}
#Schema(description = "value")
trait Value {
val value: Int
}
#Schema(description = "combine identifier and value")
trait Event extends Identifier with Value
#Schema(description = "response to data query")
case class Response(event: Event)
This produces
"Response" : {
"required" : [ "event" ],
"type" : "object",
"properties" : {
"event" : {
"$ref" : "#/components/schemas/Event"
}
},
"description" : "response to data query"
},
"Event" : {
"type" : "object",
"description" : "combine identifier and value"
}
Unfortunately the schema Event does not contain any information. Is there a way to annotate such a structure successfully?
Minimal example: swagger-akka-http-annotate-traits-test

How to access arguments on child resolver from parent call in AWS Appsync

I have two types: Todo and Comment.
type Todo {
id: ID!
name: String
description: String
priority: Int
status: TodoStatus
comments: [Comment]
}
type Comment {
todoid: ID!
commentid: String!
content: String
}
Then I have a Query getTodo but the thing is I want to include a content arg that filters the comment (child) if the string passed is in the content of Comment.
getTodo(id: ID!, content: String!): Todo
I have tried attaching a resolver to comments (under Todo). If I add a filter here, how will I be able to get the ctx.args.content which was passed in getTodo(id: ID!, content: String!).
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
## Provide a query expression. **
"expression": "todoid = :id",
"expressionValues" : {
":id" : {
"S" : "${ctx.args.id}"
}
}
},
"filter": {
"expression": "contains(content, :content)",
"expressionValues" : {
":content": {
"S": "${ctx.args.content}"
}
}
}
}
Or if I remove this filter and leave it like this:
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
## Provide a query expression. **
"expression": "todoid = :id",
"expressionValues" : {
":id" : {
"S" : "${ctx.args.id}"
}
}
}
}
How will I modify getTodo Resolver to fetch comments (with content that contains the string passed)?
Can I do it like this (accessing if comments.content contains the content string args passed):
{
"version" : "2017-02-28",
"operation" : "Query",
"query" : {
## Provide a query expression. **
"expression": "id = :id",
"expressionValues" : {
":id" : {
"S" : "${ctx.args.id}"
}
}
},
"filter": {
"expression": "contains(comments.content, :content)",
"expressionValues" : {
":content": {
"S": "${ctx.args.content}"
}
}
}
}
The GraphQL arguments you are accessing via $ctx.args are available at the field level. So when you access them when resolving the Post.comments field, you get back all the arguments on that field and that field only.
So to get the content string argument you could update your Todo type to:
type Todo {
id: ID!
name: String
description: String
priority: Int
status: TodoStatus
comments(content: String): [Comment]
}
Another way, if you don't want to expose the content argument on the Post.comments field and keep the argument on the Query.getTodo field, you could pass the arguments via the source. In your Query.getTodo resolver you could return the content field as part of the todo result. You would then be able to access it inside the Todo.comments resolver via $ctx.source.content.

Spring Cloud Contract provider return same as request

I'm working with two microservices using Spring Cloud Contract. One providing its contract, and the other one consuming it. In one scenario the provider response is the same that the request.
So the provider contract is like this:
Contract.make {
request {
method 'POST'
url '/provider/foo'
body(
"foo": $(regex("[a-zA-Z0-9]{20}"))
)
}
response {
status 200
body(
"fooResponse": fromRequest().body("\$.foo")
)
}
And the generated wiremock mapping:
{
"id" : "a80c0871-f4c0-49e3-8cc1-94de39899669",
"request" : {
"url" : "/provider/foo",
"method" : "POST",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(#.['foo'] =~ /[a-zA-Z0-9]{20}/)]"
} ]
},
"response" : {
"status" : 200,
"body" : "{\"fooResponse\":\"{{{jsonpath this '$.foo'}}}\"}",
"transformers" : [ "response-template" ]
},
"uuid" : "a80c0871-f4c0-49e3-8cc1-94de39899669",
"scenarioName" : "scenarioReturnSameAsRequest",
"requiredScenarioState" : "Started"
}
But when my code calls to the provider, with foo as any text, the wiremock returns:
{
"fooResponse" : "{{{jsonpath this '$.foo'}}}"
}
How can I build a contract that responses the same parameters as the request body?
Edit
I tried with a fixed value on the response and works fine:
Contract.make {
request {
method 'POST'
url '/provider/foo'
body(
"foo": $(regex("[a-zA-Z0-9]{20}"))
)
}
response {
status 200
body(
"fooResponse": "fooValue"
)
}
Now wiremock return:
{
"fooResponse" : "fooValue"
}
Maybe is not supported getting from request a regex value?
I think the mapping should contain request.body instead of this. Also I wonder if you need to use 3 times a { or just 2 times. Or do you need to escape these?
Possible mapping:
"response" : {
"status" : 200,
"body" : "{\"fooResponse\":\"{{jsonpath request.body '$.foo'}}\"}",
"transformers" : [ "response-template" ]
},
See also the chapter JSONPath helper on http://wiremock.org/docs/response-templating
I had the same problem once. You can try to use value() like this:
"fooResponse": value(fromRequest().body('$.foo'))

MongoDB: Finding a value where object name contains url

We are using learninglocker and I am trying to query its mongodb. learninglocker puts escaped urls as object names, which makes them more difficult to search. I am returning 0 results when I would expect to return several.
My find is as follows:
{"statement.object.definition.extensions.http://activitystrea&46;ms/schema/1&46;0/device.device_type": "app"}
I assume that this should be escaped somehow, however, am unsure how.
http://activitystrea&46;ms/schema/1&46;0/device
Sample object:
"statement": {
"version" : "1.0.0",
"actor" : { },
"verb" : { },
"context" : { },
"object" : {
"definition" : {
"extensions" : {
"http://activitystrea&46;ms/schema/1&46;0/device" : {
"device_type" : "app"
}
}
}
}
}

Elasticsearch doesn't find value in range query

I launch following query:
GET archive-bp/_search
{
"query": {
"bool" : {
"filter" : [ {
"bool" : {
"should" : [ {
"terms" : {
"naDataOwnerCode" : [ "ACME-FinServ", "ACME-FinServ CA", "ACME-FinServ NY", "ACME-FinServ TX", "ACME-Shipping APA", "ACME-Shipping Eur", "ACME-Shipping LATAM", "ACME-Shipping ME", "ACME-TelCo-CN", "ACME-TelCo-ESAT", "ACME-TelCo-NL", "ACME-TelCo-PL", "ACME-TelCo-RO", "ACME-TelCo-SA", "ACME-TelCo-Treasury", "Default" ]
}
},
{
"bool" : {
"must_not" : {
"exists" : {
"field" : "naDataOwnerCode"
}
}
}
} ]
}
}, {
"range" : {
"bankCommunicationStatusDate" : {
"from" : "2006-02-27T06:45:47.000Z",
"to" : null,
"time_zone" : "+02:00",
"include_lower" : true,
"include_upper" : true
}
}
} ]
}
}
}
And I receive no results, but the field exists in my index.
When I strip off the data owner part, I still have no results. When I strip off the bankCommunicationDate, I get 10 results, so there is the problem.
The query of only the bankCommunicationDate:
GET archive-bp/_search
{
"query" :
{
"range" : {
"bankCommunicationStatusDate" : {
"from" : "2016-04-27T09:45:43.000Z",
"to" : "2026-04-27T09:45:43.000Z",
"time_zone" : "+02:00",
"include_lower" : true,
"include_upper" : true
}
}
}
}
The mapping of my index contains the following bankCommunicationStatusDate field:
"bankCommunicationStatusDate": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
And there are values for the field bankCommunicationStatusDate in elasticsearch:
"bankCommunicationStatusDate": "2016-04-27T09:45:43.000Z"
"bankCommunicationStatusDate": "2016-04-27T09:45:47.000Z"
What is wrong?
What version of Elastic Search do you use?
I guess the reason is that you should use "gte/lte" instead of "from/to/include_lower/include_upper".
According to documentation to version 0.90.4
https://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-range-query.html
Deprecated in 0.90.4.
The from, to, include_lower and include_upper parameters have been deprecated in favour of gt,gte,lt,lte.
The strange thing is that I have tried your example on elastic search version 1.7 and it returns data!
I guess real depreciation took place much later - between 1.7 and maybe newer version you have.
BTW. You can isolate the problem even further using Sense plugin for Chrome and this code:
DELETE /test
PUT /test
{
"mappings": {
"myData" : {
"properties": {
"bankCommunicationStatusDate": {
"type": "date"
}
}
}
}
}
PUT test/myData/1
{
"bankCommunicationStatusDate":"2016-04-27T09:45:43.000Z"
}
PUT test/myData/2
{
"bankCommunicationStatusDate":"2016-04-27T09:45:47.000Z"
}
GET test/_search
{
"query" :
{
"range" : {
"bankCommunicationStatusDate" : {
"gte" : "2016-04-27T09:45:43.000Z",
"lte" : "2026-04-27T09:45:43.000Z"
}
}
}
}