Bing Search API error using odata4j - java

I am trying to run Bing search API. I used odata4j and tried the code provided here:
How to use Bing search api in Java
ODataConsumer c = ODataConsumers
.newBuilder("https://api.datamarket.azure.com/Bing/Search")
.setClientBehaviors(OClientBehaviors.basicAuth("accountKey", "{your account key here}"))
.build();
OQueryRequest<OEntity> oRequest = c.getEntities("Web")
.custom("Query", "stackoverflow bing api");
Enumerable<OEntity> entities = oRequest.execute();
After I registered in the bing service, I obtained the key and placed it inside the double quotation in the above code. I got the following error:
Exception in thread "main" java.lang.RuntimeException: Expected status OK, found Bad Request. Server response:
Parameter: Query is not of type String
at org.odata4j.jersey.consumer.ODataJerseyClient.doRequest(ODataJerseyClient.java:165)
at org.odata4j.consumer.AbstractODataClient.getEntities(AbstractODataClient.java:69)
at org.odata4j.consumer.ConsumerQueryEntitiesRequest.doRequest(ConsumerQueryEntitiesRequest.java:59)
at org.odata4j.consumer.ConsumerQueryEntitiesRequest.getEntries(ConsumerQueryEntitiesRequest.java:50)
at org.odata4j.consumer.ConsumerQueryEntitiesRequest.execute(ConsumerQueryEntitiesRequest.java:40)
at BingAPI.main(BingAPI.java:20)
Caused by: org.odata4j.exceptions.UnsupportedMediaTypeException: Unknown content type text/plain;charset=utf-8
at org.odata4j.format.FormatParserFactory.getParser(FormatParserFactory.java:78)
at org.odata4j.jersey.consumer.ODataJerseyClient.doRequest(ODataJerseyClient.java:161)
... 5 more
I could not figure out the problem.

All what you need is to set your query like that %27stackoverflow bing api%27
Here is my source code:
ODataConsumer consumer = ODataConsumers
.newBuilder("https://api.datamarket.azure.com/Bing/Search/v1/")
.setClientBehaviors(
OClientBehaviors.basicAuth("accountKey",
"{My Account ID}"))
.build();
System.out.println(consumer.getServiceRootUri() + consumer.toString());
OQueryRequest<OEntity> oQueryRequest = consumer.getEntities("Web")
.custom("Query", "%27stackoverflow%27");
System.out.println("oRequest : " + oQueryRequest);
Enumerable<OEntity> entities = oQueryRequest.execute();
System.out.println(entities.elementAt(0));

You can further try different queries with different filters by keep adding name-value pairs by using .custom("Type of parameter","parameter") of the oQueryrequest object.Say you want to search for indian food but you want only small square images.
ODataConsumer consumer = ODataConsumers
.newBuilder("https://api.datamarket.azure.com/Bing/Search/v1/")
.setClientBehaviors(
OClientBehaviors.basicAuth("accountKey",
"YOUR ACCOUNT KEY"))
.build();
System.out.println(consumer.getServiceRootUri() + consumer.toString());
OQueryRequest<OEntity> oQueryRequest = consumer.getEntities("Image")
.custom("Query", "%27indian food%27");
oQueryRequest.custom("Adult", "%27Moderate%27");
oQueryRequest.custom("ImageFilters", "%27Size:Small+Aspect:Square%27");
System.out.println("oRequest : " + oQueryRequest);
Enumerable<OEntity> entities = oQueryRequest.execute();
int count = 0;
Iterator<OEntity> iter = entities.iterator();
System.out.println(iter.next());

Related

AWS SDK Java DynamoDB - Query with Expression Attribute Name - An expression attribute value used in expression is not defined

Similar to: I cannot query my dynamodb table from aws lambda due to wrong filterexpression? and DynamoDB update error Invalid UpdateExpression: An expression attribute value used in expression is not defined
I am trying to code a way to query DynamoDB tables using partial matches on Partition Key / Sort Key in Java.
The DynamoDB table I am trying to access has a Partition key of "Type" (A restricted key word in DynamoDB, I know, but not my choice) and a Sort key of "Id". I know the "Type" but not the full Id, so I have researched the Query method using AWS SDK 2.x source code and have implemented as shown below:
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("begins_with ( " + idKey + ", :" + idValue + " )
AND #t = :" + typeValue)
.expressionAttributeNames(expressionNames)
.build();
QueryResponse response = dynamoDbClient.query(request);
However, when I run this code, I get the following error message:
Exception in thread "main" software.amazon.awssdk.services.dynamodb.model.DynamoDbException:
Invalid KeyConditionExpression: An expression attribute value used in expression is not defined; attribute value: :typeValue
It's as if it's not recognizing the fact that I have told the code use the Expression Attribute Names feature to replace the "#t" with "Type" (Which is a reserved keyword in DynamoDB)
Can anyone help?
EDIT: References for code:
https://docs.aws.amazon.com/code-samples/latest/catalog/javav2-dynamodb-src-main-java-com-example-dynamodb-Query.java.html
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html
https://www.javadoc.io/static/software.amazon.awssdk/dynamodb/2.7.14/software/amazon/awssdk/services/dynamodb/model/QueryRequest.html#expressionAttributeNames--
The name is fine, but you're prefixing both values with ':'. That causes a lookup in ExpressionAttributeValues, which you did not provide.
Never try to write dynamic values directly into the query string.
Your expressionAttributeName looks fine, but you forgot to provide a value for :typeValue so dynamoDB cannot know what to look for.
In addition to what you did, you need to add an expressionAttributeValue where you can provide proper values. See documentation here
Fixed Code for whoever wants it in the future (Thanks to #aherve and #MattTimmermans)
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
String typeKey = "typeKey";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
expressionNames.put("#i", "Id");
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":typeName", AttributeValue.builder().s(typeValue).build());
expressionValues.put(":idName", AttributeValue.builder().s(idValue).build());
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("#t = :typeName AND begins_with ( #i, :idName )")
.expressionAttributeNames(expressionNames)
.expressionAttributeValues(expressionValues)
.build();
response = dynamoDbClient.query(request);

Get binary document from QueryResult Couchbase response

I am using Couchbase 3.2 SDK, to query couchbase server. Like below
QueryResult result = cluster.query(
"SELECT *, Meta().id FROM bucketName USE KEYS ?",
queryOptions().parameters(JsonArray.from("pk")).readonly(true));
The response is like
[{"id":"pk","bucketName":"<binary (21 b)>"}]
My Document is a byte[], How can I get byte[] from the query response.
I have tried
parsing to custom object by doing
result.rowsAs(CustomClass.class)
Also tried
for (JsonObject row : result.rowsAsObject()) {
resposne.put((String) row.get("id"), ((String)row.get("ratingsAndReviewCollection")).getBytes("UTF-8"));
}
but both of them does not return the same doc that i had put.
This thread talks about this but does not give clear solution to this.
GetResult s = cluster.bucket("bucketName").defaultCollection().get("pk");
byte[] doc = s.contentAs(byte[].class);
It is not possible with N1QL, hence the solution in the referenced thread and the solution I provided to the specific question asked.
To pair arguments with results, get creative with reactor. The following is with spring-data-couchbase, where findById() returns Airport. Using the SDK replace findById() with get() which returns a GetResult.
Flux<Pair<String, Mono<Airport>>> pairFlux = Flux.fromIterable(list).map((airport) -> Pair.of(airport.getId(), airportRepository.findById(airport.getId())));
List<Pair<String, Mono<Airport>>> airportPairs = pairFlux.collectList().block();
for (Pair<String, Mono<Airport>> airportPair : airportPairs) {
System.out.println("id: " + airportPair.getFirst() + " airport: " + airportPair.getSecond().block());
}

Connect to HP quality center alm (version 12.50)

We need in our company to connect to HP alm and get differents tests and defects using Java. I work on 64bits machine (jdk 1.8). I tried many solutions on the web, here is different tests and errors I get on each test.
First method: Connecting using comp4j
Here is my Java code:
String url = "https://*****.saas.hpe.com/qcbin/";
String domain = "DEFAULT_827852153";
String project = "827852153_DEMO";
String username = "****";
String password = "*****";
try {
ITDConnection itd = ClassFactory.createTDConnection();
itd.initConnectionEx(url);
System.out.println("Test1:" + itd.connected());
itd.connectProjectEx(domain, project, username, password);
} catch (Exception e) {
e.printStackTrace();
}
The exception I get:
com4j.ExecutionException: com4j.ComException: 80040154 CoCreateInstance failed : Classe non enregistrée : .\com4j.cpp:153
at com4j.ComThread.execute(ComThread.java:236)
at com4j.Task.execute(Task.java:26)
at com4j.COM4J.createInstance(COM4J.java:99)
at com4j.COM4J.createInstance(COM4J.java:74)
at com.mercury.qualitycenter.otaclient.ClassFactory.createTDConnection(Unknown Source)
at infrastructure.Test.main(Test.java:24)
Second method: Connecting using rest api
I followed this tutorial step by step
https://www.consulting-bolte.de/index.php/tech-blog/hp-alm/hp-alm-rest-api/115-connect-to-hp-alm-via-java-using-rest-api
This tutorial uses ALM REST API official documentation
( https://admhelp.microfocus.com/alm/en/12.60/api_refs/REST_TECH_PREVIEW/ALM_REST_API_TP.html#REST_API_Tech_Preview/CodeSamples/infrastructure/RestConnector.htm%3FTocPath%3DExample%2520Application%7Cinfrastructure%7C_____10).
Whatever user or password I pass to the login method it returns status code 200. So login and password aren't considered in the code. But when i try read defects using this code:
AlmConnector alm = new AlmConnector();
RestConnector conn = RestConnector.getInstance();
conn.init(new HashMap<String, String>(), Constants.HOST,
Constants.DOMAIN, Constants.PROJECT);
alm.login("***", "***");
conn.getQCSession();
String defectUrl = conn.buildEntityCollectionUrl("defect");
defectUrl += "/89";
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Accept", "application/xml");
conn.first = false;
Response res = conn.httpGet(defectUrl, null, requestHeaders);
String postedEntityReturnedXml = res.toString();
Entity entity = EntityMarshallingUtils.marshal(Entity.class,
postedEntityReturnedXml);
List<Field> fields = entity.getFields().getField();
for (Field field : fields) {
System.out.println(field.getName() + " : "
+ field.getValue().size());
}
alm.logout();
alm = null;
I get this exception:
Exception in thread "main" javax.xml.bind.UnmarshalException: élément inattendu (URI : "", local : "html"). Les éléments attendus sont <{}Entity>
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:681)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
at
...........
I didn't change anything in the api infrastructure code.
I just want to write a simple Java code which allows me to connect to HP alm and just read defects.
For the COM4J case: you have three issues:
You have to use 32-bit version of Java, since OTAClient.dll is 32-bit and there is no 64-bit version of it unfortunately
You need to install ALM Connectivity Add-in from (https://yoursever/qcbin/PlugIns/TDConnectivity/TDConnect.exe) or register ALM Client
ALM server URL must end with qcbin, while you have: String url = "https://*****.saas.hpe.com/qcbin/"; (ends with /)
For the REST API case: looks like you got HTML instead of XML which is possible when error happens and return code is not 200, then ALM might return HTML with some error message. I would start with checking HTTP return code and checking what is in postedEntityReturnedXml
As a side note - we are developing a product for integration with ALM which is called Bumblebee (https://www.agiletestware.com/bumblebee), so maybe you might have a look at it.

How to get the API Endpoint of a SoapUI TestStep using Java

I would like to know how to get the API end point of a TestStep in SoapUI Xml using Java.
I have used the following,
for (int i=0; i<numberOfTestSteps; i++) {
WsdlTestStep testStep = testCase.getTestStepAt(i);
WsdlTestCaseRunner runner = new WsdlTestCaseRunner(testCase, new StringToObjectMap());
runner.runTestStep(testStep);
List<TestStepResult> resultList = runner.getResults();
for (TestStepResult result : resultList) {
String endPoint = ((MessageExchange)result).getEndpoint();
System.out.println("End Point = " + endPoint);
}
}
It only gives "www.test.com:8080". But I need the API end point as in the image.
Please someone help me to solve this.
Below should give you what you are looking for:
String resourcePath = ((MessageExchange)result).getResource().getFullPath();
System.out.println("Resource Path = " + resourcePath);
You may look at respective SoapUI's API
There is very simply way too if you wish to show that value from with SoapUI Project itself.
In the test case, there might be a REST Request Test step type. Add a Script Assertion as shown below:
log.info messageExchange.endpoint

Open graph fetching meta data

I am using open graph library to fetch the metadata from url.
I am getting the title and description from url link which follow og tag rules. How to get metadata from url link which don't follow og tag.
my simple code :
OpenGraph data = new OpenGraph(url, true);
response.setDescription(data.getContent("description"));
response.setMetaDataImage(data.getContent("image"));
response.setTitle(data.getContent("title"));
response.setMetaDataUrl(data.getContent("url"));
Data fetch is null.
I think you're talking about this library. If so, the boolean in the constructor serves the purpose:
public OpenGraph(String url, boolean ignoreSpecErrors) {
...
}
The way I use this library to fetch, for example, images is as follows:
OpenGraph og = new OpenGraph(url, true);
MetaElement[] imageElements = og.getProperties("image");
Perhaps you are just using the wrong getter? If the page has og tags, this snippet should work!
I had similar issues with opengraph-java (ie. getting null response).
I tried the example in the docs, but the response was null
OpenGraph movie = new OpenGraph("http://www.rottentomatoes.com/m/back_to_the_future/", true);
System.out.println("movie = " + movie)); // movie = null
Trying the false option for ignoreSpecErrors throws an exception java.lang.Exception: Does not conform to Open Graph protocol
So I made a library called ogmapper that's a little more flexible.
DefaultOgMapper ogMapper = new JsoupOgMapperFactory().build();
OgTags ogTags = ogMapper.process(new URL("http://www.rottentomatoes.com/m/back_to_the_future/"));
System.out.println("title = " + ogTags.getTitle()); // title = Back to the Future (1985)
Hopefully this is helpful!

Categories