Created
August 26, 2014 19:25
-
-
Save hernanliendo/0914e5acd0b61c49d6fb to your computer and use it in GitHub Desktop.
Hackademy - BigQueryClientFactory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ar.com.zupcat.lib.bean.audit; | |
import ar.com.zupcat.lib.bean.enums.ErrorType; | |
import ar.com.zupcat.lib.exception.GAEException; | |
import com.google.api.client.auth.oauth2.Credential; | |
import com.google.api.client.auth.oauth2.TokenResponse; | |
import com.google.api.client.googleapis.auth.oauth2.*; | |
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.jackson.JacksonFactory; | |
import com.google.api.services.bigquery.Bigquery; | |
import com.google.api.services.bigquery.BigqueryScopes; | |
import java.io.*; | |
import java.util.Collections; | |
import java.util.Properties; | |
public final class BigQueryClientFactory { | |
private static final String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"; | |
private static final String PREVIOUSLY_AUTHORIZED_TOKENS_FILE = "google-cloud-previously-authorized-tokens.properties"; | |
// Objects for handling HTTP transport and JSON formatting of API calls | |
private final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); | |
private final JsonFactory JSON_FACTORY = new JacksonFactory(); | |
private final GoogleClientSecrets googleClientSecrets; | |
private final String appName; | |
private final BigQueryClient bigQueryClientFactory; | |
/** | |
* @param projectNumberId Google Cloud ProjectNumber. It could be seen in, for instance, https://console.developers.google.com/project/apps~topgoalsprod | |
* @param appName just a reference name. For instance topgoalsprod | |
* @param clientSecretsJson obtained by creating a OAuth ClientId on, for instance, https://console.developers.google.com/project/apps~topgoalsprod/apiui/credential - Then you should add the downloaded json file content. See main method in this class for an example | |
*/ | |
public BigQueryClientFactory(final String projectNumberId, final String appName, final String clientSecretsJson) { | |
try { | |
this.appName = appName; | |
googleClientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new StringReader(clientSecretsJson)); | |
final Bigquery bigquery; | |
final String previouslyAuthorizedTokens = tryLoadPreviouslyAuthorizedTokens(); | |
if (previouslyAuthorizedTokens != null) { | |
final GoogleCredential credential = new GoogleCredential.Builder() | |
.setTransport(HTTP_TRANSPORT) | |
.setJsonFactory(JSON_FACTORY) | |
.setClientSecrets(googleClientSecrets) | |
.build() | |
.setFromTokenResponse(new TokenResponse().setRefreshToken(previouslyAuthorizedTokens)); | |
credential.refreshToken(); | |
bigquery = buildService(credential); | |
} else { | |
final String authorizeUrl = new GoogleAuthorizationCodeRequestUrl( | |
googleClientSecrets, | |
REDIRECT_URI, | |
Collections.singleton(BigqueryScopes.BIGQUERY)).setState("").build(); | |
System.err.println("Paste this URL into a web browser to authorize BigQuery Access:\n" + authorizeUrl); | |
System.err.println("... and type the code you received here: "); | |
final BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); | |
final String authorizationCode = in.readLine(); | |
// Exchange the auth code for an access token and refesh token | |
final Credential credential = exchangeCode(authorizationCode); | |
// Store the refresh token for future use. | |
savePreviouslyAuthorizedTokens(credential.getRefreshToken()); | |
bigquery = buildService(credential); | |
} | |
bigQueryClientFactory = new BigQueryClient(projectNumberId, bigquery); | |
} catch (final Exception _exception) { | |
throw new GAEException(ErrorType.PROGRAMMING, _exception); | |
} | |
} | |
public BigQueryClient getBigQueryClientFactory() { | |
return bigQueryClientFactory; | |
} | |
private Bigquery buildService(final Credential credential) { | |
return new Bigquery.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(appName).build(); | |
} | |
private Credential exchangeCode(final String authorizationCode) throws IOException { | |
final GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, | |
JSON_FACTORY, | |
googleClientSecrets, | |
Collections.singleton(BigqueryScopes.BIGQUERY)) | |
.setAccessType("offline").setApprovalPrompt("force").build(); | |
final GoogleTokenResponse response = flow.newTokenRequest(authorizationCode).setRedirectUri(REDIRECT_URI).execute(); | |
return flow.createAndStoreCredential(response, null); | |
} | |
private String tryLoadPreviouslyAuthorizedTokens() { | |
String result = null; | |
try { | |
final Properties properties = new Properties(); | |
properties.load(new FileInputStream(PREVIOUSLY_AUTHORIZED_TOKENS_FILE)); | |
result = (String) properties.get("freshToken"); | |
} catch (final Exception _exception) { | |
// ok to ignore | |
} | |
return result; | |
} | |
private void savePreviouslyAuthorizedTokens(final String freshToken) { | |
try { | |
final Properties properties = new Properties(); | |
properties.setProperty("freshToken", freshToken); | |
properties.store(new FileOutputStream(PREVIOUSLY_AUTHORIZED_TOKENS_FILE), null); | |
} catch (final Exception _exception) { | |
// ok to ignore | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment