google dialogflow how to query subset of knowledgebases in a mega bot - java

I have a mega bot eg: projectID_stage with id=stage-aahedc and there are two sub agents: projectID_automated id=stageautomated-spiccu and projectC.
the projectID_automated has knowledge base enabled. and it's included in the projectID_stage.
The problem:
When I trying to do a detectIntent request with some part of knowledgebase set. it failed because of permission denied.
the code is similar with - https://github.com/googleapis/java-dialogflow/blob/master/samples/snippets/src/main/java/com/example/dialogflow/DetectIntentKnowledge.java (except I added two knowledge names)
import com.google.cloud.dialogflow.v2beta1.*;
import com.google.common.collect.*;
import java.io.*;
import java.util.*;
public class DetectIntentTexts {
// DialogFlow API Detect Intent sample with text inputs.
public static Map<String, QueryResult> detectIntentTexts(
String projectId, List<String> texts, String sessionId, String languageCode, String... kbNames)
throws IOException {
Map<String, QueryResult> queryResults = Maps.newHashMap();
// Instantiates a client
try (SessionsClient sessionsClient = SessionsClient.create()) {
// Set the session name using the sessionId (UUID) and projectID (my-project-id)
SessionName session = SessionName.of(projectId, sessionId);
System.out.println("Session Path: " + session.toString());
// Detect intents for each text input
for (String text : texts) {
// Set the text (hello) and language code (en-US) for the query
TextInput.Builder textInput =
TextInput.newBuilder().setText(text).setLanguageCode(languageCode);
// Build the query with the TextInput
QueryInput queryInput = QueryInput.newBuilder().setText(textInput).build();
QueryParameters queryParameters =
QueryParameters.newBuilder().addKnowledgeBaseNames(kbNames[0])
.addKnowledgeBaseNames(kbNames[1]).build();
DetectIntentRequest detectIntentRequest =
DetectIntentRequest.newBuilder()
.setSession(session.toString())
.setQueryInput(queryInput)
.setQueryParams(queryParameters)
.build();
// Performs the detect intent request
DetectIntentResponse response = sessionsClient.detectIntent(detectIntentRequest);
// Display the query result
QueryResult queryResult = response.getQueryResult();
System.out.println("====================");
System.out.format("Query Text: '%s'\n", queryResult.getQueryText());
System.out.format(
"Detected Intent: %s (confidence: %f)\n",
queryResult.getIntent().getDisplayName(), queryResult.getIntentDetectionConfidence());
System.out.format(
"Fulfillment Text: '%s'\n",
queryResult.getFulfillmentMessagesCount() > 0
? queryResult.getFulfillmentMessages(0).getText()
: "Triggered Default Fallback Intent");
queryResults.put(text, queryResult);
}
}
return queryResults;
}
}
// [END dialogflow_detect_intent_text]
and the main function is like below:
String projectID_automated = "stageautomated-spiccu";
String projectID_stage = "stage-aahedc";
String finalProjectID = projectID_stage;
String sessionID = "123456789";
String language = "en-US";
List<String> text = Arrays.asList("is it safe for my family and pets");
// when you trying to list out the kbs....
// listKbs(projectID);
// projects/<Project ID>/knowledgeBases/<Knowledge Base ID>`
String kb1 = "pest control-1", kb2 = "pest control-2";
String full1 = "projects/" + projectID_automated + "/knowledgeBases/MTE0NTc1ODUxNjIwNTM3NDY2ODg";
String full2 = "projects/" + projectID_automated + "/knowledgeBases/Njg0NTg5OTE0MzYyNjM1ODc4NA";
Map<String, QueryResult> r = DetectIntentTexts.detectIntentTexts(finalProjectID, text, sessionID, language, full1, full2);
System.out.println(r);
When using the projectID_automated for full1 and full2, it failed with below error:
Caused by: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Project 'stageautomated-spiccu' in knowledge_base_names does not match project 'stage-aahedc' in session.
When using the projectID_stage for full1 and full2,
String full1 = "projects/" + projectID_stage + "/knowledgeBases/MTE0NTc1ODUxNjIwNTM3NDY2ODg";
String full2 = "projects/" + projectID_stage + "/knowledgeBases/Njg0NTg5OTE0MzYyNjM1ODc4NA";
it failed with below error in the query result
diagnostic_info {
fields {
key: "knowledge_connector_error"
value {
string_value: "INVALID_ARGUMENT: UNAUTHORIZED: You can\'t query KnowledgeBase under project: stage-aahedc, which is different than your agent project: stageautomated-spiccu"
}
}
Environment details
dialogflow#detectIntent
OS type and version: macos 10
Java version: jdk11
dialogflow version(s): dialogflow es + 'com.google.api.grpc:proto-google-cloud-dialogflow-v2beta1:0.99.5'
and 'com.google.cloud:google-cloud-dialogflow:4.1.5'

Related

Amazon Dynamodb ConditionalCheckFailedException throws java InaccessibleObjectException

I am using updateItem based on some condition. It works fine if condition is met, but it throws ConditionalCheckFailedException along with java InaccessibleObjectException if condition fails.
Why is it throwing InaccessibleObjectException? Also, how to handle it?
Update: Error also occurs in case of ValidationException
updateItemSpec = new UpdateItemSpec()
.withConditionExpression()
table.update(updateItemSpec).getItem()
You are using an old Java API for Amazon DynamoDB. To update a table, consider moving away from V1 and use the Enhanced Client - which is part of the AWS SDK for Java V2. More information here:
Mapping items in DynamoDB tables
Here is the code to update a table using the Enhanced Client.
public class EnhancedModifyItem {
public static void main(String[] args) {
String usage = "Usage:\n" +
" UpdateItem <key> <email> \n\n" +
"Where:\n" +
" key - the name of the key in the table (id120).\n" +
" email - the value of the modified email column.\n" ;
if (args.length != 2) {
System.out.println(usage);
System.exit(1);
}
String key = args[0];
String email = args[1];
Region region = Region.US_EAST_1;
DynamoDbClient ddb = DynamoDbClient.builder()
.region(region)
.build();
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
.dynamoDbClient(ddb)
.build();
String updatedValue = modifyItem(enhancedClient,key,email);
System.out.println("The updated name value is "+updatedValue);
ddb.close();
}
public static String modifyItem(DynamoDbEnhancedClient enhancedClient, String keyVal, String email) {
try {
//Create a DynamoDbTable object
DynamoDbTable<Customer> mappedTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
//Create a KEY object
Key key = Key.builder()
.partitionValue(keyVal)
.build();
// Get the item by using the key and update the email value.
Customer customerRec = mappedTable.getItem(r->r.key(key));
customerRec.setEmail(email);
mappedTable.updateItem(customerRec);
return customerRec.getEmail();
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
}
You can find all V2 DynamoDB examples here.

NotesException: A required argument has not been provided

My XPage gathers information which I use to populate a document in a different Domino database. I use a link button (so I can open another XPage after submission). The onClick code is as follows:
var rtn = true
var util = new utilities()
var hostURL = configBean.getValue("HostURL");
var userAttachment;
//set up info needed for checking duplicates
var attachName=getComponent("attachmentIdentifier").getValue();
var serialNbr = getComponent("serialNumber").getValue();
userAttachment = user+"~"+attachName;
var userSerial = user+"~"+serialNbr;
//Done setting info needed
//check for duplicates
rtn = utilBean.checkAttachmentName(userAttachment, userSerial)
//done
if(rtn==true){
var doc:Document = document1;
dBar.info("ALL IS GOOD");
var noteID:String=document1.getNoteID();
dBar.info("Calling saveNewAttachment using NoteID " + noteID )
rtn=utilBean.saveNewAttachment(session,noteID ); //<<< I get error here
dBar.info("rtn = " + rtn)
return "xsp-success";
view.postScript("window.open('"+sessionScope.nextURL+"')")
}else if (rtn==false){
errMsgArray = utilBean.getErrorMessages();
for(err in errMsgArray){
//for (i=0; i < errMsgArray.size(); i++){
dBar.info("err: "+ err.toString());
if (err== "nameUsed"){
//send message to XPXage
facesContext.addMessage(attachmentIdentifier.getClientId(facesContext) , msg(langBean.getValue("duplicateName")));
}
if(err=="serialUsed"){
//send message to XPXage
facesContext.addMessage(serialNumber.getClientId(facesContext) , msg(langBean.getValue("duplicateSerial")));
}
}
return "xsp-failure";
}
And the java code that delivers the error is this
public boolean saveNewAttachment(Session ses, String noteID)
throws NotesException {
debugMsg("Entering saveNewAttachment and NOTEID = "+noteID);
// this is used when the user saves an attachment to to the
// user profiles db
boolean rtn = false;
Document doc;
ConfigBean configBean = (ConfigBean)
ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(),
"configBean");
String dbName = (String) configBean.getValue("WebsiteDbPath");
debugMsg("A");
Database thisDB = ses.getDatabase(ses.getServerName(), dbName, false);
String value;
try {
debugMsg("noteID: "+noteID);
The next line throws the NotesException error
doc = thisDB.getDocumentByID("noteID");
debugMsg("C");
} catch (Exception e) {
debugMsg("utilitiesBean.saveAttachment: " + e.toString());
e.printStackTrace();
System.out.println("utilitiesBean.saveAttachment: " + e.toString());
throw new RuntimeException("utilitiesBean.saveAttachment: "
+ e.toString());
}
return rtn;
}
I might be going about this wrong. I want to save the document which the data is bound to the User Profile database but if I submit it I need to redirect it to a different page. That is why I am using a link, however, I am having a hard time trying to get the document saved.
Has document1 been saved before this code is called? If not, it's not in the backend database to retrieve via getDocumentByID().
I'm assuming this line has been copied into here incorrectly, because "noteID" is not a NoteID or a variable holding a NoteID, it's a string.
doc = thisDB.getDocumentByID("noteID");

JUnit testing (positive and negative testing)

This is the code I have written for JUnit Testing for positive and negative testing.
#Test
public void getMaintenenceIntervalsByMetadataOKTest() throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.set("vinModelYear", "2016");
params.set("vinModelCode", "1633F6");
params.set("vinEngineCode", "CZTA");
params.set("interval", "100000");
params.set("vinTransmissionCode", "");
params.set("importerNumber", "");
params.set("makeCode", "V");
params.set("descriptionText", "");
params.set("languageCode", "en-US");
params.set("dealerCode", "408083");
mvc.perform(get("/upg-admin-controller/maintenence-intervals-by-metadata")
.contentType(MediaType.APPLICATION_JSON)
.params(params))
.andExpect(status().isAccepted());
}
#Test
public void getMaintenenceIntervalsByMetadata400Test()
throws Exception {
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.set("vinModelYear", "2000");
params.set("vinModelCode", "8727R9");
params.set("vinEngineCode", "GTAV");
params.set("interval", "100000");
params.set("vinTransmissionCode", "");
params.set("importerNumber", "");
params.set("makeCode", "T");
params.set("descriptionText", "");
params.set("languageCode", "sp-MX");
params.set("dealerCode", "120021");
mvc.perform(get("/upg-admin-controller/maintenence-intervals-by-metadata")
.contentType(MediaType.APPLICATION_JSON)
.params(params))
.andExpect(status().isBadRequest());
}
Error:
Error: java.lang.AssertionError: Status expected:<202> but was:<400>.
I have been trying to fix it but cannot find a solution. Using EclEmma extension on Eclipse. (sorry if the code is out of line. The text box is small it splits one line of code into two lines.)
Also this is the Controller code that I am working with that has the QueryParams.
#RequestMapping(value = "/maintenence-intervals-by-metadata", method = RequestMethod.GET)
public ResponseEntity<List<AdminMaintenanceIntervalReponse>> findMaintenenceIntervalsByMetadata( #QueryParam("modelYear") String modelYear,
#QueryParam("modelCode") String modelCode, #QueryParam("engineCode") String engineCode, #QueryParam("interval") String interval ,
#QueryParam("transmissionCode") String transmissionCode , #QueryParam("importer") String importer, #QueryParam("make") String make,
#QueryParam("descriptionText") String descriptionText, #QueryParam("languageCode") String languageCode, #QueryParam("dealerCode") String dealerCode, #QueryParam("brand") String Brand) throws MPMSException {
LOGGER.log(Level.INFO, "Entered UPGAdminServiceController, getAllMaintenenceIntervalsByMetadata");
LOGGER.log(Level.INFO, "modelYear =" + modelYear +" modelCode = " + modelCode +" engineCode = " + engineCode +" interval = " + interval + "transmissionCode = " + transmissionCode + "importer = " + importer + "make = " + make + "descriptionText = " + descriptionText);
List<AdminMaintenanceIntervalReponse> allMaintenanceIntervalsList = new ArrayList<AdminMaintenanceIntervalReponse>();
try{
Integer modelYearParam = null;
if (modelYear!=null){
modelYearParam = Integer.parseInt(modelYear);
}
Integer intervalParam = null;
if (interval!=null){
intervalParam = Integer.parseInt(interval);
}
String modelCodeParam = null;
if (modelCode!=null){
modelCodeParam = String.valueOf(modelCode);
}
String engineCodeParam = null;
if (engineCode!=null){
engineCodeParam = String.valueOf(engineCode);
}
String transmissionCodeParam = null;
if (transmissionCode!=null){
transmissionCodeParam = String.valueOf(transmissionCode);
}
Integer importerParam = null;
if (importer!=null){
importerParam = Integer.parseInt(importer);
}
String makeParam = null;
if (make!=null){
makeParam = String.valueOf(make);
}
if (descriptionText!=null){
String.valueOf(descriptionText);
}
allMaintenanceIntervalsList = upgAdminMaintenanceCalcService.findMaintenanceIntervalsByMetadata(modelYearParam, modelCodeParam, engineCodeParam, intervalParam, transmissionCodeParam, importerParam, makeParam, descriptionText, languageCode, dealerCode);
} catch(MPMSException e){
throw e;
} catch (Exception e) {
throw new MPMSException(ErrorConstants.UNKNOWN.getErrorCode(), "No Data Available", ErrorConstants.UNKNOWN.toString(), e);
}
return new ResponseEntity<List<AdminMaintenanceIntervalReponse>>(allMaintenanceIntervalsList, HttpStatus.OK);
}
Can someone please help me correct this issue.
Your /maintenence-intervals-by-metadata endpoint has the following query parameters:
#QueryParam("modelYear")
#QueryParam("modelCode")
#QueryParam("engineCode")
#QueryParam("interval")
#QueryParam("transmissionCode")
#QueryParam("importer")
#QueryParam("make")
#QueryParam("descriptionText")
#QueryParam("languageCode")
#QueryParam("dealerCode")
#QueryParam("brand")
But your test is submitting a [GET] request to /maintenence-intervals-by-metadata with the following named parameters:
params.set("vinModelYear", "2016");
params.set("vinModelCode", "1633F6");
params.set("vinEngineCode", "CZTA");
params.set("interval", "100000");
params.set("vinTransmissionCode", "");
params.set("importerNumber", "");
params.set("makeCode", "V");
params.set("descriptionText", "");
params.set("languageCode", "en-US");
params.set("dealerCode", "408083");
So, the query params you supply do not match the query params expected by the /maintenence-intervals-by-metadata endpoint. There are name mismatches:
modelYear vs. vinModelYear
modelCode vs. vinModelCode
... etc
And at least one query parameter is not supplied: the endpoint declares #QueryParam("brand") but you are not supplying a parameter named "brand".
I suspect the message associated with the 400 error might include something like: Required String parameter '...' is not present.
If you change your invocation such that every one of the query parameters defined by the /maintenence-intervals-by-metadata endpoint has a supplied parameter value of the correct type (a String) then I think the 400 will no longer occur.

Java ExecutorService Runnable doesn't update value

I'm using Java to download HTML contents of websites whose URLs are stored in a database. I'd like to put their HTML into database, too.
I'm using Jsoup for this purpose:
public String downloadHTML(String byLink) {
String htmlInPage = "";
try {
Document doc = Jsoup.connect(byLink).get();
htmlInPage = doc.html();
} catch (org.jsoup.UnsupportedMimeTypeException e) {
// process this and some other exceptions
}
return htmlInPage;
}
I'd like to download websites concurrently and use this function:
public void downloadURL(int websiteId, String url,
String categoryName, ExecutorService executorService) {
executorService.submit((Runnable) () -> {
String htmlInPage = downloadHTML(url);
System.out.println("Category: " + categoryName + " " + websiteId + " " + url);
String insertQuery =
"INSERT INTO html_data (website_id, html_contents) VALUES (?,?)";
dbUtils.query(insertQuery, websiteId, htmlInPage);
});
}
dbUtils is my class based on Apache Commons DbUtils. Details are here: http://pastebin.com/iAKXchbQ
And I'm using everything mentioned above in a such way: (List<Object[]> details are explained on pastebin, too)
public static void main(String[] args) {
DbUtils dbUtils = new DbUtils("host", "db", "driver", "user", "pass");
List<String> categoriesList =
Arrays.asList("weapons", "planes", "cooking", "manga");
String sql = "SELECT lw.id, lw.website_url, category_name " +
"FROM list_of_websites AS lw JOIN list_of_categories AS lc " +
"ON lw.category_id = lc.id " +
"where category_name = ? ";
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (String category : categoriesList) {
List<Object[]> sitesInCategory = dbUtils.select(sql, category );
for (Object[] entry : sitesInCategory) {
int websiteId = (int) entry[0];
String url = (String) entry[1];
String categoryName = (String) entry[2];
downloadURL(websiteId, url, categoryName, executorService);
}
}
executorService.shutdown();
}
I'm not sure if this solution is correct but it works. Now I want to modify code to save HTML not from all websites in my database, but only their fixed ammount in each category.
For example, download and save HTML of 50 websites from the "weapons" category, 50 from "planes", etc. I don't think it's necessary to use sql for this purpose: if we select 50 sites per category, it doesn't mean we save them all, because of possibly incorrect syntax and connection problems.
I've tryed to create separate class implementing Runnable with fields: counter and maxWebsitesPerCategory, but these variables aren't updated. Another idea was to create field Map<String,Integer> sitesInCategory instead of counter, put each category as a key there and increment its value until it reaches maxWebsitesPerCategory, but it didn't work, too. Please, help me!
P.S: I'll also be grateful for any recommendations connected with my realization of concurrent downloading (I haven't worked with concurrency in Java before and this is my first attempt)
How about this?
for (String category : categoriesList) {
dbUtils.select(sql, category).stream()
.limit(50)
.forEach(entry -> {
int websiteId = (int) entry[0];
String url = (String) entry[1];
String categoryName = (String) entry[2];
downloadURL(websiteId, url, categoryName, executorService);
});
}
sitesInCategory has been replaced with a stream of at most 50 elements, then your code is run on each entry.
EDIT
In regard to comments. I've gone ahead and restructured a bit, you can modify/implement the content of the methods I've suggested.
public void werk(Queue<Object[]> q, ExecutorService executorService) {
executorService.submit(() -> {
try {
Object[] o = q.remove();
try {
String html = downloadHTML(o); // this takes one of your object arrays and returns the text of an html page
insertIntoDB(html); // this is the code in the latter half of your downloadURL method
}catch (/*narrow exception type indicating download failure*/Exception e) {
werk(q, executorService);
}
}catch (NoSuchElementException e) {}
});
}
^^^ This method does most of the work.
for (String category : categoriesList) {
Queue<Object[]> q = new ConcurrentLinkedQueue<>(dbUtils.select(sql, category));
IntStream.range(0, 50).forEach(i -> werk(q, executorService));
}
^^^ this is the for loop in your main
Now each category tries to download 50 pages, upon failure of downloading a page it moves on and tries to download another page. In this way, you will either download 50 pages or have attempted to download all pages in the category.

Bulk Deletion of Rally Test Cases using Java

I need to delete several test cases i have in rally. Rally website says that the only way around this problem is to communication with Rally API and write a small bulk deletion script.
E.g. i need to delete from TC100 - TC150.
Anyone can help me with this? I am using java.
Thanks.
Per Rally Rest toolkit for Java documentation there is a Delete method.
Here is a code example that queries test cases by a tag name and then bulk-deletes these test cases. Your query criteria will be different, but if you choose to identify test cases by tag, note that Tags.Name contains "tag1" returns test cases that may have more than one tag applied, and not only those that a single "tag1".
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.QueryRequest;
import com.rallydev.rest.response.QueryResponse;
import com.rallydev.rest.request.DeleteRequest;
import com.rallydev.rest.response.DeleteResponse;
import com.rallydev.rest.util.Fetch;
import com.rallydev.rest.util.QueryFilter;
import java.net.URI;
public class GetTestCasesByTagAndBulkDelete {
public static void main(String[] args) throws Exception {
String host = "https://rally1.rallydev.com";
String apiKey = "_abc123"; //use your api key
String applicationName = "Find TestCases by Tag and bulk delete";
String workspaceRef = "/workspace/12345";
RallyRestApi restApi = null;
try {
restApi = new RallyRestApi(new URI(host),apiKey);
restApi.setApplicationName(applicationName);
QueryRequest request = new QueryRequest("TestCase");
request.setWorkspace(workspaceRef);
request.setFetch(new Fetch(new String[] {"Name", "FormattedID", "Tags"}));
request.setLimit(1000);
request.setScopedDown(false);
request.setScopedUp(false);
request.setQueryFilter(new QueryFilter("Tags.Name", "contains", "\"tag1\""));
QueryResponse response = restApi.query(request);
System.out.println("Successful: " + response.wasSuccessful());
System.out.println("Results Size: " + response.getResults().size());
for (int i=0; i<response.getResults().size();i++){
JsonObject tcJsonObject = response.getResults().get(i).getAsJsonObject();
System.out.println("Name: " + tcJsonObject.get("Name") + " FormattedID: " + tcJsonObject.get("FormattedID"));
int numberOfTags = tcJsonObject.getAsJsonObject("Tags").get("Count").getAsInt();
QueryRequest tagRequest = new QueryRequest(tcJsonObject.getAsJsonObject("Tags"));
tagRequest.setFetch(new Fetch("Name","FormattedID"));
//load the collection
JsonArray tags = restApi.query(tagRequest).getResults();
for (int j=0;j<numberOfTags;j++){
System.out.println("Tag Name: " + tags.get(j).getAsJsonObject().get("Name"));
}
System.out.println("deleting " + tcJsonObject.get("FormattedID")) ;
DeleteRequest deleteRequest = new DeleteRequest(tcJsonObject.get("_ref").getAsString());
DeleteResponse deleteResponse = restApi.delete(deleteRequest);
}
} finally {
if (restApi != null) {
restApi.close();
}
}
}
}

Categories