-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OKTA-526761: Add Caching support (#768)
* add caching
- Loading branch information
1 parent
11657ec
commit 44bed7a
Showing
29 changed files
with
2,451 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright 2014 Stormpath, Inc. | ||
* Modifications Copyright 2018 Okta, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.okta.sdk.cache; | ||
|
||
/** | ||
* A Cache efficiently stores temporary objects primarily to improve an application's performance. | ||
* <p> | ||
* This interface provides an abstraction (wrapper) API on top of an underlying | ||
* cache framework's cache instance (e.g. JCache, Ehcache, Hazelcast, JCS, OSCache, JBossCache, TerraCotta, Coherence, | ||
* GigaSpaces, etc, etc), allowing a Okta SDK user to configure any cache mechanism they choose. | ||
* | ||
* @since 0.5.0 | ||
*/ | ||
public interface Cache<K, V> { | ||
|
||
/** | ||
* Returns the cached value stored under the specified {@code key} or | ||
* {@code null} if there is no cache entry for that {@code key}. | ||
* | ||
* @param key the key that the value was previous added with | ||
* @return the cached object or {@code null} if there is no entry for the specified {@code key} | ||
*/ | ||
V get(K key); | ||
|
||
|
||
/** | ||
* Adds a cache entry. | ||
* | ||
* @param key the key used to identify the object being stored. | ||
* @param value the value to be stored in the cache. | ||
* @return the previous value associated with the given {@code key} or {@code null} if there was no previous value | ||
*/ | ||
V put(K key, V value); | ||
|
||
|
||
/** | ||
* Removes the cached value stored under the specified {@code key}. | ||
* | ||
* @param key the key used to identify the object being stored. | ||
* @return the removed value or {@code null} if there was no value cached. | ||
*/ | ||
V remove(K key); | ||
} |
89 changes: 89 additions & 0 deletions
89
api/src/main/java/com/okta/sdk/cache/CacheConfigurationBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright 2014 Stormpath, Inc. | ||
* Modifications Copyright 2018 Okta, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.okta.sdk.cache; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* A Builder to specify configuration for {@link Cache} regions. This is usually used while building a CacheManager via | ||
* the {@link CacheManagerBuilder}. CacheConfigurationBuilders can be constructed with the {@link Caches Caches} | ||
* utility class. For example: | ||
* <pre> | ||
* Caches.named("cacheRegionNameHere") | ||
* .{@link #withTimeToLive(long, TimeUnit) withTimeToLive(1, TimeUnit.DAYS)} | ||
* .{@link #withTimeToIdle(long, TimeUnit) withTimeToIdle(2, TimeUnit.HOURS)}; | ||
* </pre> | ||
* or | ||
* <pre> | ||
* Caches.forResource(Account.class) | ||
* .{@link #withTimeToLive(long, TimeUnit) withTimeToLive(1, TimeUnit.DAYS)} | ||
* .{@link #withTimeToIdle(long, TimeUnit) withTimeToIdle(2, TimeUnit.HOURS)}; | ||
* </pre> | ||
* | ||
* @see #withTimeToLive(long, TimeUnit) | ||
* @see #withTimeToIdle(long, TimeUnit) | ||
* @see Caches#forResource(Class) | ||
* @see Caches#named(String) | ||
* @since 0.5.0 | ||
*/ | ||
public interface CacheConfigurationBuilder { | ||
|
||
/** | ||
* Sets the associated {@code Cache} region's entry Time to Live (TTL). | ||
* <p> | ||
* Time to Live is the amount of time a cache entry may exist after first being created before it will expire and no | ||
* longer be available. If a cache entry ever becomes older than this amount of time (regardless of how often | ||
* it is accessed), it will be removed from the cache as soon as possible. | ||
* <p> | ||
* If this value is not configured, it is assumed that the Cache's entries could potentially live indefinitely. | ||
* Note however that entries can still be expunged due to other conditions (e.g. memory constraints, Time to | ||
* Idle setting, etc). | ||
* <b>Usage</b> | ||
* <pre> | ||
* ...withTimeToLive(30, TimeUnit.MINUTES)... | ||
* ...withTimeToLive(1, TimeUnit.HOURS)... | ||
* </pre> | ||
* | ||
* @param ttl Time To Live scalar value | ||
* @param ttlTimeUnit Time to Live unit of time | ||
* @return the associated {@code Cache} region's entry Time to Live (TTL). | ||
*/ | ||
CacheConfigurationBuilder withTimeToLive(long ttl, TimeUnit ttlTimeUnit); | ||
|
||
/** | ||
* Sets the associated {@code Cache} region's entry Time to Idle (TTI). | ||
* <p> | ||
* Time to Idle is the amount of time a cache entry may be idle (unused / not accessed) before it will expire and | ||
* no longer be available. If a cache entry is not accessed at all after this amount of time, it will be removed | ||
* from the cache as soon as possible. | ||
* <p> | ||
* If this value is not configured, it is assumed that the Cache's entries could potentially live indefinitely. | ||
* Note however that entries can still be expunged due to other conditions (e.g. memory constraints, Time to | ||
* Live setting, etc). | ||
* <b>Usage</b> | ||
* <pre> | ||
* ...withTimeToIdle(30, TimeUnit.MINUTES)... | ||
* ...withTimeToIdle(1, TimeUnit.HOURS)... | ||
* </pre> | ||
* | ||
* @param tti Time To Idle scalar value | ||
* @param ttiTimeUnit Time to Idle unit of time | ||
* @return the associated {@code Cache} region's entry Time to Idle (TTI). | ||
*/ | ||
CacheConfigurationBuilder withTimeToIdle(long tti, TimeUnit ttiTimeUnit); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright 2014 Stormpath, Inc. | ||
* Modifications Copyright 2018 Okta, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.okta.sdk.cache; | ||
|
||
/** | ||
* A CacheManager provides and maintains the lifecycle of {@link Cache Cache} instances. | ||
* <p> | ||
* This interface provides an abstraction (wrapper) API on top of an underlying | ||
* cache framework's main Manager component (e.g. JCache, Ehcache, Hazelcast, JCS, OSCache, JBossCache, TerraCotta, | ||
* Coherence, GigaSpaces, etc, etc), allowing a Okta SDK user to configure any cache mechanism they choose. | ||
* | ||
* @since 0.5.0 | ||
*/ | ||
public interface CacheManager { | ||
|
||
/** | ||
* Acquires the cache with the specified {@code name}. If a cache does not yet exist with that name, a new one | ||
* will be created with that name and returned. | ||
* | ||
* @param name the name of the cache to acquire. | ||
* @param <K> type of cache key | ||
* @param <V> type of cache value | ||
* @return the Cache with the given name | ||
*/ | ||
<K, V> Cache<K, V> getCache(String name); | ||
} |
123 changes: 123 additions & 0 deletions
123
api/src/main/java/com/okta/sdk/cache/CacheManagerBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
* Copyright 2014 Stormpath, Inc. | ||
* Modifications Copyright 2018 Okta, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.okta.sdk.cache; | ||
|
||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* Builder for creating simple {@link CacheManager} instances <b>suitable for SINGLE-JVM APPLICATIONS</b>. If your | ||
* application is deployed (mirrored or clustered) across multiple JVMs, you might not | ||
* want to use this builder and use your own clusterable CacheManager implementation instead. See Clustering below. | ||
* <b>Clustering</b> | ||
* <b>The default CacheManager instances created by this Builder DO NOT SUPPORT CLUSTERING</b>. | ||
* <p> | ||
* If you use this Builder and your application is deployed on multiple JVMs, <b>each of your application instances will | ||
* have <em>their own</em> local cache of Okta data</b>. Depending on your application requirements, and your | ||
* cache TTL and TTI settings, this could introduce a significant difference in cached data seen by your application | ||
* instances, which would likely impact user management behavior. For example, one application instance could see an | ||
* account as ENABLED, but the other application instance could see it as DISABLED. | ||
* <p> | ||
* For some applications, this discrepancy might be an acceptable trade-off, especially if you configure | ||
* {@link #withDefaultTimeToIdle(long, TimeUnit) timeToIdle} and | ||
* {@link #withDefaultTimeToLive(long, TimeUnit) timeToLive} settings low enough. For example, | ||
* maybe a TTL of 5 or 10 minutes is an acceptable time to see 'stale' account data. For other applications, this might | ||
* not be acceptable. If it is acceptable, configuring the timeToIdle and timeToLive settings will allow you to | ||
* fine-tune how much variance you allow. | ||
* <p> | ||
* However, if you are concerned about this difference in data and you want the Okta SDK's cache to be coherent | ||
* across your application nodes (typically a good thing to have), it is strongly recommended that you do not use this | ||
* Builder and instead configure the Okta SDK with a clustered {@code CacheManager} implementation of your choosing. | ||
* This approach still gives you excellent performance improvements and ensures that your cached data is coherent (seen | ||
* as the same) across all of your application instances. | ||
* <p> | ||
* This comes with an increased cost of course: setting up a caching product and/or cluster. However, this is not | ||
* much of a problem in practice: most multi-instance applications already leverage caching clusters for their own | ||
* application needs. In these environments, and with a proper {@code CacheManager} implementation leveraging a | ||
* clustered cache, the Okta Java SDK will live quite happily using this same caching infrastructure. | ||
* <p> | ||
* A coherent cache deployment ensures all of your application instances/nodes can utilize the same cache policy and | ||
* see the same cached security/identity data. Some example clustered caching solutions: Hazelcast, | ||
* Ehcache+Terracotta, Memcache, Redis, Coherence, GigaSpaces, etc. | ||
* | ||
* @since 0.5.0 | ||
*/ | ||
public interface CacheManagerBuilder { | ||
|
||
/** | ||
* Sets the default Time to Live (TTL) for all cache regions managed by the {@link #build() built} | ||
* {@code CacheManager}. You may override this default for individual cache regions by using the | ||
* {@link #withCache(CacheConfigurationBuilder) withCache} for each region you wish to configure. | ||
* <p> | ||
* Time to Live is the amount of time a cache entry may exist after first being created before it will expire and no | ||
* longer be available. If a cache entry ever becomes older than this amount of time (regardless of how often | ||
* it is accessed), it will be removed from the cache as soon as possible. | ||
* <p> | ||
* If this value is not configured, it is assumed that cache entries could potentially live indefinitely. | ||
* Note however that entries can still be expunged due to other conditions (e.g. memory constraints, Time to | ||
* Idle setting, etc). | ||
* <b>Usage</b> | ||
* <pre> | ||
* ...withDefaultTimeToLive(30, TimeUnit.MINUTES)... | ||
* ...withDefaultTimeToLive(1, TimeUnit.HOURS)... | ||
* </pre> | ||
* | ||
* @param ttl default Time To Live scalar value | ||
* @param timeUnit default Time to Live unit of time | ||
* @return the builder instance for method chaining. | ||
*/ | ||
CacheManagerBuilder withDefaultTimeToLive(long ttl, TimeUnit timeUnit); | ||
|
||
/** | ||
* Sets the default Time to Idle (TTI) for all cache regions managed by the {@link #build() built} | ||
* {@code CacheManager}. You may override this default for individual cache regions by using the | ||
* {@link #withCache(CacheConfigurationBuilder) withCache} for each region you wish to configure. | ||
* <p> | ||
* Time to Idle is the amount of time a cache entry may be idle (unused / not accessed) before it will expire and | ||
* no longer be available. If a cache entry is not accessed at all after this amount of time, it will be removed | ||
* from the cache as soon as possible. | ||
* <p> | ||
* If this value is not configured, it is assumed that cache entries could potentially live indefinitely. | ||
* Note however that entries can still be expunged due to other conditions (e.g. memory constraints, Time to | ||
* Live setting, etc). | ||
* <b>Usage</b> | ||
* <pre> | ||
* ...withDefaultTimeToLive(30, TimeUnit.MINUTES)... | ||
* ...withDefaultTimeToLive(1, TimeUnit.HOURS)... | ||
* </pre> | ||
* | ||
* @param tti default Time To Idle scalar value | ||
* @param timeUnit default Time to Idle unit of time | ||
* @return the builder instance for method chaining. | ||
*/ | ||
CacheManagerBuilder withDefaultTimeToIdle(long tti, TimeUnit timeUnit); | ||
|
||
/** | ||
* Adds configuration settings for a specific Cache region managed by the {@link #build() built} | ||
* {@code CacheManager}, like the region's Time to Live and Time to Idle. | ||
* | ||
* @param builder the CacheConfigurationBuilder instance that will be used to a cache's configuration. | ||
* @return this instance for method chaining. | ||
*/ | ||
CacheManagerBuilder withCache(CacheConfigurationBuilder builder); | ||
|
||
/** | ||
* Returns a new {@link CacheManager} instance reflecting Builder's current configuration. | ||
* | ||
* @return a new {@link CacheManager} instance reflecting Builder's current configuration. | ||
*/ | ||
CacheManager build(); | ||
} |
Oops, something went wrong.