1818
1919import static com .google .common .base .MoreObjects .firstNonNull ;
2020
21- import com .google .cloud . http . HttpTransportOptions ;
21+ import com .google .auth . Credentials ;
2222import com .google .cloud .ServiceDefaults ;
2323import com .google .cloud .ServiceOptions ;
2424import com .google .cloud .ServiceRpc ;
2525import com .google .cloud .TransportOptions ;
26+ import com .google .cloud .http .HttpTransportOptions ;
2627import com .google .cloud .translate .Translate .TranslateOption ;
28+ import com .google .cloud .translate .spi .TranslateRpcFactory ;
2729import com .google .cloud .translate .spi .v2 .HttpTranslateRpc ;
2830import com .google .cloud .translate .spi .v2 .TranslateRpc ;
29- import com .google .cloud .translate .spi .TranslateRpcFactory ;
3031import com .google .common .collect .ImmutableSet ;
31-
3232import java .util .List ;
3333import java .util .Locale ;
3434import java .util .Objects ;
3535import java .util .Set ;
36+ import java .util .logging .Level ;
37+ import java .util .logging .Logger ;
3638
37- public class TranslateOptions extends
38- ServiceOptions <Translate , TranslateOptions > {
39-
39+ public class TranslateOptions extends ServiceOptions <Translate , TranslateOptions > {
4040 private static final long serialVersionUID = -572597134540398216L ;
41+ private static final Logger logger = Logger .getLogger (TranslateOptions .class .getName ());
42+
43+ public static final String API_KEY_ENV_NAME = "GOOGLE_API_KEY" ;
44+
4145 private static final String API_SHORT_NAME = "Translate" ;
4246 private static final String DEFAULT_HOST = "https://translation.googleapis.com" ;
43- private static final String API_KEY_ENV_NAME = "GOOGLE_API_KEY" ;
4447 private static final Set <String > SCOPES =
4548 ImmutableSet .of ("https://www.googleapis.com/auth/cloud-platform" );
4649
@@ -80,6 +83,12 @@ private Builder(TranslateOptions options) {
8083 this .apiKey = options .apiKey ;
8184 }
8285
86+ /**
87+ * Returns the authentication credentials.
88+ */
89+ public Credentials getCredentials () {
90+ return credentials ;
91+ }
8392
8493 @ Override
8594 public Builder setTransportOptions (TransportOptions transportOptions ) {
@@ -101,11 +110,12 @@ public Builder setProjectId(String projectId) {
101110 return self ();
102111 }
103112
104-
105113 /**
106- * Sets the API key used to issue requets. If not set, the API key is looked for in the
107- * {@code GOOGLE_API_KEY} environment variable. For instructions on how to get an API key see
108- * <a href="https://cloud.google.com/translate/v2/quickstart">Translate quickstart</a>.
114+ * Sets the API key used to issue requests. This will be ignored if credentials are explicitly
115+ * set with {@link ServiceOptions.Builder#setCredentials setCredentials}. If neither are set,
116+ * and no Application Default Credentials are available, an API key is looked for in the
117+ * {@code GOOGLE_API_KEY} environment variable. For instructions on how to get an API key see <a
118+ * href="https://cloud.google.com/translate/v2/quickstart">Translate quickstart</a>.
109119 */
110120 public Builder setApiKey (String apiKey ) {
111121 this .apiKey = apiKey ;
@@ -114,7 +124,7 @@ public Builder setApiKey(String apiKey) {
114124
115125
116126 /**
117- * Sets the code for the default target language. If not set, english ({@code en}) is used.
127+ * Sets the code for the default target language. If not set, English ({@code en}) is used.
118128 * {@link Translate#translate(List, TranslateOption...)} and
119129 * {@link Translate#translate(String, TranslateOption...)} calls will use this
120130 * value unless a {@link TranslateOption#targetLanguage(String)} option is explicitly
@@ -135,8 +145,45 @@ public TranslateOptions build() {
135145
136146 private TranslateOptions (Builder builder ) {
137147 super (TranslateFactory .class , TranslateRpcFactory .class , builder , new TranslateDefaults ());
138- this .apiKey = builder .apiKey != null ? builder .apiKey : getDefaultApiKey ();
139- this .targetLanguage = firstNonNull (builder .targetLanguage , Locale .ENGLISH .getLanguage ());
148+ // Use following order of precedence for authentication, avoiding backend conflicts (#1405):
149+ // 1. explicitly set credentials
150+ // 2. explicitly set API key
151+ // 3. Application Default Credentials (e.g., through GOOGLE_APPLICATION_CREDENTIALS)
152+ // 4. default API key (through GOOGLE_API_KEY)
153+ if (builder .getCredentials () != null ) {
154+ // credentials assigned from builder in superclass constructor
155+ apiKey = null ;
156+ if (builder .apiKey != null ) {
157+ logger .log (
158+ Level .WARNING , "Ignoring API key: using explicit setting for credentials instead." );
159+ } else if (getDefaultApiKey () != null ) {
160+ logger .log (
161+ Level .WARNING ,
162+ String .format (
163+ "Ignoring API key set in environment variable %s: using explicit setting for credentials instead." ,
164+ API_KEY_ENV_NAME ));
165+ }
166+ } else if (builder .apiKey != null ) {
167+ credentials = null ;
168+ apiKey = builder .apiKey ;
169+ logger .log (
170+ Level .WARNING ,
171+ String .format (
172+ "Ignoring Application Default Credentials: using explicit setting for API key instead." ,
173+ ServiceOptions .CREDENTIAL_ENV_NAME ));
174+ } else if (credentials != null ) { // credentials assigned from ADC in superclass constructor
175+ apiKey = null ;
176+ if (getDefaultApiKey () != null ) {
177+ logger .log (
178+ Level .WARNING ,
179+ String .format (
180+ "Ignoring API key set in environment variable %s: using Application Default Credentials instead." ,
181+ API_KEY_ENV_NAME ));
182+ }
183+ } else {
184+ apiKey = getDefaultApiKey ();
185+ }
186+ targetLanguage = firstNonNull (builder .targetLanguage , Locale .ENGLISH .getLanguage ());
140187 }
141188
142189 private static class TranslateDefaults implements
@@ -162,6 +209,10 @@ public static HttpTransportOptions getDefaultHttpTransportOptions() {
162209 return HttpTransportOptions .newBuilder ().build ();
163210 }
164211
212+ public static String getDefaultApiKey () {
213+ return System .getProperty (API_KEY_ENV_NAME , System .getenv (API_KEY_ENV_NAME ));
214+ }
215+
165216 @ Override
166217 protected boolean projectIdRequired () {
167218 return false ;
@@ -182,13 +233,8 @@ protected String getDefaultHost() {
182233 }
183234
184235
185- protected String getDefaultApiKey () {
186- return System .getProperty (API_KEY_ENV_NAME , System .getenv (API_KEY_ENV_NAME ));
187- }
188-
189-
190236 /**
191- * Returns the API key, to be used used to send requests.
237+ * Returns the API key, to be used to send requests.
192238 */
193239 public String getApiKey () {
194240 return apiKey ;
0 commit comments