Skip to content

Commit 6dfef63

Browse files
committed
feat: defer validation of serviceURL until first use
1 parent e7ccbe4 commit 6dfef63

File tree

7 files changed

+90
-46
lines changed

7 files changed

+90
-46
lines changed

src/main/java/com/ibm/cloud/sdk/core/http/RequestBuilder.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,13 @@ public static RequestBuilder head(HttpUrl url) {
108108
/**
109109
* Creates a properly encoded HttpUrl object with no path parameters.
110110
*
111-
* @param endPoint the API end point
111+
* @param serviceUrl the base service URL associated with the service instance
112112
* @param pathSegments the path segments for a specific API call
113113
* @return the HttpUrl object
114114
*/
115-
public static HttpUrl constructHttpUrl(String endPoint, String[] pathSegments) {
116-
HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(endPoint).newBuilder();
115+
public static HttpUrl constructHttpUrl(String serviceUrl, String[] pathSegments) {
116+
Validator.notEmpty(serviceUrl, "The serviceUrl cannot be null");
117+
HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(serviceUrl).newBuilder();
117118
for (String segment : pathSegments) {
118119
httpUrlBuilder.addPathSegments(segment);
119120
}
@@ -123,13 +124,14 @@ public static HttpUrl constructHttpUrl(String endPoint, String[] pathSegments) {
123124
/**
124125
* Creates a properly encoded HttpUrl object with path parameters.
125126
*
126-
* @param endPoint the API end point
127+
* @param serviceUrl the base service URL associated with the service instance
127128
* @param pathSegments the path segments for a specific API call
128129
* @param pathParameters the path parameters for a specific API call
129130
* @return the HttpUrl object
130131
*/
131-
public static HttpUrl constructHttpUrl(String endPoint, String[] pathSegments, String[] pathParameters) {
132-
HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(endPoint).newBuilder();
132+
public static HttpUrl constructHttpUrl(String serviceUrl, String[] pathSegments, String[] pathParameters) {
133+
Validator.notEmpty(serviceUrl, "The serviceUrl cannot be null");
134+
HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(serviceUrl).newBuilder();
133135
for (int i = 0; i < pathSegments.length; i++) {
134136
httpUrlBuilder.addPathSegments(pathSegments[i]);
135137
if (i < pathParameters.length) {

src/main/java/com/ibm/cloud/sdk/core/service/BaseService.java

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public abstract class BaseService {
6363

6464
private static final String ERRORMSG_NO_AUTHENTICATOR = "Authentication information was not properly configured.";
6565

66-
private String endPoint;
66+
private String serviceUrl;
6767
private final String name;
6868
private Authenticator authenticator;
6969

@@ -101,7 +101,7 @@ public BaseService(final String name, Authenticator authenticator) {
101101
Map<String, String> props = CredentialUtils.getServiceProperties(name);
102102
String url = props.get(PROPNAME_URL);
103103
if (StringUtils.isNotEmpty(url)) {
104-
setEndPoint(url);
104+
this.setServiceUrl(url);
105105
}
106106

107107
// Configure a default client instance.
@@ -228,16 +228,6 @@ protected final <T> ServiceCall<T> createServiceCall(final Request request, fina
228228
return new WatsonServiceCall<>(call, converter);
229229
}
230230

231-
/**
232-
* Gets the API end point.
233-
*
234-
*
235-
* @return the API end point
236-
*/
237-
public String getEndPoint() {
238-
return endPoint;
239-
}
240-
241231
/**
242232
* Gets the name.
243233
*
@@ -264,21 +254,27 @@ protected void setAuthentication(final Builder builder) {
264254
}
265255
}
266256

257+
/**
258+
* Gets the API end point.
259+
*
260+
*
261+
* @return the API end point
262+
* @deprecated Use getServiceURL() instead.
263+
*/
264+
@Deprecated
265+
public String getEndPoint() {
266+
return this.getServiceUrl();
267+
}
268+
267269
/**
268270
* Sets the end point.
269271
*
270272
* @param endPoint the new end point. Will be ignored if empty or null
273+
* @deprecated Use setServiceURL() instead.
271274
*/
275+
@Deprecated
272276
public void setEndPoint(final String endPoint) {
273-
if (CredentialUtils.hasBadStartOrEndChar(endPoint)) {
274-
throw new IllegalArgumentException("The URL shouldn't start or end with curly brackets or quotes. Please "
275-
+ "remove any surrounding {, }, or \" characters.");
276-
}
277-
278-
if ((endPoint != null) && !endPoint.isEmpty()) {
279-
String newEndPoint = endPoint.endsWith("/") ? endPoint.substring(0, endPoint.length() - 1) : endPoint;
280-
this.endPoint = newEndPoint;
281-
}
277+
this.setServiceUrl(endPoint);
282278
}
283279

284280
/**
@@ -302,6 +298,32 @@ public Authenticator getAuthenticator() {
302298
return this.authenticator;
303299
}
304300

301+
/**
302+
* Set the service URL (the base URL for the service instance).
303+
* @param serviceUrl the new service URL value
304+
*/
305+
public void setServiceUrl(String serviceUrl) {
306+
if (CredentialUtils.hasBadStartOrEndChar(serviceUrl)) {
307+
throw new IllegalArgumentException("The URL shouldn't start or end with curly brackets or quotes. Please "
308+
+ "remove any surrounding {, }, or \" characters.");
309+
}
310+
311+
// Remove any potential trailing / character from the input value.
312+
String newValue = serviceUrl;
313+
if ((newValue != null) && !newValue.isEmpty()) {
314+
newValue = newValue.endsWith("/") ? newValue.substring(0, newValue.length() - 1) : newValue;
315+
}
316+
this.serviceUrl = newValue;
317+
}
318+
319+
/**
320+
* Returns the service URL value associated with this service instance.
321+
* @return the service URL
322+
*/
323+
public String getServiceUrl() {
324+
return this.serviceUrl;
325+
}
326+
305327
/*
306328
* (non-Javadoc)
307329
*
@@ -310,11 +332,7 @@ public Authenticator getAuthenticator() {
310332
@Override
311333
public String toString() {
312334
final StringBuilder builder = new StringBuilder().append(name).append(" [");
313-
314-
if (endPoint != null) {
315-
builder.append("endPoint=").append(endPoint);
316-
}
317-
335+
builder.append("serviceUrl=").append(serviceUrl != null ? serviceUrl : "<null>");
318336
return builder.append(']').toString();
319337
}
320338

src/test/java/com/ibm/cloud/sdk/core/test/service/AuthenticationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public void testCredentialFileAuthenticator() {
8989
TestService service = new TestService("natural_language_classifier", null);
9090
assertNotNull(service.getAuthenticator());
9191
assertEquals(Authenticator.AUTHTYPE_IAM, service.getAuthenticator().authenticationType());
92-
assertEquals("https://gateway.watsonplatform.net/natural-language-classifier/api", service.getEndPoint());
92+
assertEquals("https://gateway.watsonplatform.net/natural-language-classifier/api", service.getServiceUrl());
9393
OkHttpClient client = service.getClient();
9494
assertNotNull(client);
9595
assertFalse(client.hostnameVerifier() instanceof OkHostnameVerifier);

src/test/java/com/ibm/cloud/sdk/core/test/service/ErrorResponseTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public class TestService extends BaseService {
5252
}
5353

5454
ServiceCall<GenericModel> testMethod() {
55-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
55+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
5656
return createServiceCall(builder.build(), ResponseConverterUtils.getObject(GenericModel.class));
5757
}
5858
}
@@ -69,7 +69,7 @@ ServiceCall<GenericModel> testMethod() {
6969
public void setUp() throws Exception {
7070
super.setUp();
7171
service = new TestService(new NoAuthAuthenticator());
72-
service.setEndPoint(getMockWebServerUrl());
72+
service.setServiceUrl(getMockWebServerUrl());
7373
}
7474

7575
/**

src/test/java/com/ibm/cloud/sdk/core/test/service/HeadersTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public TestService(Authenticator auth) {
4444
}
4545

4646
public ServiceCall<TestModel> testMethod() {
47-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
47+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
4848
return createServiceCall(builder.build(), ResponseConverterUtils.getObject(TestModel.class));
4949
}
5050
}
@@ -61,7 +61,7 @@ public ServiceCall<TestModel> testMethod() {
6161
public void setUp() throws Exception {
6262
super.setUp();
6363
service = new TestService(new NoAuthAuthenticator());
64-
service.setEndPoint(getMockWebServerUrl());
64+
service.setServiceUrl(getMockWebServerUrl());
6565
}
6666

6767
/**

src/test/java/com/ibm/cloud/sdk/core/test/service/RequestBuilderTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import static org.junit.Assert.assertEquals;
3232
import static org.junit.Assert.assertNotNull;
33+
import static org.junit.Assert.assertNotEquals;
3334

3435
/**
3536
* The Class RequestBuilderTest.
@@ -245,4 +246,27 @@ public void testSpecialCharacterQuery() {
245246
final Request request = RequestBuilder.get(HttpUrl.parse(url)).query("ä&ö", "ö=ü").build();
246247
assertEquals(url + "?%C3%A4%26%C3%B6=%C3%B6%3D%C3%BC", request.url().toString());
247248
}
249+
250+
@Test
251+
public void testConstructHttpUrlGood() {
252+
String[] pathSegments = { "v1/seg1", "seg2", "seg3"};
253+
String[] pathParameters = { "param1", "param2" };
254+
HttpUrl url = RequestBuilder.constructHttpUrl("https://myserver.com/testservice/api", pathSegments, pathParameters);
255+
assertNotNull(url);
256+
assertNotEquals("https://myserver.com/testservice/api/v1/seg1/param1/seg2/param3/seg3", url);
257+
}
258+
259+
@Test(expected = IllegalArgumentException.class)
260+
public void testConstructHttpUrlEmpty() {
261+
String[] pathSegments = { "v1/seg1", "seg2", "seg3"};
262+
String[] pathParameters = { "param1", "param2" };
263+
HttpUrl url = RequestBuilder.constructHttpUrl("", pathSegments, pathParameters);
264+
}
265+
266+
@Test(expected = IllegalArgumentException.class)
267+
public void testConstructHttpUrlNull() {
268+
String[] pathSegments = { "v1/seg1", "seg2", "seg3"};
269+
String[] pathParameters = { "param1", "param2" };
270+
HttpUrl url = RequestBuilder.constructHttpUrl(null, pathSegments, pathParameters);
271+
}
248272
}

src/test/java/com/ibm/cloud/sdk/core/test/service/ResponseTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,52 +64,52 @@ public class TestService extends BaseService {
6464
}
6565

6666
ServiceCall<TestModel> getTestModel() {
67-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
67+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
6868
return createServiceCall(builder.build(), ResponseConverterUtils.getObject(TestModel.class));
6969
}
7070

7171
ServiceCall<TestModel> getTestModel2() {
72-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
72+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
7373
ResponseConverter<TestModel> responseConverter =
7474
ResponseConverterUtils.getValue(new TypeToken<TestModel>(){}.getType());
7575
return createServiceCall(builder.build(), responseConverter);
7676
}
7777

7878
ServiceCall<Void> headMethod() {
79-
RequestBuilder builder = RequestBuilder.head(HttpUrl.parse(getEndPoint() + "/v1/test"));
79+
RequestBuilder builder = RequestBuilder.head(HttpUrl.parse(getServiceUrl() + "/v1/test"));
8080
return createServiceCall(builder.build(), ResponseConverterUtils.getVoid());
8181
}
8282

8383
ServiceCall<String> getString() {
84-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
84+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
8585
ResponseConverter<String> responseConverter =
8686
ResponseConverterUtils.getValue(new TypeToken<String>(){}.getType());
8787
return createServiceCall(builder.build(), responseConverter);
8888
}
8989

9090
ServiceCall<List<String>> getListString() {
91-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
91+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
9292
ResponseConverter<List<String>> responseConverter =
9393
ResponseConverterUtils.getValue(new TypeToken<List<String>>(){}.getType());
9494
return createServiceCall(builder.build(), responseConverter);
9595
}
9696

9797
ServiceCall<Long> getLong() {
98-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
98+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
9999
ResponseConverter<Long> responseConverter =
100100
ResponseConverterUtils.getValue(new TypeToken<Long>(){}.getType());
101101
return createServiceCall(builder.build(), responseConverter);
102102
}
103103

104104
ServiceCall<List<Long>> getListLong() {
105-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
105+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
106106
ResponseConverter<List<Long>> responseConverter =
107107
ResponseConverterUtils.getValue(new TypeToken<List<Long>>(){}.getType());
108108
return createServiceCall(builder.build(), responseConverter);
109109
}
110110

111111
ServiceCall<List<TestModel>> getListTestModel() {
112-
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getEndPoint() + "/v1/test"));
112+
RequestBuilder builder = RequestBuilder.get(HttpUrl.parse(getServiceUrl() + "/v1/test"));
113113
ResponseConverter<List<TestModel>> responseConverter =
114114
ResponseConverterUtils.getValue(new TypeToken<List<TestModel>>(){}.getType());
115115
return createServiceCall(builder.build(), responseConverter);
@@ -138,7 +138,7 @@ ServiceCall<List<TestModel>> getListTestModel() {
138138
public void setUp() throws Exception {
139139
super.setUp();
140140
service = new TestService(new NoAuthAuthenticator());
141-
service.setEndPoint(getMockWebServerUrl());
141+
service.setServiceUrl(getMockWebServerUrl());
142142
}
143143

144144
/**

0 commit comments

Comments
 (0)