Skip to content

Commit 42e806e

Browse files
copybara-service[bot]Zhenyi Qi
andauthored
BREAKING_CHANGE: [vertexai] Change VertexAI to Builder pattern and remove setters. (#10600)
PiperOrigin-RevId: 617935686 Co-authored-by: Zhenyi Qi <zhenyiqi@google.com>
1 parent 17b01c6 commit 42e806e

File tree

3 files changed

+183
-130
lines changed

3 files changed

+183
-130
lines changed

java-vertexai/google-cloud-vertexai/src/main/java/com/google/cloud/vertexai/VertexAI.java

Lines changed: 105 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.cloud.vertexai.api.PredictionServiceClient;
3333
import com.google.cloud.vertexai.api.PredictionServiceSettings;
3434
import com.google.common.base.Strings;
35+
import com.google.common.collect.ImmutableList;
3536
import java.io.IOException;
3637
import java.util.List;
3738
import java.util.concurrent.locks.ReentrantLock;
@@ -56,9 +57,10 @@ public class VertexAI implements AutoCloseable {
5657

5758
private final String projectId;
5859
private final String location;
59-
private String apiEndpoint;
60-
private CredentialsProvider credentialsProvider = null;
61-
private Transport transport = Transport.GRPC;
60+
private final String apiEndpoint;
61+
private final Transport transport;
62+
// Will be null if the user doesn't provide Credentials or scopes
63+
private final CredentialsProvider credentialsProvider;
6264
// The clients will be instantiated lazily
6365
private PredictionServiceClient predictionServiceClient = null;
6466
private LlmUtilityServiceClient llmUtilityClient = null;
@@ -74,79 +76,104 @@ public VertexAI(String projectId, String location) {
7476
this.projectId = projectId;
7577
this.location = location;
7678
this.apiEndpoint = String.format("%s-aiplatform.googleapis.com", this.location);
79+
this.transport = Transport.GRPC;
80+
this.credentialsProvider = null;
7781
}
7882

79-
/**
80-
* Construct a VertexAI instance with default transport layer.
81-
*
82-
* @param projectId the default project to use when making API calls
83-
* @param location the default location to use when making API calls
84-
* @param transport the default {@link Transport} layer to use to send API requests
85-
*/
86-
public VertexAI(String projectId, String location, Transport transport) {
87-
this(projectId, location);
83+
private VertexAI(
84+
String projectId,
85+
String location,
86+
String apiEndpoint,
87+
Transport transport,
88+
Credentials credentials,
89+
List<String> scopes) {
90+
if (!scopes.isEmpty() && credentials != null) {
91+
throw new IllegalArgumentException(
92+
"At most one of Credentials and scopes should be specified.");
93+
}
94+
checkArgument(!Strings.isNullOrEmpty(projectId), "projectId can't be null or empty");
95+
checkArgument(!Strings.isNullOrEmpty(location), "location can't be null or empty");
96+
checkArgument(!Strings.isNullOrEmpty(apiEndpoint), "apiEndpoint can't be null or empty");
97+
checkNotNull(transport, "transport can't be null");
98+
99+
this.projectId = projectId;
100+
this.location = location;
101+
this.apiEndpoint = apiEndpoint;
88102
this.transport = transport;
103+
if (credentials != null) {
104+
this.credentialsProvider = FixedCredentialsProvider.create(credentials);
105+
} else {
106+
this.credentialsProvider =
107+
scopes.size() == 0
108+
? null
109+
: GoogleCredentialsProvider.newBuilder()
110+
.setScopesToApply(scopes)
111+
.setUseJwtAccessWithScope(true)
112+
.build();
113+
}
89114
}
90115

91-
/**
92-
* Construct a VertexAI instance with custom credentials.
93-
*
94-
* @param projectId the default project to use when making API calls
95-
* @param location the default location to use when making API calls
96-
* @param credentials the custom credentials to use when making API calls
97-
*/
98-
public VertexAI(String projectId, String location, Credentials credentials) {
99-
this(projectId, location);
100-
this.credentialsProvider = FixedCredentialsProvider.create(credentials);
101-
}
116+
/** Builder for {@link VertexAI}. */
117+
public static class Builder {
118+
private String projectId;
119+
private String location;
120+
private Credentials credentials;
121+
private String apiEndpoint;
122+
private Transport transport = Transport.GRPC;
123+
private ImmutableList<String> scopes = ImmutableList.of();
102124

103-
/**
104-
* Construct a VertexAI instance with default transport layer and custom credentials.
105-
*
106-
* @param projectId the default project to use when making API calls
107-
* @param location the default location to use when making API calls
108-
* @param transport the default {@link Transport} layer to use to send API requests
109-
* @param credentials the default custom credentials to use when making API calls
110-
*/
111-
public VertexAI(String projectId, String location, Transport transport, Credentials credentials) {
112-
this(projectId, location, credentials);
113-
this.transport = transport;
114-
}
125+
public VertexAI build() {
126+
checkNotNull(projectId, "projectId must be set.");
127+
checkNotNull(location, "location must be set.");
128+
// Default ApiEndpoint is set here as we need to make sure location is set.
129+
if (apiEndpoint == null) {
130+
apiEndpoint = String.format("%s-aiplatform.googleapis.com", location);
131+
}
115132

116-
/**
117-
* Construct a VertexAI instance with application default credentials.
118-
*
119-
* @param projectId the default project to use when making API calls
120-
* @param location the default location to use when making API calls
121-
* @param scopes List of scopes in the default credentials. Make sure you have specified
122-
* "https://www.googleapis.com/auth/cloud-platform" scope to access resources on Vertex AI.
123-
*/
124-
public VertexAI(String projectId, String location, List<String> scopes) throws IOException {
125-
this(projectId, location);
126-
127-
CredentialsProvider credentialsProvider =
128-
scopes.size() == 0
129-
? null
130-
: GoogleCredentialsProvider.newBuilder()
131-
.setScopesToApply(scopes)
132-
.setUseJwtAccessWithScope(true)
133-
.build();
134-
this.credentialsProvider = credentialsProvider;
135-
}
133+
return new VertexAI(projectId, location, apiEndpoint, transport, credentials, scopes);
134+
}
136135

137-
/**
138-
* Construct a VertexAI instance with default transport layer and application default credentials.
139-
*
140-
* @param projectId the default project to use when making API calls
141-
* @param location the default location to use when making API calls
142-
* @param transport the default {@link Transport} layer to use to send API requests
143-
* @param scopes List of scopes in the default credentials. Make sure you have specified
144-
* "https://www.googleapis.com/auth/cloud-platform" scope to access resources on Vertex AI.
145-
*/
146-
public VertexAI(String projectId, String location, Transport transport, List<String> scopes)
147-
throws IOException {
148-
this(projectId, location, scopes);
149-
this.transport = transport;
136+
public Builder setProjectId(String projectId) {
137+
checkArgument(!Strings.isNullOrEmpty(projectId), "projectId can't be null or empty");
138+
139+
this.projectId = projectId;
140+
return this;
141+
}
142+
143+
public Builder setLocation(String location) {
144+
checkArgument(!Strings.isNullOrEmpty(location), "location can't be null or empty");
145+
146+
this.location = location;
147+
return this;
148+
}
149+
150+
public Builder setApiEndpoint(String apiEndpoint) {
151+
checkArgument(!Strings.isNullOrEmpty(apiEndpoint), "apiEndpoint can't be null or empty");
152+
153+
this.apiEndpoint = apiEndpoint;
154+
return this;
155+
}
156+
157+
public Builder setTransport(Transport transport) {
158+
checkNotNull(transport, "transport can't be null");
159+
160+
this.transport = transport;
161+
return this;
162+
}
163+
164+
public Builder setCredentials(Credentials credentials) {
165+
checkNotNull(credentials, "credentials can't be null");
166+
167+
this.credentials = credentials;
168+
return this;
169+
}
170+
171+
public Builder setScopes(List<String> scopes) {
172+
checkNotNull(scopes, "scopes can't be null");
173+
174+
this.scopes = ImmutableList.copyOf(scopes);
175+
return this;
176+
}
150177
}
151178

152179
/**
@@ -155,7 +182,7 @@ public VertexAI(String projectId, String location, Transport transport, List<Str
155182
* @return {@link Transport} layer used when sending API requests.
156183
*/
157184
public Transport getTransport() {
158-
return this.transport;
185+
return transport;
159186
}
160187

161188
/**
@@ -164,7 +191,7 @@ public Transport getTransport() {
164191
* @return Project ID in string format.
165192
*/
166193
public String getProjectId() {
167-
return this.projectId;
194+
return projectId;
168195
}
169196

170197
/**
@@ -173,7 +200,7 @@ public String getProjectId() {
173200
* @return Location in string format.
174201
*/
175202
public String getLocation() {
176-
return this.location;
203+
return location;
177204
}
178205

179206
/**
@@ -182,7 +209,7 @@ public String getLocation() {
182209
* @return API endpoint in string format.
183210
*/
184211
public String getApiEndpoint() {
185-
return this.apiEndpoint;
212+
return apiEndpoint;
186213
}
187214

188215
/**
@@ -192,40 +219,13 @@ public String getApiEndpoint() {
192219
* VertexAI object.
193220
*/
194221
public Credentials getCredentials() throws IOException {
195-
return credentialsProvider.getCredentials();
196-
}
197-
198-
/** Sets the value for {@link #getTransport()}. */
199-
public void setTransport(Transport transport) {
200-
checkNotNull(transport, "Transport can't be null.");
201-
if (this.transport == transport) {
202-
return;
203-
}
204-
205-
this.transport = transport;
206-
resetClients();
207-
}
208-
209-
/** Sets the value for {@link #getApiEndpoint()}. */
210-
public void setApiEndpoint(String apiEndpoint) {
211-
checkArgument(!Strings.isNullOrEmpty(apiEndpoint), "Api endpoint can't be null or empty.");
212-
if (this.apiEndpoint == apiEndpoint) {
213-
return;
214-
}
215-
this.apiEndpoint = apiEndpoint;
216-
resetClients();
217-
}
218-
219-
private void resetClients() {
220-
if (this.predictionServiceClient != null) {
221-
this.predictionServiceClient.close();
222-
this.predictionServiceClient = null;
223-
}
224-
225-
if (this.llmUtilityClient != null) {
226-
this.llmUtilityClient.close();
227-
this.llmUtilityClient = null;
222+
// TODO(b/330780087): support getCredentials() when default credentials (no user provided
223+
// credentials or scopes) are used.
224+
if (credentialsProvider == null) {
225+
throw new IllegalStateException(
226+
"Either Credentials or scopes needs to be provided while instantiating VertexAI.");
228227
}
228+
return credentialsProvider.getCredentials();
229229
}
230230

231231
/**

0 commit comments

Comments
 (0)