diff --git a/cds-feature-ai-core/pom.xml b/cds-feature-ai-core/pom.xml index 7658c88..45109b8 100644 --- a/cds-feature-ai-core/pom.xml +++ b/cds-feature-ai-core/pom.xml @@ -51,6 +51,43 @@ ${project.artifactId} + + com.sap.cds + cds-maven-plugin + + + cds.install-node + + install-node + + + + cds.build + + cds + + + ./src/main/resources/cds/com.sap.cds/ai + + build --for java --src ./ --dest ../../../../../../gen/srv + + + + + cds.generate + + generate + + + com.sap.cds.feature.aicore.generated.cds4j + ${project.basedir}/src/gen/srv/src/main/resources/edmx/csn.json + + AICore.** + + + + + org.jacoco jacoco-maven-plugin diff --git a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ActionHandler.java b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ActionHandler.java index b811c96..611cd23 100644 --- a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ActionHandler.java +++ b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ActionHandler.java @@ -3,6 +3,8 @@ */ package com.sap.cds.feature.aicore.core.handler; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.Deployments; + import com.sap.ai.sdk.core.client.DeploymentApi; import com.sap.ai.sdk.core.model.AiDeploymentModificationRequest; import com.sap.ai.sdk.core.model.AiDeploymentTargetStatus; @@ -40,7 +42,7 @@ public void onResourceGroupForTenant(EventContext context) { @On(event = "stop", entity = AICoreService.DEPLOYMENTS) public void onStop(EventContext context) { Map keys = asMap(context.get("keys")); - String deploymentId = (String) keys.get("id"); + String deploymentId = (String) keys.get(Deployments.ID); String resourceGroupId = resolveResourceGroup(keys); DeploymentApi api = service.getDeploymentApi(); diff --git a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ConfigurationHandler.java b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ConfigurationHandler.java index d3fb8d9..9fd641f 100644 --- a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ConfigurationHandler.java +++ b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ConfigurationHandler.java @@ -8,12 +8,15 @@ import com.sap.ai.sdk.core.model.AiConfigurationBaseData; import com.sap.ai.sdk.core.model.AiConfigurationList; import com.sap.ai.sdk.core.model.AiParameterArgumentBinding; -import com.sap.cds.CdsData; import com.sap.cds.feature.aicore.core.AICoreService; import com.sap.cds.feature.aicore.core.AICoreServiceImpl; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ArtifactArgumentBinding; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.Configurations; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ParameterArgumentBinding; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ParameterArgumentBindingList; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ResourceGroups; import com.sap.cds.ql.cqn.AnalysisResult; import com.sap.cds.ql.cqn.CqnAnalyzer; -import com.sap.cds.ql.cqn.CqnInsert; import com.sap.cds.ql.cqn.CqnSelect; import com.sap.cds.reflect.CdsModel; import com.sap.cds.services.cds.CdsCreateEventContext; @@ -22,6 +25,7 @@ import com.sap.cds.services.handler.annotations.On; import com.sap.cds.services.handler.annotations.ServiceName; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import org.slf4j.Logger; @@ -54,98 +58,91 @@ public void onRead(CdsReadEventContext context) { keys, values); - String id = (String) keys.get("id"); + String id = (String) keys.get(Configurations.ID); if (id != null) { AiConfiguration config = configurationApi.get(resourceGroupId, id); - context.setResult(List.of(toMap(config, resourceGroupId))); + context.setResult(List.of(toConfigurations(config, resourceGroupId))); } else { - String scenarioId = (String) values.get("scenarioId"); + String scenarioId = (String) values.get(Configurations.SCENARIO_ID); AiConfigurationList result = configurationApi.query(resourceGroupId, scenarioId, null, null, null, null, null, null); List> results = - mapResources(result.getResources(), c -> toMap(c, resourceGroupId)); + mapResources(result.getResources(), c -> toConfigurations(c, resourceGroupId)); logger.debug("ConfigurationApi.query returned {} resources", results.size()); context.setResult(results); } } @On(event = CqnService.EVENT_CREATE, entity = AICoreService.CONFIGURATIONS) - public void onCreate(CdsCreateEventContext context) { - CqnInsert insert = context.getCqn(); - List> entries = insert.entries(); + public void onCreate(CdsCreateEventContext context, List entries) { List> results = new ArrayList<>(); - for (Map entry : entries) { + for (Configurations entry : entries) { String resourceGroupId = resolveResourceGroup(entry); - String name = (String) entry.get("name"); - String executableId = (String) entry.get("executableId"); - String scenarioId = (String) entry.get("scenarioId"); AiConfigurationBaseData request = AiConfigurationBaseData.create() - .name(name) - .executableId(executableId) - .scenarioId(scenarioId); + .name(entry.getName()) + .executableId(entry.getExecutableId()) + .scenarioId(entry.getScenarioId()); - @SuppressWarnings("unchecked") - List> paramBindings = - (List>) entry.get("parameterBindings"); + Collection paramBindings = + entry.getParameterBindings(); if (paramBindings != null) { List sdkBindings = paramBindings.stream() .map( p -> AiParameterArgumentBinding.create() - .key((String) p.get("key")) - .value((String) p.get("value"))) + .key(p.getKey()) + .value(p.getValue())) .toList(); request.parameterBindings(sdkBindings); } var response = configurationApi.create(resourceGroupId, request); - CdsData result = CdsData.create(entry); - result.put("id", response.getId()); - results.add(result); + entry.setId(response.getId()); + results.add(entry); logger.debug( "Created configuration {} in resource group {}", response.getId(), resourceGroupId); } context.setResult(results); } - private CdsData toMap(AiConfiguration config, String resourceGroupId) { - CdsData data = CdsData.create(); - data.put("id", config.getId()); - data.put("name", config.getName()); - data.put("executableId", config.getExecutableId()); - data.put("scenarioId", config.getScenarioId()); - data.put("createdAt", config.getCreatedAt()); + private Configurations toConfigurations(AiConfiguration config, String resourceGroupId) { + Configurations data = Configurations.create(); + data.setId(config.getId()); + data.setName(config.getName()); + data.setExecutableId(config.getExecutableId()); + data.setScenarioId(config.getScenarioId()); + data.put(Configurations.CREATED_AT, config.getCreatedAt()); if (config.getParameterBindings() != null) { - List bindings = + List bindings = config.getParameterBindings().stream() .map( b -> { - CdsData bm = CdsData.create(); - bm.put("key", b.getKey()); - bm.put("value", b.getValue()); + ParameterArgumentBinding bm = ParameterArgumentBinding.create(); + bm.setKey(b.getKey()); + bm.setValue(b.getValue()); return bm; }) .toList(); - data.put("parameterBindings", bindings); + data.put(Configurations.PARAMETER_BINDINGS, bindings); } if (config.getInputArtifactBindings() != null) { - List bindings = + List bindings = config.getInputArtifactBindings().stream() .map( b -> { - CdsData bm = CdsData.create(); - bm.put("key", b.getKey()); - bm.put("artifactId", b.getArtifactId()); + ArtifactArgumentBinding bm = ArtifactArgumentBinding.create(); + bm.setKey(b.getKey()); + bm.setArtifactId(b.getArtifactId()); return bm; }) .toList(); - data.put("inputArtifactBindings", bindings); + data.put(Configurations.INPUT_ARTIFACT_BINDINGS, bindings); } - data.putPath("resourceGroup.resourceGroupId", resourceGroupId); + data.setResourceGroup(ResourceGroups.create(resourceGroupId)); return data; } } diff --git a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandler.java b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandler.java index f1e6c76..931c2a4 100644 --- a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandler.java +++ b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandler.java @@ -10,15 +10,14 @@ import com.sap.ai.sdk.core.model.AiDeploymentModificationRequest; import com.sap.ai.sdk.core.model.AiDeploymentResponseWithDetails; import com.sap.ai.sdk.core.model.AiDeploymentTargetStatus; -import com.sap.cds.CdsData; import com.sap.cds.feature.aicore.core.AICoreService; import com.sap.cds.feature.aicore.core.AICoreServiceImpl; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.Deployments; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ResourceGroups; import com.sap.cds.ql.cqn.AnalysisResult; import com.sap.cds.ql.cqn.CqnAnalyzer; import com.sap.cds.ql.cqn.CqnDelete; -import com.sap.cds.ql.cqn.CqnInsert; import com.sap.cds.ql.cqn.CqnSelect; -import com.sap.cds.ql.cqn.CqnUpdate; import com.sap.cds.reflect.CdsModel; import com.sap.cds.services.ErrorStatuses; import com.sap.cds.services.ServiceException; @@ -57,53 +56,49 @@ public void onRead(CdsReadEventContext context) { String resourceGroupId = resolveResourceGroup(merge(keys, values)); - String id = (String) keys.get("id"); + String id = (String) keys.get(Deployments.ID); if (id != null) { AiDeploymentResponseWithDetails deployment = deploymentApi.get(resourceGroupId, id); - context.setResult(List.of(toMap(deployment, resourceGroupId))); + context.setResult(List.of(toDeployments(deployment, resourceGroupId))); } else { AiDeploymentList result = deploymentApi.query(resourceGroupId, null, null, null, null, null, null, null); - context.setResult(mapResources(result.getResources(), d -> toMap(d, resourceGroupId))); + context.setResult( + mapResources(result.getResources(), d -> toDeployments(d, resourceGroupId))); } } @On(event = CqnService.EVENT_CREATE, entity = AICoreService.DEPLOYMENTS) - public void onCreate(CdsCreateEventContext context) { - CqnInsert insert = context.getCqn(); - List> entries = insert.entries(); + public void onCreate(CdsCreateEventContext context, List entries) { List> results = new ArrayList<>(); - for (Map entry : entries) { + for (Deployments entry : entries) { String resourceGroupId = resolveResourceGroup(entry); - String configurationId = (String) entry.get("configurationId"); + String configurationId = entry.getConfigurationId(); AiDeploymentCreationRequest request = AiDeploymentCreationRequest.create().configurationId(configurationId); - if (entry.containsKey("ttl")) { - request.ttl((String) entry.get("ttl")); + if (entry.getTtl() != null) { + request.ttl(entry.getTtl()); } var response = deploymentApi.create(resourceGroupId, request); - CdsData result = CdsData.create(entry); - result.put("id", response.getId()); - result.put("status", response.getStatus().getValue()); - results.add(result); + entry.setId(response.getId()); + entry.setStatus(response.getStatus().getValue()); + results.add(entry); logger.debug("Created deployment {} in resource group {}", response.getId(), resourceGroupId); } context.setResult(results); } @On(event = CqnService.EVENT_UPDATE, entity = AICoreService.DEPLOYMENTS) - public void onUpdate(CdsUpdateEventContext context) { - CqnUpdate update = context.getCqn(); - List> entries = update.entries(); + public void onUpdate(CdsUpdateEventContext context, List entries) { if (entries.isEmpty()) { throw new ServiceException(ErrorStatuses.BAD_REQUEST, "No update payload provided"); } - Map data = entries.get(0); - if (!data.containsKey("targetStatus") && !data.containsKey("configurationId")) { + Deployments data = entries.get(0); + if (data.getTargetStatus() == null && data.getConfigurationId() == null) { throw new ServiceException( ErrorStatuses.BAD_REQUEST, "Update payload must contain 'targetStatus' or 'configurationId'"); @@ -111,24 +106,23 @@ public void onUpdate(CdsUpdateEventContext context) { CdsModel model = context.getModel(); CqnAnalyzer analyzer = CqnAnalyzer.create(model); - Map keys = analyzer.analyze(update).targetKeys(); + Map keys = analyzer.analyze(context.getCqn()).targetKeys(); - String deploymentId = (String) keys.get("id"); + String deploymentId = (String) keys.get(Deployments.ID); String resourceGroupId = resolveResourceGroup(merge(keys, data)); AiDeploymentModificationRequest modRequest = AiDeploymentModificationRequest.create(); - if (data.containsKey("targetStatus")) { - String targetStatus = (String) data.get("targetStatus"); - modRequest.targetStatus(AiDeploymentTargetStatus.fromValue(targetStatus)); + if (data.getTargetStatus() != null) { + modRequest.targetStatus(AiDeploymentTargetStatus.fromValue(data.getTargetStatus())); } - if (data.containsKey("configurationId")) { - modRequest.configurationId((String) data.get("configurationId")); + if (data.getConfigurationId() != null) { + modRequest.configurationId(data.getConfigurationId()); } deploymentApi.modify(resourceGroupId, deploymentId, modRequest); logger.debug("Updated deployment {} in resource group {}", deploymentId, resourceGroupId); - context.setResult(List.of(CdsData.create(data))); + context.setResult(List.of(data)); } @On(event = CqnService.EVENT_DELETE, entity = AICoreService.DEPLOYMENTS) @@ -138,7 +132,7 @@ public void onDelete(CdsDeleteEventContext context) { CqnAnalyzer analyzer = CqnAnalyzer.create(model); Map keys = analyzer.analyze(delete).targetKeys(); - String deploymentId = (String) keys.get("id"); + String deploymentId = (String) keys.get(Deployments.ID); String resourceGroupId = resolveResourceGroup(keys); deploymentApi.delete(resourceGroupId, deploymentId); @@ -147,90 +141,51 @@ public void onDelete(CdsDeleteEventContext context) { } // CPD-OFF - SDK types AiDeploymentResponseWithDetails and AiDeployment share no common interface - private CdsData toMap(AiDeploymentResponseWithDetails d, String resourceGroupId) { - return buildDeploymentData( - d.getId(), - d.getDeploymentUrl(), - d.getConfigurationId(), - d.getConfigurationName(), - d.getExecutableId(), - d.getScenarioId(), - d.getStatus().getValue(), - d.getStatusMessage(), - d.getTargetStatus().getValue(), - d.getLastOperation() != null ? d.getLastOperation().getValue() : null, - d.getLatestRunningConfigurationId(), - d.getTtl(), - d.getCreatedAt(), - d.getModifiedAt(), - d.getSubmissionTime(), - d.getStartTime(), - d.getCompletionTime(), - resourceGroupId); - } - - private CdsData toMap(AiDeployment d, String resourceGroupId) { - return buildDeploymentData( - d.getId(), - d.getDeploymentUrl(), - d.getConfigurationId(), - d.getConfigurationName(), - d.getExecutableId(), - d.getScenarioId(), - d.getStatus().getValue(), - d.getStatusMessage(), - d.getTargetStatus().getValue(), - d.getLastOperation() != null ? d.getLastOperation().getValue() : null, - d.getLatestRunningConfigurationId(), - d.getTtl(), - d.getCreatedAt(), - d.getModifiedAt(), - d.getSubmissionTime(), - d.getStartTime(), - d.getCompletionTime(), - resourceGroupId); + private static Deployments toDeployments( + AiDeploymentResponseWithDetails d, String resourceGroupId) { + Deployments data = Deployments.create(); + data.setId(d.getId()); + data.setDeploymentUrl(d.getDeploymentUrl()); + data.setConfigurationId(d.getConfigurationId()); + data.setConfigurationName(d.getConfigurationName()); + data.setExecutableId(d.getExecutableId()); + data.setScenarioId(d.getScenarioId()); + data.setStatus(d.getStatus().getValue()); + data.setStatusMessage(d.getStatusMessage()); + data.setTargetStatus(d.getTargetStatus().getValue()); + data.setLastOperation(d.getLastOperation() != null ? d.getLastOperation().getValue() : null); + data.setLatestRunningConfigurationId(d.getLatestRunningConfigurationId()); + data.setTtl(d.getTtl()); + data.put(Deployments.CREATED_AT, d.getCreatedAt()); + data.put(Deployments.MODIFIED_AT, d.getModifiedAt()); + data.put(Deployments.SUBMISSION_TIME, d.getSubmissionTime()); + data.put(Deployments.START_TIME, d.getStartTime()); + data.put(Deployments.COMPLETION_TIME, d.getCompletionTime()); + data.setResourceGroup(ResourceGroups.create(resourceGroupId)); + return data; } - // CPD-ON - - private static CdsData buildDeploymentData( - String id, - String deploymentUrl, - String configurationId, - String configurationName, - String executableId, - String scenarioId, - String status, - String statusMessage, - String targetStatus, - String lastOperation, - String latestRunningConfigurationId, - String ttl, - Object createdAt, - Object modifiedAt, - Object submissionTime, - Object startTime, - Object completionTime, - String resourceGroupId) { - CdsData data = CdsData.create(); - data.put("id", id); - data.put("deploymentUrl", deploymentUrl); - data.put("configurationId", configurationId); - data.put("configurationName", configurationName); - data.put("executableId", executableId); - data.put("scenarioId", scenarioId); - data.put("status", status); - data.put("statusMessage", statusMessage); - data.put("targetStatus", targetStatus); - data.put("lastOperation", lastOperation); - data.put("latestRunningConfigurationId", latestRunningConfigurationId); - data.put("ttl", ttl); - data.put("createdAt", createdAt); - data.put("modifiedAt", modifiedAt); - data.put("submissionTime", submissionTime); - data.put("startTime", startTime); - data.put("completionTime", completionTime); - data.putPath("resourceGroup.resourceGroupId", resourceGroupId); + private static Deployments toDeployments(AiDeployment d, String resourceGroupId) { + Deployments data = Deployments.create(); + data.setId(d.getId()); + data.setDeploymentUrl(d.getDeploymentUrl()); + data.setConfigurationId(d.getConfigurationId()); + data.setConfigurationName(d.getConfigurationName()); + data.setExecutableId(d.getExecutableId()); + data.setScenarioId(d.getScenarioId()); + data.setStatus(d.getStatus().getValue()); + data.setStatusMessage(d.getStatusMessage()); + data.setTargetStatus(d.getTargetStatus().getValue()); + data.setLastOperation(d.getLastOperation() != null ? d.getLastOperation().getValue() : null); + data.setLatestRunningConfigurationId(d.getLatestRunningConfigurationId()); + data.setTtl(d.getTtl()); + data.put(Deployments.CREATED_AT, d.getCreatedAt()); + data.put(Deployments.MODIFIED_AT, d.getModifiedAt()); + data.put(Deployments.SUBMISSION_TIME, d.getSubmissionTime()); + data.put(Deployments.START_TIME, d.getStartTime()); + data.put(Deployments.COMPLETION_TIME, d.getCompletionTime()); + data.setResourceGroup(ResourceGroups.create(resourceGroupId)); return data; } + // CPD-ON } diff --git a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandler.java b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandler.java index 1037b68..aa61f7f 100644 --- a/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandler.java +++ b/cds-feature-ai-core/src/main/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandler.java @@ -12,10 +12,10 @@ import com.sap.cds.CdsData; import com.sap.cds.feature.aicore.core.AICoreService; import com.sap.cds.feature.aicore.core.AICoreServiceImpl; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ResourceGroups; import com.sap.cds.ql.cqn.AnalysisResult; import com.sap.cds.ql.cqn.CqnAnalyzer; import com.sap.cds.ql.cqn.CqnDelete; -import com.sap.cds.ql.cqn.CqnInsert; import com.sap.cds.ql.cqn.CqnSelect; import com.sap.cds.ql.cqn.CqnUpdate; import com.sap.cds.reflect.CdsModel; @@ -53,9 +53,9 @@ public void onRead(CdsReadEventContext context) { Map keys = analysis.targetKeys(); Map values = analysis.targetValues(); - String resourceGroupId = (String) keys.get("resourceGroupId"); + String resourceGroupId = (String) keys.get(ResourceGroups.RESOURCE_GROUP_ID); if (resourceGroupId == null) { - resourceGroupId = (String) values.get("resourceGroupId"); + resourceGroupId = (String) values.get(ResourceGroups.RESOURCE_GROUP_ID); } if (resourceGroupId != null) { @@ -63,8 +63,8 @@ public void onRead(CdsReadEventContext context) { context.setResult(List.of(toMap(rg))); } else { List labelSelector = null; - if (values.containsKey("tenantId")) { - String tenantId = (String) values.get("tenantId"); + if (values.containsKey(ResourceGroups.TENANT_ID)) { + String tenantId = (String) values.get(ResourceGroups.TENANT_ID); labelSelector = List.of(AICoreServiceImpl.TENANT_LABEL_KEY + "=" + tenantId); } BckndResourceGroupList result = @@ -74,18 +74,16 @@ public void onRead(CdsReadEventContext context) { } @On(event = CqnService.EVENT_CREATE, entity = AICoreService.RESOURCE_GROUPS) - public void onCreate(CdsCreateEventContext context) { - CqnInsert insert = context.getCqn(); - List> entries = insert.entries(); + public void onCreate(CdsCreateEventContext context, List entries) { List> results = new ArrayList<>(); - for (Map entry : entries) { - String resourceGroupId = (String) entry.get("resourceGroupId"); + for (ResourceGroups entry : entries) { + String resourceGroupId = entry.getResourceGroupId(); BckndResourceGroupsPostRequest request = BckndResourceGroupsPostRequest.create().resourceGroupId(resourceGroupId); @SuppressWarnings("unchecked") - List> labels = (List>) entry.get("labels"); + List> labels = (List>) entry.get(ResourceGroups.LABELS); List mergedLabels = new ArrayList<>(); // User-supplied labels take precedence: if they include the tenant label key, we skip @@ -95,12 +93,11 @@ public void onCreate(CdsCreateEventContext context) { && labels.stream() .anyMatch(l -> AICoreServiceImpl.TENANT_LABEL_KEY.equals(l.get("key"))); - if (entry.containsKey("tenantId") && !userSuppliedTenantLabel) { - String tenantId = (String) entry.get("tenantId"); + if (entry.getTenantId() != null && !userSuppliedTenantLabel) { mergedLabels.add( BckndResourceGroupLabel.create() .key(AICoreServiceImpl.TENANT_LABEL_KEY) - .value(tenantId)); + .value(entry.getTenantId())); } if (labels != null) { @@ -131,7 +128,7 @@ public void onUpdate(CdsUpdateEventContext context) { BckndResourceGroupPatchRequest patchRequest = BckndResourceGroupPatchRequest.create(); @SuppressWarnings("unchecked") - List> labels = (List>) data.get("labels"); + List> labels = (List>) data.get(ResourceGroups.LABELS); if (labels != null) { patchRequest.labels(toSdkLabels(labels)); } @@ -155,11 +152,11 @@ public void onDelete(CdsDeleteEventContext context) { } private String resolveResourceGroupId(Map keys) { - if (keys.containsKey("resourceGroupId")) { - return (String) keys.get("resourceGroupId"); + if (keys.containsKey(ResourceGroups.RESOURCE_GROUP_ID)) { + return (String) keys.get(ResourceGroups.RESOURCE_GROUP_ID); } - if (keys.containsKey("tenantId")) { - return service.resourceGroupForTenant((String) keys.get("tenantId")); + if (keys.containsKey(ResourceGroups.TENANT_ID)) { + return service.resourceGroupForTenant((String) keys.get(ResourceGroups.TENANT_ID)); } return service.getDefaultResourceGroup(); } @@ -174,24 +171,25 @@ private static List toSdkLabels(List labels = new ArrayList<>(rg.getLabels().size()); for (BckndResourceGroupLabel l : rg.getLabels()) { - CdsData lm = CdsData.create(); - lm.put("key", l.getKey()); - lm.put("value", l.getValue()); + var lm = + com.sap.cds.feature.aicore.generated.cds4j.aicore.BckndResourceGroupLabel.create(); + lm.setKey(l.getKey()); + lm.setValue(l.getValue()); labels.add(lm); if (AICoreServiceImpl.TENANT_LABEL_KEY.equals(l.getKey())) { - data.put("tenantId", l.getValue()); + data.setTenantId(l.getValue()); } } - data.put("labels", labels); + data.put(ResourceGroups.LABELS, labels); } return data; } diff --git a/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandlerTest.java b/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandlerTest.java index 9b4da06..00fe4a0 100644 --- a/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandlerTest.java +++ b/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/DeploymentHandlerTest.java @@ -10,7 +10,7 @@ import com.sap.ai.sdk.core.client.DeploymentApi; import com.sap.cds.feature.aicore.core.AICoreServiceImpl; -import com.sap.cds.ql.cqn.CqnUpdate; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.Deployments; import com.sap.cds.services.ErrorStatuses; import com.sap.cds.services.ServiceException; import com.sap.cds.services.cds.CdsUpdateEventContext; @@ -28,7 +28,6 @@ class DeploymentHandlerTest { @Mock private AICoreServiceImpl service; @Mock private DeploymentApi deploymentApi; @Mock private CdsUpdateEventContext context; - @Mock private CqnUpdate update; private DeploymentHandler cut; @@ -40,10 +39,9 @@ void setup() { @Test void onUpdate_emptyEntries_throwsBadRequest() { - when(context.getCqn()).thenReturn(update); - when(update.entries()).thenReturn(List.of()); + List entries = List.of(); - assertThatThrownBy(() -> cut.onUpdate(context)) + assertThatThrownBy(() -> cut.onUpdate(context, entries)) .isInstanceOfSatisfying( ServiceException.class, e -> assertThat(e.getErrorStatus()).isEqualTo(ErrorStatuses.BAD_REQUEST)) @@ -54,10 +52,9 @@ void onUpdate_emptyEntries_throwsBadRequest() { @Test void onUpdate_payloadWithoutTargetStatusOrConfigurationId_throwsBadRequest() { - when(context.getCqn()).thenReturn(update); - when(update.entries()).thenReturn(List.of(Map.of("ttl", "1d"))); + List entries = List.of(Deployments.of(Map.of("ttl", "1d"))); - assertThatThrownBy(() -> cut.onUpdate(context)) + assertThatThrownBy(() -> cut.onUpdate(context, entries)) .isInstanceOfSatisfying( ServiceException.class, e -> assertThat(e.getErrorStatus()).isEqualTo(ErrorStatuses.BAD_REQUEST)) diff --git a/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandlerTest.java b/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandlerTest.java index 8c9743a..925737d 100644 --- a/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandlerTest.java +++ b/cds-feature-ai-core/src/test/java/com/sap/cds/feature/aicore/core/handler/ResourceGroupHandlerTest.java @@ -12,7 +12,7 @@ import com.sap.ai.sdk.core.model.BckndResourceGroupLabel; import com.sap.ai.sdk.core.model.BckndResourceGroupsPostRequest; import com.sap.cds.feature.aicore.core.AICoreServiceImpl; -import com.sap.cds.ql.cqn.CqnInsert; +import com.sap.cds.feature.aicore.generated.cds4j.aicore.ResourceGroups; import com.sap.cds.services.cds.CdsCreateEventContext; import java.util.List; import java.util.Map; @@ -29,7 +29,6 @@ class ResourceGroupHandlerTest { @Mock private AICoreServiceImpl service; @Mock private ResourceGroupApi resourceGroupApi; @Mock private CdsCreateEventContext context; - @Mock private CqnInsert insert; private ResourceGroupHandler handler; @@ -42,10 +41,9 @@ void setUp() { @Test void onCreate_withTenantIdOnly_setsOnlyTenantLabel() { Map entry = Map.of("resourceGroupId", "rg-1", "tenantId", "tenant-a"); - when(context.getCqn()).thenReturn(insert); - when(insert.entries()).thenReturn(List.of(entry)); + List entries = List.of(ResourceGroups.of(entry)); - handler.onCreate(context); + handler.onCreate(context, entries); BckndResourceGroupsPostRequest request = captureCreateRequest(); assertThat(request.getResourceGroupId()).isEqualTo("rg-1"); @@ -62,10 +60,9 @@ void onCreate_withLabelsOnly_setsOnlyUserLabels() { "rg-2", "labels", List.of(Map.of("key", "env", "value", "prod"), Map.of("key", "team", "value", "ai"))); - when(context.getCqn()).thenReturn(insert); - when(insert.entries()).thenReturn(List.of(entry)); + List entries = List.of(ResourceGroups.of(entry)); - handler.onCreate(context); + handler.onCreate(context, entries); BckndResourceGroupsPostRequest request = captureCreateRequest(); assertThat(request.getResourceGroupId()).isEqualTo("rg-2"); @@ -84,10 +81,9 @@ void onCreate_withTenantIdAndLabels_keepsTenantLabelAndUserLabels() { "tenant-b", "labels", List.of(Map.of("key", "env", "value", "prod"))); - when(context.getCqn()).thenReturn(insert); - when(insert.entries()).thenReturn(List.of(entry)); + List entries = List.of(ResourceGroups.of(entry)); - handler.onCreate(context); + handler.onCreate(context, entries); BckndResourceGroupsPostRequest request = captureCreateRequest(); // Tenant label first, then user-supplied labels — and tenant label is NOT lost. @@ -107,10 +103,9 @@ void onCreate_userSuppliedTenantLabelTakesPrecedence() { "tenant-auto", "labels", List.of(Map.of("key", AICoreServiceImpl.TENANT_LABEL_KEY, "value", "tenant-user"))); - when(context.getCqn()).thenReturn(insert); - when(insert.entries()).thenReturn(List.of(entry)); + List entries = List.of(ResourceGroups.of(entry)); - handler.onCreate(context); + handler.onCreate(context, entries); BckndResourceGroupsPostRequest request = captureCreateRequest(); assertThat(request.getLabels())