|
52 | 52 | import com.openai.azure.AzureOpenAIServiceVersion; |
53 | 53 | import com.openai.client.okhttp.OpenAIOkHttpClient; |
54 | 54 | import com.openai.credential.BearerTokenCredential; |
| 55 | +import java.net.MalformedURLException; |
| 56 | +import java.net.URL; |
55 | 57 | import java.util.ArrayList; |
56 | 58 | import java.util.List; |
57 | 59 | import java.util.Map; |
@@ -419,31 +421,36 @@ private OpenAIOkHttpClient.Builder createOpenAIOkHttpClientDelegateBuilder() { |
419 | 421 | OpenAIOkHttpClient.Builder builder = OpenAIOkHttpClient.builder(); |
420 | 422 | ConnectionsClient connectionsClient = this.buildConnectionsClient(); |
421 | 423 | if (openAIConnectionName == null) { |
422 | | - throw LOGGER.logExceptionAsError(new IllegalArgumentException("OpenAI connection name is not set.")); |
423 | | - } |
424 | | - Connection connection = connectionsClient.getConnection(openAIConnectionName, true); |
425 | | - if (connection.getType() != ConnectionType.AZURE_OPEN_AI) { |
426 | | - throw LOGGER.logExceptionAsError(new IllegalArgumentException("The connection is not of type OPENAI.")); |
427 | | - } |
428 | | - String azureOpenAIEndpoint = connection.getTarget(); |
429 | | - if (azureOpenAIEndpoint.endsWith("/")) { |
430 | | - azureOpenAIEndpoint = azureOpenAIEndpoint.substring(0, azureOpenAIEndpoint.length() - 1); |
431 | | - } |
432 | | - builder.baseUrl(azureOpenAIEndpoint); |
433 | | - BaseCredentials credentials = connection.getCredentials(); |
434 | | - if (credentials.getType() == CredentialType.API_KEY && credentials instanceof ApiKeyCredentials) { |
435 | | - String apiKey = ((ApiKeyCredentials) credentials).getApiKey(); |
436 | | - builder.apiKey(apiKey); |
437 | | - } else if (credentials.getType() == CredentialType.ENTRA_ID) { |
438 | | - if (tokenCredential == null) { |
439 | | - throw LOGGER |
440 | | - .logExceptionAsError(new IllegalArgumentException("Credential is required for OpenAI connection.")); |
441 | | - } |
| 424 | + // use the parent resource |
| 425 | + String azureOpenAIEndpoint = getOpenAIInferenceUrl(this.endpoint); |
| 426 | + builder.baseUrl(azureOpenAIEndpoint); |
442 | 427 | builder.credential(BearerTokenCredential |
443 | | - .create(getBearerTokenSupplier(tokenCredential, "https://cognitiveservices.azure.com/.default"))); |
| 428 | + .create(getBearerTokenSupplier(this.tokenCredential, "https://cognitiveservices.azure.com/.default"))); |
444 | 429 | } else { |
445 | | - throw LOGGER.logExceptionAsError( |
446 | | - new IllegalArgumentException("Unsupported credential type for OpenAI connection.")); |
| 430 | + Connection connection = connectionsClient.getConnection(openAIConnectionName, true); |
| 431 | + if (connection.getType() != ConnectionType.AZURE_OPEN_AI) { |
| 432 | + throw LOGGER.logExceptionAsError(new IllegalArgumentException("The connection is not of type OPENAI.")); |
| 433 | + } |
| 434 | + String azureOpenAIEndpoint = connection.getTarget(); |
| 435 | + if (azureOpenAIEndpoint.endsWith("/")) { |
| 436 | + azureOpenAIEndpoint = azureOpenAIEndpoint.substring(0, azureOpenAIEndpoint.length() - 1); |
| 437 | + } |
| 438 | + builder.baseUrl(azureOpenAIEndpoint); |
| 439 | + BaseCredentials credentials = connection.getCredentials(); |
| 440 | + if (credentials.getType() == CredentialType.API_KEY && credentials instanceof ApiKeyCredentials) { |
| 441 | + String apiKey = ((ApiKeyCredentials) credentials).getApiKey(); |
| 442 | + builder.apiKey(apiKey); |
| 443 | + } else if (credentials.getType() == CredentialType.ENTRA_ID) { |
| 444 | + if (tokenCredential == null) { |
| 445 | + throw LOGGER.logExceptionAsError( |
| 446 | + new IllegalArgumentException("Credential is required for OpenAI connection.")); |
| 447 | + } |
| 448 | + builder.credential(BearerTokenCredential |
| 449 | + .create(getBearerTokenSupplier(tokenCredential, "https://cognitiveservices.azure.com/.default"))); |
| 450 | + } else { |
| 451 | + throw LOGGER.logExceptionAsError( |
| 452 | + new IllegalArgumentException("Unsupported credential type for OpenAI connection.")); |
| 453 | + } |
447 | 454 | } |
448 | 455 | if (azureOpenAIServiceVersion != null) { |
449 | 456 | builder.azureServiceVersion(azureOpenAIServiceVersion); |
@@ -602,6 +609,31 @@ private static Supplier<String> getBearerTokenSupplier(TokenCredential credentia |
602 | 609 | }; |
603 | 610 | } |
604 | 611 |
|
| 612 | + /** |
| 613 | + * Converts an input URL in the format: |
| 614 | + * https://[host-name]/[some-path] |
| 615 | + * to: |
| 616 | + * https://[host-name] |
| 617 | + * |
| 618 | + * @param inputUrl The input endpoint URL used to construct AIProjectClient. |
| 619 | + * @return The endpoint URL required to construct an AzureOpenAI client. |
| 620 | + */ |
| 621 | + private static String getOpenAIInferenceUrl(String inputUrl) { |
| 622 | + URL parsed = null; |
| 623 | + try { |
| 624 | + parsed = new URL(inputUrl); |
| 625 | + } catch (MalformedURLException e) { |
| 626 | + throw LOGGER |
| 627 | + .logExceptionAsError(new IllegalArgumentException("Invalid endpoint URL format. Malformed.", e)); |
| 628 | + } |
| 629 | + if (!"https".equals(parsed.getProtocol()) || parsed.getHost().isEmpty()) { |
| 630 | + throw LOGGER.logExceptionAsError( |
| 631 | + new IllegalArgumentException("Invalid endpoint URL format. Must be an https URL with a host.")); |
| 632 | + } |
| 633 | + String newUrl = "https://" + parsed.getHost(); |
| 634 | + return newUrl; |
| 635 | + } |
| 636 | + |
605 | 637 | /** |
606 | 638 | * Create an instance of the AIProjectClientBuilder. |
607 | 639 | */ |
|
0 commit comments