Getting AmazonClientException when connecting DynamoDB from Java Client - java

Getting the following exception when trying to run DynamoDB Java example client program:
Caught an AmazonClientException, which means the client encountered a serious internal problem while trying to communicate with AWS, such as not being able to access the network.
Error Message: Unable to execute HTTP request: This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server
Please provide me suggation how to resolve this.I have tried to use ClientConfiguration to setup proxy but error is still same.
P.S. I have my accesskeys working as I can create DynamoDB Table from AWS Toolkit in eclipse
Full application code Below :
/*
* Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.PutItemResult;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.dynamodbv2.util.TableUtils;
/**
* This sample demonstrates how to perform a few simple operations with the
* Amazon DynamoDB service.
*/
public class AmazonDynamoDBSample {
/*
* Before running the code:
* Fill in your AWS access credentials in the provided credentials
* file template, and be sure to move the file to the default location
* (C:\\Users\\245819\\.aws\\credentials) where the sample code will load the
* credentials from.
* https://console.aws.amazon.com/iam/home?#security_credential
*
* WARNING:
* To avoid accidental leakage of your credentials, DO NOT keep
* the credentials file in your source directory.
*/
static AmazonDynamoDBClient dynamoDB;
/**
* The only information needed to create a client are security credentials
* consisting of the AWS Access Key ID and Secret Access Key. All other
* configuration, such as the service endpoints, are performed
* automatically. Client parameters, such as proxies, can be specified in an
* optional ClientConfiguration object when constructing a client.
*
* #see com.amazonaws.auth.BasicAWSCredentials
* #see com.amazonaws.auth.ProfilesConfigFile
* #see com.amazonaws.ClientConfiguration
*/
private static void init() throws Exception {
/*
* The ProfileCredentialsProvider will return your [default]
* credential profile by reading from the credentials file located at
* (C:\\Users\\245819\\.aws\\credentials).
*/
AWSCredentials credentials = null;
try {
credentials = new ProfileCredentialsProvider("AWS NEW").getCredentials();
} catch (Exception e) {
throw new AmazonClientException(
"Cannot load the credentials from the credential profiles file. " +
"Please make sure that your credentials file is at the correct " +
"location (C:\\Users\\245819\\.aws\\credentials), and is in valid format.",
e);
}
dynamoDB = new AmazonDynamoDBClient(credentials);
Region sAsiaEast1 = Region.getRegion(Regions.AP_SOUTHEAST_1);
dynamoDB.setRegion(sAsiaEast1);
}
public static void main(String[] args) throws Exception {
init();
try {
String tableName = "my-favorite-movies-table";
/* ClientConfiguration clientCfg = new ClientConfiguration();
clientCfg.setProtocol(Protocol.HTTP);
clientCfg.setProxyHost("proxy.tcs.com");
clientCfg.setProxyPort(80);
clientCfg.setProxyUsername("245819");
clientCfg.setProxyPassword("Kolkata#31");
*/
// Create a table with a primary hash key named 'name', which holds a string
CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(tableName)
.withKeySchema(new KeySchemaElement().withAttributeName("name").withKeyType(KeyType.HASH))
.withAttributeDefinitions(new AttributeDefinition().withAttributeName("name").withAttributeType(ScalarAttributeType.S))
.withProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits(1L).withWriteCapacityUnits(1L));
// Create table if it does not exist yet
TableUtils.createTableIfNotExists(dynamoDB, createTableRequest);
// wait for the table to move into ACTIVE state
TableUtils.waitUntilActive(dynamoDB, tableName);
// Describe our new table
DescribeTableRequest describeTableRequest = new DescribeTableRequest().withTableName(tableName);
TableDescription tableDescription = dynamoDB.describeTable(describeTableRequest).getTable();
System.out.println("Table Description: " + tableDescription);
// Add an item
Map<String, AttributeValue> item = newItem("Bill & Ted's Excellent Adventure", 1989, "****", "James", "Sara");
PutItemRequest putItemRequest = new PutItemRequest(tableName, item);
PutItemResult putItemResult = dynamoDB.putItem(putItemRequest);
System.out.println("Result: " + putItemResult);
// Add another item
item = newItem("Airplane", 1980, "*****", "James", "Billy Bob");
putItemRequest = new PutItemRequest(tableName, item);
putItemResult = dynamoDB.putItem(putItemRequest);
System.out.println("Result: " + putItemResult);
// Scan items for movies with a year attribute greater than 1985
HashMap<String, Condition> scanFilter = new HashMap<String, Condition>();
Condition condition = new Condition()
.withComparisonOperator(ComparisonOperator.GT.toString())
.withAttributeValueList(new AttributeValue().withN("1985"));
scanFilter.put("year", condition);
ScanRequest scanRequest = new ScanRequest(tableName).withScanFilter(scanFilter);
ScanResult scanResult = dynamoDB.scan(scanRequest);
System.out.println("Result: " + scanResult);
} catch (AmazonServiceException ase) {
System.out.println("Caught an AmazonServiceException, which means your request made it "
+ "to AWS, but was rejected with an error response for some reason.");
System.out.println("Error Message: " + ase.getMessage());
System.out.println("HTTP Status Code: " + ase.getStatusCode());
System.out.println("AWS Error Code: " + ase.getErrorCode());
System.out.println("Error Type: " + ase.getErrorType());
System.out.println("Request ID: " + ase.getRequestId());
} catch (AmazonClientException ace) {
System.out.println("Caught an AmazonClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with AWS, "
+ "such as not being able to access the network.");
System.out.println("Error Message: " + ace.getMessage());
}
}
private static Map<String, AttributeValue> newItem(String name, int year, String rating, String... fans) {
Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
item.put("name", new AttributeValue(name));
item.put("year", new AttributeValue().withN(Integer.toString(year)));
item.put("rating", new AttributeValue(rating));
item.put("fans", new AttributeValue().withSS(fans));
return item;
}
}

Related

Amazon Advertising API: Cannot locate SignedRequestHelper class

I have got code from amazon scratchpad and got the package required. The SignedRequestHelper class is not in the package and i am unable to run the program. I am attempting to get the price of the item using the amazon asin number.
package com.amazon.advertising.api.sample;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/*
* This class shows how to make a simple authenticated call to the
* Amazon Product Advertising API.
*
* See the README.html that came with this sample for instructions on
* configuring and running the sample.
*/
public class lookup {
/*
* Your AWS Access Key ID, as taken from the AWS Your Account page.
*/
private static final String AWS_ACCESS_KEY_ID = "XXXXXX";
/*
* Your AWS Secret Key corresponding to the above ID, as taken from the AWS
* Your Account page.
*/
private static final String AWS_SECRET_KEY = "XXXXXXX";
/*
* Use the end-point according to the region you are interested in.
*/
private static final String ENDPOINT = "webservices.amazon.com";
public static void main(String[] args) {
/*
* Set up the signed requests helper.
*/
SignedRequestsHelper helper;
try {
} catch (Exception e) {
e.printStackTrace();
return;
}
String requestUrl = null;
Map<String, String> params = new HashMap<String, String>();
params.put("Service", "AWSECommerceService");
params.put("Operation", "ItemLookup");
params.put("AWSAccessKeyId", "XXXXXX");
params.put("AssociateTag", "XXXXX");
params.put("ItemId", "B01H57GXUQ");
params.put("IdType", "ASIN");
params.put("ResponseGroup", "Images,ItemAttributes,Offers");
requestUrl = helper.sign(params);
System.out.println("Signed URL: \"" + requestUrl + "\"");
}
}
How would i be able to get the signedrequestshelper method or how would i be able to change the code?
SignedRequestHelper is a class available in one of the code samples from AWS here:
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/AuthJavaSampleSig2.html
You can copy/paste the code in your project to make it run and work.

Adding Content-Type Headers to Java HTTP echo server

I'm playing with HTTPservers and running into an issue. I need to add ContentType headers to the response, but when I do the client gets ERR_EMPTY_RESPONSE.
If I remove:
headers.add("Content-Type", "text/html");
Then the server works fine, but I need to pass the CType headers for my app. What gives? How do I include Content-Type headers?
/*
* EchoServer.java
*
* Accept an HTTP request and echo it back as the HTTP response.
*
* Copyright (c) 2005 Sun Microsystems, Inc
* Copyright (c) 2008 Operational Dynamics Consulting, Pty Ltd
*
* The code in this file is made available to you by its authors under the
* terms of the "GNU General Public Licence, version 2" See the LICENCE file
* for the terms governing usage and redistribution.
*/
/*
* This code is a simple derivation of the example in the package
* documentation for com.sun.net.httpserver, as found in file
* jdk/src/share/classes/com/sun/net/httpserver/package-info.java as shipped
* with the openjdk 1.6 b08 code drop. Used under the terms of the GPLv2.
*/
import static java.net.HttpURLConnection.HTTP_OK;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.util.List;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpExchange.*;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
/**
* Echo the body of an HTTP request back as the HTTP response. This is merely
* a simple exercise of the Secret Sun Web Server. As configured, the URL to
* access it is http://localhost:8000/echo.
*
* #author Andrew Cowie
*/
public final class Test {
public static void main(String[] args) throws IOException {
final InetSocketAddress addr;
final HttpServer server;
addr = new InetSocketAddress(8000);
server = HttpServer.create(addr, 10);
server.createContext("/echo", new EchoHandler());
server.start();
}
}
class EchoHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
final InputStream is;
final OutputStream os;
StringBuilder buf;
int b;
final String request, response;
buf = new StringBuilder();
/*
* Get the request body and decode it. Regardless of what you are
* actually doing, it is apparently considered correct form to consume
* all the bytes from the InputStream. If you don't, closing the
* OutputStream will cause that to occur
*/
is = t.getRequestBody();
while ((b = is.read()) != -1) {
buf.append((char) b);
}
is.close();
if (buf.length() > 0) {
request = URLDecoder.decode(buf.toString(), "UTF-8");
} else {
request = null;
}
/*
* Construct our response:
*/
buf = new StringBuilder();
buf.append("<html><head><title>HTTP echo server</title></head><body>");
buf.append("<p><pre>");
buf.append(t.getRequestMethod() + " " + t.getRequestURI() + " " + t.getProtocol() + "\n");
/*
* Process the request headers. This is a bit involved due to the
* complexity arising from the fact that headers can be repeated.
*/
Headers headers = t.getRequestHeaders();
for (String name : headers.keySet()) {
List<String> values = headers.get(name);
for (String value : values) {
buf.append(name + ": " + value + "\n");
}
}
/*
* If there was an actual body to the request, add it:
*/
if (request != null) {
buf.append("\n");
buf.append(request);
}
buf.append("</pre></p>");
buf.append("</body></html>\n");
response = buf.toString();
System.out.println(response);
/*
* And now send the response. We could have instead done this
* dynamically, using 0 as the response size (forcing chunked
* encoding) and writing the bytes of the response directly to the
* OutputStream, but building the String first allows us to know the
* exact length so we can send a response with a known size. Better :)
*/
headers.add("Content-Type", "text/html");
t.sendResponseHeaders(HTTP_OK, response.length());
os = t.getResponseBody();
os.write(response.getBytes());
/*
* And we're done!
*/
os.close();
t.close();
}
}
You are extracting the headers from the request and changing request headers doesn't make any sense. you will need to modify the response headers. You can do so by the adding the following
t.getResponseHeaders().add("Content-Type", "text/html");

Google Drive API REST V2 insert file into folder file not found

I am trying to upload a file into one of my company's Google Drive folders but I haven't managed to achieve this without client intervention. So, whenever I use this:
package sample;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
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.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.ParentReference;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class DriveCommandLine_srive
{
private static String CLIENT_ID = "myClientID.apps.googleusercontent.com";
private static String CLIENT_SECRET = "myClientSecret";
private static String REDIRECT_URI = "mything";
public static void main( String[] args ) throws IOException
{
HttpTransport httpTransport = new NetHttpTransport( );
JsonFactory jsonFactory = new JacksonFactory( );
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Arrays.asList( DriveScopes.DRIVE ) ).setAccessType( "online" ).setApprovalPrompt( "auto" ).build( );
System.out.println("xxxxx : " + DriveScopes.DRIVE);
String url = flow.newAuthorizationUrl( ).setRedirectUri( REDIRECT_URI ).build( );
System.out.println( "Please open the following URL in your browser then type the authorization code:" );
System.out.println( " " + url );
BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
String code = br.readLine( );
GoogleTokenResponse response = flow.newTokenRequest( code ).setRedirectUri( REDIRECT_URI ).execute( );
GoogleCredential credential = new GoogleCredential( ).setFromTokenResponse( response );
// Create a new authorized API client
Drive service = new Drive.Builder( httpTransport, jsonFactory, credential ).build( );
insertFile(service, "Test File Drive", "This is a test file","myCompanysFolderID" , "text/plain", "./data/document.txt");
}
/**
* Insert new file.
*
* #param service Drive API service instance.
* #param title Title of the file to insert, including the extension.
* #param description Description of the file to insert.
* #param parentId Optional parent folder's ID.
* #param mimeType MIME type of the file to insert.
* #param filename Filename of the file to insert.
* #return Inserted file metadata if successful, {#code null} otherwise.
*/
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
}
I manage to successfully upload the file to the company's folder, but I have to authorize it manually and paste the code each time. So, as I want to make this in an automatic way, I changed the authorization "method" to one that uses a service account p12 key to authorize the client. This is the new code after the change:
package sample;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.FileContent;
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.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.ParentReference;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class DriveCommandLine2
{
private static final String KEY_FILE_LOCATION = "data/myp12Key.p12";
**//Note: this is the mail from a service account in my dev console, it is different from the OAuth client I use in the previous method.**
private static final String SERVICE_ACCOUNT_EMAIL ="myServiceAccountEmail#appspot.gserviceaccount.com";
/** Application name. */
private static final String APPLICATION_NAME =
"Drive API Java Quickstart";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
public static void main( String[] args ) throws Exception
{
//Drive service = getServiceManual();
Drive service = initializeDrive();
//insertFile(service, "Test File Drive", "This is a test file","myCompanyFolderID" , "text/plain", "./data/document.txt");
insertFile(service, "Test File Drive", "This is a test file","" , "text/plain", "./data/document.txt");
}
/**
* Insert new file.
*
* #param service Drive API service instance.
* #param title Title of the file to insert, including the extension.
* #param description Description of the file to insert.
* #param parentId Optional parent folder's ID.
* #param mimeType MIME type of the file to insert.
* #param filename Filename of the file to insert.
* #return Inserted file metadata if successful, {#code null} otherwise.
*/
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
/////////////////////
///NEW GOOGLE ANALYTICS AUTH
public static java.io.File convIs2File(InputStream inputStream, java.io.File file)
{
java.io.OutputStream outputStream = null;
try {
// write the inputStream to a FileOutputStream
outputStream = new java.io.FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
// outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
private static Drive initializeDrive() throws Exception {
// Initializes an authorized analytics service object.
// Construct a GoogleCredential object with the service account email
// and p12 file downloaded from the developer console.
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
InputStream is = DriveCommandLine2.class.getClassLoader().getResourceAsStream(KEY_FILE_LOCATION);
java.io.File f = java.io.File.createTempFile("myP12Key", ".p12");
java.io.File f_used = convIs2File(is,f);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(f_used)
.setServiceAccountScopes(DriveScopes.all())
.build();
// Construct the Analytics service object.
return new Drive.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
}
}
But when I run this code, I get the following error:
An error occured: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"location" : "file",
"locationType" : "other",
"message" : "File not found: myCompanyFolderID",
"reason" : "notFound"
} ],
"message" : "File not found: myCompanyFolderID"
}
So, my guess is that in the previous authorization way, I am using my Client_ID and Client_Secrets to authorize my app to insert things into my company's Drive space, so I find myCompanyFolder and I am able to insert the file successfully, however, in the second method, I am trying to insert the file into the service account Drive space that I am not able to access (I know this because when I try to insert it in Drive's root, it works perfectly, however, I am not able to see the file in my root).
So at the end, my question is, is there a way to insert the file into my company's drive folder without doing the manual authorization? That is, how do I authorize my app to upload the file in my company's drive without human interaction?
I think the client_secrets way won't work as I tried it before and it asks me to do it manually the first time I run the code. As I am running my code from a JAR file in a Linux server, this is not practical at all and doesn't work for me.
Thanks!
The 404: File not found means that the user does not have read access to a file or the file does not exist.
Make sure that you provide the correct access_token when making the request for file metadata. Try to regenerate the authorization code, access_token. You need to authorize and authenticate your requests on the behalf of the user, a key and your client ID will not be enough to access user's document.
The documentation suggest to report to users that they do not have read access to the file or that the file does not exist. Tell them that they should ask the owner for permission to the file.

Insufficient Permission when run youtube retriving comments

This is my whole code. I want to give a video ID which from youtube to get the comments related to this vedio ID. But always show that I have Insufficient Permission.
I have tried to address this, and found youtube .commentThreads().list("snippet").setVideoId("tLTm_POao1c") .setTextFormat("plainText").execute(); is the problem. Specifically, execute() in this line calls "Insufficient Permission".
Why is this?
package com.google.api.services.samples.youtube.cmdline.youtube_cmdline_addsubscription_sample;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import com.google.api.client.util.Preconditions;//aiyamaya
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.java6.auth.oauth2.FileCredentialStore;
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.json.GoogleJsonResponseException;
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.services.youtube.YouTube;
import com.google.api.services.youtube.model.ResourceId;
import com.google.api.services.youtube.model.Subscription;
import com.google.api.services.youtube.model.SubscriptionSnippet;
import com.google.common.collect.Lists;
import com.google.api.services.youtube.model.CommentThreadListResponse;
import com.google.api.services.youtube.model.CommentThread;
import com.google.api.services.youtube.model.CommentSnippet;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.samples.youtube.cmdline.youtube_cmdline_addsubscription_sample.Auth;
//import com.google.api.services.samples.youtube.cmdline.Auth;
/**
* Demo of subscribing user to a channel using the YouTube Data API (V3) with
* OAuth2 for authorization.
*
* #author Ibrahim Ulukaya
*/
public class AddSubscription {
/** Global instance of the HTTP transport. */
// private static final HttpTransport HTTP_TRANSPORT = new
// NetHttpTransport();
/** Global instance of the JSON factory. */
// private static final JsonFactory JSON_FACTORY = new JacksonFactory();
/** Global instance of Youtube object to make all API requests. */
private static YouTube youtube;
public static void main(String[] args) {
System.setProperty("proxySet", "true");
System.setProperty("proxyHost", "bproxy.rmit.edu.au");
System.setProperty("proxyPort", "8080");
List<String> scopes = Lists
.newArrayList("https://www.googleapis.com/auth/youtube");
try {
// Authorization.
Credential credential = Auth.authorize(scopes, "commentthreads");
// This object is used to make YouTube Data API requests.
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT,
Auth.JSON_FACTORY, credential).setApplicationName(
"youtube-cmdline-commentthreads-sample").build();
// YouTube object used to make all API requests.
CommentThreadListResponse videoCommentsListResponse = youtube
.commentThreads().list("snippet").setVideoId("tLTm_POao1c")
.setTextFormat("plainText").execute();
List<CommentThread> videoComments = videoCommentsListResponse
.getItems();
} catch (GoogleJsonResponseException e) {
System.err.println("GoogleJsonResponseException code: "
+ e.getDetails().getCode() + " : "
+ e.getDetails().getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
e.printStackTrace();
} catch (Throwable t) {
System.err.println("Throwable: " + t.getMessage());
t.printStackTrace();
}
}
/*
* Returns a channel id (String) from user via the terminal.
*/
}
This is the error information:
May 22, 2015 8:19:15 AM com.google.api.client.util.store.FileDataStoreFactory setPermissionsToOwnerOnly
WARNING: unable to change permissions for everybody: C:\Users\E18300\.oauth-credentials
May 22, 2015 8:19:15 AM com.google.api.client.util.store.FileDataStoreFactory setPermissionsToOwnerOnly
WARNING: unable to change permissions for owner: C:\Users\E18300\.oauth-credentials
2015-05-22 08:19:15.192:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2015-05-22 08:19:15.193:INFO::jetty-6.1.26
2015-05-22 08:19:15.212:INFO::Started SocketConnector#localhost:8080
2015-05-22 08:19:20.433:INFO::Stopped SocketConnector#localhost:8080
GoogleJsonResponseException code: 403 : Insufficient Permission
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Insufficient Permission"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1045)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.google.api.services.samples.youtube.cmdline.youtube_cmdline_addsubscription_sample.AddSubscription.main(AddSubscription.java:86)
The documentation lacks in this part, but you need to use the scope https://www.googleapis.com/auth/youtube.force-ssl to retrieve comments from the YouTube API. Took me way too much time to solve this issue.
var OAUTH2_SCOPES = [
'https://www.googleapis.com/auth/youtube',
'https://www.googleapis.com/auth/youtube.force-ssl'
];
to retrieve comments from the YouTube API add
https://www.googleapis.com/auth/youtube.force-ssl
this into OAUTH2_SCOPES array
As the error message indicates, your request does not have sufficient permissions. If you look at the API Reference Overview you will see:
Every request must either specify an API key (with the key parameter) or provide an OAuth 2.0 token. Your API key is available in the API console's API Access pane for your project.
For example I am able to view the comment thread list for a video by making a GET request to this link in the browser directly:
https://www.googleapis.com/youtube/v3/commentThreads?part=snippet&key=YOUR_KEY&videoId=tLTm_POao1c. You will need to replace YOUR_KEY with your application key that you can find in your Google developer console.
I don't know why the code sample for comment threads does not mention anything about the need to include the API key (probably because it is assumed that you read the API Overview first). But
if you look at this other code sample, you will see that you can include a developer key in a local file that you can load into a Properties object:
// Read the developer key from the properties file.
Properties properties = new Properties();
try {
InputStream in = Search.class.getResourceAsStream("/" + PROPERTIES_FILENAME);
properties.load(in);
} catch (IOException e) {
System.err.println("There was an error reading " + PROPERTIES_FILENAME + ": " + e.getCause()
+ " : " + e.getMessage());
System.exit(1);
}
Further down the line, the api key is extracted from the Properties object and is used in the search API call:
// Set your developer key from the Google Developers Console for
// non-authenticated requests. See:
// https://console.developers.google.com/
String apiKey = properties.getProperty("youtube.apikey");
search.setKey(apiKey);
search.setQ(queryTerm);
In a similar manner, you can call setKey() on your code, as described by the JavaDocs: https://developers.google.com/resources/api-libraries/documentation/youtube/v3/java/latest/com/google/api/services/youtube/YouTube.CommentThreads.List.html#setKey(java.lang.String)
So, you may need to add something like this:
CommentThreadListResponse videoCommentsListResponse = youtube.commentThreads()
.list("snippet")
.setKey(YOUR_KEY)
.setVideoId("tLTm_POao1c")
.setTextFormat("plainText")
.execute();
You don't even need the Properties file, unless you plan to change the API key after you write the code and deploy it.
You only need a key to retrieve comments. Something like this:
String apiUrl = "https://www.googleapis.com/youtube/v3/commentThreads?part=snippet%2Creplies&videoId=" + ytId + "&moderationStatus=published&order=relevance&maxResults=5&key=" + apiKey;
Then handle the Json response.

Can we use YouTube Analytics Api using Java and Eclipse?

I tried reading google tutorials and doing the YouTube Analytics Api example. But, I am unable to make the code. Can someone help me to make it (using Java and Eclipse) ?
it shows an error in Import file
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtubeAnalytics.YoutubeAnalytics;
import com.google.api.services.youtubeAnalytics.model.ResultTable;
import com.google.api.services.youtubeAnalytics.model.ResultTable.ColumnHeaders;
import com.google.common.collect.Lists;
Example :
package com.google.api.services.samples.youtube.cmdline.youtube_analytics_cmdline_report_sample;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigDecimal;
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.java6.auth.oauth2.FileCredentialStore;
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.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.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtubeAnalytics.YoutubeAnalytics;
import com.google.api.services.youtubeAnalytics.model.ResultTable;
import com.google.api.services.youtubeAnalytics.model.ResultTable.ColumnHeaders;
import com.google.common.collect.Lists;
public class Samp {
/**
* Demo displaying YouTube metrics from a user's channel using the YouTube Data and YouTube
* Analytics APIs. It also uses OAuth2 for authorization.
*
* #author Christoph Schwab-Ganser and Jeremy Walker
*/
public class YouTubeAnalyticsReports {
/** Global instance of the HTTP transport. */
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
/** Global instance of Youtube object to make general YouTube API requests. */
private static YouTube youtube;
/** Global instance of YoutubeAnalytics object to make analytic API requests. */
private static YoutubeAnalytics analytics;
/**
* Authorizes the installed application to access user's protected YouTube data.
*
* #param scopes list of scopes needed to access general and analytic YouTube info.
*/
private static Credential authorize(List<String> scopes) throws Exception {
// Load client secrets.
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(
JSON_FACTORY,
YouTubeAnalyticsReports.class.getResourceAsStream("/client_secrets.json"));
// Checks that the defaults have been replaced (Default = "Enter X here").
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.err.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=youtube"
+ "into youtube-analytics-cmdline-report-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// Set up file credential store.
FileCredentialStore credentialStore =
new FileCredentialStore(
new File(System.getProperty("user.home"),
".credentials/youtube-analytics-api-report.json"),
JSON_FACTORY);
// Set up authorization code flow.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT,
JSON_FACTORY,
clientSecrets,
scopes)
.setCredentialStore(credentialStore).build();
// Authorize.
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
/**
* Authorizes user, gets user's default channel via YouTube Data API, and gets/prints stats on
* user's channel using the YouTube Analytics API.
*
* #param args command line args (not used).
*/
public static void main(String[] args) {
// Scopes required to access YouTube general and analytics information.
List<String> scopes = Lists.newArrayList(
"https://www.googleapis.com/auth/yt-analytics.readonly",
"https://www.googleapis.com/auth/youtube.readonly"
);
try {
Credential credential = authorize(scopes);
// YouTube object used to make all non-analytic API requests.
youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("youtube-analytics-api-report-example")
.build();
// YouTube object used to make all analytic API requests.
analytics = new YoutubeAnalytics.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName("youtube-analytics-api-report-example")
.build();
// Constructs request to get channel id for current user.
YouTube.Channels.List channelRequest = youtube.channels().list("id,snippet");
channelRequest.setMine(true);
channelRequest.setFields("items(id,snippet/title)");
ChannelListResponse channels = channelRequest.execute();
// List of channels associated with user.
List<Channel> listOfChannels = channels.getItems();
// Grab default channel which is always the first item in the list.
Channel defaultChannel = listOfChannels.get(0);
String channelId = defaultChannel.getId();
PrintStream writer = System.out;
if (channelId == null) {
writer.println("No channel found.");
} else {
writer.println("Default Channel: " + defaultChannel.getSnippet().getTitle() +
" ( " + channelId + " )\n");
printData(writer, "Views Over Time.", executeViewsOverTimeQuery(analytics, channelId));
printData(writer, "Top Videos", executeTopVideosQuery(analytics, channelId));
printData(writer, "Demographics", executeDemographicsQuery(analytics, channelId));
}
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
e.printStackTrace();
} catch (Throwable t) {
System.err.println("Throwable: " + t.getMessage());
t.printStackTrace();
}
}
/**
* Returns the views and unique viewers per day.
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeViewsOverTimeQuery(YoutubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2012-01-01", // Start date.
"2012-01-14", // End date.
"views,uniques") // Metrics.
.setDimensions("day")
.setSort("day")
.execute();
}
/**
* Returns the top video by views.
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeTopVideosQuery(YoutubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2012-01-01", // Start date.
"2012-08-14", // End date.
"views,subscribersGained,subscribersLost") // Metrics.
.setDimensions("video")
.setSort("-views")
.setMaxResults(10)
.execute();
}
/**
* Returns the demographics report
*
* #param analytics the analytics service object used to access the API.
* #param id the string id from which to retrieve data.
* #return the response from the API.
* #throws IOException if an API error occurred.
*/
private static ResultTable executeDemographicsQuery(YoutubeAnalytics analytics,
String id) throws IOException {
return analytics.reports()
.query("channel==" + id, // channel id
"2007-01-01", // Start date.
"2012-08-14", // End date.
"viewerPercentage") // Metrics.
.setDimensions("ageGroup,gender")
.setSort("-viewerPercentage")
.execute();
}
/**
* Prints the output from the API. The channel name is printed along with
* each column name and all the data in the rows.
* #param writer stream to output to
* #param title title of the report
* #param results data returned from the API.
*/
private static void printData(PrintStream writer, String title, ResultTable results) {
writer.println("Report: " + title);
if (results.getRows() == null || results.getRows().isEmpty()) {
writer.println("No results Found.");
} else {
// Print column headers.
for (ColumnHeaders header : results.getColumnHeaders()) {
writer.printf("%30s", header.getName());
}
writer.println();
// Print actual data.
for (List<Object> row : results.getRows()) {
for (int colNum = 0; colNum < results.getColumnHeaders().size(); colNum++) {
ColumnHeaders header = results.getColumnHeaders().get(colNum);
Object column = row.get(colNum);
if ("INTEGER".equals(header.getUnknownKeys().get("dataType"))) {
long l = ((BigDecimal) column).longValue();
writer.printf("%30d", l);
} else if ("FLOAT".equals(header.getUnknownKeys().get("dataType"))) {
writer.printf("%30f", column);
} else if ("STRING".equals(header.getUnknownKeys().get("dataType"))) {
writer.printf("%30s", column);
} else {
// default output.
writer.printf("%30s", column);
}
}
writer.println();
}
writer.println();
}
}
}
}
It would be helpful if you could state what error do you see in Imports?
But assuming you are finding errors in Imports it means you are missing project dependencies in your project path. Find the dependencies in Maven POM.xml. If you are not using Maven to build your project, then please download all the dependent JAR files as mentioned in POM.xml

Categories