I made a batch program which get some spread sheets and update them with Client Login method.
It had moved until 26 May.
But, it is no longer work now because authentication error happen.
I want to execute a batch program for SpreadSheets using the cron.
So, I tried to read the below pages and to migrate to OAuth2.0 method.
https://developers.google.com/api-client-library/java/google-api-java-client/client-login
https://developers.google.com/google-apps/spreadsheets/authorize
However, I couldn't understand how I use OAuth2.0 as a batch in Java code.
What I want to know is an authentication way that it doesn't need to operate manually when Spread Sheets API is run.
Please tell me a solution of this problem.
Thank you.
// current java source code
public static SpreadsheetService getService() {
SpreadsheetService service = new SpreadsheetService("MySpreadsheetIntegration");
service.setProtocolVersion(SpreadsheetService.Versions.V3);
// get Username and Password from JSON file
String username = getValueJsonFile("Username", JSON_FILE);
String password = getValueJsonFile("Password", JSON_FILE);
try {
service.setUserCredentials(username, password);
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("Error code: " + e.getCodeName());
log.error(getMessage("WRONG_USER_PASS"));
}
return service;
}
Related
I have an endpoint in Spring MVC controller that allow user to start download a file while I still process necessary data on the server. The endpoint looks like this:
#GetMapping(value = "/download.csv")
public void download(HttpServletResponse response) {
try {
response.setContentType(APPLICATION_OCTET_STREAM);
response.addHeader("Content-Disposition", "attachment; filename=name.csv");
final List listOfIds = getListOfIds();
for (id in ids) {
final String data = getAdditionalData(id)
write(data, response.getOutputStream())
response.flushBuffer()
}
} catch (Exception ex) {
// handle error
}
}
This code works fine, when the user accesses the download endpoint, the web browser will immediately ask if the user wants to save the file. Then I can process the expensive getAdditionalData(id) calls on the server during user downloading, instead of letting the user wait until I processed all the ids which could take a long time.
However, there is one problem: when getAdditionalData(id) fails and throws an exception, the web browser will show the download as "completed" instead of "failed" and leave a partial result to the user.
My problem is: is there any way from this endpoint to tell the web browser the download has failed so it won't show "completed" to the user? Thanks.
I am trying to setup Google Cloud Vision API, I have defined a Application Credential Variable through CMD by using set GOOGLE_APPLICATION_CREDENTIALS PathToJSON however this still does not allow me to connect to Google Cloud Vision API for OCR.
I have also tried to set it manually through the windows UI, however still no luck, I created and defined a project in the Google Cloud page, and generated a credential key, when it asked me "Are you planning to use this API with App Engine or Compute Engine?", I selected No.
I am currently using Googles boilerplate code
public class DetectText {
public static void main(String args[])
{
try{
detectText();
}catch (IOException e)
{
e.printStackTrace();
}
}
public static void detectText() throws IOException {
// TODO(developer): Replace these variables before running the sample.
String filePath = "C:\\Users\\Programming\\Desktop\\TextDetection\\Capture.PNG";
detectText(filePath);
}
// Detects text in the specified image.
public static void detectText(String filePath) throws IOException {
List<AnnotateImageRequest> requests = new ArrayList<>();
ByteString imgBytes = ByteString.readFrom(new FileInputStream(filePath));
Image img = Image.newBuilder().setContent(imgBytes).build();
Feature feat = Feature.newBuilder().setType(Feature.Type.TEXT_DETECTION).build();
AnnotateImageRequest request =
AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).build();
requests.add(request);
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (ImageAnnotatorClient client = ImageAnnotatorClient.create()) {
BatchAnnotateImagesResponse response = client.batchAnnotateImages(requests);
List<AnnotateImageResponse> responses = response.getResponsesList();
for (AnnotateImageResponse res : responses) {
if (res.hasError()) {
System.out.format("Error: %s%n", res.getError().getMessage());
return;
}
// For full list of available annotations, see http://g.co/cloud/vision/docs
for (EntityAnnotation annotation : res.getTextAnnotationsList()) {
System.out.format("Text: %s%n", annotation.getDescription());
System.out.format("Position : %s%n", annotation.getBoundingPoly());
}
}
}
}
static void authExplicit(String jsonPath) throws IOException {
}
}
I am not using a server or Google compute virtual machine.
Can someone please explain to me what the problem is, and how I would go about fixing it?
Stack Trace
java.io.IOException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
at com.google.auth.oauth2.DefaultCredentialsProvider.getDefaultCredentials(DefaultCredentialsProvider.java:134)
at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:119)
at com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(GoogleCredentials.java:91)
at com.google.api.gax.core.GoogleCredentialsProvider.getCredentials(GoogleCredentialsProvider.java:67)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:142)
at com.google.cloud.vision.v1.stub.GrpcImageAnnotatorStub.create(GrpcImageAnnotatorStub.java:117)
at com.google.cloud.vision.v1.stub.ImageAnnotatorStubSettings.createStub(ImageAnnotatorStubSettings.java:156)
at com.google.cloud.vision.v1.ImageAnnotatorClient.<init>(ImageAnnotatorClient.java:136)
at com.google.cloud.vision.v1.ImageAnnotatorClient.create(ImageAnnotatorClient.java:117)
at com.google.cloud.vision.v1.ImageAnnotatorClient.create(ImageAnnotatorClient.java:108)
at DetectText.detectText(DetectText.java:54)
at DetectText.detectText(DetectText.java:36)
at DetectText.main(DetectText.java:25)
Based on your error message, it seems that the GOOGLE_APPLICATION_CREDENTIALS environment variable is not being found.
On one hand, before trying to run the text detection sample code, follow the steps outlined in the documentation in order to discard that any of them has been skipped.
On the other hand, if you are using an IDE such as IntelliJ or Eclipse, you have to set the environment variable GOOGLE_APPLICATION_CREDENTIALS global through Windows System Properties, so it can be used by the IDE. Nevertheless, when testing I had to close and reopen the IDE for the changes to take effect and the aforementioned error would not appear.
Additionally, there is also a way to specify the location of the JSON file within the code, as shown in this example. However, it is not advisable to put it that way, it is best to use the environment variables.
I am following https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-bulk-identity-mgmt to do Bulk upload of Device Identities in Azure IoT Hub. All codes given here are in C# so I am converting it to JAVA equivalent.
Using Import devices example – bulk device provisioning I am getting following json-
{"id":"d3d78b0d-6c8c-4ef5-a321-91fbb6a4b7d1","importMode":"create","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"f8/UZcYbhPxnNdbSl2J+0Q==","secondaryKey":"lbq4Y4Z8qWmfUxAQjRsDjw=="}}}
{"id":"70bbe407-8d65-4f57-936f-ef402aa66d07","importMode":"create","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"9e7fDNIFbMu/NmOfxo/vGg==","secondaryKey":"nwFiKR4HV9KYHzkeyu8nLA=="}}}
To import the file from blob following function is called-
CompletableFuture<JobProperties> importJob = registryManager
.importDevicesAsync(inURI, outURI);
In the above code, we need to provide URI with SAS code, for that Get the container SAS URI equivalent code is below-
static String GetContainerSasUri(CloudBlobContainer container) {
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.setSharedAccessExpiryTime(new Date(new Date().getTime() + TimeUnit.DAYS.toMillis(1)));
sasConstraints.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE,
SharedAccessBlobPermissions.LIST, SharedAccessBlobPermissions.DELETE));
BlobContainerPermissions permissions = new BlobContainerPermissions();
permissions.setPublicAccess(BlobContainerPublicAccessType.CONTAINER);
permissions.getSharedAccessPolicies().put("testpolicy", sasConstraints);
try {
container.uploadPermissions(permissions);
} catch (StorageException e1) {
e1.printStackTrace();
}
String sasContainerToken = null;
try {
sasContainerToken = container.generateSharedAccessSignature(sasConstraints, "testpolicy");
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (StorageException e) {
e.printStackTrace();
}
System.out.println("URI " + container.getUri() +"?"+ sasContainerToken);
return container.getUri() + "?" + sasContainerToken;
}
Now the problem is coming here. For the output container I am getting following error-
java.util.concurrent.ExecutionException: com.microsoft.azure.sdk.iot.service.exceptions.IotHubBadFormatException: Bad message format! ErrorCode:BlobContainerValidationError;Unauthorized to write to output blob container. Tracking ID:2dcb2efbf1e14e33ba60dc8415dc03c3-G:4-TimeStamp:11/08/2017 16:16:10
Please help me to know why I am getting Bad Message Format error? Is there a problem with the SAS key generating code or my blob container is not having Write permission?
are you using a service or Account-level SAS? The error thrown suggests the service isn't authorized or have the delegated permissions to write to the designated blob container. Check out the resource here on how to setup an account level SAS and how to delegate read, write and delete operations on blob containers. https://learn.microsoft.com/en-us/rest/api/storageservices/Delegating-Access-with-a-Shared-Access-Signature?redirectedfrom=MSDN "snipped content: "An account-level SAS, introduced with version 2015-04-05. The account SAS delegates access to resources in one or more of the storage services. All of the operations available via a service SAS are also available via an account SAS. Additionally, with the account SAS, you can delegate access to operations that apply to a given service, such as Get/Set Service Properties and Get Service Stats. You can also delegate access to read, write, and delete operations on blob containers, tables, queues, and file shares that are not permitted with a service SAS. See Constructing an Account SAS for more information about account SAS."
I was facing the same issue while using private storage account as import/output container.
It is working smooth after I started using public storage account.
Anyway, it should work even with private storage account. So, I have raised an issue. For more into, you may refer this link.
I am currently working on a installed desktop application implemented in java. I intend to integrate Google Calendar API into the application.
During the authorization procedure, I come to this stage where I am able to get the authorization code only through triggering a browser where the user consent page is displayed. Users then have to click "accept" and will be redirected to a webpage where the authorization code is presented. Users are to copy this code to the Eclipse System.in in order for the authorization process to continue (to exchange the authorization code for a TokenResponse).
My question is that how can I simplify this process so that the user won't have to do this stupid copy-and-paste stuff for the authorization code to be received? (This won't work anyway, if the project is compiled into a jar file...) Currently all I know is that I will need to provide a callbackurl or something, I just can't figure this out. Therefore, I would appreciate a more concrete answer, rather than simply tell me the concepts.
Thanks in advance.
You have to use a service account (which comes with a private key) in order to skip the step involving user interaction. There is a detailed guide about this here.
The oauth2 authorization grant flow (I think, that's what you are doing) defines that your application gets the flow back via a HTTP redirect.
It's like this:
Your application opens a socket and listens there for HTTP requests
It now opens the browser and lets the user enter his/her credentials
The user clicks submit and sends the credentials to the oauth server
The server checks the credentials and, if correct, redirects the browser to your application (to the socket you opened in 1.)
Your application gets the auth code from the browser and exchanges it with the access ticket.
To let the server know where to redirect to, you use the oauth parameter redirect_uri in step 2.
This page seems to indicate that the auth code is in the title of the browser window, and the desktop app is expected to read it from there. (Gack.)
I found the solution.
Note: this is java code, but I bet it works the same way in all other languages.
The problem is my server is very restricted with and so I cannot start either browser there(since that is just a server without UI), either start localhost server for getting the code.
All you need is custom VerificationCodeReceiver:
VerificationCodeReceiver inbrowserListener = new VerificationCodeReceiver() {
#Override
public String getRedirectUri() throws IOException {
return "urn:ietf:wg:oauth:2.0:oob";
}
#Override
public String waitForCode() throws IOException {
// Reading console line
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
}
#Override
public void stop() throws IOException {
}
};
then simply use it in usual flow:
private static Credential getCredentials() {
.....
return new AuthorizationCodeInstalledApp(flow, inbrowserListener).authorize("user");
}
I'm currently trying to connect to the Bloomberg API but after trying for a day still not able to get it running.
Below is sample code from the API Guide, the part where I keep getting "Could not start session." when trying to connect.
public static void main(String[] args) throws Exception {
SessionOptions sessionOptions = new SessionOptions();
sessionOptions.setServerHost("localhost"); // default value
sessionOptions.setServerPort(8194); // default value
Session session = new Session(sessionOptions);
if (!session.start()) {
System.out.println("Could not start session.");
System.exit(1);
}
if (!session.openService("//blp/refdata")) {
System.out.println("Could not open service " +
"//blp/refdata");
System.exit(1);
}
}
I also tried the async example available in the guide, but no luck as well.
Is there anything that I missed in order to use the API? Or if I have to apply for an account in order to use the API, please do let me know :)
Your program runs fine on my machine. The few things you should check:
Are you on a Bloomberg terminal machine? (I assume you are using the desktop version)
Do you have a Bloomberg session open?
Is the bbcom.exe process running?
Just read the last line of your question: you need to have a Bloomberg account to be able to use their API and retrieve data.
My problem was solved after running "bbcomm.exe"
Check the following:
https://github.com/matthewgilbert/pdblp/issues/55