Skip to content

Commit 6413a35

Browse files
committed
---
yaml --- r: 4765 b: refs/heads/logging-alpha c: 804d447 h: refs/heads/master i: 4763: 0310cf5
1 parent d22a81b commit 6413a35

28 files changed

Lines changed: 370 additions & 198 deletions

File tree

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ refs/heads/compute-alpha: 969cba2627f1d53d352cc4a5ffe0879dacf65e6c
1212
refs/heads/dns-alpha: 2f90e7e338349287ace33375896907af0f032ca1
1313
refs/heads/dns-alpha-batch: 17442b07867021b85d0452f5f3eda29a3413288f
1414
refs/heads/gcs-nio: 283aeaf15efdcf3621eb6859f05e55ad7764375d
15-
refs/heads/logging-alpha: b29df666b81d8d3045d95c4a8633002fe0136d2e
15+
refs/heads/logging-alpha: 804d44785aa5ff1c3d6654dbb57a56f8ee81b2af
1616
refs/tags/v0.1.0: a615317f7424ed58621b1f65d5c4d8cbbe8a6ed8
1717
refs/tags/v0.1.1: 7a7f6985fe465e9dd6a075af55493f42b4933be0
1818
refs/tags/v0.1.2: 3eb3fe866ba22487686048f45d927b8c8638ea3f

branches/logging-alpha/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,22 @@ public boolean exists() {
128128

129129
/**
130130
* Checks if this job has completed its execution, either failing or succeeding. If the job does
131-
* not exist this method returns {@code true}. You can wait for job completion with:
131+
* not exist this method returns {@code false}. To correctly wait for job's completion check that
132+
* the job exists first, using {@link #exists()}:
132133
* <pre> {@code
133-
* while(!job.isDone()) {
134-
* Thread.sleep(1000L);
134+
* if (job.exists()) {
135+
* while(!job.isDone()) {
136+
* Thread.sleep(1000L);
137+
* }
135138
* }}</pre>
136139
*
137-
* @return {@code true} if this job is in {@link JobStatus.State#DONE} state or if it does not
138-
* exist, {@code false} if the state is not {@link JobStatus.State#DONE}
140+
* @return {@code true} if this job is in {@link JobStatus.State#DONE} state, {@code false} if the
141+
* state is not {@link JobStatus.State#DONE} or the job does not exist
139142
* @throws BigQueryException upon failure
140143
*/
141144
public boolean isDone() {
142145
Job job = bigquery.getJob(jobId(), BigQuery.JobOption.fields(BigQuery.JobField.STATUS));
143-
return job == null || job.status().state() == JobStatus.State.DONE;
146+
return job != null && job.status().state() == JobStatus.State.DONE;
144147
}
145148

146149
/**

branches/logging-alpha/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public void testIsDone_NotExists() throws Exception {
172172
expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null);
173173
replay(bigquery);
174174
initializeJob();
175-
assertTrue(job.isDone());
175+
assertFalse(job.isDone());
176176
}
177177

178178
@Test

branches/logging-alpha/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,13 @@
2525
import java.io.IOException;
2626
import java.io.InputStream;
2727
import java.io.Serializable;
28+
import java.lang.reflect.InvocationTargetException;
2829
import java.lang.reflect.Method;
30+
import java.security.InvalidKeyException;
31+
import java.security.NoSuchAlgorithmException;
2932
import java.security.PrivateKey;
33+
import java.security.Signature;
34+
import java.security.SignatureException;
3035
import java.util.Collection;
3136
import java.util.Objects;
3237

@@ -35,16 +40,26 @@
3540
*/
3641
public abstract class AuthCredentials implements Restorable<AuthCredentials> {
3742

38-
private static class AppEngineAuthCredentials extends AuthCredentials {
43+
/**
44+
* Represents built-in credentials when running in Google App Engine.
45+
*/
46+
public static class AppEngineAuthCredentials extends AuthCredentials
47+
implements ServiceAccountSigner {
3948

4049
private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials();
4150
private static final AppEngineAuthCredentialsState STATE = new AppEngineAuthCredentialsState();
4251

43-
private static class AppEngineCredentials extends GoogleCredentials {
52+
private AppEngineCredentials credentials;
53+
54+
private static class AppEngineCredentials extends GoogleCredentials
55+
implements ServiceAccountSigner {
4456

4557
private final Object appIdentityService;
58+
private final String account;
4659
private final Method getAccessToken;
4760
private final Method getAccessTokenResult;
61+
private final Method signForApp;
62+
private final Method getSignature;
4863
private final Collection<String> scopes;
4964

5065
AppEngineCredentials() {
@@ -59,6 +74,12 @@ private static class AppEngineCredentials extends GoogleCredentials {
5974
"com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult");
6075
this.getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class);
6176
this.getAccessToken = tokenResultClass.getMethod("getAccessToken");
77+
this.account = (String) serviceClass.getMethod("getServiceAccountName")
78+
.invoke(appIdentityService);
79+
this.signForApp = serviceClass.getMethod("signForApp", byte[].class);
80+
Class<?> signingResultClass = Class.forName(
81+
"com.google.appengine.api.appidentity.AppIdentityService$SigningResult");
82+
this.getSignature = signingResultClass.getMethod("getSignature");
6283
this.scopes = null;
6384
} catch (Exception e) {
6485
throw new RuntimeException("Could not create AppEngineCredentials.", e);
@@ -69,11 +90,14 @@ private static class AppEngineCredentials extends GoogleCredentials {
6990
this.appIdentityService = unscoped.appIdentityService;
7091
this.getAccessToken = unscoped.getAccessToken;
7192
this.getAccessTokenResult = unscoped.getAccessTokenResult;
93+
this.account = unscoped.account;
94+
this.signForApp = unscoped.signForApp;
95+
this.getSignature = unscoped.getSignature;
7296
this.scopes = scopes;
7397
}
7498

7599
/**
76-
* Refresh the access token by getting it from the App Identity service
100+
* Refresh the access token by getting it from the App Identity service.
77101
*/
78102
@Override
79103
public AccessToken refreshAccessToken() throws IOException {
@@ -98,6 +122,21 @@ public boolean createScopedRequired() {
98122
public GoogleCredentials createScoped(Collection<String> scopes) {
99123
return new AppEngineCredentials(scopes, this);
100124
}
125+
126+
@Override
127+
public String account() {
128+
return account;
129+
}
130+
131+
@Override
132+
public byte[] sign(byte[] toSign) {
133+
try {
134+
Object signingResult = signForApp.invoke(appIdentityService, (Object) toSign);
135+
return (byte[]) getSignature.invoke(signingResult);
136+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
137+
throw new SigningException("Failed to sign the provided bytes", ex);
138+
}
139+
}
101140
}
102141

103142
private static class AppEngineAuthCredentialsState
@@ -122,14 +161,27 @@ public boolean equals(Object obj) {
122161
}
123162

124163
@Override
125-
public GoogleCredentials credentials() {
126-
return new AppEngineCredentials();
164+
public AppEngineCredentials credentials() {
165+
if (credentials == null) {
166+
credentials = new AppEngineCredentials();
167+
}
168+
return credentials;
127169
}
128170

129171
@Override
130172
public RestorableState<AuthCredentials> capture() {
131173
return STATE;
132174
}
175+
176+
@Override
177+
public String account() {
178+
return credentials().account();
179+
}
180+
181+
@Override
182+
public byte[] sign(byte[] toSign) {
183+
return credentials().sign(toSign);
184+
}
133185
}
134186

135187
/**
@@ -138,8 +190,10 @@ public RestorableState<AuthCredentials> capture() {
138190
* @see <a href="https://cloud.google.com/docs/authentication#user_accounts_and_service_accounts">
139191
* User accounts and service accounts</a>
140192
*/
141-
public static class ServiceAccountAuthCredentials extends AuthCredentials {
193+
public static class ServiceAccountAuthCredentials extends AuthCredentials
194+
implements ServiceAccountSigner {
142195

196+
private final ServiceAccountCredentials credentials;
143197
private final String account;
144198
private final PrivateKey privateKey;
145199

@@ -178,23 +232,44 @@ public boolean equals(Object obj) {
178232
}
179233

180234
ServiceAccountAuthCredentials(String account, PrivateKey privateKey) {
181-
this.account = checkNotNull(account);
182-
this.privateKey = checkNotNull(privateKey);
235+
this(new ServiceAccountCredentials(null, account, privateKey, null, null));
236+
}
237+
238+
ServiceAccountAuthCredentials(ServiceAccountCredentials credentials) {
239+
this.credentials = checkNotNull(credentials);
240+
this.account = checkNotNull(credentials.getClientEmail());
241+
this.privateKey = checkNotNull(credentials.getPrivateKey());
183242
}
184243

185244
@Override
186245
public ServiceAccountCredentials credentials() {
187-
return new ServiceAccountCredentials(null, account, privateKey, null, null);
246+
return credentials;
188247
}
189248

249+
@Override
190250
public String account() {
191251
return account;
192252
}
193253

254+
/**
255+
* Returns the private key associated with the service account credentials.
256+
*/
194257
public PrivateKey privateKey() {
195258
return privateKey;
196259
}
197260

261+
@Override
262+
public byte[] sign(byte[] toSign) {
263+
try {
264+
Signature signer = Signature.getInstance("SHA256withRSA");
265+
signer.initSign(privateKey());
266+
signer.update(toSign);
267+
return signer.sign();
268+
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) {
269+
throw new SigningException("Failed to sign the provided bytes", ex);
270+
}
271+
}
272+
198273
@Override
199274
public RestorableState<AuthCredentials> capture() {
200275
return new ServiceAccountAuthCredentialsState(account, privateKey);
@@ -242,6 +317,10 @@ public boolean equals(Object obj) {
242317
}
243318
}
244319

320+
ApplicationDefaultAuthCredentials(GoogleCredentials credentials) {
321+
googleCredentials = credentials;
322+
}
323+
245324
ApplicationDefaultAuthCredentials() throws IOException {
246325
googleCredentials = GoogleCredentials.getApplicationDefault();
247326
}
@@ -320,7 +399,12 @@ public static AuthCredentials createForAppEngine() {
320399
* @throws IOException if the credentials cannot be created in the current environment
321400
*/
322401
public static AuthCredentials createApplicationDefaults() throws IOException {
323-
return new ApplicationDefaultAuthCredentials();
402+
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
403+
if (credentials instanceof ServiceAccountCredentials) {
404+
ServiceAccountCredentials serviceAccountCredentials = (ServiceAccountCredentials) credentials;
405+
return new ServiceAccountAuthCredentials(serviceAccountCredentials);
406+
}
407+
return new ApplicationDefaultAuthCredentials(credentials);
324408
}
325409

326410
/**
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.gcloud;
18+
19+
import java.util.Objects;
20+
21+
/**
22+
* Interface for a service account signer. A signer for a service account is capable of signing
23+
* bytes using the private key associated with its service account.
24+
*/
25+
public interface ServiceAccountSigner {
26+
27+
class SigningException extends RuntimeException {
28+
29+
private static final long serialVersionUID = 8962780757822799255L;
30+
31+
SigningException(String message, Exception cause) {
32+
super(message, cause);
33+
}
34+
35+
@Override
36+
public boolean equals(Object obj) {
37+
if (obj == this) {
38+
return true;
39+
}
40+
if (!(obj instanceof SigningException)) {
41+
return false;
42+
}
43+
SigningException other = (SigningException) obj;
44+
return Objects.equals(getCause(), other.getCause())
45+
&& Objects.equals(getMessage(), other.getMessage());
46+
}
47+
48+
@Override
49+
public int hashCode() {
50+
return Objects.hash(getMessage(), getCause());
51+
}
52+
}
53+
54+
/**
55+
* Returns the service account associated with the signer.
56+
*/
57+
String account();
58+
59+
/**
60+
* Signs the provided bytes using the private key associated with the service account.
61+
*
62+
* @param toSign bytes to sign
63+
* @return signed bytes
64+
* @throws SigningException if the attempt to sign the provided bytes failed
65+
*/
66+
byte[] sign(byte[] toSign);
67+
}

0 commit comments

Comments
 (0)