3232import com .google .cloud .vertexai .api .PredictionServiceClient ;
3333import com .google .cloud .vertexai .api .PredictionServiceSettings ;
3434import com .google .common .base .Strings ;
35+ import com .google .common .collect .ImmutableList ;
3536import java .io .IOException ;
3637import java .util .List ;
3738import 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