Summary
Remove implementation-detail methods from the AICoreService interface. Consolidate duplicated logic between AICoreServiceImpl and MockAICoreServiceImpl into a shared utility.
Problem
The AICoreService interface currently exposes internal state and implementation concerns:
Retry getRetry(); // Cross-module: KEEP
String getDefaultResourceGroup(); // Internal only
String getResourceGroupPrefix(); // Internal only
Map<String, String> getTenantResourceGroupCache(); // Internal only
Map<String, String> getResourceGroupDeploymentCache(); // Internal only
void clearTenantCache(String tenantId); // Internal only
String resolveResourceGroupFromKeys(Map<String, Object> keys); // Internal only
In cds-services, service interfaces (AuditLogService, MessagingService, PersistenceService, etc.) never expose mutable caches, configuration values, or resolution utilities. These are implementation details accessed via the concrete type.
Additionally, resolveResourceGroupFromKeys() is identically duplicated between AICoreServiceImpl and MockAICoreServiceImpl.
Plan
Step 1: Slim the Interface
Keep only domain-level API on AICoreService:
public interface AICoreService extends CqnService {
String DEFAULT_NAME = "AICore";
String RESOURCE_GROUPS = "AICore.resourceGroups";
String DEPLOYMENTS = "AICore.deployments";
String CONFIGURATIONS = "AICore.configurations";
String resourceGroupForTenant(String tenantId);
String deploymentId(String resourceGroupId, ModelDeploymentSpec spec);
ApiClient inferenceClient(String resourceGroupId, String deploymentId);
boolean isMultiTenancyEnabled();
Retry getRetry(); // Cross-module consumer: RecommendationConfiguration
}
Step 2: Keep Methods on Implementations
Methods removed from the interface remain as public methods on AICoreServiceImpl / MockAICoreServiceImpl (remove @Override). Handlers already receive the concrete type.
Step 3: Extract Shared Logic
Create AICoreUtils:
final class AICoreUtils {
static String resolveResourceGroupFromKeys(Map<String, Object> keys, String fallback) {
if (keys.containsKey("resourceGroup_resourceGroupId"))
return (String) keys.get("resourceGroup_resourceGroupId");
Object rgObj = keys.get("resourceGroup");
if (rgObj instanceof Map<?, ?> rgMap && rgMap.containsKey("resourceGroupId"))
return (String) rgMap.get("resourceGroupId");
return fallback;
}
}
Step 4: Update Tests
Tests currently access these methods through the AICoreService interface. Update to use AICoreServiceImpl directly (the tests already have access to the concrete type via injection/ServiceCatalog).
Caller Analysis
| Method |
Cross-Module? |
Same-Module Callers |
getRetry() |
Yes (RecommendationConfiguration, sample) |
— |
getDefaultResourceGroup() |
No |
ResourceGroupHandler, tests |
getResourceGroupPrefix() |
No |
tests |
getTenantResourceGroupCache() |
No |
AICoreSetupHandler, tests |
getResourceGroupDeploymentCache() |
No |
tests |
clearTenantCache() |
No |
AICoreSetupHandler, MockAICoreSetupHandler, tests |
resolveResourceGroupFromKeys() |
No |
AbstractCrudHandler, tests |
Files
AICoreService.java (remove 6 methods)
AICoreServiceImpl.java (remove 6 @Override)
MockAICoreServiceImpl.java (remove 6 @Override)
- New:
AICoreUtils.java
- ~12 test files (update to use concrete type)
Risk
Breaking change if external consumers call these methods through the interface. Mitigated by: this is an internal plugin, the methods serve no external use case, and the CDS model defines the real public contract.
Summary
Remove implementation-detail methods from the
AICoreServiceinterface. Consolidate duplicated logic betweenAICoreServiceImplandMockAICoreServiceImplinto a shared utility.Problem
The
AICoreServiceinterface currently exposes internal state and implementation concerns:In
cds-services, service interfaces (AuditLogService,MessagingService,PersistenceService, etc.) never expose mutable caches, configuration values, or resolution utilities. These are implementation details accessed via the concrete type.Additionally,
resolveResourceGroupFromKeys()is identically duplicated betweenAICoreServiceImplandMockAICoreServiceImpl.Plan
Step 1: Slim the Interface
Keep only domain-level API on
AICoreService:Step 2: Keep Methods on Implementations
Methods removed from the interface remain as
publicmethods onAICoreServiceImpl/MockAICoreServiceImpl(remove@Override). Handlers already receive the concrete type.Step 3: Extract Shared Logic
Create
AICoreUtils:Step 4: Update Tests
Tests currently access these methods through the
AICoreServiceinterface. Update to useAICoreServiceImpldirectly (the tests already have access to the concrete type via injection/ServiceCatalog).Caller Analysis
getRetry()RecommendationConfiguration, sample)getDefaultResourceGroup()ResourceGroupHandler, testsgetResourceGroupPrefix()getTenantResourceGroupCache()AICoreSetupHandler, testsgetResourceGroupDeploymentCache()clearTenantCache()AICoreSetupHandler,MockAICoreSetupHandler, testsresolveResourceGroupFromKeys()AbstractCrudHandler, testsFiles
AICoreService.java(remove 6 methods)AICoreServiceImpl.java(remove 6@Override)MockAICoreServiceImpl.java(remove 6@Override)AICoreUtils.javaRisk
Breaking change if external consumers call these methods through the interface. Mitigated by: this is an internal plugin, the methods serve no external use case, and the CDS model defines the real public contract.