[java-oidc-common] branch main updated: JCOMOIDC-102 - Implement metadata cache loading strategy for generic resources
Henri Mikkonen
henri.mikkonen at iki.fi
Fri Mar 1 14:01:44 UTC 2024
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-oidc-common.
View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=6bcb04c53ed49f5b287e6c305bd656dc34e84f03
The following commit(s) were added to refs/heads/main by this push:
new 6bcb04c JCOMOIDC-102 - Implement metadata cache loading strategy for generic resources
6bcb04c is described below
commit 6bcb04c53ed49f5b287e6c305bd656dc34e84f03
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Mar 1 16:01:17 2024 +0200
JCOMOIDC-102 - Implement metadata cache loading strategy for generic resources
https://shibboleth.atlassian.net/browse/JCOMOIDC-102
New DefaultResourceLoadingStrategy can be used with non-File resources.
Added new buildResourceLoadingMetadataPolicyResolver method to MetadataPolicyLookupStrategyFactory.
---
.../cache/impl/DefaultResourceLoadingStrategy.java | 99 ++++++++++++++++++++++
.../impl/MetadataPolicyLookupStrategyFactory.java | 67 +++++++++++++--
.../MetadataPolicyLookupStrategyFactoryTest.java | 10 ++-
3 files changed, 168 insertions(+), 8 deletions(-)
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultResourceLoadingStrategy.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultResourceLoadingStrategy.java
new file mode 100644
index 0000000..231cfde
--- /dev/null
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/DefaultResourceLoadingStrategy.java
@@ -0,0 +1,99 @@
+/*
+ * 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 net.shibboleth.oidc.metadata.cache.impl;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.slf4j.Logger;
+import org.springframework.core.io.Resource;
+
+import net.shibboleth.oidc.metadata.cache.CacheLoadingContext;
+import net.shibboleth.oidc.metadata.cache.CacheLoadingException;
+import net.shibboleth.oidc.metadata.cache.LoadingStrategy;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/** Default strategy for loading information from a resource.*/
+ at ThreadSafe
+public class DefaultResourceLoadingStrategy implements LoadingStrategy {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultResourceLoadingStrategy.class);
+
+ /** The metadata resource. */
+ @Nullable private final Resource metadataResource;
+
+ /** The metadata resource name to use in logs. */
+ @Nonnull @NotEmpty private final String metadataResourceFriendlyName;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param metadata the metadata resource. Can be {@literal null}.
+ */
+ public DefaultResourceLoadingStrategy(@Nullable final Resource metadata) {
+ if (metadata == null) {
+ log.warn("Resource is null, no bytes will be returned");
+ metadataResource = null;
+ metadataResourceFriendlyName = "No resource specified";
+ } else {
+ metadataResource = metadata;
+ metadataResourceFriendlyName = metadata.getDescription();
+ }
+ }
+
+ /**
+ * Get the time for the last update/modification of the metadata resource.
+ * @return The last update time.
+ * @throws IOException if the time cannot be fetched.
+ */
+ @Nullable private Instant getMetadataUpdateTime() throws IOException {
+ return metadataResource != null ? Instant.ofEpochMilli(metadataResource.lastModified()) : null;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable public byte[] load(@Nonnull final CacheLoadingContext context) throws CacheLoadingException {
+
+ if (metadataResource == null) {
+ return null;
+ }
+
+ try {
+ final Instant metadataUpdateTime = getMetadataUpdateTime();
+ if (context.getLastRefresh() == null || context.getLastUpdate() == null || metadataUpdateTime == null ||
+ metadataUpdateTime.isAfter(context.getLastRefresh())) {
+ assert metadataResource != null;
+ return metadataResource.getContentAsByteArray();
+ }
+ return null;
+ } catch (final Exception e) {
+ final String errMsg = "Unable to read metadata resource " + metadataResource;
+ log.error(errMsg, e.getMessage());
+ throw new CacheLoadingException(errMsg, e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull public String getSourceIdentifier() {
+ return metadataResourceFriendlyName;
+ }
+
+}
\ No newline at end of file
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactory.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactory.java
index 49a7909..667caed 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactory.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactory.java
@@ -26,6 +26,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
+import net.shibboleth.oidc.metadata.cache.LoadingStrategy;
import net.shibboleth.oidc.metadata.cache.MetadataCache;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.MetadataPolicyResolver;
@@ -69,17 +70,69 @@ public class MetadataPolicyLookupStrategyFactory {
final Function<ProfileRequestContext, CriteriaSet> criteriaSetLookupStrategy,
@ParameterName(name="id") @Nonnull final String id) throws ComponentInitializationException, IOException{
- final MetadataCacheBuilder.Builder<String, Map<String, MetadataPolicy>> builder =
- new MetadataCacheBuilder.Builder<>();
-
Resource fileResource = null;
if (resource != null && !resource.isEmpty()) {
final ResourceLoader resourceLoader = new PreferFileSystemResourceLoader();
fileResource = resourceLoader.getResource(resource);
}
+ @Nonnull final DefaultFileLoadingStrategy fileStrategy = new DefaultFileLoadingStrategy(fileResource);
+ return buildMetadataPolicyResolver(fileStrategy, cacheSpec, criteriaSetLookupStrategy, id);
+
+ }
+
+ /**
+ * Build a Function that maps a profile request context to a map of metadata policies. The map is resolved
+ * from a newly instantiated {@link MetadataPolicyResolver}. The Resolver calls a new {@link BatchMetadataCache}
+ * which is hard-wired to use a default file loading strategy with the file resource supplied.
+ *
+ * @param resource the resource to inject into the loading strategy. Can be null or empty.
+ * @param cacheSpec the metadata cache specification
+ * @param criteriaSetLookupStrategy the lookup strategy for the criteria set used for the metadata policy resolver.
+ * @param id the identifier/name for the back-end cache created
+ *
+ * @return the function
+ *
+ * @throws ComponentInitializationException on error.
+ * @throws IOException on error.
+ */
+ @Nonnull
+ public Function<ProfileRequestContext,Map<String,MetadataPolicy>> buildResourceLoadingMetadataPolicyResolver(
+ @ParameterName(name="resource") @Nullable final Resource resource,
+ @ParameterName(name="cacheSpec") @Nonnull
+ final BatchMetadataCacheBuilderSpec<String, Map<String, MetadataPolicy>> cacheSpec,
+ @ParameterName(name="criteriaSetLookupStrategy") @Nullable
+ final Function<ProfileRequestContext, CriteriaSet> criteriaSetLookupStrategy,
+ @ParameterName(name="id") @Nonnull final String id) throws ComponentInitializationException, IOException{
- final DefaultFileLoadingStrategy fileStrategy = new DefaultFileLoadingStrategy(fileResource);
- cacheSpec.setLoadingStrategy(fileStrategy);
+ @Nonnull final DefaultResourceLoadingStrategy resourceStrategy = new DefaultResourceLoadingStrategy(resource);
+ return buildMetadataPolicyResolver(resourceStrategy, cacheSpec, criteriaSetLookupStrategy, id);
+ }
+
+ /**
+ * Build a Function that maps a profile request context to a map of metadata policies. The map is resolved
+ * from a newly instantiated {@link MetadataPolicyResolver}. The Resolver calls a new {@link BatchMetadataCache}
+ * which is hard-wired to use a default file loading strategy with the file resource supplied.
+ *
+ * @param loadingStrategy the loading strategy containing the metadata resource.
+ * @param cacheSpec the metadata cache specification
+ * @param criteriaSetLookupStrategy the lookup strategy for the criteria set used for the metadata policy resolver.
+ * @param id the identifier/name for the back-end cache created
+ *
+ * @return the function
+ *
+ * @throws ComponentInitializationException on error.
+ * @throws IOException on error.
+ */
+ @Nonnull protected Function<ProfileRequestContext,Map<String,MetadataPolicy>> buildMetadataPolicyResolver(
+ @Nonnull final LoadingStrategy loadingStrategy,
+ @Nonnull final BatchMetadataCacheBuilderSpec<String, Map<String, MetadataPolicy>> cacheSpec,
+ @Nullable final Function<ProfileRequestContext, CriteriaSet> criteriaSetLookupStrategy,
+ @Nonnull final String id) throws ComponentInitializationException, IOException {
+
+ final MetadataCacheBuilder.Builder<String, Map<String, MetadataPolicy>> builder =
+ new MetadataCacheBuilder.Builder<>();
+
+ cacheSpec.setLoadingStrategy(loadingStrategy);
cacheSpec.setCacheId(id + "-cache");
final MetadataCache<Map<String, MetadataPolicy>> cache = builder.build(cacheSpec);
@@ -94,7 +147,7 @@ public class MetadataPolicyLookupStrategyFactory {
function.setCriteriaSetLookupStrategy(criteriaSetLookupStrategy);
return function;
-
+
}
-
+
}
\ No newline at end of file
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactoryTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactoryTest.java
index 4ffa079..67af301 100644
--- a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactoryTest.java
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/cache/impl/MetadataPolicyLookupStrategyFactoryTest.java
@@ -76,7 +76,15 @@ public class MetadataPolicyLookupStrategyFactoryTest {
factory.buildFileLoadingMetadataPolicyResolver(null,spec, null, "Mock");
assertNotNull(createdFunction);
}
-
+
+ /* Test the factory creates the function correctly. Not throwing an exception is likely enough to test this.*/
+ @Test
+ public void testFactoryBuild_ResourceBased_Success() throws ComponentInitializationException, IOException {
+ final var createdFunction =
+ factory.buildResourceLoadingMetadataPolicyResolver(null,spec, null, "Mock");
+ assertNotNull(createdFunction);
+ }
+
@Test
public void testXMLDefinitionLoads() {
final GenericXmlApplicationContext context = new GenericXmlApplicationContext();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list