44import java .io .UnsupportedEncodingException ;
55import java .net .URI ;
66import java .net .URISyntaxException ;
7+ import java .util .ArrayList ;
78import java .util .HashMap ;
9+ import java .util .Iterator ;
810import java .util .List ;
911import java .util .Map ;
1012import java .util .Optional ;
3840import com .axway .apim .lib .errorHandling .AppException ;
3941import com .axway .apim .lib .errorHandling .ErrorCode ;
4042import com .axway .apim .lib .utils .Utils ;
43+ import com .axway .apim .lib .utils .rest .DELRequest ;
4144import com .axway .apim .lib .utils .rest .GETRequest ;
4245import com .axway .apim .lib .utils .rest .POSTRequest ;
4346import com .axway .apim .lib .utils .rest .PUTRequest ;
@@ -340,14 +343,14 @@ public ClientApplication createOrUpdateApplication(ClientApplication desiredApp,
340343 RestAPICall request ;
341344 if (actualApp ==null ) {
342345 FilterProvider filter = new SimpleFilterProvider ().setDefaultFilter (
343- SimpleBeanPropertyFilter .serializeAllExcept (new String [] {"credentials" , "appQuota" , "organization" , "image" ,"oauthResources " }));
346+ SimpleBeanPropertyFilter .serializeAllExcept (new String [] {"credentials" , "appQuota" , "organization" , "image" ,"appScopes " }));
344347 mapper .setFilterProvider (filter );
345348 String json = mapper .writeValueAsString (desiredApp );
346349 HttpEntity entity = new StringEntity (json , ContentType .APPLICATION_JSON );
347350 request = new POSTRequest (entity , uri );
348351 } else {
349352 FilterProvider filter = new SimpleFilterProvider ().setDefaultFilter (
350- SimpleBeanPropertyFilter .serializeAllExcept (new String [] {"credentials" , "appQuota" , "organization" , "image" , "apis" ,"oauthResources " }));
353+ SimpleBeanPropertyFilter .serializeAllExcept (new String [] {"credentials" , "appQuota" , "organization" , "image" , "apis" ,"appScopes " }));
351354 mapper .setFilterProvider (filter );
352355 String json = mapper .writeValueAsString (desiredApp );
353356 HttpEntity entity = new StringEntity (json , ContentType .APPLICATION_JSON );
@@ -376,12 +379,12 @@ public ClientApplication createOrUpdateApplication(ClientApplication desiredApp,
376379 saveImage (desiredApp , actualApp );
377380 saveAPIAccess (desiredApp , actualApp );
378381 saveCredentials (desiredApp , actualApp );
379- saveOauthResources (desiredApp , actualApp );
382+ manageOAuthResources (desiredApp , actualApp );
380383 saveQuota (desiredApp , actualApp );
381384 return createdApp ;
382385
383386 } catch (Exception e ) {
384- throw new AppException ("Error creating/updating application" , ErrorCode .CANT_CREATE_API_PROXY , e );
387+ throw new AppException ("Error creating/updating application" , ErrorCode .ERR_CREATING_APPLICATION , e );
385388 }
386389 }
387390
@@ -562,31 +565,25 @@ private void saveAPIAccess(ClientApplication app, ClientApplication actualApp) t
562565 accessAdapter .saveAPIAccess (app .getApiAccess (), app , Type .applications );
563566 }
564567
565- private void saveOauthResources (ClientApplication desiredApp , ClientApplication actualApp ) throws AppException {
566- if (desiredApp .getOauthResources ()==null || desiredApp .getOauthResources ().size ()==0 ) return ;
567-
568+ private void manageOAuthResources (ClientApplication desiredApp , ClientApplication actualApp ) throws AppException {
569+ List <ClientAppOauthResource > scopes2Update = new ArrayList <ClientAppOauthResource >();
570+ List <ClientAppOauthResource > scopes2Create = new ArrayList <ClientAppOauthResource >();
571+ List <ClientAppOauthResource > scopes2Delete = new ArrayList <ClientAppOauthResource >();
572+ getScopes2AddOrUpdate (actualApp , desiredApp , scopes2Update , scopes2Create , scopes2Delete );
573+ saveOrUpdateOAuthResources (desiredApp , scopes2Create , false );
574+ saveOrUpdateOAuthResources (desiredApp , scopes2Update , true );
575+ deleteOAuthResources (desiredApp , scopes2Delete );
576+ }
577+
578+ private void saveOrUpdateOAuthResources (ClientApplication desiredApp , List <ClientAppOauthResource > scopes2Create , boolean update ) throws AppException {
579+ if (scopes2Create ==null || scopes2Create .size ()==0 ) return ;
568580 HttpResponse httpResponse = null ;
569- for (ClientAppOauthResource res : desiredApp . getOauthResources () ) {
581+ for (ClientAppOauthResource res : scopes2Create ) {
570582 String endpoint = "oauthresource" ;
571- if (actualApp !=null && actualApp .getOauthResources ().contains (res )) //nothing to do
572- continue ;
573-
574583 try {
575- boolean update = false ;
576- if (actualApp !=null && actualApp .getOauthResources ()!=null ) {
577- Optional <ClientAppOauthResource > opt = actualApp .getOauthResources ().stream ().filter (o -> o .getScope ().equals (res .getScope ())).findFirst ();
578- if (opt .isPresent ()) {
579- //I found an oauth resource with same scope name but different in some properties, I have to update it
580- String oauthResourceId = opt .get ().getId ();
581- endpoint += "/" +oauthResourceId ;
582- res .setId (oauthResourceId );
583- res .setApplicationId (opt .get ().getApplicationId ());
584- res .setUriprefix (opt .get ().getUriprefix ());
585- update = true ;
586- LOG .debug ("Oauth resource already exists, updating" );
587- } else {
588- LOG .debug ("Oauth resource not found, creating" );
589- }
584+ if (update ) {
585+ endpoint += "/" +res .getId ();
586+ LOG .debug ("Oauth resource already exists, updating" );
590587 } else {
591588 LOG .debug ("Oauth resource not found, creating" );
592589 }
@@ -612,7 +609,78 @@ private void saveOauthResources(ClientApplication desiredApp, ClientApplication
612609 } catch (Exception ignore ) { }
613610 }
614611 }
615- }
612+ }
613+
614+ private void deleteOAuthResources (ClientApplication desiredApp , List <ClientAppOauthResource > scopes2Delete ) throws AppException {
615+ if (scopes2Delete ==null || scopes2Delete .size ()==0 ) return ;
616+ HttpResponse httpResponse = null ;
617+ for (ClientAppOauthResource res : scopes2Delete ) {
618+ try {
619+ URI uri = new URIBuilder (cmd .getAPIManagerURL ()).setPath (cmd .getApiBasepath ()+"/applications/" +desiredApp .getId ()+"/oauthresource/" +res .getId ()).build ();
620+ RestAPICall request = new DELRequest (uri , true );
621+ httpResponse = request .execute ();
622+ int statusCode = httpResponse .getStatusLine ().getStatusCode ();
623+ if (statusCode != 204 ){
624+ LOG .error ("Error deleting application scope. Response-Code: " +statusCode +". Got response: '" +EntityUtils .toString (httpResponse .getEntity ())+"'" );
625+ throw new AppException ("Error deleting application scope. Response-Code: " +statusCode +"" , ErrorCode .API_MANAGER_COMMUNICATION );
626+ }
627+ LOG .info ("Application scope: " +res .getScope ()+" for application: " +desiredApp .getName ()+" successfully deleted" );
628+ } catch (Exception e ) {
629+ throw new AppException ("Error deleting application scope" , ErrorCode .API_MANAGER_COMMUNICATION , e );
630+ } finally {
631+ try {
632+ ((CloseableHttpResponse )httpResponse ).close ();
633+ } catch (Exception ignore ) { }
634+ }
635+ }
636+ }
637+
638+ private void getScopes2AddOrUpdate (ClientApplication actualApp , ClientApplication desiredApp ,
639+ List <ClientAppOauthResource > scopes2Update , List <ClientAppOauthResource > scopes2Create , List <ClientAppOauthResource > scopes2Delete ) throws AppException {
640+ if ((desiredApp .getOauthResources ()==null || desiredApp .getOauthResources ().size ()==0 ) &&
641+ (actualApp .getOauthResources ()==null || actualApp .getOauthResources ().size ()==0 )) return ;
642+ List <ClientAppOauthResource > existingScopes = null ;
643+ List <ClientAppOauthResource > desiredScopes = desiredApp .getOauthResources ();
644+ if (actualApp !=null ) {
645+ existingScopes = actualApp .getOauthResources ();
646+ }
647+ if (existingScopes ==null ) existingScopes = new ArrayList <ClientAppOauthResource >();
648+ boolean existingScopeFound = false ;
649+ if (desiredScopes !=null ) {
650+ // Iterate over the given desired scopes
651+ Iterator <ClientAppOauthResource > it = desiredScopes .iterator ();
652+ while (it .hasNext ()) {
653+ ClientAppOauthResource desiredScope = it .next ();
654+ // Compare each desired scope, if it is already included in the existing scopes
655+ for (ClientAppOauthResource existingScope : existingScopes ) {
656+ // If it is the same scope (based on the name) ...
657+ if (desiredScope .getScope ().equals (existingScope .getScope ())) {
658+ // Check, if the scopes are not equal and if so take over the configuration and put it to the list of scopes to update
659+ if (!desiredScope .equals (existingScope )) {
660+ existingScope .setDefaultScope (desiredScope .isDefaultScope ());
661+ existingScope .setEnabled (desiredScope .isEnabled ());
662+ scopes2Update .add (existingScope );
663+ }
664+ existingScopeFound = true ;
665+ break ;
666+ }
667+ }
668+ if (!existingScopeFound ) scopes2Create .add (desiredScope );
669+ }
670+ // finally iterate over all existing scopes and check if they are still desired
671+ for (ClientAppOauthResource existingScope : existingScopes ) {
672+ boolean actualScopeFound = false ;
673+ for (ClientAppOauthResource desiredScope : desiredScopes ) {
674+ if (existingScope .getScope ().equals (desiredScope .getScope ())) {
675+ actualScopeFound = true ;
676+ break ; // As the actual scope is still desired
677+ }
678+ }
679+ if (!actualScopeFound ) scopes2Delete .add (existingScope );
680+ }
681+ }
682+ return ;
683+ }
616684
617685
618686 public void setTestApiManagerResponse (ClientAppFilter filter , String apiManagerResponse ) {
0 commit comments