Not able to download google sheet from google drive. Facing 403 Insufficient Permission issue.
Please check below code.
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME = "Drive 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/drive-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/drive-java-quickstart
*/
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE_METADATA_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.
InputStream in = Quickstart.class.getResourceAsStream("/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 Drive client service.
*
* #return an authorized Drive client service
* #throws IOException
*/
public static Drive getDriveService() throws IOException {
Credential credential = authorize();
return new Drive.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.
Drive service = getDriveService();
// 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.size() == 0) {
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());
}
}
downloadFile(service, "1l0dX1hOdk0xX5T2ruqnci-75sMwziwiih9BFGX6DcdA");
}
private static void downloadFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getName());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
OutputStream outputStream = new ByteArrayOutputStream();
service.files().export(fileId, "application/x-vnd.oasis.opendocument.spreadsheet")
.executeMediaAndDownloadTo(outputStream);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
}
}
}
**Output:**
403 error is displayed after executing above code. Please check below output of above code.
Credentials saved to /home/nikhil/.credentials/drive-java-quickstart
Files:
nikhil (1zNmRFWe_HABvhP_HukQIcOVdUoLllKB49RpPK3_XXn4)
Test Sheet (1l0dX1hOdk0xX5T2ruqnci-75sMwziwiih9BFGX6DcdA)
Getting started (0Bx8dATp9NaeXc3RhcnRlcl9maWxlX2Rhc2hlclYw)
Title: Test Sheet
Description: null
MIME type: application/vnd.google-apps.spreadsheet
An error occurred: com.google.api.client.http.HttpResponseException: 403
Forbidden
{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
}
],
"code": 403,
"message": "Insufficient Permission"
}
}
Change the scope and data store directory.
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
".credentials/drive-java-quickstart.json");
Added File path for saving the file to local machine.
public static void initialMethod() throws IOException {
// Build a new authorized API client service.
Drive service = getDriveService();
downloadFile(service, "1JYlTtznsCll16upwIIbgXjqDvjsAFO5krSiGjvciO70");
}
private static void downloadFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getName());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
OutputStream outputStream = new FileOutputStream(new java.io.File(Constant.DRIVE_EXCEL_PATH + "Test.xlsx"));
service.files().export(fileId, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
.executeMediaAndDownloadTo(outputStream);
System.out.println(outputStream);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
} catch (Exception e) {
System.out.println("An error occurred: " + e);
}
}
Above code helps for downloading file from google drive.
Related
I have started the Docker containers and channels as per the "Build your First network" example
from the Hyperledger fabric docs .
I am trying to query a value from the ledger using Fabric Java SDK . The Fabric samples release version I am using is fabric-samples-release-1.0.
I get a certificate verification failed exception during channel initialize
Here is my Java code
public class javaSDKSample {
private static final Logger log = Logger.getLogger(HFJavaSDKBasicExample.class);
public static void main(String[] args) throws Exception {
// create fabric-ca client
HFCAClient caClient = getHfCaClient("http://{remotemachineURL}:7054", null);
// enroll or load admin
AppUser admin = getAdmin(caClient);
log.info(admin);
// register and enroll new user
// AppUser appUser = getUser(caClient, admin, "hfuser7");
// log.info(appUser);
// get HFC client instance
HFClient client = getHfClient();
// set user context
client.setUserContext(admin);
// get HFC channel using the client
Channel channel = getChannel(client);
log.info("Channel: " + channel.getName());
//createCar(client, channel, "CAR18", "MAKE7", "MODEL7", "BLACK", "JOHN", true);
// queryBlockChain(client);
}
/**
* Invoke blockchain query
*
* #param client The HF Client
* #throws ProposalException
* #throws InvalidArgumentException
*/
static void queryBlockChain(HFClient client) throws ProposalException, InvalidArgumentException {
// get channel instance from client
Channel channel = client.getChannel("mychannel");
// create chaincode request
QueryByChaincodeRequest qpr = client.newQueryProposalRequest();
// build cc id providing the chaincode name. Version is omitted here.
ChaincodeID fabcarCCId = ChaincodeID.newBuilder().setName("mycc").build();
qpr.setChaincodeID(fabcarCCId);
// CC function to be called
qpr.setFcn("query");
qpr.setArgs(new String[]{"a"});
Collection<ProposalResponse> res = channel.queryByChaincode(qpr);
// display response
for (ProposalResponse pres : res) {
String stringResponse = new String(pres.getChaincodeActionResponsePayload());
log.info(stringResponse);
}
}
static void createCar(HFClient client,Channel channel, String key, String make,String model,String color,String owner, Boolean doCommit)
throws Exception {
TransactionProposalRequest req = client.newTransactionProposalRequest();
ChaincodeID cid = ChaincodeID.newBuilder().setName("fabcar").build();
req.setChaincodeID(cid);
req.setFcn("createCar");
req.setArgs(new String[] { key, make,model,color,owner });
System.out.println("Executing for " + key);
Collection<ProposalResponse> resps = channel.sendTransactionProposal(req);
if (doCommit) {
channel.sendTransaction(resps);
}
}
/**
* Initialize and get HF channel
*
* #param client The HFC client
* #return Initialized channel
* #throws InvalidArgumentException
* #throws TransactionException
*/
static Channel getChannel(HFClient client) throws InvalidArgumentException, TransactionException {
// initialize channel
// peer name and endpoint in fabcar network
Properties peerProperties = new Properties();
peerProperties.setProperty("pemFile", "D:/FabricCert/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt");
peerProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
peerProperties.setProperty("hostnameOverride", "peer0.org1.example.com");
peerProperties.setProperty("sslProvider", "openSSL");
peerProperties.setProperty("negotiationType", "TLS");
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
Peer peer = client.newPeer("peer0.org1.example.com", "grpcs://{remotemachineURL}:7051");
// eventhub name and endpoint in fabcar network
final Properties eventHubProperties = new Properties();
eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
EventHub eventHub = client.newEventHub("eventhub01", "grpcs://{remotemachineURL}:7053",eventHubProperties);
// orderer name and endpoint in fabcar network
Properties ordererProperties = new Properties();
ordererProperties.setProperty("pemFile", "D:/FabricCert/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt");
ordererProperties.setProperty("trustServerCertificate", "true"); //testing environment only NOT FOR PRODUCTION!
ordererProperties.setProperty("hostnameOverride", "orderer.example.com");
ordererProperties.setProperty("sslProvider", "openSSL");
ordererProperties.setProperty("negotiationType", "TLS");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
Orderer orderer = client.newOrderer("orderer.example.com", "grpcs://{remotemachineURL}:7050");
// channel name in fabcar network
Channel channel = client.newChannel("mychannel");
channel.addPeer(peer);
channel.addEventHub(eventHub);
channel.addOrderer(orderer);
channel.initialize();
return channel;
}
/**
* Create new HLF client
*
* #return new HLF client instance. Never null.
* #throws CryptoException
* #throws InvalidArgumentException
*/
static HFClient getHfClient() throws Exception {
// initialize default cryptosuite
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
// setup the client
HFClient client = HFClient.createNewInstance();
client.setCryptoSuite(cryptoSuite);
return client;
}
/**
* Register and enroll user with userId.
* If AppUser object with the name already exist on fs it will be loaded and
* registration and enrollment will be skipped.
*
* #param caClient The fabric-ca client.
* #param registrar The registrar to be used.
* #param userId The user id.
* #return AppUser instance with userId, affiliation,mspId and enrollment set.
* #throws Exception
*/
static AppUser getUser(HFCAClient caClient, AppUser registrar, String userId) throws Exception {
AppUser appUser = tryDeserialize(userId);
System.out.println("appUser"+appUser);
if (appUser == null) {
RegistrationRequest rr = new RegistrationRequest(userId, "org1");
String enrollmentSecret = caClient.register(rr, registrar);
Enrollment enrollment = getEnrollment();
enrollment = caClient.enroll(userId, enrollmentSecret);
byte[] certFile = Base64.encodeBase64(enrollment.getCert().getBytes());
byte[] keyFile = Base64.encodeBase64(enrollment.getKey().toString().getBytes());
BufferedWriter bufferedWriter = null;
File myFile = new File("D:/keyfile.key");
// check if file exist, otherwise create the file before writing
if (!myFile.exists()) {
myFile.createNewFile();
}
Writer writer = new FileWriter(myFile);
bufferedWriter = new BufferedWriter(writer);
bufferedWriter.write(enrollment.getKey().toString());
bufferedWriter.close();
appUser = new AppUser(userId, "org1", "Org1MSP", enrollment);
serialize(appUser);
}
return appUser;
}
public static Enrollment getEnrollment() {
return new Enrollment() {
public PrivateKey getKey() {
PrivateKey privateKey = null;
try {
File privateKeyFile = findFileSk("D:/FabricCert/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp/keystore");
privateKey = getPrivateKeyFromBytes(IOUtils.toByteArray(new FileInputStream(privateKeyFile)));
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return privateKey;
}
public String getCert() {
String certificate = null;
try {
File certificateFile = new File("D:/FabricCert/crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp/signcerts/Admin#org1.example.com-cert.pem");
certificate = new String(IOUtils.toByteArray(new FileInputStream(certificateFile)), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return certificate;
}
};
}
static PrivateKey getPrivateKeyFromBytes(byte[] data) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
final Reader pemReader = new StringReader(new String(data));
final PrivateKeyInfo pemPair;
try (PEMParser pemParser = new PEMParser(pemReader)) {
pemPair = (PrivateKeyInfo) pemParser.readObject();
}
PrivateKey privateKey = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getPrivateKey(pemPair);
return privateKey;
}
/**
* Enroll admin into fabric-ca using {#code admin/adminpw} credentials.
* If AppUser object already exist serialized on fs it will be loaded and
* new enrollment will not be executed.
*
* #param caClient The fabric-ca client
* #return AppUser instance with userid, affiliation, mspId and enrollment set
* #throws Exception
*/
static AppUser getAdmin(HFCAClient caClient) throws Exception {
AppUser admin = tryDeserialize("admin");
if (admin == null) {
Enrollment adminEnrollment = caClient.enroll("admin", "adminpw");
admin = new AppUser("admin", "org1", "Org1MSP", adminEnrollment);
serialize(admin);
}
return admin;
}
/**
* Get new fabric-ca client
*
* #param caUrl The fabric-ca-server endpoint url
* #param caClientProperties The fabri-ca client properties. Can be null.
* #return new client instance. never null.
* #throws Exception
*/
static HFCAClient getHfCaClient(String caUrl, Properties caClientProperties) throws Exception {
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
HFCAClient caClient = HFCAClient.createNewInstance(caUrl, caClientProperties);
caClient.setCryptoSuite(cryptoSuite);
return caClient;
}
// user serialization and deserialization utility functions
// files are stored in the base directory
/**
* Serialize AppUser object to file
*
* #param appUser The object to be serialized
* #throws IOException
*/
static void serialize(AppUser appUser) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(
Paths.get(appUser.getName() + ".jso")))) {
oos.writeObject(appUser);
}
}
/**
* Deserialize AppUser object from file
*
* #param name The name of the user. Used to build file name ${name}.jso
* #return
* #throws Exception
*/
static AppUser tryDeserialize(String name) throws Exception {
if (Files.exists(Paths.get(name + ".jso"))) {
return deserialize(name);
}
return null;
}
static AppUser deserialize(String name) throws Exception {
try (ObjectInputStream decoder = new ObjectInputStream(
Files.newInputStream(Paths.get(name + ".jso")))) {
return (AppUser) decoder.readObject();
}
}
static File findFileSk(String directorys) {
File directory = new File(directorys);
File[] matches = directory.listFiles((dir, name) -> name.endsWith("_sk"));
if (null == matches) {
throw new RuntimeException(format("Matches returned null does %s directory exist?", directory.getAbsoluteFile().getName()));
}
if (matches.length != 1) {
throw new RuntimeException(format("Expected in %s only 1 sk file but found %d", directory.getAbsoluteFile().getName(), matches.length));
}
return matches[0];
}}
And this is my error trace
DEBUG ReferenceCountedOpenSslContext - verification of certificate failed
java.security.cert.CertificateException: No subject alternative DNS name matching {remotemachineURL} found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:191)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback.verify(ReferenceCountedOpenSslClientContext.java:223)
at io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:606)
at org.apache.tomcat.jni.SSL.readFromSSL(Native Method)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData(ReferenceCountedOpenSslEngine.java:470)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:927)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1033)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1076)
at io.netty.handler.ssl.SslHandler$SslEngineType$1.unwrap(SslHandler.java:206)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1117)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1039)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:129)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:745)
I am trying to initialize "mychannel" with peer0 from org1 and orderer and query for a value from the "byfn" network .
Please ignore extra code if any or the comments .
Thanks
Code worked , apparently there was some problem with the Enrollment .
I had used a bad certificate . Changed certificate for enrollment and it worked
Solved .Thanks
I basically have a dynamic WEB-APP which through a servlet I am trying to retrieve a youtube video comments.
Although there is alot of article about it in the web but I don't know why none worked for me.
First Attempt:
private static int counter = 0;
private static YouTube youtube;
public static void getYoutubeOauth() throws Exception {
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = Auth.authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "KIgxmV9xXBQ";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
// Get next page of video comments threads
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
With this I am getting nullpointerexception at line: Credential credential = Auth.authorize(scopes, "commentthreads");
If you can please explain what is scope and where do you get it from.
Second Attempt I tried creating a different function for getting credentials.
Second Attempt:
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
// Load client secrets.
Reader clientSecretReader = new InputStreamReader(
Auth.class.getResourceAsStream("/home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json"));
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
// Checks that the defaults have been replaced (Default = "Enter X here").
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
return null;
}
// This creates the credentials datastore at ~/.oauth-credentials/${credentialDatastore}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
.build();
// Build the local server and bind it to port 8080
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build();
// Authorize.
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
Here also Im getting an nullpointerexception at line Reader clientSecretReader = new InputStreamReader(... although If I would try nano /home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json in my terminal I can access the file.
Question: How to authorize my web-app and read client_secrets.json from an external directory.
Was a bit painful but made the second solution working.
So what I was doing wrong was that I was calling Auth.class.getResourceAsStream which it requires the data to be available to classLoader but to my classLoader it was not.
so what I had to do is to request my client_secrets.json from an external directory which then you have to use FileInputStream other than getResourceAsStream.
Both FileInputStream and getResourceAsStream works fine but they differ on your situation and different code.
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
Reader clientSecretReader = new InputStreamReader(
new FileInputStream("/client_secrets.json"));
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
System.out.println(clientSecretReader.toString());
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
return null;
}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
.build();
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8081).build();
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
private static int counter = 0;
private static YouTube youtube;
public static void getYoutubeOauth() throws Exception {
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "KIgxmV9xXBQ";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
private static YouTube.CommentThreads.List prepareListRequest(String videoId) throws Exception {
return youtube.commentThreads()
.list("snippet,replies")
.setVideoId(videoId)
.setMaxResults(100L)
.setModerationStatus("published")
.setTextFormat("plainText");
}
private static void handleCommentsThreads(List<CommentThread> commentThreads) {
for (CommentThread commentThread : commentThreads) {
List<Comment> comments = Lists.newArrayList();
comments.add(commentThread.getSnippet().getTopLevelComment());
CommentThreadReplies replies = commentThread.getReplies();
if (replies != null)
comments.addAll(replies.getComments());
System.out.println("Found " + comments.size() + " comments.");
// Do your comments logic here
counter += comments.size();
}
}
Note: change FileInputStream location to your own location.
Then you can call getYoutubeOauth and hope for getting a working response :)
I actually have a problem, I want to know how to recover an image URL with his key in the Google Cloud Storage, here is the code.
StorageUtils.java
public class StorageUtils {
public static Storage storage;
private static final String DATETIME_FORMAT = "yyyyMMdd_HHmmss";
private static final String CAMERA_FILENAME_PREFIX = "IMG_";
/**
* Uploads a file to a bucket. Filename and content type will be based on
* the original file
* #param bucketName
* Bucket where file will be uploaded
* #param filePath
* Absolute path of the file to upload
* #throws Exception
*/
public static void uploadFile(String bucketName, String filePath)throws Exception {
Storage storage = getStorage();
String timeStamp = new SimpleDateFormat(DATETIME_FORMAT).format(new Date());
String imageFileName = CAMERA_FILENAME_PREFIX + timeStamp;
StorageObject object = new StorageObject();
object.setBucket(bucketName);
File file = new File(filePath);
InputStream stream = new FileInputStream(file);
try {
String contentType = URLConnection
.guessContentTypeFromStream(stream);
InputStreamContent content = new InputStreamContent(contentType,
stream);
Storage.Objects.Insert insert = storage.objects().insert(
bucketName, null, content);
insert.setName(imageFileName + file.getName());
insert.execute();
/////
/////
} finally {
stream.close();
}
}
public static void downloadFile(String bucketName, String fileName, String destinationDirectory) throws Exception {
File directory = new File(destinationDirectory);
if(!directory.isDirectory()) {
throw new Exception("Provided destinationDirectory path is not a directory");
}
File file = new File(directory.getAbsolutePath() + "/" + fileName);
Storage storage = getStorage();
Storage.Objects.Get get = storage.objects().get(bucketName, fileName);
FileOutputStream stream = new FileOutputStream(file);
try{
get.executeMediaAndDownloadTo(stream);
} finally {
stream.close();
}
}
/**
* Deletes a file within a bucket
*
* #param bucketName
* Name of bucket that contains the file
* #param fileName
* The file to delete
* #throws Exception
*/
public static void deleteFile(String bucketName, String fileName) throws Exception {
Storage storage = getStorage();
storage.objects().delete(bucketName, fileName).execute();
}
/**
* Creates a bucket
*
* #param bucketName
* Name of bucket to create
* #throws Exception
*/
public static void createBucket(String bucketName) throws Exception {
Storage storage = getStorage();
Bucket bucket = new Bucket();
bucket.setName(bucketName);
storage.buckets().insert(StorageConstants.PROJECT_ID_PROPERTY, bucket).execute();
}
/**
* Deletes a bucket
*
* #param bucketName
* Name of bucket to delete
* #throws Exception
*/
public static void deleteBucket(String bucketName) throws Exception {
Storage storage = getStorage();
storage.buckets().delete(bucketName).execute();
}
/**
* Lists the objects in a bucket
*
* #param bucketName bucket name to list
* #return Array of object names
* #throws Exception
*/
public static List<String> listBucket(String bucketName) throws Exception {
Storage storage = getStorage();
List<String> list = new ArrayList<String>();
List<StorageObject> objects = storage.objects().list(bucketName).execute().getItems();
if(objects != null) {
for(StorageObject o : objects) {
list.add(o.getName());
}
}
return list;
}
/**
* List the buckets with the project
* (Project is configured in properties)
*
* #return
* #throws Exception
*/
public static List<String> listBuckets() throws Exception {
Storage storage = getStorage();
List<String> list = new ArrayList<String>();
List<Bucket> buckets = storage.buckets().list(StorageConstants.PROJECT_ID_PROPERTY).execute().getItems();
if(buckets != null) {
for(Bucket b : buckets) {
list.add(b.getName());
}
}
return list;
}
private static Storage getStorage() throws Exception {
if (storage == null) {
ApacheHttpTransport httpTransport = new ApacheHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
List<String> scopes = new ArrayList<String>();
scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL);
Credential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(StorageConstants.ACCOUNT_ID_PROPERTY)
.setServiceAccountPrivateKeyFromP12File(getTempPkc12File())
.setServiceAccountScopes(scopes).build();
storage = new Storage.Builder(httpTransport, jsonFactory,
credential).setApplicationName(StorageConstants.APPLICATION_NAME_PROPERTY)
.build();
}
return storage;
}
private static File getTempPkc12File() throws IOException {
InputStream pkc12Stream = StorageConstants.CONTEXT.getAssets().open("key.p12");
File tempPkc12File = File.createTempFile("temp_pkc12_file", "p12");
OutputStream tempFileStream = new FileOutputStream(tempPkc12File);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = pkc12Stream.read(bytes)) != -1) {
tempFileStream.write(bytes, 0, read);
}
return tempPkc12File;
}
}
I am following the tutorial to get access to the GA account report data by executing a simple GA query, by using the Google Developers console.
I followed all steps mentioned in the tutorial and the code works fine.
I have included the code below.
public class GoogleAnalyticsAccess {
private static final String APPLICATION_NAME = "GAAccess/1.0";
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/analytics_sample");
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static FileDataStoreFactory dataStoreFactory;
private static HttpTransport httpTransport;
public static Credential authorizeUser() throws IOException {
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(
GoogleAnalyticsAccess.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=analytics " +
"into Dashboard/src/main/resources/client_secrets.json");
System.exit(1);
}
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY,
clientSecrets, Collections.singleton(AnalyticsScopes.ANALYTICS_READONLY))
.setDataStoreFactory(dataStoreFactory).build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static Analytics getAnalyticsServiceObject(Credential credential){
return new Analytics.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME)
.build();
}
public static String getGAAccountId(Analytics analytics) throws IOException {
String accountId =null;
Accounts accounts = analytics.management().accounts().list().execute();
List<Account> accountsList = accounts.getItems();
if(accountsList.isEmpty()){
System.err.println("No accounts found");
}
else{
for(int i=0; i<accountsList.size();i++){
if(accountsList.get(i).getName().equals("XXXX")){
accountId = accountsList.get(i).getId();
break;
}
}
}
return accountId;
}
public static String getGAWebPropertyId(Analytics analytics,String accountId) throws IOException {
String webPropertyId = null;
Webproperties webProperties = null;
webProperties = analytics.management().webproperties().list(accountId).execute();
List<Webproperty> webPropertiesList = webProperties.getItems();
if (webPropertiesList.isEmpty()) {
System.err.println("No Web Properties found");
} else {
for (int i=0; i<webPropertiesList.size();i++){
if(webPropertiesList.get(i).getName().equals("XXXX")){
webPropertyId = webPropertiesList.get(i).getId();
}
}
}
return webPropertyId;
}
public static String getGAViewId(Analytics analytics, String accountId, String webPropertyId) throws IOException {
String viewId = null;
Profiles views = analytics.management().profiles().list(accountId, webPropertyId).execute();
List<Profile> viewsList = views.getItems();
if (viewsList.isEmpty()) {
System.err.println("No profiles found");
} else {
for(int i=0; i<viewsList.size();i++){
if(viewsList.get(i).getName().equals("XXXX")){
viewId = viewsList.get(i).getId();
}
}
}
return viewId;
}
public static List<GoogleAnalyticsData> executeGAQuery(Analytics analytics, String viewId, String dimension) throws IOException {
List<GoogleAnalyticsData> dataList = new ArrayList<GoogleAnalyticsData>();
if (viewId == null) {
System.err.println("No profiles found.");
} else {
GaData gaData = analytics.data().ga().get("ga:" + viewId, "2015-02-13", "2015-02-27", "ga:users")
.setDimensions("ga:" + dimension)
.setMaxResults(200).execute();
if (gaData.getRows() == null || gaData.getRows().isEmpty()) {
System.out.println("No results Found.");
} else {
GoogleAnalyticsData data;
for (List<String> row : gaData.getRows()) {
data = new GoogleAnalyticsData();
data.setName(row.get(0));
data.setValue(Integer.parseInt(row.get(1)));
dataList.add(data);
}
}
}
return dataList;
}
public static void main(String[] args) throws GeneralSecurityException, IOException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorizeUser();
Analytics analytics = getAnalyticsServiceObject(credential);
String accountId = getGAAccountId(analytics);
String webPropertyId = getGAWebPropertyId(analytics,accountId);
String viewId = getGAViewId(analytics,accountId,webPropertyId);
List<GoogleAnalyticsData> continentDataList = executeGAQuery(analytics, viewId, "continent");
List<GoogleAnalyticsData> countryDataList = executeGAQuery(analytics, viewId, "country");
for(int i =0; i <continentDataList.size();i++){
System.out.println(continentDataList.get(i).getName() + " " + continentDataList.get(i).getValue());
}
for(int i=0; i< countryDataList.size();i++){
System.out.println(countryDataList.get(i).getName() + " " + countryDataList.get(i).getValue());
}
}
}
I get an error when I access the same GA account report data by giving the credential (Client secret and Id) of another user who also has shared access to that report data.
I am successfully able to access the report data using the other users credentials If I have already run the java application using my credentials first. But If I run the app with the other users credentials first, then I get the following error.
The Stack trace is shown below.
Exception in thread "main" java.lang.NullPointerException
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:191)
at com.google.api.client.util.Preconditions.checkNotNull(Preconditions.java:127)
at com.google.api.client.json.jackson2.JacksonFactory.createJsonParser(JacksonFactory.java:92)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:85)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:88)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
at com.google.api.client.auth.oauth2.Credential.executeRefreshToken(Credential.java:570)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at org.dashboard.access.data.GoogleAnalyticsAccess.getGAAccountId(GoogleAnalyticsAccess.java:266)
at org.dashboard.access.data.GoogleAnalyticsAccess.main(GoogleAnalyticsAccess.java:364)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
The specific exception occurs at the following line in method getGAAccountId.
Accounts accounts = analytics.management().accounts().list().execute();
Is there any workaround for this issue?
If your client_secrets.json is well configured, you just have to delete the file .store/analytics_sample and run it again.
I am trying to upload video to Youtube using the java youtube api and getting "401 Unauthorized".
I have created a service account using the developers console and using that .p12 file
Here is the code I am using.
public class YouTubeUtils {
private static YouTube youtube;
private static final String VIDEO_FORMAT = "video/*";
private static final String APPLICATION_NAME = "TestApp";
private static final String SERVICE_ACCOUNT_EMAIL = "xxxxx#developer.gserviceaccount.com";
private static HttpTransport httpTransport;
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
public static void main(String[] args) {
try {
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
if (SERVICE_ACCOUNT_EMAIL.startsWith("Enter ")) {
System.err.println(SERVICE_ACCOUNT_EMAIL);
System.exit(1);
}
String p12Content = Files.readFirstLine(new File("C:/Workspace/TestApp.p12"),
Charset.defaultCharset());
if (p12Content.startsWith("Please")) {
System.err.println(p12Content);
System.exit(1);
}
List<String> scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_UPLOAD);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(new File("C:/Workspace/TestApp.p12"))
.build();
youtube = new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
Video videoObjectDefiningMetadata = new Video();
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
VideoSnippet snippet = new VideoSnippet();
Calendar cal = Calendar.getInstance();
snippet.setTitle("Test Upload via Java on " + cal.getTime());
snippet.setDescription("Video uploaded via YouTube Data API V3 using the Java library "
+ "on " + cal.getTime());
List<String> tags = new ArrayList<String>();
tags.add("test");
tags.add("video");
snippet.setTags(tags);
videoObjectDefiningMetadata.setSnippet(snippet);
FileInputStream fin = new FileInputStream(new File("C:/Workspace/small.mp4"));
InputStreamContent mediaContent = new InputStreamContent(VIDEO_FORMAT,fin);
YouTube.Videos.Insert videoInsert = youtube.videos().insert(
"snippet,statistics,status",
videoObjectDefiningMetadata, mediaContent);
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader)
throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
System.out.println("Initiation Started");
break;
case INITIATION_COMPLETE:
System.out.println("Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
System.out.println("Upload in progress");
System.out.println("Upload percentage: "
+ uploader.getProgress());
break;
case MEDIA_COMPLETE:
System.out.println("Upload Completed!");
break;
case NOT_STARTED:
System.out.println("Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
// Call the API and upload the video.
Video returnedVideo = videoInsert.execute();
// Print data about the newly inserted video from the API
// response.
System.out
.println("\n================== Returned Video ==================\n");
System.out.println(" - Id: " + returnedVideo.getId());
System.out.println(" - Title: "
+ returnedVideo.getSnippet().getTitle());
System.out.println(" - Tags: "
+ returnedVideo.getSnippet().getTags());
System.out.println(" - Privacy Status: "
+ returnedVideo.getStatus().getPrivacyStatus());
System.out.println(" - Video Count: "
+ returnedVideo.getStatistics().getViewCount());
} catch (IOException e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
It prints
Initiation Started
Initiation Completed
and after that I am getting "401 Unauthorized"
Can someone help me on this.
Thanks
Please refer to this link, it says Service Accounts do not work with the YouTube API
Also, please refer to this link to know how to get authorization credentials and what type of credentials the Youtube API supports.
And here is an example of uploading a video to youtube using OAuth 2.0.