1313import org .slf4j .Logger ;
1414import org .slf4j .LoggerFactory ;
1515
16+ import com .axway .apim .adapter .APIManagerAdapter ;
1617import com .axway .apim .adapter .APIManagerAdapter .CacheType ;
18+ import com .axway .apim .lib .DoNothingCacheManager .DoNothingCache ;
19+ import com .axway .apim .lib .errorHandling .AppException ;
20+ import com .axway .apim .lib .errorHandling .ErrorCode ;
21+ import com .fasterxml .jackson .databind .JsonNode ;
22+ import com .fasterxml .jackson .databind .ObjectMapper ;
23+ import com .fasterxml .jackson .databind .node .ArrayNode ;
24+ import com .fasterxml .jackson .databind .node .ObjectNode ;
25+ import com .fasterxml .jackson .databind .node .TextNode ;
1726
1827public class FilteredCacheManager implements CacheManager {
1928
@@ -37,7 +46,11 @@ public void setEnabledCaches(List<CacheType> enabledCaches) {
3746 if (enabledCaches ==null || cacheManager instanceof DoNothingCacheManager ) return ;
3847 this .enabledCaches = new ArrayList <String >();
3948 for (CacheType cacheType : enabledCaches ) {
40- this .enabledCaches .add (cacheType .name ());
49+ if (cacheType .supportsImportActions ) {
50+ this .enabledCaches .add (cacheType .name ());
51+ } else {
52+ LOG .error ("The cache: " + cacheType .name () + " is currently not supported for import actions." );
53+ }
4154 }
4255 LOG .info ("Enabled caches: " + this .enabledCaches );
4356 }
@@ -95,5 +108,46 @@ public void removeCache(String arg0) {
95108 cacheManager .removeCache (arg0 );
96109 }
97110
98-
111+ /**
112+ * There are a number of entities which have references to an API (e.g. QuotaRestrictions).
113+ * These are stored/maintained with their own ID (quotaId) and cached in Ehcache.
114+ * But, if the API-ID changes, the cached reference points to an API that no longer exists.
115+ * This method is used to update all entities in the cache when the API ID of an API
116+ * changes (e.g. with a Replace Action).
117+ * @param oldApiId the ID currently used by the cached entities
118+ * @param newApiId the new ID that must be replaced
119+ * @throws AppException when the cache cannot be updated.
120+ */
121+ public void flipApiId (String oldApiId , String newApiId ) throws AppException {
122+ ObjectMapper mapper = new ObjectMapper ();
123+ Cache <String , String > appQuotaCached = getCache (CacheType .applicationsQuotaCache .name (), String .class , String .class );
124+ if (appQuotaCached instanceof DoNothingCache ) return ;
125+ LOG .debug ("Updating ApplicationQuotaCache: Flip API-ID: " + oldApiId + " --> " + newApiId );
126+ try {
127+ appQuotaCached .forEach (entry -> {
128+ try {
129+ String cachedValueString = entry .getValue ();
130+ JsonNode cachedValue = mapper .readTree (cachedValueString );
131+ // As System- and App-Default-Quotas are not cached, they can be ignored
132+ if (APIManagerAdapter .APPLICATION_DEFAULT_QUOTA .equals (cachedValue .get ("id" ).asText ()) ||
133+ APIManagerAdapter .SYSTEM_API_QUOTA .equals (cachedValue .get ("id" ).asText ())) {
134+ // Do nothing
135+ } else {
136+ ArrayNode restrictions = cachedValue .withArray ("restrictions" );
137+ for (JsonNode restriction : restrictions ) {
138+ if (oldApiId .equals (restriction .get ("api" ).asText ())) {
139+ ((ObjectNode )restriction ).replace ("api" , new TextNode (newApiId ));
140+ appQuotaCached .replace (entry .getKey (), cachedValue .toString ());
141+ }
142+ }
143+ }
144+ } catch (Exception e ) {
145+ throw new RuntimeException ("There was an error updating the cache." , e );
146+ }
147+ });
148+ } catch (Exception e ) {
149+ appQuotaCached .clear ();
150+ throw new AppException ("Error updating the cache. Cache has been cleared." , ErrorCode .UNXPECTED_ERROR , e );
151+ }
152+ }
99153}
0 commit comments