Spring Boot Graphql Remove duplicates from the Response - spring-boot

How to remove the duplicates from the response of Graphql automatically
Lets see the below graphql request I have.
query {
test1(request:{
userId: "test1#test.com"
}) {
id
name
product
}
}
And the Response is below:
{
"data": {
"test1": [{
"id": 1,
"name": "Test",
"product": "ABCD"
}, {
"id": 1,
"name": "Test",
"product": "ABCD-2"
},
]
}
}
Now if I remove the "product" in the query response field, the reponse looks like below. That is where the duplicates come.
{
"data": {
"test1": [{
"id": 1,
"name": "Test"
}, {
"id": 1,
"name": "Test"
},
]
}
}
Let me know if we have any library available to do this. We are using Spring Boot with below dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>

Related

springdoc-openapi: publish enum as reference when enum comes from generated code

I'm using
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.4.8</version>
</dependency>
For generating client-stubs via openapi-specs and generating my own openapi docoumentation.
I do have an API, lets call it just API-1, which I'm using within my project.
This API does provide an enum, simpfified this one:
#Schema(enumAsRef=true)
public enum SomethingEnum {
A,
B,
C
}
API one does provide an openapi-specification, there the enum is included as schema and referenced. That is all fine.
This enum I'm using in API-2. I let all models from API-1 generate with the openapi-generator-maven-plugin.
API-2 does provide an openapi specification, which looks simplified like this:
{
"paths": {
"/request": {
"get": {
"tags": [
"requests"
],
"operationId": "getSomething",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Something"
}
}
}
}
}
}
}
},
"schemas": {
"Something": {
"type": "object",
"properties": {
"somethingEnum": {
"type": "array",
"items": {
"type": "string",
"enum": [
"A",
"B",
"C"
]
}
},
,
"id": {
"type": "string"
}
}
}
}
}
And here is the problem: The SomethingEnum is not referenced via an Schema.
It should rather look like this:
{
"paths": {
"/request": {
"get": {
"tags": [
"requests"
],
"operationId": "getSomething",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Something"
}
}
}
}
}
}
}
},
"schemas": {
"Something": {
"type": "object",
"properties": {
"SomethingEnum ": {
"$ref": "#/components/schemas/SomethingEnum "
},
"id": {
"type": "string"
}
}
},
"SomethingEnum": {
"type": "string",
"enum": [
"A",
"B",
"C",
]
}
}
}
How can I achieve this? Is there a way I can either
configure the openapi-generator-maven-plugin to annote generated enums automatically with #Schema(enumAsRef=true)
configure springdoc somehow
?
I hope my problem is clear. Thanks for every suggestion.

NiFi Convert JSON to CSV via JsonPathReader or JsonTreeReader

I am trying to convert a JSON File into CSV but I don't seem to have any luck in doing so. My JSON looks something like that:
...
{
{"meta": {
"contentType": "Response"
},
"content": {
"data": {
"_type": "ObjectList",
"erpDataObjects": [
{
"meta": {
"lastModified": "2020-08-10T08:37:21.000+0000",
},
"head": {
"fields": {
"number": {
"value": "1",
},
"id": {
"value": "10000"
},
}
}
{
"meta": {
"lastModified": "2020-08-10T08:37:21.000+0000",
},
"head": {
"fields": {
"number": {
"value": "2",
},
"id": {
"value": "10001"
},
}
}
{
"meta": {
"lastModified": "2020-08-10T08:37:21.000+0000",
},
"head": {
.. much more data
I basically want my csv to look like this:
number,id
1,10000
2,10001
My flow looks like this:
GetFile -> Set the output-file name -> ConvertRecord -> UpdateAttribute -> PutFile
ConvertRecord uses the JsonTreeReader and a CSVRecordSetWriter
JsonTreeReader
CsvRecordSetWriter.
They both call on an AvroSchemaRegistry which looks like this:
AvroSchemaRegistry
The AvroSchema itself looks like this:
{
"type": "record",
"name": "head",
"fields":
[
{"name": "number", "type": ["string"]},
{"name": "id", "type": ["string"]},
]
}
But I only get this output:
number,id
,
Which makes sense because I'm not specifically indicating where those values are located. I used the JsonPathReader instead before but it only looked like this:
JsonPathReader
Which obvioulsy only gave me one record. I'm not really sure how I can configure either of the two to output exactly what I want. Help would be much appreciated!
Using ConvertRecord for JSON -> CSV is mostly intended for "flat" JSON files where each field in the object becomes a column in the outgoing CSV file. For nested/complex structures, consider JoltConvertRecord, it allows you to do more complex transformations. Your example doesn't appear to be valid JSON as-is, but assuming you have something like this as input:
{
"meta": {
"contentType": "Response"
},
"content": {
"data": {
"_type": "ObjectList",
"erpDataObjects": [
{
"meta": {
"lastModified": "2020-08-10T08:37:21.000+0000"
},
"head": {
"fields": {
"number": {
"value": "1"
},
"id": {
"value": "10000"
}
}
}
},
{
"meta": {
"lastModified": "2020-08-10T08:37:21.000+0000"
},
"head": {
"fields": {
"number": {
"value": "2"
},
"id": {
"value": "10001"
}
}
}
}
]
}
}
}
The following JOLT spec should give you what you want for output:
[
{
"operation": "shift",
"spec": {
"content": {
"data": {
"erpDataObjects": {
"*": {
"head": {
"fields": {
"number": {
"value": "[&4].number"
},
"id": {
"value": "[&4].id"
}
}
}
}
}
}
}
}
}
]

Parent Child Relation In Elastic Search 7.5

I am new to "Elastic Search" and currently trying to understand how does ES maintain "Parent-Child" relationship. I started with the following article:
https://www.elastic.co/blog/managing-relations-inside-elasticsearch
But the article is based on old version of ES and I am currently using ES 7.5 which states that:
The _parent field has been removed in favour of the join field.
Now I am currently following this article:
https://www.elastic.co/guide/en/elasticsearch/reference/7.5/parent-join.html
However, I am not able to get the desired result.
I have a scenario in which i have two indices "Person" and "Home". Each "Person" can have multiple "Home" which is basically a one-to-many relation. Problem is when I query to fetch all homes whose parent is "XYZ" person the answer is null.
Below are my indexes structure and search query:
Person Index:
Request URL: http://hostname/person
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"person_home": {
"type": "join",
"relations": {
"person": "home"
}
}
}
}
}
Home Index:
Request URL: http://hostname/home
{
"mappings": {
"properties": {
"state": {
"type": "text"
},
"person_home": {
"type": "join",
"relations": {
"person": "home"
}
}
}
}
}
Adding data in person Index
Request URL: http://hostname/person/_doc/1
{
"name": "shujaat",
"person_home": {
"name": "person"
}
}
Adding data in home index
Request URL: http://hostname/home/_doc/2?routing=1&refresh
{
"state": "ontario",
"person_home": {
"name": "home",
"parent": "1"
}
}
Query to fetch data: (To fetch all the records who parent is person id "1")
Request URL: http://hostname/person/_search
{
"query": {
"has_parent": {
"parent_type": "person",
"query": {
"match": {
"name": "shujaat"
}
}
}
}
}
OR
{
"query": {
"has_parent": {
"parent_type": "person",
"query": {
"match": {
"_id": "1"
}
}
}
}
}
Response:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
I am unable to understand what I am missing here or what is wrong with the above mentioned query as it not returning any data.
You should put the parent and child documents in the same index:
The join datatype is a special field that creates parent/child
relation within documents of the same index.
So the mapping would look like the following:
PUT http://hostname/person_home
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"state": {
"type": "text"
},
"person_home": {
"type": "join",
"relations": {
"person": "home"
}
}
}
}
}
Notice that it has both fields from your original person and home indexes.
The rest of your code should work just fine. Try inserting the person and home documents into the same index person_home and use the queries as you posted in the question.
What if person and home objects have overlapping field names?
Let's say, both object types have got field name but we want to index and query them separately. In this case we can come up with a mapping like this:
PUT http://hostname/person_home
{
"mappings": {
"properties": {
"person": {
"properties": {
"name": {
"type": "text"
}
}
},
"home": {
"properties": {
"name": {
"type": "keyword"
},
"state": {
"type": "text"
}
}
},
"person_home": {
"type": "join",
"relations": {
"person": "home"
}
}
}
}
}
Now, we should change the structure of the objects themselves:
PUT http://hostname/person_home/_doc/1
{
"name": "shujaat",
"person_home": {
"name": "person"
}
}
PUT http://hostname/person_home/_doc/2?routing=1&refresh
{
"home": {
"name": "primary",
"state": "ontario"
},
"person_home": {
"name": "home",
"parent": "1"
}
}
If you have to migrate old data from the two old indexes into a new merged one, reindex API may be of use.

How to convert a REST trigger pathParam to an activity input param

I am trying to create a flogo application with a path-paremeterized trigger. The trigger should respond to a call like this:
curl -X POST localhost:8080/trigger/apply
In the above example, "apply" is the string that I want to pass into the flows first activity as an input parameter called 'command'.
"handlers": [
{
"actionId": "kubectlAction",
"actionMappings": {
"input": [
{
"mapTo": "command",
"type": 1,
"value": "pathParams.command"
}
],
"output": [
{
"mapTo": "data",
"type": 1,
"value": "someResponse"
}
]
},
"settings": {
"method": "POST",
"path": "/trigger/:command"
}
}
]
I think the question is mainly, where (in which mapping scope) dies the REST input handler set the "command" property, and how do I reference it in my activity for an input Parameter.
Here are my current actions where I am trying to reference the property, but wihtout success:
"actions": [
{
"id": "kubectlAction",
"name": "my kubectl action",
"ref": "github.com/TIBCOSoftware/flogo-contrib/action/flow",
"data": {
"flow": {
"name": "my kubectl flow",
"attributes": [],
"rootTask": {
"id": 1,
"type": 1,
"tasks": [
{
"id": 2,
"type": 1,
"activityRef": "gitlab.spe.mobi/cbfr-demo/kubecontrol",
"name": "log",
"attributes": [],
"inputMappings": [
{
"type": 1,
"value": "$property[valve-red-a]",
"mapTo": "yaml"
},
{
"type": 1,
"value": "$flow.command",
"mapTo": "command"
}
]
}
],
"links": [
]
}
}
}
}
]
Any help much appreciated!!!
You should define the inputs for your flow, an the that will be used as activity input.

Elasticsearch - How to get filtered response without harming the links of each entity/field

So assuming that i have a mapping structure like the following
{
"mappings": {
"users": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
}
and I have indexed the following
users/52
{
"user": [
{
"id": 52,
"first": "John",
"last": "Smith",
"age": 21,
"school": {
"name": "STC",
"location": "Mt LV",
"District": "Western"
}
}
]
}
users/57
{
"user": [
{
"id": 57,
"first": "Alice",
"last": "White",
"age": 25,
"school": {
"name": "HFC",
"location": "DEH WLA",
"District": "Western"
}
}
]
}
What if I want to get certain fields using the id and without destroying the relationship link of each other.
For an example
If id == 57
then the return structure should consists only "first","age","school.name","school.District"
{
"user": [
{
"first": "Alice",
"age": 25,
"school": {
"name": "HFC",
"District": "Western"
}
}
]
}
How should you write a query for this sort of response in Elasticsearch?
Use response filtering in Elasticsearch. According to your scenario, a GET request would look like GET /_search?user=57&filter_path=first,age,school.name,school.District

Resources