I want to get the list of corpora.
curl -X GET --header "Authorization: Bearer xxxxxxxx(about 1200 characters IAM token)" "https://https://gateway-syd.watsonplatform.net/speech-to-text/api/v1/customizations/zzzzz(customization_id)/corpora"
result(This curl command succeeds.)
{"corpora": [
{
"out_of_vocabulary_words": 0,
"total_words": 10,
"name": "corpusname",
"status": "analyzed"
},
...
but...in Java,
HttpURLConnection urlConn = null;
try {
String urlStr ="https://https://gateway-syd.watsonplatform.net/speech-to-text/api/v1/customizations/zzzzz(customization_id)/corpora";
URL url = new URL(urlStr);
urlConn = (HttpURLConnection) url.openConnection();
String token = xxxxxxxx; // about 1200 characters IAM token
urlConn.setRequestProperty("Authorization", "Bearer " + token);
urlConn.setRequestMethod("GET");
urlConn.connect();
int status = urlConn.getResponseCode();
String resMessage = urlConn.getResponseMessage();
System.out.println("## HTTPStatus:" + status + " - " + resMessage); // "## HTTPStatus:400 - Bad Request"
} catch (xxx) {
// ...
}
result(failure)
## HTTPStatus:400 - Bad Request
I used same IAM token...
Why this error occurs?
(I'm sorry that I am not good at English.)
=============added 2020/03/03
I used watson SDK(ver.6.9.2). But another error(403) occurs...
IamOptions options = new IamOptions.Builder()
.accessToken(token)
.url(urlStr) // String urlStr = https://gateway-syd.watsonplatform.net/speech-to-text/api/v1/customizations/zzzzz(customization_id)/corpora
.build();
SpeechToText speechToText = new SpeechToText(options);
System.out.println();
ListCorporaOptions listCorporaOptions = new ListCorporaOptions.Builder()
.customizationId(customizations_id) // String curstomization_id = zzzzz
.build();
List<Corpus> corpus = speechToText.listCorpora(listCorporaOptions)
.execute()
.getCorpora(); // status: 403, error: Forbidden
System.out.println(corpus.get(0));
error:
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ForbiddenException: Forbidden]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:251)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:178)
at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:363)
at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:361)
at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:413)
at scala.concurrent.Future$$Lambda$6244/000000001ECBEAD0.apply(Unknown Source)
at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
at scala.concurrent.impl.Promise$$Lambda$3716/00000000172D40F0.apply(Unknown Source)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
Caused by: com.ibm.watson.developer_cloud.service.exception.ForbiddenException: Forbidden
at com.ibm.watson.developer_cloud.service.WatsonService.processServiceCall(WatsonService.java:474)
at com.ibm.watson.developer_cloud.service.WatsonService$WatsonServiceCall.execute(WatsonService.java:532)
at controllers.Controller.getCorpora(Controller.java:147)
at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$52(Routes.scala:1412)
at router.Routes$$anonfun$routes$1$$Lambda$6727/000000001FB17820.apply(Unknown Source)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:134)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:133)
at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$8$$anon$2$$anon$1.invocation(HandlerInvoker.scala:108)
at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:88)
at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:31)
Just use the Watson Java SDK!
https://cloud.ibm.com/apidocs/speech-to-text/speech-to-text?code=java#get-a-corpus
The example that Mike pointed to won't work with version 6, which is 2 major versions back. Can you update to version 8 of the SDK? See the migration guide.
Then your authentication code would be different and the example in the API reference should work:
IamAuthenticator authenticator = new IamAuthenticator("{apikey}");
SpeechToText speechToText = new SpeechToText(authenticator);
speechToText.setServiceUrl("{url}");
replace {url} with https://api.au-syd.speech-to-text.watson.cloud.ibm.com or https://gateway-syd.watsonplatform.net/speech-to-text/api
and replace {apikey} with your key.
Related
I try to follow instructions here (azure API reference) to manage Azure API Management through their API.
Looks like that (groovy):
import groovy.json.JsonSlurper
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClientBuilder
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
#Grab(group = 'org.apache.httpcomponents', module = 'httpclient', version = '4.5.2')
final def serviceName = 'my-api'
final def url = "https://${serviceName}.management.azure-api.net"
final String identifier = 'integration'
final byte[] primaryKey = Base64.decoder.decode('<key copy pasted from Azure web console > "API Management Service"')
final String expiry = '2018-03-01T12:26:00.0000000Z'
// SAS generation
def hmacSha256 = Mac.getInstance("HmacSHA256")
hmacSha256.init(new SecretKeySpec(primaryKey, "HmacSHA256"))
def toSign = "$identifier\n$expiry"
def signature = new String(Base64.encoder.encode(hmacSha256.doFinal(toSign.bytes)))
def sas = "SharedAccessSignature uid=${identifier}&ex=$expiry&sn=${signature}"
// URL Request
def getUsers = new HttpGet("$url/users?api-version=2017-03-01")
getUsers.setHeader('Authorization', sas)
def client = HttpClientBuilder.create().build()
def response = client.execute(getUsers)
println response
if (response.statusLine.statusCode == 200) {
println "Users: " + new JsonSlurper().parse(response.entity.content)
} else {
println "Error: ${response.entity.content.readLines()}"
}
Which result with:
HttpResponseProxy{HTTP/1.1 401 Unauthorized [Content-Length: 0, Strict-Transport-Security: max-age=31536000; includeSubDomains, WWW-Authenticate: SharedAccessSignature realm="", error="invalid_token", error_description="User is not found or signature is invalid.", Date: Wed, 14 Feb 2018 14:33:14 GMT] [Content-Length: 0,Chunked: false]}
Note: when I'm using a manually generated API, it does work. The issue is on the signature generation.
Does anyone can give me some direction or working code sample (in Java)?
For those having same issue and are lucky enough to find this answer, 2 issues:
signing algo is HmacSHA512, not HmacSHA256
primaryKey is not to be Base64 decoded. Just use it as it.
Working code (groovy):
import groovy.json.JsonSlurper
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClientBuilder
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
#Grab(group = 'org.apache.httpcomponents', module = 'httpclient', version = '4.5.2')
final def serviceName = '<your service name>'
final def url = "https://${serviceName}.management.azure-api.net"
final String identifier = '<your identifier>'
final byte[] primaryKey = '<copy paste of primaryKey>'.bytes // do not base64 decode!!!
final String expiry = LocalDateTime.now().plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'0000Z'"))
// SAS generation
def hmacSha512 = Mac.getInstance("HmacSHA512")
hmacSha512.init(new SecretKeySpec(primaryKey, "HmacSHA512"))
def dataToSign = "$identifier\n$expiry"
def signature = new String(Base64.encoder.encode(hmacSha512.doFinal(dataToSign.bytes)))
def sas = "SharedAccessSignature uid=${identifier}&ex=$expiry&sn=${signature}"
println "SAS=$sas"
// URL Request
def getUsers = new HttpGet("$url/users?api-version=2017-03-01")
getUsers.setHeader('Authorization', sas)
def client = HttpClientBuilder.create().build()
def response = client.execute(getUsers)
println response
if (response.statusLine.statusCode == 200) {
println "Users: " + new JsonSlurper().parse(response.entity.content)
} else {
println "Error: ${response.entity.content.readLines()}"
}
I'm struggling with an REST-Service written with JAX-RS.
I want to create and bind a client with the following code:
final String DEFAULT_RESOURCE_URL = "http://someURL:8180/";
try {
ResteasyClient client = new ResteasyClientBuilder().build().register(ClientResponseLoggingFilter.class);
ResteasyWebTarget target = client.target(DEFAULT_RESOURCE_URL).path(
"service/document/getdrawingbrowser/{documentId}/{documentType}/{partDocumentId}/{documentVersion}/{userName}");
HashMap<String, Object> keyValuesMap = new HashMap<String, Object>();
keyValuesMap.put("documentId", "xxxx");
keyValuesMap.put("documentType", "yyy");
keyValuesMap.put("partDocumentId", "000");
keyValuesMap.put("documentVersion", "000");
keyValuesMap.put("userName", "user");
Builder responseBuilder = target.resolveTemplates(keyValuesMap).request();
Response response = responseBuilder.get();
if (response.getStatus() == 200) {
byte[][] documents = response.readEntity(byte[][].class);
for (int i = 0; i < documents.length; i++) {
displayProperties(documents[i]);
}
} else {
Object entity = response.getEntity();
System.out.println(entity);
}
} catch (Throwable e) {
e.printStackTrace();
}
}
The REST-Service responds correctly I guess:
status: 200
date: Mon Sep 14 10:53:02 CEST 2015
last-modified: null
location: null
headers:
Connection :keep-alive,
Content-Disposition :attachment; filename=someFile.pdf,
Content-Type :application/octet-stream,
Date :Mon, 14 Sep 2015 08:53:02 GMT,
Server :WildFly/8,
Transfer-Encoding :chunked,
X-Powered-By :Undertow/1,
media-type: application
But in line 102 byte[][] documents = response.readEntity(byte[][].class); I'm getting an javax.ws.rs.ProcessingException which says:
javax.ws.rs.ProcessingException: Unable to find a MessageBodyReader of content-type application/octet-stream and type class [[B
at org.jboss.resteasy.core.interception.ClientReaderInterceptorContext.throwReaderNotFound(ClientReaderInterceptorContext.java:39)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:73)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:50)
at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.aroundReadFrom(GZIPDecodingInterceptor.java:59)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:53)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readFrom(ClientResponse.java:248)
at org.jboss.resteasy.client.jaxrs.internal.ClientResponse.readEntity(ClientResponse.java:181)
at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:217)
at DocumentTest.main(DocumentTest.java:102)
I have tried several .jar files and some approaches from here and here, but sadly, none of them worked out...
Any ideas?
Try to change you Content-Type to application/pdf.
I am having trouble while trying to make a getFeature request to a WFS server. I can make getCapabilities and describeFeatureType request.
String getCapabilities = "http://cbsservis.tkgm.gov.tr/tkgm.ows/wfs?SERVICE=WFS&REQUEST=Getcapabilities";
Map<String, String> connectionParameters = new HashMap<String, String>();
connectionParameters.put("WFSDataStoreFactory:USERNAME", "cbsdemouser");
connectionParameters.put("WFSDataStoreFactory:PASSWORD", "lp+12345");
connectionParameters.put("WFSDataStoreFactory:GET_CAPABILITIES_URL",
getCapabilities);
try {
DataStore data = DataStoreFinder.getDataStore(connectionParameters);
String typeNames[] = null;
typeNames = data.getTypeNames();
String typeName = typeNames[0];
SimpleFeatureType schema = data.getSchema(typeName);
System.out.println("Schema Attributes:"
+ schema.getAttributeCount());
SimpleFeatureSource source = data.getFeatureSource(typeName);
System.out.println("Metadata Bounds:" + source.getBounds());
FilterFactory ff = CommonFactoryFinder.getFilterFactory(GeoTools
.getDefaultHints());
DefaultQuery query = new DefaultQuery(typeName, Filter.INCLUDE);
query.setMaxFeatures(2);
SimpleFeatureCollection features = source.getFeatures(query);
String fid = null;
Iterator<SimpleFeature> iterator = (Iterator<SimpleFeature>) features
.features();
while (iterator.hasNext()) {
SimpleFeature feature = (SimpleFeature) iterator.next();
fid = feature.getID();
System.out.println(fid);
}
But when I tried to make a getFeature request, I got this errors:
WARNING: Unexpected response "401 Unauthorized" while downloading http://cbsservis.tkgm.gov.tr/tkgm.ows/wfs?service=WFS&version=1.0.0&request=DescribeFeatureType&typeName=TKGM%3Aadalar
Eyl 08, 2015 10:23:45 AM org.geotools.data.wfs.v1_0_0.NonStrictWFSStrategy createFeatureReaderGET
WARNING: java.io.IOException: org.xml.sax.SAXException: Failed to resolve
Eyl 08, 2015 10:23:45 AM org.geotools.data.wfs.v1_0_0.NonStrictWFSStrategy createFeatureReaderPOST
WARNING: java.io.IOException: Server returned HTTP response code: 500 for URL:
Implementing gcm third party server, we decided to use http integration and followed google instructions.
They provide an implementation of the integration here.
We used it and sent notifications to 500 000 users using java tasks to be more effective (we need to notify our users as quick as possible).
We were surprised because http request to GCM servers could take sometimes more than 15 sec. We set log in gcm-server source and find out this issue.
Code with custom log:
public MulticastResult sendNoRetry(Message message, List<String> registrationIds) throws IOException {
if (nonNull(registrationIds).isEmpty()) {
throw new IllegalArgumentException("registrationIds cannot be empty");
}
Date startDate = new Date();
Map<Object, Object> jsonRequest = new HashMap<Object, Object>();
setJsonField(jsonRequest, PARAM_TIME_TO_LIVE, message.getTimeToLive());
setJsonField(jsonRequest, PARAM_COLLAPSE_KEY, message.getCollapseKey());
setJsonField(jsonRequest, PARAM_RESTRICTED_PACKAGE_NAME, message.getRestrictedPackageName());
setJsonField(jsonRequest, PARAM_DELAY_WHILE_IDLE, message.isDelayWhileIdle());
setJsonField(jsonRequest, PARAM_DRY_RUN, message.isDryRun());
jsonRequest.put(JSON_REGISTRATION_IDS, registrationIds);
Map<String, String> payload = message.getData();
if (!payload.isEmpty()) {
jsonRequest.put(JSON_PAYLOAD, payload);
}
String requestBody = JSONValue.toJSONString(jsonRequest);
log.debug("JSON request: " + requestBody);
HttpURLConnection conn;
int status;
Date beforeHttpRequest = new Date();
try {
conn = post(GCM_SEND_ENDPOINT, "application/json", requestBody);
status = conn.getResponseCode();
} catch (IOException e) {
log.error("IOException posting to GCM", e);
return null;
}
Date afterHttpRequest = new Date();
String responseBody;
if (status != 200) {
try {
responseBody = getAndClose(conn.getErrorStream());
log.debug("JSON error response: " + responseBody);
} catch (IOException e) {
// ignore the exception since it will thrown an
// InvalidRequestException
// anyways
responseBody = "N/A";
log.error("Exception reading response: ", e);
}
throw new InvalidRequestException(status, responseBody);
}
try {
responseBody = getAndClose(conn.getInputStream());
} catch (IOException e) {
log.error("IOException reading response", e);
return null;
}
log.debug("JSON response: " + responseBody);
JSONParser parser = new JSONParser();
JSONObject jsonResponse;
try {
jsonResponse = (JSONObject) parser.parse(responseBody);
int success = getNumber(jsonResponse, JSON_SUCCESS).intValue();
int failure = getNumber(jsonResponse, JSON_FAILURE).intValue();
int canonicalIds = getNumber(jsonResponse, JSON_CANONICAL_IDS).intValue();
long multicastId = getNumber(jsonResponse, JSON_MULTICAST_ID).longValue();
MulticastResult.Builder builder = new MulticastResult.Builder(success, failure, canonicalIds, multicastId);
#SuppressWarnings("unchecked")
List<Map<String, Object>> results = (List<Map<String, Object>>) jsonResponse.get(JSON_RESULTS);
if (results != null) {
for (Map<String, Object> jsonResult : results) {
String messageId = (String) jsonResult.get(JSON_MESSAGE_ID);
String canonicalRegId = (String) jsonResult.get(TOKEN_CANONICAL_REG_ID);
String error = (String) jsonResult.get(JSON_ERROR);
Result result = new Result.Builder().messageId(messageId).canonicalRegistrationId(canonicalRegId).errorCode(error)
.build();
builder.addResult(result);
}
}
MulticastResult multicastResult = builder.build();
log.info("Http Request takes : "
+ (afterHttpRequest.getTime() - beforeHttpRequest.getTime()) / 1000 + " sec");
return multicastResult;
} catch (ParseException e) {
throw newIoException(responseBody, e);
} catch (CustomParserException e) {
throw newIoException(responseBody, e);
}
}
and the log:
2014-11-12 13:01:54,660 INFO executor-37 Sender:466 - Http Request takes : 4 sec
2014-11-12 13:01:57,383 INFO executor-49 Sender:466 - Http Request takes : 6 sec
2014-11-12 13:01:57,702 INFO executor-31 Sender:466 - Http Request takes : 6 sec
2014-11-12 13:01:58,565 INFO executor-42 Sender:466 - Http Request takes : 9 sec
2014-11-12 13:01:58,602 INFO executor-39 Sender:466 - Http Request takes : 7 sec
2014-11-12 13:01:59,477 INFO executor-45 Sender:466 - Http Request takes : 10 sec
2014-11-12 13:02:00,876 INFO executor-36 Sender:466 - Http Request takes : 20 sec
2014-11-12 13:02:01,018 INFO executor-43 Sender:466 - Http Request takes : 3 sec
2014-11-12 13:02:01,055 INFO executor-40 Sender:466 - Http Request takes : 6 sec
2014-11-12 13:02:02,440 INFO executor-41 Sender:466 - Http Request takes : 11 sec
2014-11-12 13:02:02,846 INFO executor-50 Sender:466 - Http Request takes : 5 sec
2014-11-12 13:02:03,135 INFO executor-47 Sender:466 - Http Request takes : 4 sec
2014-11-12 13:02:03,237 INFO executor-46 Sender:466 - Http Request takes : 4 sec
We tried it from different servers, and it is not a connectivity issue.
¿Someone may know why it takes so much time for a simple http request?
Everything ok in this code... it was as simple network issue.
I believed my server had 10 Mbytes/s upload rate, and it may be true, but in fact, it is physically far from google servers so upload rate was the bottleneck.
i have implemented the Subscriptions flow using the java library jsontoken, but am getting an error 500. happen in the sandox and production. any idea why it is?
this is the error :
POST https://checkout.google.com/inapp/api/v1/purchase_options 500 (Internal Server Error)
this is the code:
Calendar cal = Calendar.getInstance();
HmacSHA256Signer signer = new HmacSHA256Signer(ISSUER, null, SIGNING_KEY.getBytes());
JsonToken token = new JsonToken(signer);
token.setAudience("Google");
token.setParam("typ", "google/payments/inapp/subscription/v1");
token.setIssuedAt(new Instant(cal.getTimeInMillis()));
token.setExpiration(new Instant(cal.getTimeInMillis() + 60000L));
long prorated =cal.getTimeInMillis() + 2592000000L;
JsonObject request = new JsonObject();
request.addProperty("name", "Piece of Cake");
request.addProperty("description", "Virtual chocolate cake to fill your virtual tummy");
request.addProperty("sellerData", "user_id:1224245,offer_code:3098576987,affiliate:aksdfbovu9j");
request.addProperty("initialPayment", "{\"price\" : \"1.49\",\"currencyCode\" : \"USD\",\"paymentType\" : \"prorated\",}");
request.addProperty("recurrence", "{\"price\" : \"4.99\",\"currencyCode\" : \"USD\",\"startTime\" : \""+prorated+"\",\"frequency\" : \"monthly\",\"numRecurrences\" : \"12\",}");
JsonObject payload = token.getPayloadAsJsonObject();
payload.add("request", request);
token.serializeAndSign();