Skip to content

Commit 580951e

Browse files
Merge pull request #80 from gleanwork/cfreeman/server-url-normalization
Add server URL normalization for flexible .serverURL() input
2 parents 98060a5 + b452171 commit 580951e

File tree

6 files changed

+93
-11
lines changed

6 files changed

+93
-11
lines changed

.speakeasy/gen.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ generation:
2222
allOfMergeStrategy: shallowMerge
2323
requestBodyFieldName: ""
2424
versioningStrategy: automatic
25-
persistentEdits: {}
25+
persistentEdits:
26+
enabled: true
2627
tests:
2728
generateTests: true
2829
generateNewTests: false

README.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ Each namespace has its own authentication requirements and access patterns. Whil
1616
// Example of accessing Client namespace
1717
Glean glean = Glean.builder()
1818
.apiToken("client-token")
19-
.instance("instance-name")
19+
.serverURL("https://mycompany-be.glean.com")
2020
.build();
2121
glean.client().search().query()
2222
.searchRequest(SearchRequest.builder().query("search term").build())
2323
.call();
2424

25-
// Example of accessing Indexing namespace
25+
// Example of accessing Indexing namespace
2626
Glean glean = Glean.builder()
2727
.apiToken("indexing-token")
28-
.instance("instance-name")
28+
.serverURL("https://mycompany-be.glean.com")
2929
.build();
3030
glean.indexing().documents().index()
3131
.request(DocumentBulkIndexRequest.builder() /* document data */ .build())
@@ -1308,9 +1308,22 @@ many more subclasses in the JDK platform).
13081308
<!-- Start Server Selection [server] -->
13091309
## Server Selection
13101310

1311-
### Server Variables
1311+
### Server URL
13121312

1313-
The default server `https://{instance}-be.glean.com` contains variables and is set to `https://instance-name-be.glean.com` by default. To override default values, the following builder methods are available when initializing the SDK client instance:
1313+
The recommended way to configure your Glean backend is using `.serverURL()` with your deployment URL:
1314+
1315+
```java
1316+
Glean sdk = Glean.builder()
1317+
.serverURL("https://mycompany-be.glean.com")
1318+
.apiToken(System.getenv().getOrDefault("GLEAN_API_TOKEN", ""))
1319+
.build();
1320+
```
1321+
1322+
The SDK normalizer will automatically add the `https://` scheme if omitted.
1323+
1324+
### Server Variables (backwards-compatible)
1325+
1326+
Alternatively, you can use `.instance()` to configure the server URL via template variable substitution. The default server `https://{instance}-be.glean.com` is set to `https://instance-name-be.glean.com` by default.
13141327

13151328
| Variable | BuilderMethod | Default | Description |
13161329
| ---------- | --------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------ |
@@ -1333,8 +1346,7 @@ public class Application {
13331346
public static void main(String[] args) throws Exception {
13341347

13351348
Glean sdk = Glean.builder()
1336-
.serverIndex(0)
1337-
.instance("<value>")
1349+
.instance("instance-name")
13381350
.apiToken(System.getenv().getOrDefault("GLEAN_API_TOKEN", ""))
13391351
.build();
13401352

@@ -1624,7 +1636,7 @@ export X_GLEAN_INCLUDE_EXPERIMENTAL="true"
16241636
// Environment variables are automatically read by the SDK
16251637
Glean glean = Glean.builder()
16261638
.apiToken(System.getenv("GLEAN_API_TOKEN"))
1627-
.instance("instance-name")
1639+
.serverURL("https://mycompany-be.glean.com")
16281640
.build();
16291641
```
16301642

@@ -1635,7 +1647,7 @@ import com.glean.api_client.glean_api_client.hooks.GleanBuilder;
16351647

16361648
Glean glean = GleanBuilder.create()
16371649
.apiToken(System.getenv("GLEAN_API_TOKEN"))
1638-
.instance("instance-name")
1650+
.serverURL("https://mycompany-be.glean.com")
16391651
.excludeDeprecatedAfter("2026-10-15")
16401652
.includeExperimental(true)
16411653
.build();

src/main/java/com/glean/api_client/glean_api_client/hooks/GleanBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* <pre>{@code
2121
* Glean glean = GleanBuilder.create()
2222
* .apiToken("your-api-token")
23-
* .instance("instance-name")
23+
* .serverURL("https://mycompany-be.glean.com")
2424
* .excludeDeprecatedAfter("2026-10-15")
2525
* .includeExperimental(true)
2626
* .build();

src/main/java/com/glean/api_client/glean_api_client/hooks/SDKHooks.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ private SDKHooks() {
1313
}
1414

1515
public static void initialize(com.glean.api_client.glean_api_client.utils.Hooks hooks) {
16+
hooks.registerSdkInit(ServerURLNormalizerHook.createSyncHook());
17+
1618
hooks.registerAfterError(AgentFileUploadErrorHook.createSyncHook());
1719

1820
// Register the X-Glean header hook for experimental features and deprecation testing
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.glean.api_client.glean_api_client.hooks;
2+
3+
import com.glean.api_client.glean_api_client.utils.Hook;
4+
5+
import java.util.regex.Pattern;
6+
7+
public final class ServerURLNormalizerHook {
8+
9+
private static final Pattern SCHEME_PATTERN = Pattern.compile("(?i)^https?://");
10+
11+
private ServerURLNormalizerHook() {
12+
// prevent instantiation
13+
}
14+
15+
static String normalize(String url) {
16+
String normalized = url;
17+
if (!SCHEME_PATTERN.matcher(normalized).find()) {
18+
normalized = "https://" + normalized;
19+
}
20+
normalized = normalized.replaceAll("/+$", "");
21+
return normalized;
22+
}
23+
24+
public static Hook.SdkInit createSyncHook() {
25+
return data -> new Hook.SdkInitData(normalize(data.baseUrl()), data.client());
26+
}
27+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.glean.api_client.glean_api_client.hooks;
2+
3+
import com.glean.api_client.glean_api_client.utils.Hook;
4+
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.CsvSource;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
class ServerURLNormalizerHookTest {
11+
12+
@ParameterizedTest
13+
@CsvSource({
14+
"example.glean.com, https://example.glean.com",
15+
"https://example.glean.com, https://example.glean.com",
16+
"http://localhost:8080, http://localhost:8080",
17+
"https://example.glean.com///, https://example.glean.com",
18+
"https://example.glean.com/api/v1, https://example.glean.com/api/v1",
19+
"example.glean.com/, https://example.glean.com",
20+
"HTTP://EXAMPLE.COM, HTTP://EXAMPLE.COM",
21+
"HTTPS://EXAMPLE.COM, HTTPS://EXAMPLE.COM",
22+
})
23+
void normalize(String input, String expected) {
24+
assertEquals(expected, ServerURLNormalizerHook.normalize(input));
25+
}
26+
27+
@ParameterizedTest
28+
@CsvSource({
29+
"example.glean.com, https://example.glean.com",
30+
"https://example.glean.com///, https://example.glean.com",
31+
"http://localhost:8080, http://localhost:8080",
32+
})
33+
void createSyncHook(String input, String expected) {
34+
Hook.SdkInit hook = ServerURLNormalizerHook.createSyncHook();
35+
Hook.SdkInitData data = new Hook.SdkInitData(input, null);
36+
Hook.SdkInitData result = hook.sdkInit(data);
37+
assertEquals(expected, result.baseUrl());
38+
assertNull(result.client());
39+
}
40+
}

0 commit comments

Comments
 (0)