Suppressing Camel specific attributes from Camel generated swagger definition - apache-camel

I am using camel-swagger to generate the API definition of my service. Please find below the generated swagger definition -
{
"swagger" : "2.0",
"info" : {
"description" : "api.description",
"version" : "1.0",
"title" : "api.title",
"termsOfService" : "api.termsOfService",
"contact" : {
"name" : "api.contact.name",
"url" : "http://api.contact.url",
"email" : "api#demo.com"
},
"license" : {
"name" : "api.license.name",
"url" : "http://api.license.url"
}
},
"host" : "0.0.0.0:13000",
"basePath" : "/airportinfo-service/1.0",
"tags" : [ {
"name" : "airports"
} ],
"schemes" : [ "http" ],
"paths" : {
"/airports" : {
"get" : {
"tags" : [ "airports" ],
"parameters" : [ ],
"responses" : {
"200" : {
"description" : "Output type",
"schema" : {
"$ref" : "#/definitions/Airports"
}
}
},
"x-camelContextId" : "airportinfo-service",
"x-routeId" : "getAirports"
}
},
"/airports/{id}" : {
"get" : {
"tags" : [ "airports" ],
"parameters" : [ {
"name" : "id",
"in" : "path",
"description" : "",
"required" : true,
"type" : "string"
} ],
"responses" : {
"200" : {
"description" : "Output type",
"schema" : {
"$ref" : "#/definitions/Airport"
}
}
},
"x-camelContextId" : "airportinfo-service",
"x-routeId" : "getAirport"
}
},
"/airports/health" : {
"get" : {
"tags" : [ "airports" ],
"parameters" : [ ],
"responses" : {
"200" : {
"description" : "Output type",
"schema" : {
"type" : "string",
"format" : "java.lang.String"
}
}
},
"x-camelContextId" : "airportinfo-service",
"x-routeId" : "health"
}
}
},
"definitions" : {
"Airport" : {
"type" : "object",
"properties" : {
"id" : {
"type" : "integer",
"format" : "int64"
},
"airportIataCode" : {
"type" : "string"
},
"airportName" : {
"type" : "string"
},
"airportStatus" : {
"type" : "string"
},
"airportLatitude" : {
"type" : "number",
"format" : "double"
},
"airportLongitude" : {
"type" : "number",
"format" : "double"
},
"airportUrl" : {
"type" : "string"
},
"cityId" : {
"type" : "integer",
"format" : "int64"
},
"cityIataCode" : {
"type" : "string"
},
"cityName" : {
"type" : "string"
},
"cityLatitude" : {
"type" : "number",
"format" : "double"
},
"cityLongitude" : {
"type" : "number",
"format" : "double"
},
"cityStatus" : {
"type" : "string"
},
"cityCategory" : {
"type" : "string"
},
"countryId" : {
"type" : "integer",
"format" : "int64"
},
"countryIataCode" : {
"type" : "string"
},
"countryName" : {
"type" : "string"
},
"region" : {
"type" : "string"
}
},
"x-className" : {
"type" : "string",
"format" : "demo.service.composite.airportinfo.datatypes.Airport"
}
},
"Airports" : {
"type" : "object",
"properties" : {
"size" : {
"type" : "integer",
"format" : "int32"
},
"airports" : {
"type" : "array",
"items" : {
"$ref" : "#/definitions/Airport"
}
}
},
"x-className" : {
"type" : "string",
"format" : "demo.service.composite.airportinfo.datatypes.Airports"
}
}
}
}
The code that generates the aforementioned API definition is -
restConfiguration()
.component("{{server.component}}")
.host("{{server.host}}")
.port("{{server.port}}")
.bindingMode(RestBindingMode.json)
.dataFormatProperty("prettyPrint", "true")
.contextPath("/{{service.name}}/{{service.version}}")
.apiContextPath( "/" )
.apiProperty("api.title", "{{api.title}}")
.apiProperty("api.version", "{{service.version}}")
.apiProperty("api.description", "{{api.description}}")
.apiProperty("api.termsOfService", "{{api.termsOfService}}")
.apiProperty("api.contact.name", "{{api.contact.name}}")
.apiProperty("api.contact.email", "{{api.contact.email}}")
.apiProperty("api.contact.url", "{{api.contact.url}}")
.apiProperty("api.license.name", "{{api.license.name}}")
.apiProperty("api.license.url", "{{api.license.url}}")
.apiProperty("apiContextIdListing", "{{apiContextIdListing}}")
.apiProperty("apiContextIdPattern", "{{apiContextIdPattern}}");
rest("/airports")
.get()
.id("getAirports")
.outType(Airports.class)
.to("direct:getAirports")
.get("/{id}")
.id("getAirport")
.outType(Airport.class)
.to("direct:getAirport")
.get("/health")
.id("health")
.outType(String.class)
.to("direct:health");
Now, I want to import this definition in AWS API Gateway. But, the same is not getting accepted because of the following portions in the API definition given above -
Need to remove
"x-className" : {
"type" : "string",
"format" : "demo.service.composite.airportinfo.datatypes.Airport"
}
Need to remove
"x-className" : {
"type" : "string",
"format" : "demo.service.composite.airportinfo.datatypes.Airports"
}
Need to replace
"schema" : {
"type" : "string",
"format" : "java.lang.String"
}
with
"schema" : {
"format" : "String"
}
Making these changes, I am able to import the definition in AWS API Gateway easily.
Is there a way to suppress Camel specific attributes in the swagger definition generated using camel-swagger?
Thanks.

No this is not possible, they are always included.
These types are extensions, eg they start with x- as documented in the spec: https://swagger.io/specification/#specificationExtensions
I logged a ticket to add support for this in the next release: https://issues.apache.org/jira/browse/CAMEL-11957
And we also fixed the primitive types in the responses to not use the format: https://issues.apache.org/jira/browse/CAMEL-11960

Related

Query in getting value of second attribute after giving value of first attribute inside array in Mongo db

I am a newbie in Mongo .
I have a requirement to build a query from a complex document inside a collection.
{ "_id" : "http://nsgfds.com",
"has Title" : [
{
"title" : {
"language" : "eng",
"value" : "eng title"
},
"origin" : "https://Ignore",
"score" : 7.5
},
{
"title" : {
"language" : "chi",
"value" : "Chinese title"
},
"origin" : "https://Ignore",
"score" : 7.5
},
{
"title" : {
"language" : "vie",
"value" : "Vietnamese title"
},
"origin" : "https://Ignore",
"score" : 7.5
},
{
"title" : {
"language" : "asm",
"value" : "Assamese title"
},
"origin" : "https://Ignore",
"score" : 7.5
}
]
}
My query wants to return value of "value" field when "language" and "_id" values given
suppose when I give "_id" and "language" the query should return only value of the "value" field based on "_id" and "language".
My query:
db.collectionname.aggregate([
{$match: {"_id": "http://nsgfds.com"}},
{
$project: {
hasTitle: {
$filter: {
input: "$hasTitle",
as:"item",
cond: { $eq: ["$title.language:eng", "$$item.value"]}
}
}
}
}
]).pretty();
Expected output:
{
"_id" : "http://nsgfds.com",
"hasTitle" : [{"title" : {"value" : "Wiley Title English title"}]
};
Actual Output:
{
"_id" : "http://nsgfds.com",
"hasTitle" : [
{
"title" : {
"language" : "eng",
"value" : "Wiley Title English title"
},
"origin" : "https://Ignore",
"score" : 7.5
},
{
"title" : {
"language" : "chi",
"value" : "chinese title"
},
"origin" : "https://Ignore",
"score" : 7.5
},
{
"title" : {
"language" : "vie",
"value" : "Vietnamese title"
},
"origin" : "https://Ignore",
"score" : 7.5
},
{
"title" : {
"language" : "asm",
"value" : "Assamese title"
},
"origin" : "https://Ignore",
"score" : 7.5
}
]
}
The error comes from your condition, where you should compare an element of the list ($$item) with a string (eng, asm, shi ...)
{
$eq: [
"$$item.title.language",
"eng"
]
}
But this will give you :
[
{
"_id": "http://nsgfds.com",
"hasTitle": [
{
"origin": "https://Ignore",
"score": 7.5,
"title": {
"language": "eng",
"value": "eng title"
}
}
]
}
]
To get your desired output, you will need another $project
{
$project: {
"hasTitle.title.value": "$hasTitle.title.value"
}
}
result :
[
{
"_id": "http://nsgfds.com",
"hasTitle": [
{
"title": {
"value": [
"eng title"
]
}
}
]
}
]

json contain array how to populate it in thyemleaf (how can i get carv value in thyemleaf)

{
"_id" : ObjectId("6128c6c54859a6c1579f98ad"),
"classByIngredient" : "",
"cuisineStyle" : "Indian - North",
"dietPreference" : "Vegetarian",
"dishClass" : "Staple",
"dishName" : "Aloo Gobi Paratha",
"dishVariation" : "Aloo Gobi Paratha with ghee",
"dishNameLower" : "aloo gobi paratha",
"dishVariationLower" : "aloo gobi paratha with ghee",
"sizes" : [
{
"name" : "Piece",
"calories" : {
"value" : "164.0",
"unit" : "kcal"
},
"carbs" : {
"value" : "29.0",
"unit" : "gms"
},
"fat" : {
"value" : "2.9",
"unit" : "gms"
},
"fibre" : {
"value" : "0",
"unit" : "gms"
},
"iron" : {
"value" : "0.0",
"unit" : "mg"
},
"protein" : {
"value" : "4.6",
"unit" : "gms"
},
"rawWeight" : "",
"sodium" : {
"value" : "0",
"unit" : "mg"
},
"sugars" : {
"value" : "0",
"unit" : "gms"
},
"calcium" : {
"value" : "0.0",
"unit" : "mg"
},
"cookedWeight" : "100 gms",
"measurement" : "https://smit-diet-measurement.s3.amazonaws.com/Piece.png",
"type" : "ingredient"
}
],
"enable" : "true",
"householdMeasure" : "Piece",
"createdAt" : ISODate("2021-08-27T11:04:36.212Z"),
"verified" : true,
"updatedAt" : ISODate("2021-08-27T11:04:36.212Z"),
"_class" : "com.diet.library.dto.DietLibrary"
}

mongo query - getting a specific object (its `_id` is known) from array of object BUT this array is also a part of list of documents

how can I query to get the specific message from either inbox or outbox given that I have its _id --> i.e. message id.
this is my route
get("/getSpecificMessage/{Message_id}", (req, res) => {..}
what I can do is find all the buyer/dealer and then go through inbox/outbox of all the buyer/dealer and then find the message with _id i.e. message_id
--> can I do it better then that.
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e1"),
"address" : {
"proper_address" : "sarai kale khan",
"lat" : 28.58894,
"long" : "77.25692"
},
"name" : "prashant",
"password" : "jfalksdjlk;jasdl",
"email" : "prashant#gmail.com",
"inbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e4"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"from" : "1#1.com",
"message" : "message_1"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e3"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"from" : "2#2.com",
"message" : "message_2"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e2"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"from" : "3#3.com",
"message" : "message_3"
}
],
"outbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e7"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"to" : "1#1.com",
"message" : "message_4"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e6"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"to" : "1#1.com",
"message" : "message_5"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e5"),
"date" : ISODate("2018-09-04T23:03:41.627Z"),
"to" : "1#1.com",
"message" : "message_6"
}
],
"__v" : 0
}
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e8"),
"address" : {
"proper_address" : "najafgarah",
"lat" : 28.58894,
"long" : "77.25692"
},
"name" : "rahul",
"password" : "jkalsjdflasdl",
"email" : "rahul#gmail.com",
"inbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083eb"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "1#1.com",
"message" : "message_1"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ea"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "2#2.com",
"message" : "message_2"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083e9"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "3#3.com",
"message" : "message_3"
}
],
"outbox" : [
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ee"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"to" : "1#1.com",
"message" : "message_4"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ed"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"to" : "1#1.com",
"message" : "message_5"
},
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ec"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"to" : "1#1.com",
"message" : "message_6"
}
],
"__v" : 0
}
So if I have the _id = 5b8f0f4de276dd1e0ff083ea and I want
{
"_id" : ObjectId("5b8f0f4de276dd1e0ff083ea"),
"date" : ISODate("2018-09-04T23:03:41.639Z"),
"from" : "2#2.com",
"message" : "message_2"
}
I am not sure if you want it using MongoDB scripts or your app language (Nodejs if I am mistaken)
This is how it works on Mongo Shell Script
db.MODEL.find( { _id: DOCUMENT_ID },
{ inbox: { $elemMatch: { _id: MESSAGE_ID } } } )
Documentation is here
If this is not what you want, please update your post and add which language/framework you are using
This is what you could do using the aggregation framework:
var oId = new ObjectId("5b8f0f4de276dd1e0ff083ea");
db.collection.aggregate({
$match: { // can be skipped but I'd personally keep it because this will use an index on "input._id"/"output._id" (if there is one) to filter out irrelevant documents
$or: [
{ "inbox": { $elemMatch: { "_id": oId } } },
{ "outbox": { $elemMatch: { "_id": oId } } },
]
}
}, {
$project: {
result: {
$concatArrays: [
{ $filter: { "input": "$inbox", "cond": { $eq: [ "$$this._id", oId ] } } },
{ $filter: { "input": "$outbox", "cond": { $eq: [ "$$this._id", oId ] } } }
]
}
}
}, {
$unwind: "$result" // flatten the result array
}, {
$replaceRoot: {
"newRoot": "$result" // move "result" contents all the way up
}
})

Why I can't get the full document form array?

I have this document in stored in my collection:
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"companyId" : ObjectId("570269639caabe24e4e4043e"),
"descriptions" : [
{ "id" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test" },
{ "id" : ObjectId("570cd8164fff3a20f88c0dc9"), "description" : "test1" },
{ "id" : ObjectId("570ce6ba4fff3a052c8c570f"), "description" : "etr" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71716"), "description" : "43" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71717"), "description" : "43" },
{ "id" : ObjectId("570cf1b64fff3a1a14d71719"), "description" : "345" }
],
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test" },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"), "description" : "test1" }
]
}
Now I'm trying to get the objects from the options array that are matching the descriptionId and here is how I'm doing it
db.CustomFields.find({companyId: ObjectId("570269639caabe24e4e4043e")},{"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")})
But the result contains only the descriptionId - the description property is missing.
here is how the result looks like:
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a") },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a") }
]
}
Why my query is not returning the full document from the array, but only a part of it? Can you give me a push?
EDIT
This is what I'm expecting to get from the query
{ "_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a", "description" : "test") },
{ "descriptionId" : ObjectId("5707b95b8415b224a48a0b2a", "description" : "test1") }
]
}
You need to include the other query with "options.descriptionId" together with the companyId query and use projection to return just the array you want.
The following shows this:
db.customFields.find(
{
"companyId": ObjectId("570269639caabe24e4e4043e"),
"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")
},
{ "options": 1 }
);
Output
{
"_id" : ObjectId("5707b95b8415b224a48a0b2d"),
"options" : [
{
"descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"),
"description" : "test"
},
{
"descriptionId" : ObjectId("5707b95b8415b224a48a0b2a"),
"description" : "test1"
}
]
}
Try this
db.CustomFields.find({companyId: ObjectId("570269639caabe24e4e4043e"),"options.descriptionId": ObjectId("5707b95b8415b224a48a0b2a")})

how return array objects in find mongodb hierarchy data json

How to return the array object "items" as follows database db.customers using mongodb
I have problems when going to another page because the query returns me a single object, not the object array items
Customer
.find({user: req.user})
.filter(filter)
.order(sort)
.map(function(doc){
return doc.get('videos').items;
})
.page(pagination, function(err, customers){
if(err){
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else{
res.jsonp(customers);
}
});
below the json structure where is the array items:
{
"_id" : ObjectId("54de533a9585180c24f42887"),
"videos" : {
"items" : [{
"snippet" : {
"liveBroadcastContent" : "none",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/xLWBnEQQiIA/default.jpg"
}
},
"description" : "yea foodporn",
"title" : "#foodporn",
"channelId" : "UC7FN6ofleSjbqwWxt-FNDWQ",
"publishedAt" : "2015-01-16T03:21:35.000Z"
},
"id" : {
"videoId" : "xLWBnEQQiIA",
"kind" : "youtube#video"
},
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/M4htbh5SyAjA8ul83DhltycTU6E\"",
"kind" : "youtube#searchResult"
}, {
"snippet" : {
"liveBroadcastContent" : "none",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/v-1_pxe37-s/default.jpg"
}
},
"description" : "food porn delicius",
"title" : "#foodporn b",
"channelId" : "UC7FN6ofleSjbqwWxt-FNDWQ",
"publishedAt" : "2015-01-16T03:14:15.000Z"
},
"id" : {
"videoId" : "v-1_pxe37-s",
"kind" : "youtube#video"
},
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/0SfjWbYvc4M7hdvXUFAsnZF-3vU\"",
"kind" : "youtube#searchResult"
}, {
"snippet" : {
"liveBroadcastContent" : "none",
"thumbnails" : {
"default" : {
"height" : 90,
"width" : 120,
"url" : "https://i.ytimg.com/vi/DMfa1u8_3B8/default.jpg"
}
},
"description" : "o yeah foos porn",
"title" : "food porn a",
"channelId" : "UC7FN6ofleSjbqwWxt-FNDWQ",
"publishedAt" : "2015-01-16T03:03:09.000Z"
},
"id" : {
"videoId" : "DMfa1u8_3B8",
"kind" : "youtube#video"
},
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/ghsCGgrP3VQw6kH3v2LijEPPUv8\"",
"kind" : "youtube#searchResult"
}],
"pageInfo" : {
"resultsPerPage" : 50,
"totalResults" : 30
},
"nextPageToken" : "Cib3_b-JoP____96V0dSU3BHYjlCRQD_Af_-eldHUlNwR2I5QkUAARAeIbnxc1PpBEevOQAAAABfdkACSAFQAFoLCSuH7BJBzCiDEAE=",
"etag" : "\"k1sYjErg4tK7WaQQxvJkW5fVrfg/WBVbC5oh7cdDE3IlyjlCZpMW7bQ\"",
"kind" : "youtube#searchListResponse"
},
"user" : ObjectId("54de0f96b4d42d90195f892e"),
"__v" : 0
}
"user" : ObjectId("54de0f96b4d42d90195f892e"),
"__v" : 0
}
Customer.find(...).map(function(doc){
return doc.get('videos').items;
})
This what you're looking for?
I think the call you're looking for is
db.customers.find({ "user" : "xxx" }, { "videos.items" : 1 })
See the projection docs for more information about how to return specific fields from documents in a query.

Resources