@@ -202,8 +202,10 @@ public Mono<CreateServiceInstanceResponse> createServiceInstance(CreateServiceIn
202202 if (osbInterceptor != null && osbInterceptor .accept (request )) {
203203 return osbInterceptor .createServiceInstance (request );
204204 }
205- validateServiceDefinitionAndPlanIds (request .getServiceDefinition (), request .getPlan (),
206- request .getServiceDefinitionId (), request .getPlanId ());
205+ //No need to validate mandatory service id and plan Id as sc-osb does it already
206+ //See https://github.com/spring-cloud/spring-cloud-open-service-broker/blob
207+ ///7d374332419aad628ca76351fd53ca7e351c57de/spring-cloud-open-service-broker-core/src/main/java/org/springframework/cloud/servicebroker/controller/ServiceInstanceController.java#L111-L112
208+
207209 maintenanceInfoFormatterService .validateAnyCreateRequest (request );
208210 String backingServiceName = request .getServiceDefinition ().getName ();
209211 String backingServicePlanName = request .getPlan ().getName ();
@@ -213,7 +215,7 @@ public Mono<CreateServiceInstanceResponse> createServiceInstance(CreateServiceIn
213215 spacedTargetedOperations = getSpaceScopedOperations (backingServiceName );
214216 //Lookup guids necessary for low level api usage, and that CloudFoundryOperations hides in its response
215217 String spaceId = getSpacedIdFromTargettedOperationsInternals (spacedTargetedOperations );
216- String backingServicePlanId = fetchBackingServicePlanId (backingServiceName , backingServicePlanName ,
218+ String backingServicePlanId = fetchRequestedBackingServicePlanId (backingServiceName , backingServicePlanName ,
217219 spaceId );
218220
219221
@@ -305,9 +307,7 @@ public Mono<DeleteServiceInstanceResponse> deleteServiceInstance(DeleteServiceIn
305307 return osbInterceptor .deleteServiceInstance (request );
306308 }
307309
308- //Validate mandatory service id and plan Id
309- validateServiceDefinitionAndPlanIds (request .getServiceDefinition (), request .getPlan (),
310- request .getServiceDefinitionId (), request .getPlanId ());
310+ //No need to validate mandatory service id and plan Id as sc-osb does it already
311311
312312 String backingServiceInstanceName =
313313 ServiceInstanceNameHelper .truncateNameToCfMaxSize (request .getServiceInstanceId ());
@@ -475,12 +475,22 @@ public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceIn
475475 return osbInterceptor .updateServiceInstance (request );
476476 }
477477
478- validateServiceDefinitionAndPlanIds (request .getServiceDefinition (), request .getPlan (),
479- request .getServiceDefinitionId (), request .getPlanId ());
478+ //No need to validate mandatory service id as sc-osb does it already
479+ //However since planId params optional sc-osb does not yet reject planId not matching any known plan
480+ validateServicePlanId (request .getPlan (), request .getPlanId ());
481+
480482 maintenanceInfoFormatterService .validateAnyUpgradeRequest (request );
481483
482484 String backingServiceName = request .getServiceDefinition ().getName ();
483- String backingServicePlanName = request .getPlan ().getName ();
485+ String requestedBackingServicePlanName ;
486+ if (request .getPlan () != null ) {
487+ //possibly receiving a plan update, or just CF CC_NG passing the current planid unchanged
488+ //in case of param update
489+ requestedBackingServicePlanName = request .getPlan ().getName ();
490+ } else {
491+ //Possibly a K8S svcat param update which is omitting the optional planId (as specs allows)
492+ requestedBackingServicePlanName = null ;
493+ }
484494 String backingServiceInstanceName = ServiceInstanceNameHelper
485495 .truncateNameToCfMaxSize (request .getServiceInstanceId ());
486496
@@ -497,7 +507,7 @@ public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceIn
497507
498508 //Lookup guids necessary for low level api usage, and that CloudFoundryOperations hides in its response
499509 String spaceId = getSpacedIdFromTargettedOperationsInternals (spacedTargetedOperations );
500- String backingServicePlanId = fetchBackingServicePlanId (backingServiceName , backingServicePlanName , spaceId );
510+ String requestedBackingServicePlanId = fetchRequestedBackingServicePlanId (backingServiceName , requestedBackingServicePlanName , spaceId );
501511
502512 if (maintenanceInfoFormatterService .isNoOpUpgradeBackingService (request )) {
503513 LOG .info ("NoOp upgrade detected, returning early 200 OK" );
@@ -531,7 +541,7 @@ public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceIn
531541 updateServiceInstanceResponse = client .serviceInstances ()
532542 .update (org .cloudfoundry .client .v2 .serviceinstances .UpdateServiceInstanceRequest .builder ()
533543 .serviceInstanceId (existingBackingServiceInstance .getId ())
534- .servicePlanId (backingServicePlanId )
544+ .servicePlanId (requestedBackingServicePlanId ) //possibly null
535545 .parameters (formatParameters (metaData , request .getParameters ()))
536546 .maintenanceInfo (formattedForBackendInstanceMI )
537547 .acceptsIncomplete (request .isAsyncAccepted ())
@@ -581,6 +591,13 @@ public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceIn
581591 return Mono .just (responseBuilder .build ());
582592 }
583593
594+ protected void validateServicePlanId (Plan plan , String planId ) {
595+ if (planId !=null && plan == null ) {
596+ LOG .info ("Invalid plan received with unknown id {}" , planId );
597+ throw new ServiceBrokerInvalidParametersException ("Invalid plan received with unknown id:" + planId );
598+ }
599+ }
600+
584601 protected CmdbOperationState fromJson (String operation ) {
585602 try {
586603 return OBJECT_MAPPER .readValue (operation , CmdbOperationState .class );
@@ -617,8 +634,11 @@ private OperationState convertCfStateToOsbState(String cfServiceInstanceState) {
617634 }
618635 }
619636
620- private String fetchBackingServicePlanId (String backingServiceName , String backingServicePlanName , String spaceId ) {
621- //Inspired from first instrcutions of cf-java-client:
637+ private String fetchRequestedBackingServicePlanId (String backingServiceName , String updatedBackingServicePlanName , String spaceId ) {
638+ if (updatedBackingServicePlanName == null ) {
639+ return null ;
640+ }
641+ //Inspired from first instructions of cf-java-client:
622642 // org.cloudfoundry.operations.services.DefaultServices.createInstance()
623643 String backingServiceId = PaginationUtils
624644 .requestClientV2Resources (page -> client .spaces ()
@@ -641,11 +661,11 @@ private String fetchBackingServicePlanId(String backingServiceName, String backi
641661 .page (page )
642662 .serviceId (backingServiceId )
643663 .build ()))
644- .filter (resource -> backingServicePlanName .equals (ResourceUtils .getEntity (resource ).getName ()))
664+ .filter (resource -> updatedBackingServicePlanName .equals (ResourceUtils .getEntity (resource ).getName ()))
645665 .single ()
646666 .map (ResourceUtils ::getId )
647667 .onErrorResume (NoSuchElementException .class ,
648- t -> ExceptionUtils .illegalArgument ("Service plan %s does not exist" , backingServicePlanName ))
668+ t -> ExceptionUtils .illegalArgument ("Service plan %s does not exist" , updatedBackingServicePlanName ))
649669 .block ();
650670 }
651671
@@ -849,8 +869,12 @@ private Mono<UpdateServiceInstanceResponse> handleUpdateException(Exception orig
849869 .build ());
850870
851871 case OsbApiConstants .LAST_OPERATION_STATE_SUCCEEDED :
872+ Plan requestedPlan = request .getPlan ();
873+ String requestedPlanName = requestedPlan == null ?
874+ null :
875+ requestedPlan .getName ();
852876 if (updatedSi .getService ().equals (request .getServiceDefinition ().getName ()) &&
853- updatedSi .getPlan ().equals (request . getPlan (). getName () )) {
877+ updatedSi .getPlan ().equals (requestedPlanName )) {
854878 LOG .info ("Concurrent update request has completed. " +
855879 "Returning 200 OK" );
856880 //200 OK
0 commit comments