[java-shib-attribute] 01/01: IDP-2219 Improve status page / metrics when service fails to start

Rod Widdowson rdw at steadingsoftware.com
Wed Jan 3 15:32:00 UTC 2024


This is an automated email from the git hooks/post-receive script.

rdw pushed a commit to branch dev/IDP-2219
in repository java-shib-attribute.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-attribute.git;a=commit;h=1c764771914b5baae9a51de8d3cd91dae1e61245

commit 1c764771914b5baae9a51de8d3cd91dae1e61245
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Wed Jan 3 15:06:58 2024 +0000

    IDP-2219 Improve status page / metrics when service fails to start
    
    https://shibboleth.atlassian.net/browse/IDP-2219
    
    Capture failure to initialize for HTTP, LDAP, RDBMS & StorageService Data connectors
---
 .../resolver/dc/http/impl/HTTPDataConnector.java   | 19 ++++--
 .../resolver/dc/ldap/impl/LDAPDataConnector.java   | 74 ++++++++++++----------
 .../resolver/dc/rdbms/impl/RDBMSDataConnector.java | 61 ++++++++++--------
 .../storage/impl/StorageServiceDataConnector.java  | 50 ++++++++-------
 4 files changed, 118 insertions(+), 86 deletions(-)

diff --git a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnector.java b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnector.java
index b02051472..2b02e56e6 100644
--- a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnector.java
+++ b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/http/impl/HTTPDataConnector.java
@@ -19,6 +19,7 @@
 package net.shibboleth.idp.attribute.resolver.dc.http.impl;
 
 import java.io.IOException;
+import java.time.Instant;
 import java.util.Map;
 
 import javax.annotation.Nonnull;
@@ -92,11 +93,19 @@ public class HTTPDataConnector extends AbstractSearchDataConnector<HTTPSearch,HT
     
     /** {@inheritDoc} */
     public void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-        
-        if (httpClient == null) {
-            throw new ComponentInitializationException(getLogPrefix() + " HttpClient cannot be null");
+
+        try {
+	    super.doInitialize();
+
+	    if (httpClient == null) {
+		throw new ComponentInitializationException(getLogPrefix() + " HttpClient cannot be null");
+	    }
+        }
+        catch (final Exception e) {
+            setLastFail(Instant.now());
+            throw e;
         }
+
     }
 
     /** {@inheritDoc} */
@@ -115,4 +124,4 @@ public class HTTPDataConnector extends AbstractSearchDataConnector<HTTPSearch,HT
         }
     }
         
-}
\ No newline at end of file
+}
diff --git a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
index e564bd4e1..a39305277 100644
--- a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
+++ b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
@@ -15,6 +15,7 @@
 package net.shibboleth.idp.attribute.resolver.dc.ldap.impl;
 
 import java.security.GeneralSecurityException;
+import java.time.Instant;
 import java.util.Map;
 
 import javax.annotation.Nonnull;
@@ -119,39 +120,46 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
 
     /** {@inheritDoc} */
     @Override protected void doInitialize() throws ComponentInitializationException {
-        if (connectionFactory == null) {
-            throw new ComponentInitializationException(getLogPrefix() + " No connection factory was configured");
-        }
-        if (searchOperation == null) {
-            throw new ComponentInitializationException(getLogPrefix() + " No search executor was configured");
-        }
-
-        if (defaultValidator) {
-            final ConnectionFactoryValidator validator = new ConnectionFactoryValidator();
-            super.setValidator(validator);
-        }
-        if (defaultMappingStrategy) {
-            super.setMappingStrategy(new StringAttributeValueMappingStrategy());
-        }
-        super.doInitialize();
-
-        // validator should defer to data connector fail-fast-initialize during #initialize
-        final boolean throwValidateError = getValidator().isThrowValidateError();
         try {
-            getValidator().setThrowValidateError(isFailFastInitialize());
-            getValidator().validate(this);
-        } catch (final ValidationException e) {
-            log.error("{} Invalid connector configuration", getLogPrefix(), e);
-            if (isFailFastInitialize()) {
-                // Should always follow this leg.
-                throw new ComponentInitializationException(getLogPrefix() + " Invalid connector configuration", e);
+            if (connectionFactory == null) {
+                throw new ComponentInitializationException(getLogPrefix() + " No connection factory was configured");
+            }
+            if (searchOperation == null) {
+                throw new ComponentInitializationException(getLogPrefix() + " No search executor was configured");
+            }
+
+            if (defaultValidator) {
+                final ConnectionFactoryValidator validator = new ConnectionFactoryValidator();
+                super.setValidator(validator);
             }
-        } finally {
-            getValidator().setThrowValidateError(throwValidateError);
+            if (defaultMappingStrategy) {
+                super.setMappingStrategy(new StringAttributeValueMappingStrategy());
+            }
+            super.doInitialize();
+
+            // validator should defer to data connector fail-fast-initialize during #initialize
+            final boolean throwValidateError = getValidator().isThrowValidateError();
+            try {
+                getValidator().setThrowValidateError(isFailFastInitialize());
+                getValidator().validate(this);
+            } catch (final ValidationException e) {
+                log.error("{} Invalid connector configuration", getLogPrefix(), e);
+                setLastFail(Instant.now());
+                if (isFailFastInitialize()) {
+                    // Should always follow this leg.
+                    throw new ComponentInitializationException(getLogPrefix() + " Invalid connector configuration", e);
+                }
+            } finally {
+                getValidator().setThrowValidateError(throwValidateError);
+            }
+            policeForJVMTrust();
+        }
+        catch (final Exception e) {
+            setLastFail(Instant.now());
+            throw e;
         }
-        policeForJVMTrust();
     }
-    
+
 // CheckStyle: CyclomaticComplexity OFF
     /** Police TLS for JVM trust.
      * @throws ComponentInitializationException if we detect an SSL issue
@@ -191,12 +199,12 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
     @Override
     @Nullable @Unmodifiable @NotLive protected Map<String, IdPAttribute> retrieveAttributes(
             @Nullable final ExecutableSearchFilter filter) throws ResolutionException {
-        
+
         // The base class method defines the parameter is non-null, so this is arguably unneeded.
         if (filter == null) {
             throw new ResolutionException(getLogPrefix() + " Search filter cannot be null");
         }
-        
+
         try {
             assert searchOperation!=null && connectionFactory!=null;
             final SearchResponse result = filter.execute(searchOperation, connectionFactory);
@@ -206,5 +214,5 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
             throw new ResolutionException(getLogPrefix() + " Unable to execute LDAP search", e);
         }
     }
-    
-}
\ No newline at end of file
+
+}
diff --git a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnector.java b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnector.java
index 22a301304..843c8233f 100644
--- a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnector.java
+++ b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnector.java
@@ -17,6 +17,7 @@ package net.shibboleth.idp.attribute.resolver.dc.rdbms.impl;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.time.Instant;
 import java.util.Map;
 
 import javax.annotation.Nonnull;
@@ -92,31 +93,39 @@ public class RDBMSDataConnector extends AbstractSearchDataConnector<ExecutableSt
 
     /** {@inheritDoc} */
     @Override protected void doInitialize() throws ComponentInitializationException {
-        if (dataSource == null) {
-            throw new ComponentInitializationException(getLogPrefix() + " no data source was configured");
-        }
-
-        if (defaultValidator) {
-            final DataSourceValidator validator = new DataSourceValidator();
-            super.setValidator(validator);
-        }
-        if (defaultMappingStrategy) {
-            super.setMappingStrategy(new StringResultMappingStrategy());
-        }
-        super.doInitialize();
 
-        // validator should defer to data connector fail-fast-initialize during #initialize
-        final boolean throwValidateError = getValidator().isThrowValidateError();
         try {
-            getValidator().setThrowValidateError(isFailFastInitialize());
-            getValidator().validate(this);
-        } catch (final ValidationException e) {
-            log.error("{} Invalid connector configuration", getLogPrefix(), e);
-            if (isFailFastInitialize()) {
-                throw new ComponentInitializationException(getLogPrefix() + " Invalid connector configuration", e);
+            if (dataSource == null) {
+                throw new ComponentInitializationException(getLogPrefix() + " no data source was configured");
+            }
+
+            if (defaultValidator) {
+                final DataSourceValidator validator = new DataSourceValidator();
+                super.setValidator(validator);
             }
-        } finally {
-            getValidator().setThrowValidateError(throwValidateError);
+            if (defaultMappingStrategy) {
+                super.setMappingStrategy(new StringResultMappingStrategy());
+            }
+            super.doInitialize();
+
+            // validator should defer to data connector fail-fast-initialize during #initialize
+            final boolean throwValidateError = getValidator().isThrowValidateError();
+            try {
+                getValidator().setThrowValidateError(isFailFastInitialize());
+                getValidator().validate(this);
+            } catch (final ValidationException e) {
+                setLastFail(Instant.now());
+                log.error("{} Invalid connector configuration", getLogPrefix(), e);
+                if (isFailFastInitialize()) {
+                    throw new ComponentInitializationException(getLogPrefix() + " Invalid connector configuration", e);
+                }
+            } finally {
+                getValidator().setThrowValidateError(throwValidateError);
+            }
+        }
+        catch (final Exception e) {
+            setLastFail(Instant.now());
+            throw e;
         }
     }
 
@@ -138,8 +147,8 @@ public class RDBMSDataConnector extends AbstractSearchDataConnector<ExecutableSt
         if (statement == null) {
             throw new ResolutionException("Executable statement cannot be null");
         }
-        
-        
+
+
         try (final Connection connection = dataSource.getConnection()) {
             assert connection != null;
             try (final ResultSet queryResult = statement.execute(connection)) {
@@ -150,5 +159,5 @@ public class RDBMSDataConnector extends AbstractSearchDataConnector<ExecutableSt
             throw new ResolutionException(getLogPrefix() + " Unable to execute SQL query", e);
         }
     }
-    
-}
\ No newline at end of file
+
+}
diff --git a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/storage/impl/StorageServiceDataConnector.java b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/storage/impl/StorageServiceDataConnector.java
index 0b2d9d886..ff734e793 100644
--- a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/storage/impl/StorageServiceDataConnector.java
+++ b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/storage/impl/StorageServiceDataConnector.java
@@ -19,6 +19,7 @@
 package net.shibboleth.idp.attribute.resolver.dc.storage.impl;
 
 import java.io.IOException;
+import java.time.Instant;
 import java.util.Map;
 
 import javax.annotation.Nonnull;
@@ -50,16 +51,16 @@ import net.shibboleth.shared.primitive.StringSupport;
  */
 public class StorageServiceDataConnector
     extends AbstractSearchDataConnector<StorageServiceSearch, StorageMappingStrategy> {
-    
+
     /** The {@link StorageService} to use. */
     @NonnullAfterInit private StorageService storageService;
-    
+
     /** ID of the attribute generated by this data connector if simple result mapping used. */
     @Nullable private String generatedAttributeID;
-    
+
     /** Whether no record is an error. */
     private boolean noResultAnError;
-    
+
     /** Constructor. */
     public StorageServiceDataConnector() {
         setValidator(new Validator() {
@@ -84,7 +85,7 @@ public class StorageServiceDataConnector
         checkSetterPreconditions();
         storageService = Constraint.isNotNull(service, "StorageService cannot be null");
     }
-    
+
     /**
      * Sets whether the lack of a returned record constitutes an error.
      * 
@@ -94,7 +95,7 @@ public class StorageServiceDataConnector
         checkSetterPreconditions();
         noResultAnError = flag;
     }
-    
+
     /**
      * Get the ID of the attribute generated by this connector if simple result mapping used.
      * 
@@ -103,7 +104,7 @@ public class StorageServiceDataConnector
     @Nullable public String getGeneratedAttributeID() {
         return generatedAttributeID;
     }
-    
+
     /**
      * Set the ID of the attribute generated by this connector if simple result mapping used.
      * 
@@ -113,31 +114,36 @@ public class StorageServiceDataConnector
         checkSetterPreconditions();
         generatedAttributeID = StringSupport.trimOrNull(id);
     }
-    
+
     /** {@inheritDoc} */
     public void doInitialize() throws ComponentInitializationException {
 
-        if (storageService == null) {
-            throw new ComponentInitializationException(getLogPrefix() + " StorageService cannot be null");
-        }
+        try {
+            if (storageService == null) {
+                throw new ComponentInitializationException(getLogPrefix() + " StorageService cannot be null");
+            }
 
-        if (getMappingStrategy() == null) {
-            if (generatedAttributeID == null) {
-                throw new ComponentInitializationException(
-                        getLogPrefix() + " No mapping strategy or generated attribute ID set");
+            if (getMappingStrategy() == null) {
+                if (generatedAttributeID == null) {
+                    throw new ComponentInitializationException(
+                                                               getLogPrefix() + " No mapping strategy or generated attribute ID set");
+                }
+                assert generatedAttributeID != null; 
+                setMappingStrategy(new SimpleStorageMappingStrategy(generatedAttributeID));
             }
-            assert generatedAttributeID != null; 
-            setMappingStrategy(new SimpleStorageMappingStrategy(generatedAttributeID));
+
+            super.doInitialize();
+        } catch (final Exception e) {
+            setLastFail(Instant.now());
+            throw e;
         }
-        
-        super.doInitialize();
     }
 
     /** {@inheritDoc} */
     @Override
     @Nullable protected Map<String,IdPAttribute> retrieveAttributes(@Nonnull final StorageServiceSearch executable)
             throws ResolutionException {
-        
+
         try {
             assert storageService != null;
             final StorageRecord<?> record = executable.execute(storageService);
@@ -147,11 +153,11 @@ public class StorageServiceDataConnector
                 }
                 return CollectionSupport.emptyMap();
             }
-            
+
             return getMappingStrategy().map(record);
         } catch (final IOException e) {
             throw new ResolutionException(getLogPrefix() + " StorageService read failed", e);
         }
     }
 
-}
\ No newline at end of file
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list