diff --git a/src/main/java/com/sap/cloudfoundry/client/facade/Messages.java b/src/main/java/com/sap/cloudfoundry/client/facade/Messages.java index 6841acc09..288c4429f 100644 --- a/src/main/java/com/sap/cloudfoundry/client/facade/Messages.java +++ b/src/main/java/com/sap/cloudfoundry/client/facade/Messages.java @@ -25,4 +25,6 @@ private Messages() { public static final String SERVICE_OFFERING_WITH_GUID_0_NOT_FOUND = "Service offering with guid \"{0}\" not found."; public static final String FAILED_TO_FETCH_APP_LOGS_FOR_APP = "Failed to fetch app logs for app: %s"; + public static final String BUILDPACKS_ARE_REQUIRED_FOR_CNB_LIFECYCLE_TYPE = "Buildpacks are required for CNB lifecycle type."; + } diff --git a/src/main/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplication.java b/src/main/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplication.java index f71b365b8..a1d31af2d 100644 --- a/src/main/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplication.java +++ b/src/main/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplication.java @@ -1,9 +1,7 @@ package com.sap.cloudfoundry.client.facade.adapters; -import org.cloudfoundry.client.v3.BuildpackData; -import org.cloudfoundry.client.v3.applications.Application; -import org.cloudfoundry.client.v3.applications.ApplicationState; -import org.immutables.value.Value; +import java.util.Collections; +import java.util.Map; import com.sap.cloudfoundry.client.facade.domain.CloudApplication; import com.sap.cloudfoundry.client.facade.domain.CloudSpace; @@ -12,13 +10,19 @@ import com.sap.cloudfoundry.client.facade.domain.ImmutableLifecycle; import com.sap.cloudfoundry.client.facade.domain.Lifecycle; import com.sap.cloudfoundry.client.facade.domain.LifecycleType; - -import java.util.HashMap; -import java.util.Map; +import org.cloudfoundry.client.v3.BuildpackData; +import org.cloudfoundry.client.v3.CnbData; +import org.cloudfoundry.client.v3.LifecycleData; +import org.cloudfoundry.client.v3.applications.Application; +import org.cloudfoundry.client.v3.applications.ApplicationState; +import org.immutables.value.Value; @Value.Immutable public abstract class RawCloudApplication extends RawCloudEntity { + public static final String BUILDPACKS = "buildpacks"; + public static final String STACK = "stack"; + public abstract Application getApplication(); public abstract Derivable getSpace(); @@ -41,12 +45,8 @@ private static CloudApplication.State parseState(ApplicationState state) { } private static Lifecycle parseLifecycle(org.cloudfoundry.client.v3.Lifecycle lifecycle) { - Map data = new HashMap<>(); - if (lifecycle.getType() == org.cloudfoundry.client.v3.LifecycleType.BUILDPACK) { - var buildpackData = (BuildpackData) lifecycle.getData(); - data.put("buildpacks", buildpackData.getBuildpacks()); - data.put("stack", buildpackData.getStack()); - } + Map data = extractLifecycleData(lifecycle.getData()); + return ImmutableLifecycle.builder() .type(LifecycleType.valueOf(lifecycle.getType() .toString() @@ -55,4 +55,18 @@ private static Lifecycle parseLifecycle(org.cloudfoundry.client.v3.Lifecycle lif .build(); } + private static Map extractLifecycleData(LifecycleData lifecycleData) { + if (lifecycleData instanceof BuildpackData buildpackData) { + return Map.of( + BUILDPACKS, buildpackData.getBuildpacks(), + STACK, buildpackData.getStack()); + } else if (lifecycleData instanceof CnbData cnbData) { + return Map.of( + BUILDPACKS, cnbData.getBuildpacks(), + STACK, cnbData.getStack()); + } else { + return Collections.emptyMap(); + } + } + } diff --git a/src/main/java/com/sap/cloudfoundry/client/facade/domain/LifecycleType.java b/src/main/java/com/sap/cloudfoundry/client/facade/domain/LifecycleType.java index fc8f56c23..3c157afe8 100644 --- a/src/main/java/com/sap/cloudfoundry/client/facade/domain/LifecycleType.java +++ b/src/main/java/com/sap/cloudfoundry/client/facade/domain/LifecycleType.java @@ -2,10 +2,11 @@ public enum LifecycleType { - BUILDPACK, DOCKER, KPACK; + BUILDPACK, DOCKER, KPACK, CNB; public String toString() { - return this.name().toLowerCase(); + return this.name() + .toLowerCase(); } } diff --git a/src/main/java/com/sap/cloudfoundry/client/facade/domain/Staging.java b/src/main/java/com/sap/cloudfoundry/client/facade/domain/Staging.java index b3f5a8012..d9d763523 100644 --- a/src/main/java/com/sap/cloudfoundry/client/facade/domain/Staging.java +++ b/src/main/java/com/sap/cloudfoundry/client/facade/domain/Staging.java @@ -1,13 +1,13 @@ package com.sap.cloudfoundry.client.facade.domain; +import java.util.List; + import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.sap.cloudfoundry.client.facade.Nullable; import com.sap.cloudfoundry.client.facade.SkipNulls; import org.immutables.value.Value; -import java.util.List; - @Value.Immutable @JsonSerialize(as = ImmutableStaging.class) @JsonDeserialize(as = ImmutableStaging.class) @@ -26,7 +26,7 @@ public interface Staging { /** * @return Raw, free-form information regarding a detected buildpack, or null if no detected buildpack was resolved. For example, if the - * application is stopped, the detected buildpack may be null. + * application is stopped, the detected buildpack may be null. */ @Nullable String getDetectedBuildpack(); @@ -67,6 +67,9 @@ public interface Staging { @Nullable Integer getInvocationTimeout(); + @Nullable + LifecycleType getLifecycleType(); + default String getBuildpack() { return getBuildpacks().isEmpty() ? null : getBuildpacks().get(0); } diff --git a/src/main/java/com/sap/cloudfoundry/client/facade/rest/CloudControllerRestClientImpl.java b/src/main/java/com/sap/cloudfoundry/client/facade/rest/CloudControllerRestClientImpl.java index 704bca941..384f02899 100644 --- a/src/main/java/com/sap/cloudfoundry/client/facade/rest/CloudControllerRestClientImpl.java +++ b/src/main/java/com/sap/cloudfoundry/client/facade/rest/CloudControllerRestClientImpl.java @@ -19,6 +19,67 @@ import java.util.function.Supplier; import java.util.stream.Collectors; +import com.sap.cloudfoundry.client.facade.CloudOperationException; +import com.sap.cloudfoundry.client.facade.Constants; +import com.sap.cloudfoundry.client.facade.Messages; +import com.sap.cloudfoundry.client.facade.UploadStatusCallback; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudApplication; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudAsyncJob; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudBuild; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudDomain; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudEvent; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudPackage; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudProcess; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudRoute; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceBinding; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceBroker; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceInstance; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceKey; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceOffering; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServicePlan; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudStack; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudTask; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawInstancesInfo; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawUserRole; +import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawV3CloudServiceInstance; +import com.sap.cloudfoundry.client.facade.domain.BitsData; +import com.sap.cloudfoundry.client.facade.domain.CloudApplication; +import com.sap.cloudfoundry.client.facade.domain.CloudAsyncJob; +import com.sap.cloudfoundry.client.facade.domain.CloudBuild; +import com.sap.cloudfoundry.client.facade.domain.CloudDomain; +import com.sap.cloudfoundry.client.facade.domain.CloudEntity; +import com.sap.cloudfoundry.client.facade.domain.CloudEvent; +import com.sap.cloudfoundry.client.facade.domain.CloudMetadata; +import com.sap.cloudfoundry.client.facade.domain.CloudPackage; +import com.sap.cloudfoundry.client.facade.domain.CloudProcess; +import com.sap.cloudfoundry.client.facade.domain.CloudRoute; +import com.sap.cloudfoundry.client.facade.domain.CloudServiceBinding; +import com.sap.cloudfoundry.client.facade.domain.CloudServiceBroker; +import com.sap.cloudfoundry.client.facade.domain.CloudServiceInstance; +import com.sap.cloudfoundry.client.facade.domain.CloudServiceKey; +import com.sap.cloudfoundry.client.facade.domain.CloudServiceOffering; +import com.sap.cloudfoundry.client.facade.domain.CloudServicePlan; +import com.sap.cloudfoundry.client.facade.domain.CloudSpace; +import com.sap.cloudfoundry.client.facade.domain.CloudStack; +import com.sap.cloudfoundry.client.facade.domain.CloudTask; +import com.sap.cloudfoundry.client.facade.domain.Derivable; +import com.sap.cloudfoundry.client.facade.domain.DockerCredentials; +import com.sap.cloudfoundry.client.facade.domain.DockerInfo; +import com.sap.cloudfoundry.client.facade.domain.DropletInfo; +import com.sap.cloudfoundry.client.facade.domain.ErrorDetails; +import com.sap.cloudfoundry.client.facade.domain.ImmutableDropletInfo; +import com.sap.cloudfoundry.client.facade.domain.ImmutableErrorDetails; +import com.sap.cloudfoundry.client.facade.domain.ImmutableInstancesInfo; +import com.sap.cloudfoundry.client.facade.domain.ImmutableUpload; +import com.sap.cloudfoundry.client.facade.domain.InstancesInfo; +import com.sap.cloudfoundry.client.facade.domain.RouteDestination; +import com.sap.cloudfoundry.client.facade.domain.ServicePlanVisibility; +import com.sap.cloudfoundry.client.facade.domain.Staging; +import com.sap.cloudfoundry.client.facade.domain.Status; +import com.sap.cloudfoundry.client.facade.domain.Upload; +import com.sap.cloudfoundry.client.facade.domain.UserRole; +import com.sap.cloudfoundry.client.facade.dto.ApplicationToCreateDto; +import com.sap.cloudfoundry.client.facade.util.JobV3Util; import org.cloudfoundry.AbstractCloudFoundryException; import org.cloudfoundry.client.CloudFoundryClient; import org.cloudfoundry.client.v3.BuildpackData; @@ -152,69 +213,6 @@ import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; - -import com.sap.cloudfoundry.client.facade.CloudOperationException; -import com.sap.cloudfoundry.client.facade.Constants; -import com.sap.cloudfoundry.client.facade.Messages; -import com.sap.cloudfoundry.client.facade.UploadStatusCallback; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudApplication; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudAsyncJob; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudBuild; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudDomain; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudEvent; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudPackage; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudProcess; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudRoute; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceBinding; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceBroker; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceInstance; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceKey; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServiceOffering; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudServicePlan; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudStack; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawCloudTask; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawInstancesInfo; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawUserRole; -import com.sap.cloudfoundry.client.facade.adapters.ImmutableRawV3CloudServiceInstance; -import com.sap.cloudfoundry.client.facade.domain.BitsData; -import com.sap.cloudfoundry.client.facade.domain.CloudApplication; -import com.sap.cloudfoundry.client.facade.domain.CloudAsyncJob; -import com.sap.cloudfoundry.client.facade.domain.CloudBuild; -import com.sap.cloudfoundry.client.facade.domain.CloudDomain; -import com.sap.cloudfoundry.client.facade.domain.CloudEntity; -import com.sap.cloudfoundry.client.facade.domain.CloudEvent; -import com.sap.cloudfoundry.client.facade.domain.CloudMetadata; -import com.sap.cloudfoundry.client.facade.domain.CloudPackage; -import com.sap.cloudfoundry.client.facade.domain.CloudProcess; -import com.sap.cloudfoundry.client.facade.domain.CloudRoute; -import com.sap.cloudfoundry.client.facade.domain.CloudServiceBinding; -import com.sap.cloudfoundry.client.facade.domain.CloudServiceBroker; -import com.sap.cloudfoundry.client.facade.domain.CloudServiceInstance; -import com.sap.cloudfoundry.client.facade.domain.CloudServiceKey; -import com.sap.cloudfoundry.client.facade.domain.CloudServiceOffering; -import com.sap.cloudfoundry.client.facade.domain.CloudServicePlan; -import com.sap.cloudfoundry.client.facade.domain.CloudSpace; -import com.sap.cloudfoundry.client.facade.domain.CloudStack; -import com.sap.cloudfoundry.client.facade.domain.CloudTask; -import com.sap.cloudfoundry.client.facade.domain.Derivable; -import com.sap.cloudfoundry.client.facade.domain.DockerCredentials; -import com.sap.cloudfoundry.client.facade.domain.DockerInfo; -import com.sap.cloudfoundry.client.facade.domain.DropletInfo; -import com.sap.cloudfoundry.client.facade.domain.ErrorDetails; -import com.sap.cloudfoundry.client.facade.domain.ImmutableDropletInfo; -import com.sap.cloudfoundry.client.facade.domain.ImmutableErrorDetails; -import com.sap.cloudfoundry.client.facade.domain.ImmutableInstancesInfo; -import com.sap.cloudfoundry.client.facade.domain.ImmutableUpload; -import com.sap.cloudfoundry.client.facade.domain.InstancesInfo; -import com.sap.cloudfoundry.client.facade.domain.RouteDestination; -import com.sap.cloudfoundry.client.facade.domain.ServicePlanVisibility; -import com.sap.cloudfoundry.client.facade.domain.Staging; -import com.sap.cloudfoundry.client.facade.domain.Status; -import com.sap.cloudfoundry.client.facade.domain.Upload; -import com.sap.cloudfoundry.client.facade.domain.UserRole; -import com.sap.cloudfoundry.client.facade.dto.ApplicationToCreateDto; -import com.sap.cloudfoundry.client.facade.util.JobV3Util; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -283,8 +281,11 @@ public Optional bindServiceInstance(String bindingName, String applicati .name(bindingName) .type(ServiceBindingType.APPLICATION) .relationships(ServiceBindingRelationships.builder() - .application(buildToOneRelationship(applicationGuid)) - .serviceInstance(buildToOneRelationship(serviceInstanceGuid)) + .application(buildToOneRelationship( + applicationGuid)) + .serviceInstance( + buildToOneRelationship( + serviceInstanceGuid)) .build()); if (!CollectionUtils.isEmpty(parameters)) { createBindingRequest.parameters(parameters); @@ -301,7 +302,8 @@ public void createApplication(ApplicationToCreateDto applicationToCreateDto) { CreateApplicationRequest createApplicationRequest = CreateApplicationRequest.builder() .name(applicationToCreateDto.getName()) .metadata(applicationToCreateDto.getMetadata()) - .lifecycle(buildApplicationLifecycle(applicationToCreateDto.getStaging())) + .lifecycle(buildApplicationLifecycle( + applicationToCreateDto.getStaging())) .relationships(buildApplicationRelationships()) .environmentVariables(applicationToCreateDto.getEnv()) .build(); @@ -312,7 +314,26 @@ public void createApplication(ApplicationToCreateDto applicationToCreateDto) { } private Lifecycle buildApplicationLifecycle(Staging staging) { - return staging.getDockerInfo() != null ? createDockerLifecycle() : createBuildpackLifecycle(staging); + // Prioritize Docker lifecycle if DockerInfo is provided + if (staging.getDockerInfo() != null) { + return createDockerLifecycle(); + } + + // Determine lifecycle type, defaulting to BUILDPACK if lifecycleType is null + LifecycleType lifecycleType = staging.getLifecycleType() != null ? LifecycleType.valueOf(staging.getLifecycleType() + .name()) + : LifecycleType.BUILDPACK; + + return createLifecycleByType(staging, lifecycleType); + } + + private Lifecycle createLifecycleByType(Staging staging, LifecycleType lifecycleType) { + validateLifecycleConfiguration(staging, lifecycleType); + BuildpackData buildpackData = createBuildpackData(staging); + return Lifecycle.builder() + .type(lifecycleType) + .data(buildpackData) + .build(); } private Lifecycle createDockerLifecycle() { @@ -323,12 +344,10 @@ private Lifecycle createDockerLifecycle() { .build(); } - private Lifecycle createBuildpackLifecycle(Staging staging) { - BuildpackData buildpackData = createBuildpackData(staging); - return Lifecycle.builder() - .type(LifecycleType.BUILDPACK) - .data(buildpackData) - .build(); + private void validateLifecycleConfiguration(Staging staging, LifecycleType lifecycleType) { + if (lifecycleType == LifecycleType.CNB && CollectionUtils.isEmpty(staging.getBuildpacks())) { + throw new IllegalArgumentException(Messages.BUILDPACKS_ARE_REQUIRED_FOR_CNB_LIFECYCLE_TYPE); + } } private BuildpackData createBuildpackData(Staging staging) { @@ -433,8 +452,10 @@ public void createServiceInstance(CloudServiceInstance serviceInstance) { .name(serviceInstance.getName()) .metadata(serviceInstance.getV3Metadata()) .relationships(ServiceInstanceRelationships.builder() - .servicePlan(buildToOneRelationship(servicePlanGuid.toString())) - .space(buildToOneRelationship(getTargetSpaceGuid().toString())) + .servicePlan(buildToOneRelationship( + servicePlanGuid.toString())) + .space(buildToOneRelationship( + getTargetSpaceGuid().toString())) .build()) .tags(serviceInstance.getTags()) .parameters(serviceInstance.getCredentials()) @@ -450,7 +471,8 @@ public String createServiceBroker(CloudServiceBroker serviceBroker) { .map(UUID::fromString) .map(this::buildToOneRelationship) .map(spaceRelationship -> ServiceBrokerRelationships.builder() - .space(spaceRelationship) + .space( + spaceRelationship) .build()) .orElse(null); @@ -524,7 +546,9 @@ private CreateServiceBindingRequest buildServiceCredentialBindingRequest(String .name(name) .metadata(metadata) .relationships(ServiceBindingRelationships.builder() - .serviceInstance(buildToOneRelationship(serviceInstanceGuid)) + .serviceInstance( + buildToOneRelationship( + serviceInstanceGuid)) .build()); if (!CollectionUtils.isEmpty(parameters)) { createBindingRequest.parameters(parameters); @@ -546,7 +570,8 @@ public void createUserProvidedServiceInstance(CloudServiceInstance serviceInstan .syslogDrainUrl(syslogDrainUrl) .tags(serviceInstance.getTags()) .relationships(ServiceInstanceRelationships.builder() - .space(buildToOneRelationship(getTargetSpaceGuid().toString())) + .space(buildToOneRelationship( + getTargetSpaceGuid().toString())) .build()) .build()) .block(); @@ -709,7 +734,8 @@ public CloudProcess getApplicationProcess(UUID applicationGuid) { public List getApplicationRoutes(UUID applicationGuid) { return fetchList(() -> getRouteResourcesByAppGuid(applicationGuid), routeResource -> ImmutableRawCloudRoute.builder() .route(routeResource) - .applicationGuid(applicationGuid) + .applicationGuid( + applicationGuid) .build()); } @@ -736,7 +762,8 @@ public List getApplications() { public List getApplicationsByMetadataLabelSelector(String labelSelector) { assertSpaceProvided("get applications"); return fetchList(() -> getApplicationsByLabelSelector(labelSelector), application -> ImmutableRawCloudApplication.builder() - .application(application) + .application( + application) .space(target) .build()); } @@ -898,8 +925,10 @@ public List getServiceKeysWithCredentials(String serviceInstanc @Override public List getServiceKeys(CloudServiceInstance serviceInstance) { return fetchList(() -> getServiceKeyResource(serviceInstance), serviceKey -> ImmutableRawCloudServiceKey.builder() - .serviceInstance(serviceInstance) - .serviceBindingResource(serviceKey) + .serviceInstance( + serviceInstance) + .serviceBindingResource( + serviceKey) .build()); } @@ -979,7 +1008,8 @@ public void updateServicePlan(String serviceName, String planName) { .serviceInstanceId(service.getGuid() .toString()) .relationships(ServiceInstanceRelationships.builder() - .servicePlan(buildToOneRelationship(plan.getGuid())) + .servicePlan( + buildToOneRelationship(plan.getGuid())) .build()) .build()) .block(); @@ -1074,7 +1104,8 @@ private Flux getServiceInstancesByNames(List se String spaceGuid = getTargetSpaceGuid().toString(); IntFunction pageRequestSupplier = page -> ListServiceInstancesRequest.builder() .spaceId(spaceGuid) - .addAllServiceInstanceNames(serviceInstanceNames) + .addAllServiceInstanceNames( + serviceInstanceNames) .page(page) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.serviceInstancesV3() @@ -1096,7 +1127,8 @@ public List getServiceInstancesWithoutAuxiliaryContentByNa public List getServiceInstancesByMetadataLabelSelector(String labelSelector) { IntFunction pageRequestSupplier = page -> ListServiceInstancesRequest.builder() .labelSelector(labelSelector) - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .page(page) .build(); @@ -1108,7 +1140,8 @@ public List getServiceInstancesByMetadataLabelSelector(Str public List getServiceInstancesWithoutAuxiliaryContentByMetadataLabelSelector(String labelSelector) { IntFunction pageRequestSupplier = page -> ListServiceInstancesRequest.builder() .labelSelector(labelSelector) - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .page(page) .build(); @@ -1463,7 +1496,8 @@ public void bindDropletToApp(UUID dropletGuid, UUID applicationGuid) { public DropletInfo getCurrentDropletForApplication(UUID applicationGuid) { GetApplicationCurrentDropletResponse dropletResponse = delegate.applicationsV3() .getCurrentDroplet(GetApplicationCurrentDropletRequest.builder() - .applicationId(applicationGuid.toString()) + .applicationId( + applicationGuid.toString()) .build()) .block(); if (dropletResponse == null) { @@ -1496,7 +1530,8 @@ public List getPackagesForApplication(UUID applicationGuid) { private Flux getPackages(String applicationGuid) { IntFunction pageRequestSupplier = page -> ListApplicationPackagesRequest.builder() .page(page) - .applicationId(applicationGuid) + .applicationId( + applicationGuid) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.applicationsV3() .listPackages(pageRequestSupplier.apply(page))); @@ -1511,7 +1546,8 @@ public Set getUserRolesBySpaceAndUser(UUID spaceGuid, UUID userGuid) { public CloudPackage createDockerPackage(UUID applicationGuid, DockerInfo dockerInfo) { org.cloudfoundry.client.v3.packages.DockerData.Builder dockerDataBuilder = org.cloudfoundry.client.v3.packages.DockerData.builder() - .image(dockerInfo.getImage()); + .image( + dockerInfo.getImage()); if (dockerInfo.getCredentials() != null) { addNonNullDockerCredentials(dockerInfo.getCredentials(), dockerDataBuilder); } @@ -1615,7 +1651,8 @@ private Mono getServiceInstanceByGuid(UUID serviceIns private Mono getServiceInstanceResourceByName(String name) { IntFunction pageRequestSupplier = page -> ListServiceInstancesRequest.builder() - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .serviceInstanceName(name) .page(page) .build(); @@ -1637,14 +1674,18 @@ private Mono> zipWithAuxiliaryServiceInstanceCon .getId(); return getServicePlanResource(servicePlanGuid, - serviceInstanceResource.getName()).zipWhen(servicePlan -> getServiceOffering(servicePlan.getRelationships() - .getServiceOffering() - .getData() - .getId())) + serviceInstanceResource.getName()).zipWhen( + servicePlan -> getServiceOffering(servicePlan.getRelationships() + .getServiceOffering() + .getData() + .getId())) .map(tuple -> ImmutableRawCloudServiceInstance.builder() - .resource(serviceInstanceResource) - .servicePlan(tuple.getT1()) - .serviceOffering(tuple.getT2()) + .resource( + serviceInstanceResource) + .servicePlan( + tuple.getT1()) + .serviceOffering( + tuple.getT2()) .build()); } @@ -1654,8 +1695,10 @@ private boolean isUserProvided(ServiceInstanceResource serviceInstanceResource) private Flux getServiceBindingResourcesByServiceInstanceGuid(UUID serviceInstanceGuid) { IntFunction pageRequestSupplier = page -> ListServiceBindingsRequest.builder() - .serviceInstanceId(serviceInstanceGuid.toString()) - .type(ServiceBindingType.APPLICATION) + .serviceInstanceId( + serviceInstanceGuid.toString()) + .type( + ServiceBindingType.APPLICATION) .page(page) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.serviceBindingsV3() @@ -1663,10 +1706,12 @@ private Flux getServiceBindingResourcesByServi } private Mono - getServiceBindingResourceByApplicationGuidAndServiceInstanceGuid(UUID applicationGuid, UUID serviceInstanceGuid) { + getServiceBindingResourceByApplicationGuidAndServiceInstanceGuid(UUID applicationGuid, UUID serviceInstanceGuid) { IntFunction pageRequestSupplier = page -> ListServiceBindingsRequest.builder() - .applicationId(applicationGuid.toString()) - .serviceInstanceId(serviceInstanceGuid.toString()) + .applicationId( + applicationGuid.toString()) + .serviceInstanceId( + serviceInstanceGuid.toString()) .page(page) .build(); return getApplicationServiceBindingResources(pageRequestSupplier).singleOrEmpty(); @@ -1674,14 +1719,15 @@ private Flux getServiceBindingResourcesByServi private Flux getServiceBindingResourcesByApplicationGuid(UUID applicationGuid) { IntFunction pageRequestSupplier = page -> ListServiceBindingsRequest.builder() - .applicationId(applicationGuid.toString()) + .applicationId( + applicationGuid.toString()) .page(page) .build(); return getApplicationServiceBindingResources(pageRequestSupplier); } private Flux - getApplicationServiceBindingResources(IntFunction pageRequestSupplier) { + getApplicationServiceBindingResources(IntFunction pageRequestSupplier) { return PaginationUtils.requestClientV3Resources(page -> delegate.serviceBindingsV3() .list(pageRequestSupplier.apply(page))); } @@ -1827,7 +1873,8 @@ private Mono getBuildResource(UUID buildGuid) { private Flux getBuildResourcesByApplicationGuid(UUID applicationGuid) { IntFunction pageRequestSupplier = page -> ListApplicationBuildsRequest.builder() - .applicationId(applicationGuid.toString()) + .applicationId( + applicationGuid.toString()) .page(page) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.applicationsV3() @@ -1910,8 +1957,10 @@ private UUID doAddRoute(UUID domainGuid, String host, String path) { .host(host) .path(path) .relationships(RouteRelationships.builder() - .domain(buildToOneRelationship(domainGuid)) - .space(buildToOneRelationship(getTargetSpaceGuid())) + .domain(buildToOneRelationship( + domainGuid)) + .space(buildToOneRelationship( + getTargetSpaceGuid())) .build()) .build()) .block(); @@ -1923,7 +1972,8 @@ private void doCreateDomain(String name) { .create(CreateDomainRequest.builder() .name(name) .relationships(DomainRelationships.builder() - .organization(buildToOneRelationship(getTargetOrganizationGuid())) + .organization( + buildToOneRelationship(getTargetOrganizationGuid())) .build()) .build()) .block(); @@ -2023,7 +2073,8 @@ private Flux getPrivateDomainResources() { private Flux getDomainResourcesByOrganizationGuid(UUID organizationGuid) { IntFunction pageRequestSupplier = page -> ListOrganizationDomainsRequest.builder() - .organizationId(organizationGuid.toString()) + .organizationId( + organizationGuid.toString()) .page(page) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.organizationsV3() @@ -2080,7 +2131,8 @@ private Flux getRouteResourcesByDomainGuidHostAndPath(UUID domain private Flux getRouteResourcesByAppGuid(UUID applicationGuid) { IntFunction pageSupplier = page -> ListApplicationRoutesRequest.builder() - .applicationId(applicationGuid.toString()) + .applicationId( + applicationGuid.toString()) .page(page) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.applicationsV3() @@ -2106,7 +2158,8 @@ private List findServiceOfferingsByLabelAndBrokerName(Stri private Flux getServiceResources() { IntFunction pageRequestSupplier = page -> ListServiceOfferingsRequest.builder() - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .page(page) .build(); return getServiceResources(pageRequestSupplier); @@ -2121,8 +2174,9 @@ protected Mono getServiceOffering(String offeringId) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.FORBIDDEN), t -> new CloudOperationException(HttpStatus.FORBIDDEN, HttpStatus.FORBIDDEN.getReasonPhrase(), - MessageFormat.format(Messages.SERVICE_OFFERING_WITH_GUID_0_IS_NOT_AVAILABLE, - offeringId), + MessageFormat.format( + Messages.SERVICE_OFFERING_WITH_GUID_0_IS_NOT_AVAILABLE, + offeringId), t)) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.NOT_FOUND), t -> new CloudOperationException(HttpStatus.NOT_FOUND, @@ -2134,8 +2188,10 @@ protected Mono getServiceOffering(String offeringId) private Flux getServiceResourcesByBrokerGuid(UUID brokerGuid) { IntFunction pageRequestSupplier = page -> ListServiceOfferingsRequest.builder() - .serviceBrokerId(brokerGuid.toString()) - .spaceId(getTargetSpaceGuid().toString()) + .serviceBrokerId( + brokerGuid.toString()) + .spaceId( + getTargetSpaceGuid().toString()) .page(page) .build(); return getServiceResources(pageRequestSupplier); @@ -2144,7 +2200,8 @@ private Flux getServiceResourcesByBrokerGuid( private Flux getServiceResourcesByLabel(String label) { IntFunction pageRequestSupplier = page -> ListServiceOfferingsRequest.builder() .name(label) - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .page(page) .build(); return getServiceResources(pageRequestSupplier); @@ -2154,7 +2211,8 @@ private Flux getServiceResourcesByLabelAndBro IntFunction pageRequestSupplier = page -> ListServiceOfferingsRequest.builder() .name(label) .serviceBrokerName(brokerName) - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .page(page) .build(); return getServiceResources(pageRequestSupplier); @@ -2169,7 +2227,8 @@ private Mono> zipWithAuxiliaryServiceOfferingCon UUID serviceOfferingGuid = getGuid(serviceOffering); return getServicePlansFlux(serviceOfferingGuid).collectList() .map(servicePlans -> ImmutableRawCloudServiceOffering.builder() - .serviceOffering(serviceOffering) + .serviceOffering( + serviceOffering) .servicePlans(servicePlans) .build()); } @@ -2188,8 +2247,9 @@ protected Mono getServicePlanResource(String servicePlanG .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.FORBIDDEN), t -> new CloudOperationException(HttpStatus.FORBIDDEN, HttpStatus.FORBIDDEN.getReasonPhrase(), - MessageFormat.format(Messages.SERVICE_PLAN_WITH_GUID_0_NOT_AVAILABLE_FOR_SERVICE_INSTANCE_1, - servicePlanGuid, serviceInstanceName), + MessageFormat.format( + Messages.SERVICE_PLAN_WITH_GUID_0_NOT_AVAILABLE_FOR_SERVICE_INSTANCE_1, + servicePlanGuid, serviceInstanceName), t)) .onErrorMap(t -> doesErrorMatchStatusCode(t, HttpStatus.NOT_FOUND), t -> new CloudOperationException(HttpStatus.NOT_FOUND, @@ -2201,7 +2261,8 @@ protected Mono getServicePlanResource(String servicePlanG private Flux getServicePlanResourcesByServiceOfferingGuid(UUID serviceOfferingGuid) { IntFunction pageRequestSupplier = page -> ListServicePlansRequest.builder() - .serviceOfferingId(serviceOfferingGuid.toString()) + .serviceOfferingId( + serviceOfferingGuid.toString()) .page(page) .build(); return PaginationUtils.requestClientV3Resources(page -> delegate.servicePlansV3() @@ -2215,7 +2276,8 @@ private Flux getServiceKeyResource(CloudServic private Flux getServiceKeyResourcesByServiceInstanceGuid(UUID serviceInstanceGuid) { IntFunction pageRequestSupplier = page -> ListServiceBindingsRequest.builder() - .serviceInstanceId(serviceInstanceGuid.toString()) + .serviceInstanceId( + serviceInstanceGuid.toString()) .type(ServiceBindingType.KEY) .page(page) .build(); @@ -2345,7 +2407,8 @@ private UUID getRequiredApplicationGuid(String name) { private Mono getServiceInstanceByName(String name) { IntFunction pageRequestSupplier = page -> ListServiceInstancesRequest.builder() - .spaceId(getTargetSpaceGuid().toString()) + .spaceId( + getTargetSpaceGuid().toString()) .serviceInstanceName(name) .page(page) .build(); @@ -2454,8 +2517,7 @@ private UUID getGuid(Resource resource) { } private boolean doesErrorMatchStatusCode(Throwable t, HttpStatus status) { - if (t instanceof AbstractCloudFoundryException) { - AbstractCloudFoundryException e = (AbstractCloudFoundryException) t; + if (t instanceof AbstractCloudFoundryException e) { return e.getStatusCode() == status.value(); } return false; diff --git a/src/test/java/com/sap/cloudfoundry/client/facade/ApplicationsCloudControllerClientIntegrationTest.java b/src/test/java/com/sap/cloudfoundry/client/facade/ApplicationsCloudControllerClientIntegrationTest.java index 3b70cf48e..3f77206d0 100644 --- a/src/test/java/com/sap/cloudfoundry/client/facade/ApplicationsCloudControllerClientIntegrationTest.java +++ b/src/test/java/com/sap/cloudfoundry/client/facade/ApplicationsCloudControllerClientIntegrationTest.java @@ -1,21 +1,5 @@ package com.sap.cloudfoundry.client.facade; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.APPLICATION_HOST; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.DEFAULT_DOMAIN; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.DISK_IN_MB; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.HEALTH_CHECK_ENDPOINT; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.HEALTH_CHECK_TIMEMOUT; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.JAVA_BUILDPACK; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.MEMORY_IN_MB; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.NODEJS_BUILDPACK; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.STATICFILE_APPLICATION_CONTENT; -import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.STATICFILE_BUILDPACK; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; @@ -25,18 +9,11 @@ import java.util.Set; import java.util.UUID; -import org.cloudfoundry.client.v3.Metadata; -import org.cloudfoundry.client.v3.processes.HealthCheckType; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; - import com.sap.cloudfoundry.client.facade.domain.CloudApplication; import com.sap.cloudfoundry.client.facade.domain.CloudBuild; import com.sap.cloudfoundry.client.facade.domain.CloudMetadata; import com.sap.cloudfoundry.client.facade.domain.CloudPackage; +import com.sap.cloudfoundry.client.facade.domain.CloudProcess; import com.sap.cloudfoundry.client.facade.domain.CloudRoute; import com.sap.cloudfoundry.client.facade.domain.DockerInfo; import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudApplication; @@ -45,11 +22,34 @@ import com.sap.cloudfoundry.client.facade.domain.ImmutableDockerInfo; import com.sap.cloudfoundry.client.facade.domain.ImmutableStaging; import com.sap.cloudfoundry.client.facade.domain.InstancesInfo; +import com.sap.cloudfoundry.client.facade.domain.LifecycleType; import com.sap.cloudfoundry.client.facade.domain.Staging; import com.sap.cloudfoundry.client.facade.domain.Status; import com.sap.cloudfoundry.client.facade.dto.ApplicationToCreateDto; -import com.sap.cloudfoundry.client.facade.domain.CloudProcess; import com.sap.cloudfoundry.client.facade.dto.ImmutableApplicationToCreateDto; +import org.cloudfoundry.client.v3.Metadata; +import org.cloudfoundry.client.v3.processes.HealthCheckType; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.APPLICATION_HOST; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.DEFAULT_DOMAIN; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.DISK_IN_MB; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.HEALTH_CHECK_ENDPOINT; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.HEALTH_CHECK_TIMEMOUT; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.JAVA_BUILDPACK; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.MEMORY_IN_MB; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.NODEJS_BUILDPACK; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.STATICFILE_APPLICATION_CONTENT; +import static com.sap.cloudfoundry.client.facade.IntegrationTestConstants.STATICFILE_BUILDPACK; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; class ApplicationsCloudControllerClientIntegrationTest extends CloudControllerClientIntegrationTest { @@ -157,11 +157,11 @@ void updateApplicationHealthcheckType() { createAndVerifyDefaultApplication(applicationName); UUID applicationGuid = client.getApplicationGuid(applicationName); delegate.applicationsV2() - .update(org.cloudfoundry.client.v2.applications.UpdateApplicationRequest - .builder() - .applicationId(applicationGuid.toString()) - .healthCheckType(HealthCheckType.NONE.getValue()) - .build()) + .update(org.cloudfoundry.client.v2.applications.UpdateApplicationRequest.builder() + .applicationId(applicationGuid.toString()) + .healthCheckType( + HealthCheckType.NONE.getValue()) + .build()) .block(); CloudProcess cloudProcess = client.getApplicationProcess(applicationGuid); assertEquals(com.sap.cloudfoundry.client.facade.domain.HealthCheckType.NONE, cloudProcess.getHealthCheckType()); @@ -422,6 +422,24 @@ void createApplicationWithBuildpacks() { } } + @Test + @DisplayName("Create application with CNB lifecycle and verify attributes") + void createCnbApplication() { + String applicationName = "test-app-17"; + Staging staging = ImmutableStaging.builder() + .lifecycleType(LifecycleType.CNB) + .addBuildpacks(JAVA_BUILDPACK, STATICFILE_BUILDPACK) + .build(); + CloudRoute route = getImmutableCloudRoute(); + try { + verifyApplicationWillBeCreated(applicationName, staging, Set.of(route)); + } catch (Exception e) { + fail(e); + } finally { + client.deleteApplication(applicationName); + } + } + private void verifyApplicationWillBeCreated(String applicationName, Staging staging, Set routes) { ApplicationToCreateDto applicationToCreateDto = ImmutableApplicationToCreateDto.builder() .name(applicationName) diff --git a/src/test/java/com/sap/cloudfoundry/client/facade/CloudControllerClientIntegrationTest.java b/src/test/java/com/sap/cloudfoundry/client/facade/CloudControllerClientIntegrationTest.java index f98dc8c01..20bf66456 100644 --- a/src/test/java/com/sap/cloudfoundry/client/facade/CloudControllerClientIntegrationTest.java +++ b/src/test/java/com/sap/cloudfoundry/client/facade/CloudControllerClientIntegrationTest.java @@ -1,7 +1,5 @@ package com.sap.cloudfoundry.client.facade; -import static org.junit.jupiter.api.Assertions.assertNotNull; - import java.net.MalformedURLException; import java.net.URI; import java.net.URL; @@ -9,14 +7,6 @@ import java.util.HashMap; import java.util.Map; -import com.sap.cloudfoundry.client.facade.rest.CloudControllerRestClient; -import com.sap.cloudfoundry.client.facade.rest.CloudControllerRestClientFactory; -import org.cloudfoundry.client.CloudFoundryClient; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.TestInfo; - import com.sap.cloudfoundry.client.facade.adapters.ImmutableCloudFoundryClientFactory; import com.sap.cloudfoundry.client.facade.domain.CloudSpace; import com.sap.cloudfoundry.client.facade.domain.ImmutableLifecycle; @@ -25,6 +15,13 @@ import com.sap.cloudfoundry.client.facade.domain.Staging; import com.sap.cloudfoundry.client.facade.rest.CloudSpaceClient; import com.sap.cloudfoundry.client.facade.util.RestUtil; +import org.cloudfoundry.client.CloudFoundryClient; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; + +import static org.junit.jupiter.api.Assertions.assertNotNull; abstract class CloudControllerClientIntegrationTest { @@ -70,11 +67,18 @@ protected Lifecycle createLifecycle(Staging staging) { .data(Map.of()) .build(); } + var data = new HashMap(); data.put("buildpacks", staging.getBuildpacks()); data.put("stack", DEFAULT_STACK); + + // Default to BUILDPACK if lifecycleType is null + LifecycleType lifecycleType = staging.getLifecycleType() != null + ? staging.getLifecycleType() + : LifecycleType.BUILDPACK; + return ImmutableLifecycle.builder() - .type(LifecycleType.BUILDPACK) + .type(lifecycleType) .data(data) .build(); } diff --git a/src/test/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplicationTest.java b/src/test/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplicationTest.java index 7261c138a..8ec2510ce 100644 --- a/src/test/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplicationTest.java +++ b/src/test/java/com/sap/cloudfoundry/client/facade/adapters/RawCloudApplicationTest.java @@ -3,6 +3,11 @@ import java.util.List; import java.util.Map; +import com.sap.cloudfoundry.client.facade.domain.CloudApplication; +import com.sap.cloudfoundry.client.facade.domain.CloudSpace; +import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudApplication; +import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudSpace; +import com.sap.cloudfoundry.client.facade.domain.ImmutableLifecycle; import org.cloudfoundry.client.v3.BuildpackData; import org.cloudfoundry.client.v3.DockerData; import org.cloudfoundry.client.v3.Lifecycle; @@ -11,12 +16,6 @@ import org.cloudfoundry.client.v3.applications.ApplicationState; import org.junit.jupiter.api.Test; -import com.sap.cloudfoundry.client.facade.domain.CloudApplication; -import com.sap.cloudfoundry.client.facade.domain.CloudSpace; -import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudApplication; -import com.sap.cloudfoundry.client.facade.domain.ImmutableCloudSpace; -import com.sap.cloudfoundry.client.facade.domain.ImmutableLifecycle; - class RawCloudApplicationTest { private static final String STATE = "STARTED"; @@ -27,19 +26,24 @@ class RawCloudApplicationTest { .name(SPACE_NAME) .build(); private static final String EXPECTED_BUILDPACK = "ruby_buildpack"; + private static final String BUILDPACK_URL = "custom-buildpack-url"; + private static final String EXPECTED_STACK = "cflinuxfs3"; private static final CloudApplication.State EXPECTED_STATE = CloudApplication.State.STARTED; @Test void testDeriveForBuildpackApp() { - RawCloudEntityTest.testDerive(buildApplication(buildBuildpackLifecycle()), - buildRawApplication(buildBuildpackLifecycleResource())); + RawCloudEntityTest.testDerive(buildApplication(buildBuildpackLifecycle()), buildRawApplication(buildBuildpackLifecycleResource())); } @Test void testDeriveForDockerApp() { - RawCloudEntityTest.testDerive(buildApplication(buildDockerLifecycle()), - buildRawApplication(buildDockerLifecycleResource())); + RawCloudEntityTest.testDerive(buildApplication(buildDockerLifecycle()), buildRawApplication(buildDockerLifecycleResource())); + } + + @Test + void testDeriveForCnbApp() { + RawCloudEntityTest.testDerive(buildApplication(buildCnbLifecycle()), buildRawApplication(buildCnbLifecycleResource())); } private static CloudApplication buildApplication(com.sap.cloudfoundry.client.facade.domain.Lifecycle lifecycle) { @@ -56,13 +60,15 @@ private static CloudApplication buildApplication(com.sap.cloudfoundry.client.fac private static com.sap.cloudfoundry.client.facade.domain.Lifecycle buildBuildpackLifecycle() { return ImmutableLifecycle.builder() .type(com.sap.cloudfoundry.client.facade.domain.LifecycleType.BUILDPACK) - .data(buildBuildpackLifecycleData()) + .data(buildLifecycleData(EXPECTED_BUILDPACK)) .build(); } - private static Map buildBuildpackLifecycleData() { - return Map.of("buildpacks", List.of(EXPECTED_BUILDPACK), - "stack", EXPECTED_STACK); + private com.sap.cloudfoundry.client.facade.domain.Lifecycle buildCnbLifecycle() { + return ImmutableLifecycle.builder() + .type(com.sap.cloudfoundry.client.facade.domain.LifecycleType.CNB) + .data(buildLifecycleData(BUILDPACK_URL)) + .build(); } private static com.sap.cloudfoundry.client.facade.domain.Lifecycle buildDockerLifecycle() { @@ -72,6 +78,10 @@ private static com.sap.cloudfoundry.client.facade.domain.Lifecycle buildDockerLi .build(); } + private static Map buildLifecycleData(String buildpack) { + return Map.of("buildpacks", List.of(buildpack), "stack", EXPECTED_STACK); + } + private static RawCloudApplication buildRawApplication(Lifecycle lifecycle) { return ImmutableRawCloudApplication.builder() .application(buildApplicationResource(lifecycle)) @@ -101,6 +111,16 @@ private static Lifecycle buildBuildpackLifecycleResource() { .build(); } + private Lifecycle buildCnbLifecycleResource() { + return Lifecycle.builder() + .type(LifecycleType.CNB) + .data(BuildpackData.builder() + .buildpack(BUILDPACK_URL) + .stack(STACK_NAME) + .build()) + .build(); + } + private static Lifecycle buildDockerLifecycleResource() { return Lifecycle.builder() .type(LifecycleType.DOCKER)