Skip to content

Commit

Permalink
Refactor AiCoreDeployment
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlesDuboisSAP committed Oct 16, 2024
1 parent c0af7db commit bb2ae4c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 84 deletions.
92 changes: 14 additions & 78 deletions core/src/main/java/com/sap/ai/sdk/core/AiCoreDeployment.java
Original file line number Diff line number Diff line change
@@ -1,103 +1,39 @@
package com.sap.ai.sdk.core;

import com.sap.cloud.sdk.cloudplatform.connectivity.DefaultHttpDestination;
import com.sap.cloud.sdk.cloudplatform.connectivity.Destination;
import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationProperty;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException;
import com.sap.cloud.sdk.services.openapi.apiclient.ApiClient;
import java.util.function.Function;
import javax.annotation.Nonnull;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/** Connectivity convenience methods for AI Core with deployment. */
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
@RequiredArgsConstructor
public class AiCoreDeployment implements AiCoreDestination {

private static final String AI_RESOURCE_GROUP = "URL.headers.AI-Resource-Group";

// the delegating AI Core Service instance
@Nonnull private final AiCoreService service;
private final AiCoreService aiCoreService;

// the deployment id handler to be used, based on instance
@Nonnull private final Function<AiCoreDeployment, String> deploymentId;

// the resource group, "default" if null
@Getter(AccessLevel.PROTECTED)
@Nonnull
private final String resourceGroup;

/**
* Default constructor with "default" resource group.
*
* @param service The AI Core service.
* @param deploymentId The deployment id handler.
*/
public AiCoreDeployment(
@Nonnull final AiCoreService service,
@Nonnull final Function<AiCoreDeployment, String> deploymentId) {
this(service, deploymentId, "default");
public AiCoreDeployment withResourceGroup(@Nonnull final String resourceGroup) {
aiCoreService.setResourceGroup(resourceGroup);
return this;
}

@Nonnull
@Override
public Destination destination() {
final var dest = service.baseDestinationHandler.apply(service);
final var builder = service.builderHandler.apply(service, dest);
destinationSetUrl(builder, dest);
destinationSetHeaders(builder);
return builder.build();
public Destination destination() throws DestinationAccessException, DestinationNotFoundException {
aiCoreService.deploymentId = deploymentId.apply(this);
return aiCoreService.destination();
}

@Nonnull
@Override
public ApiClient client() {
final var destination = destination();
return service.clientHandler.apply(service, destination);
aiCoreService.deploymentId = deploymentId.apply(this);
return aiCoreService.client();
}

/**
* Update and set the URL for the destination.
*
* @param builder The destination builder.
* @param dest The original destination reference.
*/
protected void destinationSetUrl(
@Nonnull final DefaultHttpDestination.Builder builder, @Nonnull final Destination dest) {
String uri = dest.get(DestinationProperty.URI).get();
if (!uri.endsWith("/")) {
uri = uri + "/";
}
builder.uri(uri + "v2/inference/deployments/%s/".formatted(getDeploymentId()));
}

/**
* Update and set the default request headers for the destination.
*
* @param builder The destination builder.
*/
protected void destinationSetHeaders(@Nonnull final DefaultHttpDestination.Builder builder) {
builder.property(AI_RESOURCE_GROUP, getResourceGroup());
}

/**
* Set the resource group.
*
* @param resourceGroup The resource group.
* @return A new instance of the AI Core service.
*/
@Nonnull
public AiCoreDeployment withResourceGroup(@Nonnull final String resourceGroup) {
return new AiCoreDeployment(service, deploymentId, resourceGroup);
}

/**
* Get the deployment id.
*
* @return The deployment id.
*/
@Nonnull
protected String getDeploymentId() {
return deploymentId.apply(this);
String getResourceGroup() {
return aiCoreService.getResourceGroup();
}
}
45 changes: 39 additions & 6 deletions core/src/main/java/com/sap/ai/sdk/core/AiCoreService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
import java.util.function.BiFunction;
import java.util.function.Function;
import javax.annotation.Nonnull;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
Expand All @@ -32,18 +35,29 @@
@RequiredArgsConstructor
public class AiCoreService implements AiCoreDestination {

final Function<AiCoreService, Destination> baseDestinationHandler;
Function<AiCoreService, Destination> baseDestinationHandler;
final BiFunction<AiCoreService, Destination, ApiClient> clientHandler;
final BiFunction<AiCoreService, Destination, DefaultHttpDestination.Builder> builderHandler;

private static final DeploymentCache DEPLOYMENT_CACHE = new DeploymentCache();

private static final String AI_RESOURCE_GROUP = "URL.headers.AI-Resource-Group";

@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.PROTECTED)
@Nonnull
private String resourceGroup;

@Nonnull String deploymentId;

/** The default constructor. */
public AiCoreService() {
this(
AiCoreService::getBaseDestination,
AiCoreService::getApiClient,
AiCoreService::getDestinationBuilder);
AiCoreService::getDestinationBuilder,
"default",
"");
baseDestinationHandler = AiCoreService::getBaseDestination;
}

@Nonnull
Expand All @@ -57,18 +71,37 @@ public ApiClient client() {
@Override
public Destination destination() {
final var dest = baseDestinationHandler.apply(this);
return builderHandler.apply(this, dest).build();
final var builder = builderHandler.apply(this, dest);
if (!deploymentId.isEmpty()) {
destinationSetUrl(builder, dest);
destinationSetHeaders(builder);
}
return builder.build();
}

protected void destinationSetUrl(
@Nonnull final DefaultHttpDestination.Builder builder, @Nonnull final Destination dest) {
String uri = dest.get(DestinationProperty.URI).get();
if (!uri.endsWith("/")) {
uri = uri + "/";
}
builder.uri(uri + "v2/inference/deployments/%s/".formatted(deploymentId));
}

protected void destinationSetHeaders(@Nonnull final DefaultHttpDestination.Builder builder) {
builder.property(AI_RESOURCE_GROUP, getResourceGroup());
}

/**
* Set a specific base destination.
*
* @param destination The destination to be used for AI Core service calls.
* @return A new instance of the AI Core Service based on the provided destination.
* @return The AI Core Service based on the provided destination.
*/
@Nonnull
public AiCoreService withDestination(@Nonnull final Destination destination) {
return new AiCoreService((service) -> destination, clientHandler, builderHandler);
baseDestinationHandler = (service) -> destination;
return this;
}

/**
Expand Down

0 comments on commit bb2ae4c

Please sign in to comment.