Java : How to extract parameters from Google Dialogflow V2 response - java

Does anyone know how to extract the parameters returned by the Google dialogflow v2 response? I am able to get the intents and confidence properly as there are high level methods available to do so. But it seems there is no method to get the parameters/list of params. The response contains a google protobuf Struct that has the params. Does anyone know how to extract the parameter names and values from it.
Here is a sample response
query_text: "next friday"
parameters {
fields {
key: "appointmentDate"
value {
struct_value {
fields {
key: "date"
value {
string_value: "2019-05-31T12:00:00+10:00"
}
}
}
}
}
}
all_required_params_present: true
fulfillment_messages {
text {
text: ""
}
}
intent {
name: "projects/dksjdkjsjksd-c824f/agent/intents/89a100c4973a"
display_name: "captureDate"
}
intent_detection_confidence: 1.0
language_code: "en"

It would be something lilke this:
for (Entry<String, Value> entry : queryResult.getParameters().getFieldsMap().entrySet()) {
if (entry.getValue().getKindCase().getNumber() == Value.STRING_VALUE_FIELD_NUMBER) {
log.debug("FOUND PARAM. KEY:" + entry.getKey() + " STRING VALUE: "
+ entry.getValue().getStringValue());
} else if (entry.getValue().getKindCase().getNumber() == Value.STRUCT_VALUE_FIELD_NUMBER) {
log.debug("FOUND PARAM. KEY:" + entry.getKey() + " STRUCT VALUE: "
+ entry.getValue().getStructValue());
}
else if (entry.getValue().getKindCase().getNumber() == Value.NUMBER_VALUE_FIELD_NUMBER) {
log.debug("FOUND PARAM. KEY:" + entry.getKey() + " NUMBER VALUE: "
+ String.valueOf(entry.getValue().getNumberValue()));
}
}

I was too focussed to parse and map the proto buffer to a Java bean. After spending hours and posting a question, a simple thought striked to my mind to find a way to convert the proto buffer to a json. And then it was all simple because I found this API
JsonFormat.printToString(protoMessage)
It sounds simple now but that is all because I changed my problem solving strategy from learning proto buffer and decoding it, to rather use a proto to json convertor and work with json format, which understand much better.

Related

Base64 JAVA encode with dynamic values in SCALA - GATLING

I'm USING GATLING AND trying to use in java's library "Base64" in scala for sending encode uder:password in header ("authorization") request, with dynamic values:
I'm trying to do as follow :
val register = {
exec(request.asJSON
.check(status.is(200))
.check(jsonPath("$..user").saveAs("user"))
.check(jsonPath("$..password").saveAs("password"))
).pause(1)
}
val myvalue: HttpRequestBuilder = Utils.createPostFormParamsRequest(
"myvalue",
login,
Map("value"-> ("Basic " + Base64.getEncoder.encodeToString((("${user}").getBytes() + ":" + ("${password}").getBytes()).getBytes("utf-8")))),
Map())
I'd tried also Base64.getEncoder.encodeToString(("${uesr}" + ":" + "${password}").getBytes("utf-8"))))
But it seems like the Base64 take the String "${user}" and not the actual value, so the encryption does not work properly.
I'd tried to :
val helper = {
exec { session =>
val user : String= (session("user").as[String])
val password : String= (session("password").as[String])
val temp = "Basic " + Base64.getEncoder.encodeToString((user + ":" + password).getBytes("utf-8"))
val temp2: HttpRequestBuilder = Utils.createPostFormParamsRequest(
"bla",
login,
Map("value"-> temp),
Map())
val assert = {
exec(helper.asJSON
.check(status.is(200))
.check(header("answer").saveAs("answer"))
).pause(1)
}
session
}
And here the encryption works properly, but the "exec" do not.
There is a way to save the values in run time without part of the exec?
I don't know Gatling that well, but I think this should work. It's not the prettiest but without seeing the full code and how it's used it's a bit difficult to come up with something that looks good:
var token: String = null
val registerAssert = exec(...)
def finalToken = {
Utils.createPostFormParamsRequest(
"Final token",
Constants.LOGIN,
Map("Authorization"-> token),
Map())
}
def saveToken(s: Session) = {
token = "Basic " + Base64.getEncoder.encodeToString((s("uuid").as[String].getBytes() + ":" + s("secret").as[String].getBytes()).getBytes("utf-8")
s
}
// now you're actually executing the above
scenario(...)
.exec(registerAssert)
.exec(saveToken(_))
.exec(finalToken) // I'm assuming finalToken is executable
The intention of this is to first save the token value in a class variable, and then only construct the finalToken request (which uses that token) afterwards. Hence the def, and when it's called the token value will have been set.

Create Release Notes using JIRA Rest API in HTML format in groovy

I am working on a script where I need to create the release notes using JIRA REST API in HTML format for any project.The below four field should come in that release notes.
Issue Key Module Summary Release Note
I am trying the below code but it is giving me only the issue Key field but need all other fields as well and in html file.Could you please suggest me on this?
Issue:1
Initially it was giving me the output in below format:
NTTB-2141
NTTB-2144
NTTB-2140
But now it is giving me the output json fromat way.
Code which I am trying from the groovy console:
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7' )
import groovyx.net.http.RESTClient
final String USAGE =
"Usage: -Djira.username=xxx -Djira.password=xxx -Djira.fixVersion=1.0"
String jiraUsername = 'ABCDEF'
String jiraPassword = '********'
String jiraFixVersion = '3.8.101'
println "Getting issues..."
if (!jiraUsername?.trim()) {
fail("Empty property: jira.username " + USAGE)
}
if (!jiraPassword?.trim()) {
fail("Empty property: jira.password " + USAGE)
}
if (!jiraFixVersion?.trim()) {
fail("Empty property: jira.fixVersion " + USAGE)
}
final String JIRA_SEARCH_URL = "https://jira.test.com/rest/api/latest/"
// see JIRA docs about search:
// https://docs.atlassian.com/jira/REST/latest/#idp1389824
String JQL = "project = NCCB"
JQL += " AND issuetype in standardIssueTypes()"
JQL += " AND status in (Resolved, Closed)"
JQL += " AND fixVersion = \"${jiraFixVersion}\""
def jira = new RESTClient(JIRA_SEARCH_URL)
def query = [:]
query['os_username'] = jiraUsername
query['os_password'] = jiraPassword
query['jql'] = JQL
query['startAt'] = 0
query['maxResults'] = 1000
try {
def resp = jira.get(path: "search",
contentType: "application/json",
query: query)
assert resp.status == 200
assert (resp.data instanceof net.sf.json.JSON)
resp.data.issues.each { issue ->
println issue.key
}
println "Total issues: " + resp.data.total
} catch (groovyx.net.http.HttpResponseException e) {
if (e.response.status == 400) {
// HTTP 400: Bad Request, JIRA JQL error
fail("JIRA query failed: ${e.response.data}", e)
} else {
fail("Failure HTTP status ${e.response.status}", e)
}
}
I suspect the code is right, except for that assertion:
assert (resp.data instanceof net.sf.json.JSON)
I get a groovy.json.internal.LazyMap (maybe you have changed versions of Groovy or Jira or something).
As a result, the assertion fails and Groovy tries to be helpful by giving you a comparison... but it shows you the toString() of the result, which is a huge mess of maps.
If you remove that assertion, it works for me, and I suspect it will work for you too.
Edit: huh... you cannot literally take "all" data and print to html. You will have to select the properties you need, and those depend on your Jira configuration. Here is an example with only 2 properties that should be universal:
def resp = jira.get(path: "search",
contentType: "application/json",
query: query)
assert resp.status == 200
def output = new File('issues.html')
output << "<html><body><ul>"
resp.data.issues.each { issue ->
def url = "https://yourjirainstance/browse/${issue.key}"
output << "<li>${issue.key}: ${issue.fields.summary}</li>"
}
output << "</ul></body></html>"
println "Exported ${resp.data.total} issues to ${output.name}"
See here details about what the service will give you.
If you just want an HTML dump, maybe the REST API is not what you want: you can also ask Jira to export results of JQL as a printable output (that will actually be html).

Get request parameter with Play Framework?

I am learning play framework and understand that I can map a request such as /manager/user as:
GET /manage/:user Controllers.Application.some(user:String)
How would I map a request like /play/video?video_id=1sh1?
You have at least two possibilities, let's call them approach1 and approach2.
In the first approach you can declare a routes param with some default value. 0 is good candidate, as it will be easiest to build some condition on top of it. Also it's typesafe, and pre-validates itself. I would recommend this solution at the beginning.
Second approach reads params directly from request as a String so you need to parse it to integer and additionally validate if required.
routes:
GET /approach1 controllers.Application.approach1(video_id: Int ?=0)
GET /approach2 controllers.Application.approach2
actions:
public static Result approach1(int video_id) {
if (video_id == 0) return badRequest("Wrong video ID");
return ok("1: Display video no. " + video_id);
}
public static Result approach2() {
int video_id = 0;
if (form().bindFromRequest().get("video_id") != null) {
try {
video_id = Integer.parseInt(form().bindFromRequest().get("video_id"));
} catch (Exception e) {
Logger.error("int not parsed...");
}
}
if (video_id == 0) return badRequest("Wrong video ID");
return ok("2: Display video no. " + video_id);
}
PS: LOL I just realized that you want to use String identifier... anyway both approaches will be similar :)
I would do it simply using:
GET /play/video Controllers.Application.video(video_id:String)
And at controller you would of course have, something like:
public static Result video(String video_id) {
return ok("We got video id of: " + video_id);
}
Alternatively, you dont have to add video_id:String since play seems to treat parameters as String by default, so it also works like this (at least with newest play):
GET /play/video Controllers.Application.video(video_id)
Typing localhost:9000/play/video?video_id=1sh1 to address bar should now you give view which prints:
We got video id of: 1sh1
To add more parameters is simple, like this:
GET /play/video controllers.Application.video(video_id:String, site:String, page:Integer)
Controller:
public static Result video(String video_id, String site, Integer page) {
return ok("We got video id of: " + video_id + " site: " + site + " page: " + page);
}
Typing localhost:9000/play/video?video_id=1as1&site=www.google.com&page=3 to address bar should now you give view which prints:
We got video id of: 1as1 site: www.google.com page: 3
You're welcome ^^.
I'm not quite sure if I got what you meant if you meant just to map a url to function in controller the answer of biesior is perfect but if you mean submitting a form with get method like
#helper.form(action = routes.YourController.page1()) {
}
and having the form's parameter in the url in the url-rewrited format like
page1/foo/bar instead of page1?param1=foo&param2=bar
There is no way to do that because that's http specs
I do often circumvent this limitation by getting the parameters in the first function in controller and then redirect them to another view just like the following
public static Result page1(){
String param1 = Form.form().bindFromRequest().get("param1");
String param2= Form.form().bindFromRequest().get("param2");
return ( redirect( routes.YourController.page2(param1,param2)));
}
Then have whatever in the page2
public static Result page2(String param1,String param2){
...............
}
And have this in the routes file :
GET page2/:param1/:param2 controllers.YourControllers.page2(param1 : String, param2 : String )
I hope it'd help but I'm not sure that's the best practise
Ok so I just read up the documentation and what I understand is that you need to
GET /play/video Controllers.Application.video()
And then in the controller call the getQueryString of the HttpRequest object
http://www.playframework.com/documentation/api/2.1.0/java/index.html

Obtain a share UpdateKey from LinkedIn using LinkedIn J and getNetworkUpdates() with Coldfusion

Using the "Network Updates API" example at the following link I am able to post network updates with no problem using client.postNetworkUpdate(updateText).
http://code.google.com/p/linkedin-j/wiki/GettingStarted
So posting works great.. However posting an update does not return an "UpdateKey" which is used to retrieve stats for post itself such as comments, likes, etc. Without the UpdateKey I cannot retrieve stats. So what I would like to do is post, then retrieve the last post using the getNetworkUpdates() function, and in that retrieval will be the UpdateKey that I need to use later to retrieve stats. Here's a sample script in Java on how to get network updates, but I need to do this in Coldfusion instead of Java.
Network network = client.getNetworkUpdates(EnumSet.of(NetworkUpdateType.STATUS_UPDATE));
System.out.println("Total updates fetched:" + network.getUpdates().getTotal());
for (Update update : network.getUpdates().getUpdateList()) {
System.out.println("-------------------------------");
System.out.println(update.getUpdateKey() + ":" + update.getUpdateContent().getPerson().getFirstName() + " " + update.getUpdateContent().getPerson().getLastName() + "->" + update.getUpdateContent().getPerson().getCurrentStatus());
if (update.getUpdateComments() != null) {
System.out.println("Total comments fetched:" + update.getUpdateComments().getTotal());
for (UpdateComment comment : update.getUpdateComments().getUpdateCommentList()) {
System.out.println(comment.getPerson().getFirstName() + " " + comment.getPerson().getLastName() + "->" + comment.getComment());
}
}
}
Anyone have any thoughts on how to accomplish this using Coldfusion?
Thanks
I have not used that api, but I am guessing you could use the first two lines to grab the number of updates. Then use the overloaded client.getNetworkUpdates(start, end) method to retrieve the last update and obtain its key.
Totally untested, but something along these lines:
<cfscript>
...
// not sure about accessing the STATUS_UPDATE enum. One of these should work:
// method 1
STATUS_UPDATE = createObject("java", "com.google.code.linkedinapi.client.enumeration.NetworkUpdateType$STATUS_UPDATE");
// method 2
NetworkUpdateType = createObject("java", "com.google.code.linkedinapi.client.enumeration.NetworkUpdateType");
STATUS_UPDATE = NetworkUpdateType.valueOf("STATUS_UPDATE");
enumSet = createObject("java", "java.util.EnumSet");
network = yourClientObject.getNetworkUpdates(enumSet.of(STATUS_UPDATE));
numOfUpdates = network.getUpdates().getTotal();
// Add error handling in case numOfUpdates = 0
result = yourClientObject.getNetworkUpdates(numOfUpdates, numOfUpdates);
lastUpdate = result.getUpdates().getUpdateList().get(0);
key = lastUpdate.getUpdateKey();
</cfscript>
You can also use socialauth library to retrieve updates and post status on linkedin.
http://code.google.com/p/socialauth

Reading request data on RESTlet

I am trying to create a restful service, using GAE and RESTlet on the server side and jQuery on the client side. Dispite the very poor documentation on RESTlet, I am determined to familiarise myself with a restful framework. However, I can't even get the basic functionality out of it.
The problem I have is that out of GET, POST, PUT and DELETE, only DELETE requests appear to deliver the data part.
The calls are made like this:
function put() {
try {
$.ajax({
url : url,
type : "PUT", //Same for GET, POST and DELETE
data : data,
success : function(data) {
try {
$("#results").text(data);
} catch (e) {
alert(e);
}
}
});
} catch (e) {
alert(e);
}
}
On the server-side I have a resource attached on a router, and it goes like this:
public class TaskResource extends ServerResource
{
String userID = "jada";
#Override
public void doInit()
{
super.doInit();
userID = (String) getRequestAttributes().get("user");
}
#Get
public String toString(String str)
{
return "GET: task of " + userID + " ||| DATA: " + str;
}
#Put
public String putit(String str)
{
return "PUT: task of " + userID + " ||| DATA: " + str;
}
#Post
public String postit(String str)
{
return "POST: task of " + userID + " ||| DATA: " + str;
}
#Delete
public String deleteit(String str)
{
return "DELETE: task of " + userID + " ||| DATA: " + str;
}
}
In the four cases above, as str, GET gets a null argument (understandable), PUT and POST get empty strings and DELETE gets the data actually sent.
I have experimented with changing the type of the arguments (to Representation or Form) and with more specific annotations (e.g #Get("xml")). No success so far.
Any recommendations are welcome.
Recommendation: Use a better-documented ReST framework. They're definitely out there. Jersey, for example, is really easy to get up and running, and it has the benefit of being an implementation of JAX-RS, of which there are several other mature implementations that you can play around with once you learn the API.
So, you are trying to fetch the request entity. I'm not sure if methods marked with #Put or #Post should have the request entity automatically passed in like you are expecting. I'm not sure why it works for DELETE though and not the others. Anyways, try the code below out and see if you get anything. If getEntityAsText() still comes up empty, there is likely something else going on.
Try this out:
#Put
public String putit() {
return this.getRequest().getEntityAsText();
}

Categories

Resources