I have written an elastic query and it's working completely fine(verified in Kibana). But I have to call this query in java to convert it. I am trying to do it using the repository Query method. But its giving me error while compilation only. Please suggest the correct way to do it.
Error: Reason: No property searchLocationOnLevel found for type LocationSearch!; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property searchLocationOnLevel found for type LocationSearch!
Elastic Query(Working)
GET dev_skp_location/_search
{
"query": {
"bool":{
"must":[
{
"regexp": { "name": ".*pur*"}
},
{
"nested": {
"path": "locationType",
"query": {
"bool": {
"must": [
{
"match": { "locationType.level": "1" }
}]
}
},
"score_mode": "avg"
}
}
]
}
}
}
The JPA way I am implemented it.
#Query("{\n" +
" \"bool\":{\n" +
" \"must\":[\n" +
" {\n" +
" \"regexp\": { \"name\": \".*pur*\"}\n" +
" },\n" +
" {\n" +
" \"nested\": {\n" +
" \"path\": \"locationType\",\n" +
" \"query\": {\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" { \n" +
" \"match\": { \"locationType.level\": \"1\" } \n" +
" \n" +
" }]\n" +
" }\n" +
" },\n" +
" \"score_mode\": \"avg\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }")
Page<LocationSearch> searchLocationOnLevel(String loc, String level, Pageable pageable);
I was able to figure out later how to do it, but I still feel JPA should have worked too. Anyone who has a better explanation for this is most welcome.
I wrote a Query Builder method and called by using normal Elastic Search Query Methods.
public Query AutoCompleteLocationQueryBuilder(String locationTerm, String level, Long tenantId){
QueryBuilder tenantQuery = QueryBuilders
.matchQuery("tenantId", tenantId);
String regexExpression = ".*" + locationTerm + "*";
QueryBuilder regexQuery = QueryBuilders.regexpQuery("name",regexExpression);
String nestedPath="locationType";
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
MatchQueryBuilder matchQuery =
QueryBuilders.matchQuery("locationType.level", level);
NestedQueryBuilder nestedQuery = QueryBuilders
.nestedQuery(nestedPath, boolQueryBuilder.must(matchQuery), ScoreMode.Avg);
QueryBuilder finalQuery = QueryBuilders.boolQuery()
.must(tenantQuery)
.must(regexQuery)
.must(nestedQuery);
return new NativeSearchQueryBuilder()
.withQuery(finalQuery)
.build()
.setPageable(PageRequest.of(0, 10));
}
I send a http POST request to an azure timeseries insights by using the standard Spring Boot weblient.
Inside the response body I miss values.
Environment:
Windows 10
Java 11 (ibm-semeru_jdk-11.0.13+8_openj9 and amazon-corretto_jdk11.0.13_8)
Spring Boot 2.5.6
OkHttpClient 4.9.2
IntelliJ IDEA 2021.2.3
Here are my steps:
I try this with the spring boot webclient
final ResponseEntity<String> responseEntity = webClient.post()
.uri(tsiUrl)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(requestBody)
.retrieve()
.toEntity(String.class)
.block();
return responseEntity != null ? responseEntity.getBody() : null;
and this with OkHttpClient (to verify the response, but I get the same reponse content)
public class App
{
public static final okhttp3.MediaType JSON = okhttp3.MediaType.get("application/json; charset=utf-8");
public static void main( String[] args )
{
String requestBody = "{\n"
+ " \"aggregateSeries\": {\n"
+ " \"searchSpan\": {\n"
+ " \"from\": \"2021-01-01T00:00Z\",\n"
+ " \"to\": \"2021-12-31T00:00:01Z\"\n"
+ " },\n"
+ " \"timeSeriesId\": [\n"
+ " \"edge-goldwind-qa-002-astraios\",\n"
+ " \"GcmProcessed\"\n"
+ " ],\n"
+ " \"interval\": \"P1D\",\n"
+ " \"inlineVariables\": {\n"
+ " \"gcm01DeteriorationMax\": {\n"
+ " \"kind\": \"numeric\",\n"
+ " \"value\": {\n"
+ " \"tsx\": \"$event.GCM01Deterioration.Double\"\n"
+ " },\n"
+ " \"filter\": null,\n"
+ " \"aggregation\": {\n"
+ " \"tsx\": \"max($value)\"\n"
+ " }\n"
+ " },\"gcm01TemperatureOpticsMax\": {\n"
+ " \"kind\": \"numeric\",\n"
+ " \"value\": {\n"
+ " \"tsx\": \"$event.GCM01TemperatureOptics.Long\"\n"
+ " },\n"
+ " \"filter\": null,\n"
+ " \"aggregation\": {\n"
+ " \"tsx\": \"max($value)\"\n"
+ " }\n"
+ " }\n"
+ " },\n"
+ " \"projectedVariables\": [\n"
+ " \"gcm01DeteriorationMax\",\n"
+ " \"gcm01TemperatureOpticsMax\"\n"
+ " ]\n"
+ " }\n"
+ "}";
String token = "bearertoken"; //removed original bearer token
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.header("Authorization", "Bearer " + token)
.url("https://1ff924d7-55b5-48c7-8c29-7fcbc18b8776.env.timeseries.azure.cn/timeseries/query?api-version=2020-07-31&storeType=WarmStore")
.post(RequestBody.create(requestBody, JSON))
.build();
Response response = client.newCall(request).execute();
final ResponseBody body = response.body();
final String string = body.string();
} catch (Exception e) {
e.fillInStackTrace();
}
}
}
and I send this POST body:
{
"aggregateSeries": {
"searchSpan": {
"from": "2021-01-01T00:00Z",
"to": "2021-12-31T00:00:01Z"
},
"timeSeriesId": [
"edge-goldwind-qa-002-astraios",
"GcmProcessed"
],
"interval": "P1D",
"inlineVariables": {
"gcm01DeteriorationMax": {
"kind": "numeric",
"value": {
"tsx": "$event.GCM01Deterioration.Double"
},
"filter": null,
"aggregation": {
"tsx": "max($value)"
}
},"gcm01TemperatureOpticsMax": {
"kind": "numeric",
"value": {
"tsx": "$event.GCM01TemperatureOptics.Long"
},
"filter": null,
"aggregation": {
"tsx": "max($value)"
}
}
},
"projectedVariables": [
"gcm01DeteriorationMax",
"gcm01TemperatureOpticsMax"
]
}
}
The result of the Spring Boot webclient and OkHttpClient (not expected)
{"values":[null,..,null,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,null,...,null],"name":"gcm01DeteriorationMax","type":"Double"}
(I removed all the null values, to see the differences simple)
But if I send the same POST with Postman I get this result (expected):
{"values":[null,..,null,69.209999084472656,95.569999694824219,87.209999084472656,90.419998168945313,89.419998168945313,65.120002746582031,73.19000244140625,75.6500015258789,77.44000244140625,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,100.0,null,null,null,null,null,null,null,null,null,100.0,100.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,null,..,null],"name":"gcm01DeteriorationMax","type":"Double"}
As you can see the result of the Postman contains more values and less null values.
I have tried the same POST with .Net Core 5 httpclient and I get the same results as with the Postman.
My question is, does anyone have an idea what is going wrong here?
I am trying to make a google actions using DialogFlow api in java.
I am using Webhook for request Response for actions on DialogFlow Shown in
below image.
when Trying This Code it works fine and gives proper response as dialogflow have predefined actions facility.
Code:
#PostMapping("/webhook")
public ResponseEntity payload(RequestBody FulfillmentResponse fulfillmentResponse) {
log.info(fulfillmentResponse.getQueryResult().getQueryText());
return ResponseEntity.ok(HttpStatus.OK);
}
But When I am giving response Dynamically. It gives me an error.
Code:
#PostMapping("/webhook")
public ResponseEntity payload(RequestBody FulfillmentResponse fulfillmentResponse) {
log.info(fulfillmentResponse.getQueryResult().getQueryText());
return ResponseEntity.ok("{\n" +
" \"data\": {\n" +
" \"google\": {\n" +
" \"expectUserResponse\": true,\n" +
" \"richResponse\": {\n" +
" \"items\": [\n" +
" {\n" +
" \"simpleResponse\": {\n" +
" \"textToSpeech\": \"Choose a item\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"systemIntent\": {\n" +
" \"intent\": \"assistant.intent.action.TEXT\",\n" +
" \"data\": {\n" +
" \"#type\": \"type.googleapis.com/google.actions.v2.OptionValueSpec\",\n" +
" \"listSelect\": {\n" +
" \"title\": \"Hello\",\n" +
" \"items\": [\n" +
" {\n" +
" \"optionInfo\": {\n" +
" \"key\": \"first title\"\n" +
" },\n" +
" \"description\": \"first description\",\n" +
" \"image\": {\n" +
" \"url\": \"https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png\",\n" +
" \"accessibilityText\": \"first alt\"\n" +
" },\n" +
" \"title\": \"first title\"\n" +
" },\n" +
" {\n" +
" \"optionInfo\": {\n" +
" \"key\": \"second\"\n" +
" },\n" +
" \"description\": \"second description\",\n" +
" \"image\": {\n" +
" \"url\": \"https://lh3.googleusercontent.com/Nu3a6F80WfixUqf_ec_vgXy_c0-0r4VLJRXjVFF_X_CIilEu8B9fT35qyTEj_PEsKw\",\n" +
" \"accessibilityText\": \"second alt\"\n" +
" },\n" +
" \"title\": \"second title\"\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}");
}
Error:
2018-11-02 16:14:43.906 IST Error in fulfillment status received from app endpoint. See ResponseMetadata in the response. Status code: 14. Error message: Webhook error (206)
{
insertId: "6nwj8wf153t5q"
labels: {
channel: "preview"
querystream: "GOOGLE_USER"
source: "AOG_REQUEST_RESPONSE"
}
logName: "projects/elysiot-217606/logs/actions.googleapis.com%2Factions"
receiveTimestamp: "2018-11-02T10:44:43.940057016Z"
resource: {
labels: {
action_id: "actions.intent.TEXT"
project_id: "elysiot-217606"
version_id: ""
}
type: "assistant_action"
}
severity: "ERROR"
textPayload: "Error in fulfillment status received from app endpoint. See ResponseMetadata in the response. Status code: 14. Error message: Webhook error (206)"
timestamp: "2018-11-02T10:44:43.906927701Z"
trace: "projects/847724381623/traces/ABwppHFGjhCqYgY_YpSxJp5p9-s6NpvBRVzWdzGRhfypm0eZcqzYjDqjCVsdpxVXofc4xpOFLs4eAtWf9Ek"
}
same error in the form of screenshot:
I assume you are building the JSON response using Java. The request is sent from AoG to Dialogflow which invokes your webhook. In this case, Dialogflow wraps the original AoG request into a "originalDetectIntentRequest" as described in https://developers.google.com/actions/build/json/dialogflow-webhook-json
Since you are parsing the JSON request and building the response in your webhook, you should refer to the above URL for the raw JSON protocol.
Hope this helps.
We can surely, define string in Strings.xml & call - in that case the line break is not an issue.
But suppose I want to put it in my java page -- if I put it as follows - it will bring error
String strJson="
{
\"Employee\" :[
{
\"id\":\"01\",
\"name\":\"Gopal Varma\",
\"salary\":\"500000\"
},
{
\"id\":\"02\",
\"name\":\"Sairamkrishna\",
\"salary\":\"500000\"
},
{
\"id\":\"03\",
\"name\":\"Sathish kallakuri\",
\"salary\":\"600000\"
}
]
}";
I can fix the error by making it in a single line
String strJson=" { \"Employee\" :[ { \"id\":\"01\",\"name\":\"Gopal Varma\",\"salary\":\"500000\"},{\"id\":\"02\",\"name\":\"Sairamkrishna\",\"salary\":\"500000\"}, { \"id\":\"03\", \"name\":\"Sathish kallakuri\", \"salary\":\"600000\" } ] }";
But I want to know, instead is there any escape char or something to fix the error.
Java String literals cannot span multiple lines, but you can do this.
String strJson = "{\n" +
" \"Employee\" :[\n" +
" {\n" +
" \"id\":\"01\",\n" +
" \"name\":\"Gopal Varma\",\n" +
" \"salary\":\"500000\"\n" +
" }\n" +
" ]\n" +
"}";
You need to escape the strings properly,
Try this,
String strJson = "{" +
"\"Employee\": [{" +
"\"id\": \"01\"," +
"\"name\": \"Gopal Varma\"," +
"\"salary\": \"500000\"" +
"}, {" +
"\"id\": \"02\"," +
"\"name\": \"Sairamkrishna\"," +
"\"salary\": \"500000\"" +
"}, {" +
"\"id\": \"03\"," +
"\"name\": \"Sathish kallakuri\"," +
"\"salary\": \"600000\"" +
"}]" +
"}";
I have a JSON file, as String:
String compString = "{\n" +
" \"Component\": {\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]\n" +
" }\n" +
" }";
I have a bean representing it (correct if incorrectly)
public class Component {
String name;
String environment;
List<String> hosts = new ArrayList<String>();
List<String> directories = new ArrayList<String>();
// standard getters and setters
}
I am trying to feed this String to this class by:
Gson gson = new Gson();
Component component = gson.fromJson(compString, Component.class);
System.out.println(component.getName());
Above does not work. (I am getting null back, as if Component's name value is never set)
What am i missing please?
In fact, you have to remove the enclosing class from Json.
Indeed, JSON begins with the content of the enclosing class.
So your JSON would be:
String compString = "{\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]\n" +
" }\n";
String compString =
" {\n" +
" \"name\": \"Application\",\n" +
" \"environment\": \"QA\",\n" +
" \"hosts\": [\n" +
" \"box1\",\n" +
" \"box2\"\n" +
" ],\n" +
" \"directories\": [\n" +
" \"/path/to/dir1/\",\n" +
" \"/path/to/dir2/\",\n" +
" \"/path/to/dir1/subdir/\",\n" +
" ]}" ;
I think you should read more about json, I have removed something in your json string and then success.