From 759ac5f42c6aff901dbeede4fbf1a1d2e08cad0f Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 4 Dec 2019 19:43:32 +0100 Subject: common EGIZ code-style refactoring --- .../metadata/AbstractChainingMetadataProvider.java | 929 +++++++++++---------- 1 file changed, 490 insertions(+), 439 deletions(-) (limited to 'eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java') diff --git a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java index 08ef26ab..ec81353a 100644 --- a/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java +++ b/eaaf_modules/eaaf_module_pvp2_core/src/main/java/at/gv/egiz/eaaf/modules/pvp2/impl/metadata/AbstractChainingMetadataProvider.java @@ -1,29 +1,22 @@ -/******************************************************************************* - * Copyright 2017 Graz University of Technology - * EAAF-Core Components has been developed in a cooperation between EGIZ, - * A-SIT Plus, A-SIT, and Graz University of Technology. +/* + * Copyright 2017 Graz University of Technology EAAF-Core Components has been developed in a + * cooperation between EGIZ, A-SIT Plus, A-SIT, and Graz University of Technology. * - * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work except in + * compliance with the Licence. You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ -/******************************************************************************* - *******************************************************************************/ + * Unless required by applicable law or agreed to in writing, software distributed under the Licence + * is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the Licence for the specific language governing permissions and limitations under + * the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text file for details on the + * various modules and licenses. The "NOTICE" text file is part of the distribution. Any derivative + * works that you distribute must include a readable copy of the "NOTICE" text file. +*/ + package at.gv.egiz.eaaf.modules.pvp2.impl.metadata; import java.io.IOException; @@ -35,9 +28,12 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Timer; - import javax.xml.namespace.QName; - +import at.gv.egiz.components.spring.api.IDestroyableObject; +import at.gv.egiz.eaaf.core.api.IGarbageCollectorProcessing; +import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataProvider; +import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; import org.apache.commons.lang3.StringUtils; import org.opensaml.saml2.metadata.EntitiesDescriptor; import org.opensaml.saml2.metadata.EntityDescriptor; @@ -52,419 +48,474 @@ import org.opensaml.xml.XMLObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.components.spring.api.IDestroyableObject; -import at.gv.egiz.eaaf.core.api.IGarbageCollectorProcessing; -import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPVPMetadataProvider; -import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IRefreshableMetadataProvider; - public abstract class AbstractChainingMetadataProvider extends SimpleMetadataProvider - implements ObservableMetadataProvider, IGarbageCollectorProcessing, - IRefreshableMetadataProvider, IDestroyableObject, IPVPMetadataProvider { - - private static final Logger log = LoggerFactory.getLogger(AbstractChainingMetadataProvider.class); - - private MetadataProvider internalProvider = null; - private static Object mutex = new Object(); - private Timer timer = null; - - - public AbstractChainingMetadataProvider() { - internalProvider = new ChainingMetadataProvider(); - - } - - public final Timer getTimer() { - return this.timer; - - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() - */ - @Override - public void runGarbageCollector() { - synchronized (mutex) { - /**add new Metadataprovider or remove Metadataprovider which are not in use any more.**/ - try { - log.trace("Check consistence of PVP2X metadata"); - addAndRemoveMetadataProvider(); - - } catch (EAAFConfigurationException e) { - log.error("Access to MOA-ID configuration FAILED.", e); - - } - } - - } - - public void fullyDestroy() { - internalDestroy(); - - } - - @Override - public synchronized boolean refreshMetadataProvider(String entityID) { - try { - //check if metadata provider is already loaded - try { - if (internalProvider.getEntityDescriptor(entityID) != null) - return true; - - } catch (MetadataProviderException e) {} - - - //reload metadata provider - String metadataURL = getMetadataURL(entityID); - if (StringUtils.isNotEmpty(metadataURL)) { - Map actuallyLoadedProviders = getAllActuallyLoadedProviders(); - - // check if MetadataProvider is actually loaded - if (actuallyLoadedProviders.containsKey(metadataURL)) { - actuallyLoadedProviders.get(metadataURL).refresh(); - log.info("SAML2 metadata for service provider: " - + entityID + " is refreshed."); - return true; - - } else { - //load new Metadata Provider - if (timer == null) - timer = new Timer(true); - - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - chainProvider.addMetadataProvider(createNewMetadataProvider(entityID)); - - emitChangeEvent(); - log.info("SAML2 metadata for service provider: " - + entityID + " is added."); - return true; - - } - - } else - log.debug("Can not refresh SAML2 metadata: NO SAML2 metadata URL for SP with Id: " + entityID); - - } catch (MetadataProviderException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } catch (IOException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } catch (EAAFConfigurationException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } catch (CertificateException e) { - log.warn("Refresh SAML2 metadata for service provider: " - + entityID + " FAILED.", e); - - } - - return false; - - } - - public void internalDestroy() { - if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { - log.info("Destrorying PVP-Authentication MetaDataProvider."); - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - List providers = chainProvider.getProviders(); - for (MetadataProvider provider : providers) { - if (provider instanceof HTTPMetadataProvider) { - HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; - log.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI()); - httpprovider.destroy(); - - } else { - log.warn("MetadataProvider can not be destroyed."); - } - } - - internalProvider = new ChainingMetadataProvider(); - - if (timer != null) - timer.cancel(); - - } else { - log.warn("ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); - } - } - - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#requireValidMetadata() - */ - @Override - public boolean requireValidMetadata() { - return internalProvider.requireValidMetadata(); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setRequireValidMetadata(boolean) - */ - @Override - public void setRequireValidMetadata(boolean requireValidMetadata) { - internalProvider.setRequireValidMetadata(requireValidMetadata); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadataFilter() - */ - @Override - public MetadataFilter getMetadataFilter() { - return internalProvider.getMetadataFilter(); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setMetadataFilter(org.opensaml.saml2.metadata.provider.MetadataFilter) - */ - @Override - public void setMetadataFilter(MetadataFilter newFilter) - throws MetadataProviderException { - internalProvider.setMetadataFilter(newFilter); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadata() - */ - @Override - public XMLObject getMetadata() throws MetadataProviderException { - return internalProvider.getMetadata(); - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntitiesDescriptor(java.lang.String) - */ - @Override - public EntitiesDescriptor getEntitiesDescriptor(String entitiesID) - throws MetadataProviderException { - EntitiesDescriptor entitiesDesc = null; - try { - entitiesDesc = internalProvider.getEntitiesDescriptor(entitiesID); - - if (entitiesDesc == null) { - log.debug("Can not find PVP metadata for entityID: " + entitiesID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entitiesID)) - return internalProvider.getEntitiesDescriptor(entitiesID); - - } - - } catch (MetadataProviderException e) { - log.debug("Can not find PVP metadata for entityID: " + entitiesID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entitiesID)) - return internalProvider.getEntitiesDescriptor(entitiesID); - - } - - return entitiesDesc; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntityDescriptor(java.lang.String) - */ - @Override - public EntityDescriptor getEntityDescriptor(String entityID) - throws MetadataProviderException { - EntityDescriptor entityDesc = null; - try { - entityDesc = internalProvider.getEntityDescriptor(entityID); - if (entityDesc == null) { - log.debug("Can not find PVP metadata for entityID: " + entityID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entityID)) - return internalProvider.getEntityDescriptor(entityID); - - } - - } catch (MetadataProviderException e) { - log.debug("Can not find PVP metadata for entityID: " + entityID - + " Start refreshing process ..."); - if (refreshMetadataProvider(entityID)) - return internalProvider.getEntityDescriptor(entityID); - - } - -// if (entityDesc != null) -// lastAccess.put(entityID, new Date()); - - return entityDesc; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang.String, javax.xml.namespace.QName) - */ - @Override - public List getRole(String entityID, QName roleName) - throws MetadataProviderException { - List result = internalProvider.getRole(entityID, roleName); - -// if (result != null) -// lastAccess.put(entityID, new Date()); - - return result; - } - - /* (non-Javadoc) - * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang.String, javax.xml.namespace.QName, java.lang.String) - */ - @Override - public RoleDescriptor getRole(String entityID, QName roleName, - String supportedProtocol) throws MetadataProviderException { - RoleDescriptor result = internalProvider.getRole(entityID, roleName, supportedProtocol); - -// if (result != null) -// lastAccess.put(entityID, new Date()); - - return result; - } - - /* (non-Javadoc) - * @see org.opensaml.saml2.metadata.provider.ObservableMetadataProvider#getObservers() - */ - @Override - public List getObservers() { - return ((ChainingMetadataProvider) internalProvider).getObservers(); - } - - - /** - * Get the URL to metadata for a specific entityID - * - * @param entityId - * @return - * @throws EAAFConfigurationException - */ - protected abstract String getMetadataURL(String entityId) throws EAAFConfigurationException; - - /** - * Creates a new implementation specific SAML2 metadata provider - * - * @param entityId - * @return - * @throws EAAFConfigurationException - * @throws IOException - * @throws CertificateException - * @throws ConfigurationException - */ - protected abstract MetadataProvider createNewMetadataProvider(String entityId) throws EAAFConfigurationException, IOException, CertificateException; - - /** - * Get a List of metadata URLs for all SAML2 SPs from configuration - * - * @throws EAAFConfigurationException - */ - protected abstract List getAllMetadataURLsFromConfiguration() throws EAAFConfigurationException; - - - protected void emitChangeEvent() { - if ((getObservers() == null) || (getObservers().size() == 0)) { - return; - } - - List tempObserverList = new ArrayList(getObservers()); - for (ObservableMetadataProvider.Observer observer : tempObserverList) - if (observer != null) - observer.onEvent(this); - } - - private Map getAllActuallyLoadedProviders() { - Map loadedproviders = new HashMap(); - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - //make a Map of all actually loaded HTTPMetadataProvider - List providers = chainProvider.getProviders(); - for (MetadataProvider provider : providers) { - if (provider instanceof HTTPMetadataProvider) { - HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; - loadedproviders.put(httpprovider.getMetadataURI(), httpprovider); - - } - } - - return loadedproviders; - } - - private void addAndRemoveMetadataProvider() throws EAAFConfigurationException { - if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { - log.info("Reload MOAMetaDataProvider."); - - /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) - *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ - Map providersinuse = new HashMap(); - ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; - - //get all actually loaded metadata providers - Map loadedproviders = getAllActuallyLoadedProviders(); - - /* TODO: maybe add metadata provider destroy after timeout. - * But could be a problem if one Metadataprovider load an EntitiesDescriptor - * with more the multiple EntityDescriptors. If one of this EntityDesciptors - * are expired the full EntitiesDescriptor is removed. - * - * Timeout requires a better solution in this case! - */ - - //load all SAML2 SPs form configuration and - //compare actually loaded Providers with configured SAML2 SPs - List allMetadataURLs = getAllMetadataURLsFromConfiguration(); - - if (allMetadataURLs != null) { - Iterator metadataURLInterator = allMetadataURLs.iterator(); - while (metadataURLInterator.hasNext()) { - String metadataurl = metadataURLInterator.next(); - try { - if (StringUtils.isNotEmpty(metadataurl)) { - if (loadedproviders.containsKey(metadataurl)) { - // SAML2 SP is actually loaded, to nothing - providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); - loadedproviders.remove(metadataurl); - - } - } - } catch (Throwable e) { - log.error( - "Failed to add Metadata (unhandled reason: " + e.getMessage(), e); - - } - } - } - - //remove all actually loaded MetadataProviders with are not in ConfigurationDB any more - Collection notusedproviders = loadedproviders.values(); - for (HTTPMetadataProvider provider : notusedproviders) { - String metadataurl = provider.getMetadataURI(); - try { - provider.destroy(); - - /*OpenSAML ChainingMetadataProvider can not remove a MetadataProvider (UnsupportedOperationException) - *The ChainingMetadataProvider use internal a unmodifiableList to hold all registrated MetadataProviders.*/ - //chainProvider.removeMetadataProvider(provider); - log.info("Remove not used MetadataProvider with MetadataURL " + metadataurl); - - } catch (Throwable e) { - log.error("HTTPMetadataProvider with URL " + metadataurl - + " can not be removed from the list of actually loaded Providers.", e); - - } - - } - - try { - chainProvider.setProviders(new ArrayList(providersinuse.values())); - emitChangeEvent(); - - } catch (MetadataProviderException e) { - log.warn("ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy", e); - - } - - } else - log.warn("ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy"); - - } + implements ObservableMetadataProvider, IGarbageCollectorProcessing, + IRefreshableMetadataProvider, IDestroyableObject, IPvpMetadataProvider { + + private static final Logger log = LoggerFactory.getLogger(AbstractChainingMetadataProvider.class); + + private MetadataProvider internalProvider = null; + private static Object mutex = new Object(); + private Timer timer = null; + + + public AbstractChainingMetadataProvider() { + internalProvider = new ChainingMetadataProvider(); + + } + + public final Timer getTimer() { + return this.timer; + + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.config.auth.IGarbageCollectorProcessing#runGarbageCollector() + */ + @Override + public void runGarbageCollector() { + synchronized (mutex) { + /* add new Metadataprovider or remove Metadataprovider which are not in use any more. */ + try { + log.trace("Check consistence of PVP2X metadata"); + addAndRemoveMetadataProvider(); + + } catch (final EaafConfigurationException e) { + log.error("Access to MOA-ID configuration FAILED.", e); + + } + } + + } + + @Override + public void fullyDestroy() { + internalDestroy(); + + } + + @Override + public synchronized boolean refreshMetadataProvider(final String entityID) { + try { + // check if metadata provider is already loaded + try { + if (internalProvider.getEntityDescriptor(entityID) != null) { + return true; + } + + } catch (final MetadataProviderException e) { + log.debug("Metadata for EntityId: {} is not valid. Starting refresh ... ", entityID); + + } + + + // reload metadata provider + final String metadataUrl = getMetadataUrl(entityID); + if (StringUtils.isNotEmpty(metadataUrl)) { + final Map actuallyLoadedProviders = + getAllActuallyLoadedProviders(); + + // check if MetadataProvider is actually loaded + if (actuallyLoadedProviders.containsKey(metadataUrl)) { + actuallyLoadedProviders.get(metadataUrl).refresh(); + log.info("SAML2 metadata for service provider: " + entityID + " is refreshed."); + return true; + + } else { + // load new Metadata Provider + if (timer == null) { + timer = new Timer(true); + } + + final ChainingMetadataProvider chainProvider = + (ChainingMetadataProvider) internalProvider; + chainProvider.addMetadataProvider(createNewMetadataProvider(entityID)); + + emitChangeEvent(); + log.info("SAML2 metadata for service provider: " + entityID + " is added."); + return true; + + } + + } else { + log.debug( + "Can not refresh SAML2 metadata: NO SAML2 metadata URL for SP with Id: " + entityID); + } + + } catch (final MetadataProviderException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } catch (final IOException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } catch (final EaafConfigurationException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } catch (final CertificateException e) { + log.warn("Refresh SAML2 metadata for service provider: " + entityID + " FAILED.", e); + + } + + return false; + + } + + /** + * Close metadata provider and remove all loaded metadata. + * + */ + public void internalDestroy() { + if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { + log.info("Destrorying PVP-Authentication MetaDataProvider."); + final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + final List providers = chainProvider.getProviders(); + for (final MetadataProvider provider : providers) { + if (provider instanceof HTTPMetadataProvider) { + final HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; + log.debug("Destroy HTTPMetadataProvider +" + httpprovider.getMetadataURI()); + httpprovider.destroy(); + + } else { + log.warn("MetadataProvider can not be destroyed."); + } + } + + internalProvider = new ChainingMetadataProvider(); + + if (timer != null) { + timer.cancel(); + } + + } else { + log.warn( + "ReInitalize MOAMetaDataProvider is not possible! MOA-ID Instance has to be restarted manualy"); + } + } + + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#requireValidMetadata() + */ + @Override + public boolean requireValidMetadata() { + return internalProvider.requireValidMetadata(); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setRequireValidMetadata + * (boolean) + */ + @Override + public void setRequireValidMetadata(final boolean requireValidMetadata) { + internalProvider.setRequireValidMetadata(requireValidMetadata); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadataFilter() + */ + @Override + public MetadataFilter getMetadataFilter() { + return internalProvider.getMetadataFilter(); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#setMetadataFilter(org. + * opensaml.saml2.metadata.provider.MetadataFilter) + */ + @Override + public void setMetadataFilter(final MetadataFilter newFilter) throws MetadataProviderException { + internalProvider.setMetadataFilter(newFilter); + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getMetadata() + */ + @Override + public XMLObject getMetadata() throws MetadataProviderException { + return internalProvider.getMetadata(); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntitiesDescriptor( + * java.lang.String) + */ + @Override + public EntitiesDescriptor getEntitiesDescriptor(final String entitiesID) + throws MetadataProviderException { + EntitiesDescriptor entitiesDesc = null; + try { + entitiesDesc = internalProvider.getEntitiesDescriptor(entitiesID); + + if (entitiesDesc == null) { + log.debug("Can not find PVP metadata for entityID: " + entitiesID + + " Start refreshing process ..."); + if (refreshMetadataProvider(entitiesID)) { + return internalProvider.getEntitiesDescriptor(entitiesID); + } + + } + + } catch (final MetadataProviderException e) { + log.debug("Can not find PVP metadata for entityID: " + entitiesID + + " Start refreshing process ..."); + if (refreshMetadataProvider(entitiesID)) { + return internalProvider.getEntitiesDescriptor(entitiesID); + } + + } + + return entitiesDesc; + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getEntityDescriptor( + * java.lang.String) + */ + @Override + public EntityDescriptor getEntityDescriptor(final String entityID) + throws MetadataProviderException { + EntityDescriptor entityDesc = null; + try { + entityDesc = internalProvider.getEntityDescriptor(entityID); + if (entityDesc == null) { + log.debug("Can not find PVP metadata for entityID: " + entityID + + " Start refreshing process ..."); + if (refreshMetadataProvider(entityID)) { + return internalProvider.getEntityDescriptor(entityID); + } + + } + + } catch (final MetadataProviderException e) { + log.debug( + "Can not find PVP metadata for entityID: " + entityID + " Start refreshing process ..."); + if (refreshMetadataProvider(entityID)) { + return internalProvider.getEntityDescriptor(entityID); + } + + } + + // if (entityDesc != null) + // lastAccess.put(entityID, new Date()); + + return entityDesc; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang. + * String, javax.xml.namespace.QName) + */ + @Override + public List getRole(final String entityID, final QName roleName) + throws MetadataProviderException { + final List result = internalProvider.getRole(entityID, roleName); + + // if (result != null) + // lastAccess.put(entityID, new Date()); + + return result; + } + + /* + * (non-Javadoc) + * + * @see at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IEAAFMetadataProvider#getRole(java.lang. + * String, javax.xml.namespace.QName, java.lang.String) + */ + @Override + public RoleDescriptor getRole(final String entityID, final QName roleName, + final String supportedProtocol) throws MetadataProviderException { + final RoleDescriptor result = internalProvider.getRole(entityID, roleName, supportedProtocol); + + // if (result != null) + // lastAccess.put(entityID, new Date()); + + return result; + } + + /* + * (non-Javadoc) + * + * @see org.opensaml.saml2.metadata.provider.ObservableMetadataProvider#getObservers() + */ + @Override + public List getObservers() { + return ((ChainingMetadataProvider) internalProvider).getObservers(); + } + + + /** + * Get the URL to metadata for a specific entityID. + * + * @param entityId EntityId + * @return URL to metadata + * @throws EaafConfigurationException In case of an error + */ + protected abstract String getMetadataUrl(String entityId) throws EaafConfigurationException; + + /** + * Creates a new implementation specific SAML2 metadata provider. + * + * @param entityId EntityId + * @return MetadataProvider + * @throws EaafConfigurationException In case of an error + * @throws IOException In case of an error + * @throws CertificateException In case of an error + * @throws ConfigurationException In case of an error + */ + protected abstract MetadataProvider createNewMetadataProvider(String entityId) + throws EaafConfigurationException, IOException, CertificateException; + + /** + * Get a List of metadata URLs for all SAML2 SPs from configuration. + * + * @throws EaafConfigurationException In case of an error + */ + protected abstract List getAllMetadataUrlsFromConfiguration() + throws EaafConfigurationException; + + + protected void emitChangeEvent() { + if ((getObservers() == null) || (getObservers().size() == 0)) { + return; + } + + final List tempObserverList = new ArrayList<>(getObservers()); + for (final ObservableMetadataProvider.Observer observer : tempObserverList) { + if (observer != null) { + observer.onEvent(this); + } + } + } + + private Map getAllActuallyLoadedProviders() { + final Map loadedproviders = + new HashMap<>(); + final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + // make a Map of all actually loaded HTTPMetadataProvider + final List providers = chainProvider.getProviders(); + for (final MetadataProvider provider : providers) { + if (provider instanceof HTTPMetadataProvider) { + final HTTPMetadataProvider httpprovider = (HTTPMetadataProvider) provider; + loadedproviders.put(httpprovider.getMetadataURI(), httpprovider); + + } + } + + return loadedproviders; + } + + private void addAndRemoveMetadataProvider() throws EaafConfigurationException { + if (internalProvider != null && internalProvider instanceof ChainingMetadataProvider) { + log.info("Reload MOAMetaDataProvider."); + + /* + * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider + * (UnsupportedOperationException) The ChainingMetadataProvider use internal a + * unmodifiableList to hold all registrated MetadataProviders. + */ + final Map providersinuse = new HashMap<>(); + final ChainingMetadataProvider chainProvider = (ChainingMetadataProvider) internalProvider; + + // get all actually loaded metadata providers + final Map loadedproviders = getAllActuallyLoadedProviders(); + + /* + * TODO: maybe add metadata provider destroy after timeout. But could be a problem if one + * Metadataprovider load an EntitiesDescriptor with more the multiple EntityDescriptors. If + * one of this EntityDesciptors are expired the full EntitiesDescriptor is removed. + * + * Timeout requires a better solution in this case! + */ + + // load all SAML2 SPs form configuration and + // compare actually loaded Providers with configured SAML2 SPs + final List allMetadataUrls = getAllMetadataUrlsFromConfiguration(); + + if (allMetadataUrls != null) { + final Iterator metadataUrlInterator = allMetadataUrls.iterator(); + while (metadataUrlInterator.hasNext()) { + final String metadataurl = metadataUrlInterator.next(); + try { + if (StringUtils.isNotEmpty(metadataurl)) { + if (loadedproviders.containsKey(metadataurl)) { + // SAML2 SP is actually loaded, to nothing + providersinuse.put(metadataurl, loadedproviders.get(metadataurl)); + loadedproviders.remove(metadataurl); + + } + } + } catch (final Throwable e) { + log.error("Failed to add Metadata (unhandled reason: " + e.getMessage(), e); + + } + } + } + + // remove all actually loaded MetadataProviders with are not in ConfigurationDB any more + final Collection notusedproviders = loadedproviders.values(); + for (final HTTPMetadataProvider provider : notusedproviders) { + final String metadataurl = provider.getMetadataURI(); + try { + provider.destroy(); + + /* + * OpenSAML ChainingMetadataProvider can not remove a MetadataProvider + * (UnsupportedOperationException) The ChainingMetadataProvider use internal a + * unmodifiableList to hold all registrated MetadataProviders. + */ + // chainProvider.removeMetadataProvider(provider); + log.info("Remove not used MetadataProvider with MetadataURL " + metadataurl); + + } catch (final Throwable e) { + log.error("HTTPMetadataProvider with URL " + metadataurl + + " can not be removed from the list of actually loaded Providers.", e); + + } + + } + + try { + chainProvider.setProviders(new ArrayList<>(providersinuse.values())); + emitChangeEvent(); + + } catch (final MetadataProviderException e) { + log.warn( + "ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy", + e); + + } + + } else { + log.warn( + "ReInitalize AbstractMetaDataProvider is not possible! Service has to be restarted manualy"); + } + + } } -- cgit v1.2.3