I went the Java Quickstart and got a working application that just shows the full list of all the users connected to the account logged into. I have gone over the Java docs and the only thing I have found that pertains to the deletion of a user is the "setDeletionTime" in the User class, but I have tried that with a dummy account and set the time to "null" and tried to create a time that was set to today and neither worked for deleting the user. I have no clue what I am missing here.
Code I am using, most of it copied from the google quickstart
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledAp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.api.services.admin.directory.model.*;
import com.google.api.services.admin.directory.Directory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME =
"Directory API Java Quickstart";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(
System.getProperty("user.home"), ".credentials/admin-directory_v1-java-quickstart");
/** Global instance of the {#link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/** Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
* at ~/.credentials/admin-directory_v1-java-quickstart
*/
private static final List<String> SCOPES =
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
* #return an authorized Credential object.
* #throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
/* This does not work as of now
InputStream in = Quickstart.class.getResourceAsStream("src/resources/client_secret.json");
*/
InputStream in = new FileInputStream("src/resources/client_secret.json");
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();
Credential credential = new AuthorizationCodeInstalledApp(
flow, new LocalServerReceiver()).authorize("user");
System.out.println(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized Admin SDK Directory client service.
* #return an authorized Directory client service
* #throws IOException
*/
public static Directory getDirectoryService() throws IOException {
Credential credential = authorize();
return new Directory.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public static void main(String[] args) throws IOException {
// Build a new authorized API client service.
Directory service = getDirectoryService();
// Print the first 10 users in the domain.
Users result = service.users().list().setCustomer("my_customer").setOrderBy("email").execute();
List<User> users = result.getUsers();
if (users == null || users.size() == 0) {
System.out.println("No users found.");
} else {
for (User user : users) {
//This is where I tried to delete the users
//I have also tried using a normal for loop and nothing changes
that
System.out.println();
}
}
}
After reading everything I could find on this that google had to offer I finally figure it out.... I think. I am going to explain it here and have this as the answer because it worked; however, if I am doing something wrong then please tell me. Anyway, here is what I did:
So first thing's first. Every action (as far as I could tell) goes through http as a URL coupled with a command. This means in order for anything to happen you have to have a transport (given by the HttpTransport class) and a factory (given by the HttpRequestFactory class) to create the HttpRequest object that holds the action/command.
The request we will be making is the DELETE request shown here under "Delete a user account"
This can all be done by doing something like this:
HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
HttpRequestFactory HTTP_REQUEST_FACTORY = HTTP_TRANSPORT.createRequestFactory();
HttpRequest deleteRequest = HTTP_REQUEST_FACTORY.buildDeleteRequest(new GenericUrl("https://www.googleapis.com/admin/directory/v1/users/userkey"));
BUT WAIT! We are missing a very important key element here. We have to supply the Factory with the correct credentials to mark the header. Basically it is to tell google that we are able to delete the user. So how do we do that?
First we must set the scope, what we want access to. Our scope is ADMIN_DIRECTORY_USER. Set the scope like this: (MAKE SURE YOU DELETE THE FILE IN THE .credentials DIRECTORY IF YOU HAVE ALREADY RAN THIS PROGRAM!!!!)
List<String> SCOPES = Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER);
Next we need to have a credentials object. This can be done by using the method google gives us in their quickstart (the authorize method). To give the credentials to our factory we simply edit the line above by passing it the credentials object:
HttpRequestFactory HTTP_REQUEST_FACTORY = HTTP_TRANSPORT.createRequestFactory(credentials);
Note: do not pass it a HttpRequestInitializer from the credentials.getRequestInitializer() method as this is null (At least for me, this could be with just the way I am doing it but I rather not try it).
Here I will attach my code to show you a completed version of this:
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.admin.directory.DirectoryScopes;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME = "Deleting user example";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".credentials/admin-directory_v1-java-quickstart");
/** Global instance of the {#link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
//This creates the factory that is used for the user made requests
private static HttpRequestFactory HTTP_REQUEST_FACTORY;
//This is the credentials for the entire application
private static Credential credential;
/** Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
* at ~/.credentials/admin-directory_v1-java-quickstart
*/
private static final List<String> SCOPES = Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
* #return an authorized Credential object.
* #throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
/* This does not work as of now
InputStream in = Quickstart.class.getResourceAsStream("src/resources/client_secret.json");
*/
InputStream in = new FileInputStream("src/resources/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
public static void main(String[] args) throws IOException {
System.out.println("Deleting user with email");
credential = authorize();
HTTP_REQUEST_FACTORY = HTTP_TRANSPORT.createRequestFactory(credential);
HttpRequest deleteRequest = HTTP_REQUEST_FACTORY.buildDeleteRequest(new GenericUrl("https://www.googleapis.com/admin/directory/v1/users/REPLACEMEWITHEMAILORUSERKEY"));
deleteRequest.execute();
}
}
Related
I am new to utilizing Docker. I have a modified version of Google Sheet's "QuickStart" tutorial Java program within a Gradle Build (It has been modified to write to a few cells rather than reading cells, the Sheet ID has been changed too...the original Quickstart link is here: https://developers.google.com/sheets/api/quickstart/java ). The Java program works on its own, but I intend write a Dockerfile that will successfully build an image from the Gradle Build I currently have so it can be run in a container. Since Dockerfile syntax is nuanced and versatile, and because a Google Sheets Gradle Build has Google dependancies, I'm having trouble figuring out what to do here. Note that the original application uses a "basic gradle build" (you type "gradle init --type basic" to make it), and the Java code is in a src/main/java directory while the necessary credentials.json file (containing my client ID and secret so Google Sheets will work) is in src/main/resources. I'm also using Gradle 5.2.1 .
Here is the Java code...
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.ValueRange;
import com.google.api.services.sheets.v4.model.UpdateValuesResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
public class SheetsQuickstart {
private static final String APPLICATION_NAME = "Google Sheets API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = SheetsQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
//System.out.println("The getCredentials will be returned");
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
//Writes a few basic things to cells in a google sheet
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
final String spreadsheetId = "16WoDySciZRhD3QSH2_V1bk5kf_IFCcrPe49NE8WRxVg";
Sheets service = new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
ValueRange body = new ValueRange().setValues(getData());
UpdateValuesResponse result =
service.spreadsheets().values().update(spreadsheetId, "B1", body)
.setValueInputOption("RAW")
.execute();
}
public static List<List<Object>> getData() {
List<Object> data1 = new ArrayList<Object>();
data1.add("test1");
data1.add("test2");
data1.add("Row");
List<Object> data2 = new ArrayList<Object>();
data2.add("test3");
data2.add("test4");
data2.add("test5");
List<Object> data3 = new ArrayList<Object>();
data3.add("test6");
List<List<Object>> data = new ArrayList<List<Object>>();
data.add(data1);
data.add(data2);
data.add(data3);
return data;
}
}
My build.gradle file looks like this...
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'SheetsQuickstart'
sourceCompatibility = 1.7
targetCompatibility = 1.7
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.api-client:google-api-client:1.23.0'
compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
compile 'com.google.apis:google-api-services-sheets:v4-rev516-1.23.0'
}
Again, I used a "grovvy basic gradle build" and the directory structure can be found at https://guides.gradle.org/creating-new-gradle-builds/ near the beginning (also I added the src/main directory in the gradle directory's root). If I'm to "dockerize" this gradle build, what are my best available options in doing so? Would it only require one dockerfile, and is there an example of what it might look like? Are there any things fundamentally wrong with how I am approaching this? Thanks.
I am trying to add code to my android app that gets information from the UI and appends to a file in google drive. I have gotten as far sign in and authorization, as well as querying the file by name. Most of the SO threads I have read are for the old API or REST API.
However, I want to open it in Read/Write, or Write Only mode. I have tried looking at the quickstart demos and the drive API, but none of them are helpful.
How can I get the driveId programatically? I have tried getting the ID from drive itself. Is there a way to build Metadata that gets the ID from the query?
If I use openFile(DriveId.decodeFromString(actual_id).asDriveFile()
I get the following error:
java.lang.IllegalArgumentException: Invalid DriveId: **actual_id**
Is getting the file ID from the sharing link wrong: drive.google.com/open?id=some_id
If so, how can I achieve this?
private String id = "1fuTq1Q6MHrchgW7sZImjvSfpAShHhsbx";
private DriveFile file = DriveId.decodeFromString(id).asDriveFile();
private void getFile() {
Query q = new Query.Builder().addFilter(Filters.and(Filters.eq(SearchableField.TITLE, "HelloWorld.txt"))).build();
}
private void appendFile() {
Task<DriveContents> openTask = getResourceClient().openFile(file, DriveFile.MODE_READ_WRITE);
openTask.continueWithTask(task -> {
DriveContents driveContents = task.getResult();
ParcelFileDescriptor pfd = driveContents.getParcelFileDescriptor();
long bytesToSkip = pfd.getStatSize();
try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
// Skip to end of file
while (bytesToSkip > 0) {
long skipped = in.skip(bytesToSkip);
bytesToSkip -= skipped;
}
}
try (OutputStream out = new FileOutputStream(pfd.getFileDescriptor())) {
out.write("Hello world".getBytes());
}
// [START drive_android_commit_contents_with_metadata]
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setStarred(true)
.setLastViewedByMeDate(new Date())
.build();
Task<Void> commitTask =
getResourceClient().commitContents(driveContents, changeSet);
// [END drive_android_commit_contents_with_metadata]
return commitTask;
})
.addOnSuccessListener(this,
aVoid -> {
//showMessage(getString(R.string.content_updated));
Log.i("DRIVE", "Sucess");
finish();
})
.addOnFailureListener(this, e -> {
Log.e(TAG, "Unable to update contents", e);
// showMessage(getString(R.string.content_update_failed));
finish();
});
}
Also the file exists and the ID is valid.. Apparently
According to the documentation for the GDAA (Google Drive Android API), it should be possible to download a file based on its ID alone by using asDriveFile().
To do that you need a query and then store the information in a Task<MetadataBuffer>, and then should be able to files.get(0).asDriveFile() in the method where you are attempting to download by FileId. But even when pulling the metadata and use the query method, you are greeted with IllegalArgumentException invalid DriveId (which IS THE SAME ID, so it was never invalid), But it STILL shows it as invalid. I got tired of wrestling with it and went to the REST API.
Things to note: The file you are downloading MUST BE: Doc/Spreadsheet/Slides, photo or apps script.
You can choose the type of file you want to export it as. Here is the "truth table" for compatibility.
From this example it is easy enough to write your data and re-upload it. However, these files have a special encoding so you can't write the data directly.
Depending on what you need to accomplish, you can use the sheets api or
apache poi
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [START drive_quickstart]
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
public class DriveQuickstart {
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
private static String fileId = "super_secret_string";
private static final String OUTPUT = "super_secret_path";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved credentials/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE); //DONT USE THIS SCOPE IN PRODUCTION!
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// Print the names and IDs for up to 10 files.
FileList result = service.files().list()
.setPageSize(10)
.setFields("nextPageToken, files(id, name)")
.execute();
List<File> files = result.getFiles();
if (files == null || files.isEmpty()) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
//Download the file from it's known ID
FileOutputStream fos = new FileOutputStream(OUTPUT);
service.files().export(fileId, "text/plain").executeMediaAndDownloadTo(fos);
//Append some data to the file
FileWriter fw = new FileWriter(OUTPUT, true);
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine();
bw.write("Goodbye, World!");
bw.newLine();
bw.close();
}
}
// [END drive_quickstart]
I am trying to create a service account key programmatically in Java with the Google Cloud SDK, for an application not running on App/Compute engine. This question is similar to mine, but it is running on App engine, so I cannot use the same code as it uses classes from the App Engine API.
The relevant code is below. My issue is that AppIdentityCredential is part of the AppEngine API and thus cannot be used here. What can I pass in as a parameter instead? The third parameter in the new Builder() method takes in an HttpRequestInitializer, but I don't understand what implementation of this interface I should pass in. Any help is appreciated.
import com.google.api.services.iam.v1.Iam;
import com.google.api.services.iam.v1.model.CreateServiceAccountKeyRequest;
import com.google.api.services.iam.v1.model.ServiceAccountKey;
AppIdentityCredential credential = new AppIdentityCredential(
Arrays.asList("https://www.googleapis.com/auth/cloud-platform"));
Iam iam = new Iam.Builder(httpTransport, JSON_FACTORY,credential)
.setApplicationName(APPLICATION_NAME).build();
ServiceAccountKey key = iam.projects().serviceAccounts().keys()
.create(SERVICE_ACCOUNT_RESOURCE_NAME, new CreateServiceAccountKeyRequest()).execute();
You can use Application Default Credentials which will allow you to use the same code to fetch the credentials based on the environment where the application is running.
For example, it lets you use your gcloud account credentials when you're developing on your system. When the code runs on Google Compute Engine or Google App Engine, the code will automatically use the associated service account credentials for authentication in the APIs. You can also override it using GOOGLE_APPLICATION_CREDENTIALS environment variable if required to load the credentials from a JSON file instead.
Here is a working example which creates a new key for an existing service account and prints it.
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.iam.v1.Iam;
import com.google.api.services.iam.v1.IamScopes;
import com.google.api.services.iam.v1.model.CreateServiceAccountKeyRequest;
import com.google.api.services.iam.v1.model.ServiceAccountKey;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
public class IamDemo {
/** Name of the application. */
private static final String APPLICATION_NAME = "IamDemoJava";
/** Project Name. */
private static final String PROJECT_NAME = "MY_PROJECT_NAME";
/** Name of the service account to create a new key for. */
private static final String SERVICE_ACCOUNT_NAME = "dummy-sa";
/** Full email address of the service account. */
private static final String SERVICE_ACCOUNT_EMAIL =
SERVICE_ACCOUNT_NAME + "#" + PROJECT_NAME + ".iam.gserviceaccount.com";
/** Full service account resource string expected by the IAM API. */
private static final String SERVICE_ACCOUNT_RESOURCE_NAME =
"projects/" + PROJECT_NAME + "/serviceAccounts/" + SERVICE_ACCOUNT_EMAIL;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
public static void main() throws IOException, GeneralSecurityException {
Iam iam = initIam();
ServiceAccountKey key = createServiceAccountKey(iam);
// Print the key
System.out.println(key.toString());
}
private static Iam initIam() throws IOException, GeneralSecurityException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// Authenticate using Google Application Default Credentials.
GoogleCredential credential = GoogleCredential.getApplicationDefault();
if (credential.createScopedRequired()) {
List<String> scopes = new ArrayList<>();
// Enable full Cloud Platform scope.
scopes.add(IamScopes.CLOUD_PLATFORM);
credential = credential.createScoped(scopes);
}
// Create IAM API object associated with the authenticated transport.
return new Iam.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
private static ServiceAccountKey createServiceAccountKey(Iam iam)
throws IOException, GeneralSecurityException {
CreateServiceAccountKeyRequest request = new CreateServiceAccountKeyRequest();
// Customize the request parameters if needed
return iam.projects()
.serviceAccounts()
.keys()
.create(SERVICE_ACCOUNT_RESOURCE_NAME, request)
.execute();
}
}
I want to fetch google analytics data using google access token, but i didn't find any example , i am getting "Exception in thread
"main" java.net.SocketException: Connection reset"
error , below is the code:-
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.analyticsreporting.v4.AnalyticsReporting;
import com.google.api.services.analyticsreporting.v4.model.DateRange;
import com.google.api.services.analyticsreporting.v4.model.Dimension;
import com.google.api.services.analyticsreporting.v4.model.GetReportsRequest;
import com.google.api.services.analyticsreporting.v4.model.GetReportsResponse;
import com.google.api.services.analyticsreporting.v4.model.Metric;
import com.google.api.services.analyticsreporting.v4.model.ReportRequest;
public class AnalyticsApiTest {
public static void main(String[] args) throws Exception {
GoogleCredential credential = GoogleCredential
.fromStream(new FileInputStream(new File("d:\\clientsecretnew.json")))
.createScoped(Collections.singleton("https://www.googleapis.com/auth/analytics.readonly"));
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
AnalyticsReporting analyticsReporting = new AnalyticsReporting.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("testing_analytics")
.build();
DateRange dateRange = new DateRange();
dateRange.setStartDate("2017-06-11");
dateRange.setEndDate("2017-06-13");
// Create the Metrics object.
Metric sessions = new Metric()
.setExpression("ga:pageview")
.setAlias("sessions");
//Create the Dimensions object.
Dimension browser = new Dimension()
.setName("ga:browser");
// Create the ReportRequest object.
ReportRequest request = new ReportRequest()
.setViewId("ga:152411###")
.setDateRanges(Arrays.asList(dateRange))
.setDimensions(Arrays.asList(browser))
.setMetrics(Arrays.asList(sessions));
ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest()
.setReportRequests(requests);
// Call the batchGet method.
GetReportsResponse response = analyticsReporting.reports().batchGet(getReport).execute();
}
}
Can anyone tell what is wrong in this??
I think you should try following Googles tutorials. This is the code i use ga:pageview is not a valid metric its ga:pageviews
My Code:
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.analyticsreporting.v4.AnalyticsReporting;
import com.google.api.services.analyticsreporting.v4.AnalyticsReportingScopes;
import com.google.api.services.analyticsreporting.v4.model.*;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
/**
* #author Linda Lawton
*/
public class ReportingSample {
/**
* Be sure to specify the name of your application. If the application name is {#code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = "DAIMTO Google Analytics Reporting V4 sample";
/** Directory to store user credentials. */
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/reporting_sample");
/**
* Global instance of the {#link DataStoreFactory}. The best practice is to make it a single
* globally shared instance across your application.
*/
private static FileDataStoreFactory dataStoreFactory;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static AnalyticsReporting service ;
/** Authorizes the installed application to access user's protected data. */
private static Credential authorize() throws Exception {
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(ReportingSample.class.getResourceAsStream("/client_secrets.json")));
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(AnalyticsReportingScopes.ANALYTICS_READONLY)).setDataStoreFactory(
dataStoreFactory).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args) {
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
// authorization
Credential credential = authorize();
// set up global Analytics instance
service = new AnalyticsReporting.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(
APPLICATION_NAME).build();
// run commands
fetchData(service);
// success!
return;
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
System.exit(1);
}
public static void fetchData(AnalyticsReporting service) throws IOException{
DateRange dateRange = new DateRange();
dateRange.setStartDate("2017-06-11");
dateRange.setEndDate("2017-06-13");
// Create the Metrics object.
Metric sessions = new Metric()
.setExpression("ga:sessions")
.setAlias("sessions");
//Create the Dimensions object.
Dimension browser = new Dimension()
.setName("ga:browser");
// Create the ReportRequest object.
ReportRequest request = new ReportRequest()
.setViewId("ga:78110423")
.setDateRanges(Arrays.asList(dateRange))
.setDimensions(Arrays.asList(browser))
.setMetrics(Arrays.asList(sessions));
ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest()
.setReportRequests(requests);
// Call the batchGet method.
GetReportsResponse response = service.reports().batchGet(getReport).execute();
}
}
I'm using a pretty simple sample to retrieve my files on google drive. There are 2 weird things
The first time when I run the sample, google says "the application would like to access your files blahblah". Well, I confirmed. But, the second time, it says "the application would like to Have offline access"... ah... why?
Probably(but I'm not sure), it's after I confirm it the 2nd time, I only get the files that I uploaded by this application
The code is
package com.google.api.services.samples.drive.cmdline;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.GoogleUtils;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.media.MediaHttpDownloader;
import com.google.api.client.googleapis.media.MediaHttpUploader;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Preconditions;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Collections;
import java.util.List;
/**
* A sample application that runs multiple requests against the Drive API. The requests this sample
* makes are:
* <ul>
* <li>Does a resumable media upload</li>
* <li>Updates the uploaded file by renaming it</li>
* <li>Does a resumable media download</li>
* <li>Does a direct media upload</li>
* <li>Does a direct media download</li>
* </ul>
*
* #author rmistry#google.com (Ravi Mistry)
*/
public class DriveSample {
/**
* Be sure to specify the name of your application. If the application name is {#code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = "testing";
private static final String UPLOAD_FILE_PATH = "c:\\Users\\bnie\\workspace\\Servers\\.project";
private static final String DIR_FOR_DOWNLOADS = "c:\\temp";
private static final java.io.File UPLOAD_FILE = new java.io.File(UPLOAD_FILE_PATH);
/** Directory to store user credentials. */
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/drive_sample");
/**
* Global instance of the {#link DataStoreFactory}. The best practice is to make it a single
* globally shared instance across your application.
*/
private static FileDataStoreFactory dataStoreFactory;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global Drive API client. */
private static Drive drive;
/** Authorizes the installed application to access user's protected data. */
private static Credential authorize() throws Exception {
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(DriveSample.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=drive "
+ "into drive-cmdline-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport,
JSON_FACTORY, clientSecrets, Collections.singleton(DriveScopes.DRIVE_FILE))
.setDataStoreFactory(dataStoreFactory).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args) {
Preconditions.checkArgument(
!UPLOAD_FILE_PATH.startsWith("Enter ") && !DIR_FOR_DOWNLOADS.startsWith("Enter "),
"Please enter the upload file path and download directory in %s", DriveSample.class);
try {
// httpTransport = GoogleNetHttpTransport.newTrustedTransport();
NetHttpTransport.Builder builder = new NetHttpTransport.Builder();
builder.trustCertificates(GoogleUtils.getCertificateTrustStore());
httpTransport = builder.build();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
// authorization
Credential credential = authorize();
// set up the global Drive instance
drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
FileList l = drive.files().list().setMaxResults(10).execute();
List<File> files = l.getItems();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getTitle(), file.getId());
}
}
// run commands
// View.header1("Starting Resumable Media Upload");
// File uploadedFile = uploadFile(false);
//
// View.header1("Updating Uploaded File Name");
// File updatedFile = updateFileWithTestSuffix(uploadedFile.getId());
//
// View.header1("Starting Resumable Media Download");
// downloadFile(false, updatedFile);
//
// View.header1("Starting Simple Media Upload");
// uploadedFile = uploadFile(true);
//
// View.header1("Starting Simple Media Download");
// downloadFile(true, uploadedFile);
//
// View.header1("Success!");
return;
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
System.exit(1);
}
/** Uploads a file using either resumable or direct media upload. */
private static File uploadFile(boolean useDirectUpload) throws IOException {
File fileMetadata = new File();
fileMetadata.setTitle(UPLOAD_FILE.getName());
FileContent mediaContent = new FileContent("image/jpeg", UPLOAD_FILE);
Drive.Files.Insert insert = drive.files().insert(fileMetadata, mediaContent);
MediaHttpUploader uploader = insert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(useDirectUpload);
uploader.setProgressListener(new FileUploadProgressListener());
return insert.execute();
}
/** Updates the name of the uploaded file to have a "drivetest-" prefix. */
private static File updateFileWithTestSuffix(String id) throws IOException {
File fileMetadata = new File();
fileMetadata.setTitle("drivetest-" + UPLOAD_FILE.getName());
Drive.Files.Update update = drive.files().update(id, fileMetadata);
return update.execute();
}
/** Downloads a file using either resumable or direct media download. */
private static void downloadFile(boolean useDirectDownload, File uploadedFile)
throws IOException {
// create parent directory (if necessary)
java.io.File parentDir = new java.io.File(DIR_FOR_DOWNLOADS);
if (!parentDir.exists() && !parentDir.mkdirs()) {
throw new IOException("Unable to create parent directory");
}
OutputStream out = new FileOutputStream(new java.io.File(parentDir, uploadedFile.getTitle()));
MediaHttpDownloader downloader =
new MediaHttpDownloader(httpTransport, drive.getRequestFactory().getInitializer());
downloader.setDirectDownloadEnabled(useDirectDownload);
downloader.setProgressListener(new FileDownloadProgressListener());
downloader.download(new GenericUrl(uploadedFile.getDownloadUrl()), out);
}
}
Try to change the scope that you used. Used the scope DriveScopes.DRIVE instead of DriveScopes.DRIVE_FILE. For more information about scopes, check this documentation.
Also check this related SO question.