@@ -362,6 +362,82 @@ private Mono<DeleteServiceInstanceResponse> handleDeleteException(Exception orig
362
362
throw new ServiceInstanceDoesNotExistException (request .getServiceInstanceId ());
363
363
}
364
364
365
+ /**
366
+ * Handle exceptions by checking current backing service instance in order to return the appropriate response
367
+ * as expected in the OSB specifications.
368
+ * @param originalException The exception occuring during processing. Note that Subclasses of
369
+ * ServiceBrokerException are considered already qualified, and returned as-is
370
+ */
371
+ private Mono <UpdateServiceInstanceResponse > handleUpdateException (Exception originalException ,
372
+ String backingServiceInstanceName ,
373
+ CloudFoundryOperations spacedTargetedOperations ,
374
+ UpdateServiceInstanceRequest request ) {
375
+ LOG .info ("Inspecting exception caught {} for possible concurrent dupl while handling request {} " , originalException , request );
376
+
377
+ if (originalException instanceof ServiceBrokerException && ! originalException .getClass ().equals (ServiceBrokerException .class )) {
378
+ LOG .info ("Exception was thrown by ourselves, and already qualified, rethrowing it unmodified" );
379
+ throw (ServiceBrokerException ) originalException ;
380
+ }
381
+
382
+ ServiceInstance updatedSi = getCfServiceInstance (spacedTargetedOperations , backingServiceInstanceName );
383
+ String spaceId = getSpacedIdFromTargettedOperationsInternals (spacedTargetedOperations );
384
+
385
+ if (updatedSi != null ) {
386
+ if (!"update" .equals (updatedSi .getLastOperation ())) {
387
+ LOG .info ("No instance in the inventory with id={} in space with id={}, and recently updated: " +
388
+ "last_operation={}, flowing up original exception" ,
389
+ request .getServiceInstanceId (), spaceId , updatedSi .getLastOperation () );
390
+ //500 error
391
+ throw new ServiceBrokerInvalidParametersException (originalException .getMessage ());
392
+ }
393
+ switch (updatedSi .getStatus ()) {
394
+ case OsbApiConstants .LAST_OPERATION_STATE_INPROGRESS :
395
+ LOG .info ("Concurrent update request is still in progress. " +
396
+ "Returning accepted: 202" );
397
+ String operation = toJson (new CmdbOperationState (updatedSi .getId (),
398
+ OsbOperation .UPDATE ));
399
+ //202 Accepted
400
+ return Mono .just (UpdateServiceInstanceResponse .builder ()
401
+ .operation (operation )
402
+ .async (true )
403
+ .build ());
404
+
405
+ case OsbApiConstants .LAST_OPERATION_STATE_SUCCEEDED :
406
+ if (updatedSi .getService ().equals (request .getServiceDefinition ().getName ()) &&
407
+ updatedSi .getPlan ().equals (request .getPlan ().getName ())) {
408
+ LOG .info ("Concurrent update request has completed. " +
409
+ "Returning 200 OK" );
410
+ //200 OK
411
+ return Mono .just (UpdateServiceInstanceResponse .builder ()
412
+ .async (false )
413
+ .build ());
414
+ }
415
+ else {
416
+ LOG .info ("Plan update did not succeed while SI update completed, assuming invalid input. " +
417
+ "Existing si service name={} and service plan={}" , updatedSi .getService (), updatedSi .getPlan ());
418
+ throw new ServiceBrokerInvalidParametersException (originalException .getMessage ());
419
+ }
420
+
421
+ case OsbApiConstants .LAST_OPERATION_STATE_FAILED :
422
+ LOG .info ("Backing service failed to update with {}, flowing up the original error to the osb " +
423
+ "client: " ,
424
+ updatedSi .getMessage (), originalException .getMessage ());
425
+ //500 error
426
+ //In the future, return the usable field once CF supports it
427
+ throw new ServiceBrokerException (originalException .getMessage ());
428
+
429
+ default :
430
+ LOG .error ("Unexpected last operation state:" + updatedSi .getStatus ());
431
+ throw new ServiceBrokerException ("Internal CF protocol error" );
432
+ }
433
+ }
434
+ LOG .info ("No existing instance in the inventory with id={} in space with id={}, assuming invalid requestrace " +
435
+ "condition " +
436
+ "among concurrent update request. Returning 410" , request .getServiceInstanceId (), spaceId );
437
+ //410 Gone
438
+ throw new ServiceInstanceDoesNotExistException (request .getServiceInstanceId ());
439
+ }
440
+
365
441
private String getRequestIncompatibilityWithExistingInstance (ServiceInstance existingServiceInstance ,
366
442
ServiceDefinition serviceDefinition , Plan plan ) {
367
443
if (! existingServiceInstance .getService ().equals (serviceDefinition .getName ())) {
@@ -615,11 +691,12 @@ public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceIn
615
691
616
692
String backingServiceName = request .getServiceDefinition ().getName ();
617
693
String backingServicePlanName = request .getPlan ().getName ();
694
+ String backingServiceInstanceName = ServiceInstanceNameHelper .truncateNameToCfMaxSize (request .getServiceInstanceId ());
618
695
619
696
//ignore race condition during space creation for K8S dupl requests
620
697
CloudFoundryOperations spacedTargetedOperations = getSpaceScopedOperations (backingServiceName );
621
698
ServiceInstance existingBackingServiceInstance = getCfServiceInstance (spacedTargetedOperations ,
622
- ServiceInstanceNameHelper . truncateNameToCfMaxSize ( request . getServiceInstanceId ()) );
699
+ backingServiceInstanceName );
623
700
//Lookup guids necessary for low level api usage, and that CloudFoundryOperations hides in its response
624
701
String spaceId = getSpacedIdFromTargettedOperationsInternals (spacedTargetedOperations );
625
702
String backingServicePlanId = fetchBackingServicePlanId (backingServiceName , backingServicePlanName , spaceId );
@@ -667,10 +744,8 @@ public Mono<UpdateServiceInstanceResponse> updateServiceInstance(UpdateServiceIn
667
744
}
668
745
responseBuilder .async (asyncProvisioning );
669
746
}
670
- catch (ClientV2Exception e ) {
671
- LOG .info ("Unable to update service, caught:" + e , e );
672
- //wrap to avoid log polution from sc-osb catching unexpectidely unknown (cf-java-client's) exceptions
673
- throw new ServiceBrokerException (e .toString ());
747
+ catch (Exception e ) {
748
+ return handleUpdateException (e , backingServiceInstanceName , spacedTargetedOperations , request );
674
749
}
675
750
finally {
676
751
//systematically try to update metadata (e.g. service instance rename) even if update failed
0 commit comments