it.publisys.ims.discovery.job.EntityTasks.java Source code

Java tutorial

Introduction

Here is the source code for it.publisys.ims.discovery.job.EntityTasks.java

Source

/*
 * IMS SPID Discovery
 * Copyright (c) 2016 Publisys S.p.A. srl (http://www.publisys.it).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package it.publisys.ims.discovery.job;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.xmlbeans.XmlException;
import org.guanxi.common.GuanxiException;
import org.guanxi.common.Utils;
import org.guanxi.common.definitions.Guanxi;
import org.guanxi.common.entity.EntityFarm;
import org.guanxi.common.entity.EntityManager;
import org.guanxi.common.entity.impl.GuanxiEntityFarmImpl;
import org.guanxi.common.entity.impl.GuanxiEntityManagerImpl;
import org.guanxi.common.metadata.Metadata;
import org.guanxi.xal.saml_2_0.metadata.EntitiesDescriptorDocument;
import org.guanxi.xal.saml_2_0.metadata.EntityDescriptorDocument;
import org.guanxi.xal.saml_2_0.metadata.EntityDescriptorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

import javax.servlet.ServletContext;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Scandisce la cartella dei metadati e ne carica il contenuto
 *
 * @author mcolucci
 * @version 1.0
 * @since <pre>11/02/16</pre>
 */
@Component
public class EntityTasks implements ServletContextAware {

    private static final Logger log = LoggerFactory.getLogger(EntityTasks.class);

    private static final String METADATA_DIR = "metadata";
    private static final String GUARDS_DIR = "guards";
    //
    private static final String PROTECTEDAPP_GUARD_XML = "protectedapp-guard.xml";
    private static final String PROTECTEDAPP_GUARD_CACHED_XML = "protectedapp-guard-cached-metadata.xml";

    //
    private ServletContext servletContext;

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    @Scheduled(fixedRate = 600000, initialDelay = 5000)
    public void reloadEntities() {
        log.debug("Reload Entities");

        log.debug("ServletContext: " + servletContext);

        try {
            Resource resourceDir = new ClassPathResource(METADATA_DIR + "/" + GUARDS_DIR);

            if (!resourceDir.exists()) {
                throw new FileNotFoundException(
                        String.format("Directory dei Medatada non presente. [%s]", resourceDir));
            }

            List<File> files = loadMetadataXml(resourceDir.getFile());
            EntitiesDescriptorDocument entitiesDescriptorDocument = storeEntitiesFile(files);

            EntityDescriptorType[] entityDescriptorTypes = loadAndCacheEntities(entitiesDescriptorDocument);
            loadEntities(entityDescriptorTypes);

        } catch (FileNotFoundException fnfe) {
            log.warn(fnfe.getMessage(), fnfe);
        } catch (IOException ioe) {
            log.warn("Caricamento Metadata non riuscito.", ioe);
        }

    }

    private void loadEntities(EntityDescriptorType[] entityDescriptorTypes) {
        Resource resource = new ClassPathResource(METADATA_DIR + "/" + PROTECTEDAPP_GUARD_XML);

        try {
            final EntityManager manager = loadEntityManager(Guanxi.CONTEXT_ATTR_IDP_ENTITY_FARM,
                    resource.getFile().getAbsolutePath());

            // Store the new entity IDs for cleaning out old ones later
            List<String> newEntityIDs = new ArrayList<>();

            Arrays.stream(entityDescriptorTypes)
                    .filter(entityDescriptor -> entityDescriptor.getSPSSODescriptorArray().length > 0)
                    .forEach(entityDescriptor -> {
                        log.info("Loading SP metadata for : " + entityDescriptor.getEntityID());
                        try {
                            Metadata metadataHandler = manager.createNewEntityHandler();
                            metadataHandler.setPrivateData(entityDescriptor);

                            manager.addMetadata(metadataHandler);

                            newEntityIDs.add(entityDescriptor.getEntityID());
                        } catch (GuanxiException ge) {
                            log.warn(
                                    String.format("Non sono riuscito a caricari i metadati del Service Provider %s",
                                            entityDescriptor.getEntityID()),
                                    ge);
                        }
                    });

            // Remove expired entities from the manager
            String[] oldEntityIDs = manager.getEntityIDs();
            for (String oldEntityID : oldEntityIDs) {
                if (!newEntityIDs.contains(oldEntityID)) {
                    manager.removeMetadata(oldEntityID);
                }
            }
        } catch (Exception ge) {
            log.error("Could not get an entity handler from the metadata manager", ge);
        }
    }

    private EntityManager loadEntityManager(String contextKey, String metadataURL) {
        EntityFarm farm = (EntityFarm) servletContext.getAttribute(contextKey);
        if (farm == null) {
            farm = new GuanxiEntityFarmImpl();

            GuanxiEntityManagerImpl entityManager = new GuanxiEntityManagerImpl();
            entityManager.init();
            entityManager.setEntityHandlerClass("org.guanxi.common.metadata.impl.GuanxiSAML2MetadataImpl");
            //entityManager.setTrustEngine(new org.guanxi.idp.trust.impl.IdPTrustEngineImpl);

            Map<String, EntityManager> entityManagers = new HashMap<>();
            entityManagers.put(metadataURL, entityManager);

            farm.setEntityManagers(entityManagers);

            servletContext.setAttribute(Guanxi.CONTEXT_ATTR_ENGINE_ENTITY_FARM, farm);
        }
        return farm.getEntityManagerForSource(metadataURL);
    }

    private EntitiesDescriptorDocument storeEntitiesFile(List<File> files) {
        Resource resource = new ClassPathResource(METADATA_DIR + "/" + PROTECTEDAPP_GUARD_XML);

        EntitiesDescriptorDocument entities = EntitiesDescriptorDocument.Factory.newInstance();

        EntityDescriptorType[] arrayEntities = new EntityDescriptorType[files.size()];

        for (int i = 0; i < files.size(); i++) {
            File f = files.get(i);

            log.debug(String.format("Metadata: %s", f.getAbsolutePath()));

            try {
                EntityDescriptorDocument singolo = EntityDescriptorDocument.Factory.parse(f);
                arrayEntities[i] = singolo.getEntityDescriptor();
            } catch (IOException ioe) {
                log.error(String.format("Errore di lettura del file %s", f.getAbsolutePath()), ioe);
            } catch (XmlException xmle) {
                log.error(String.format("Errore durante il parsing del file %s", f.getAbsolutePath()), xmle);
            }

        }

        entities.addNewEntitiesDescriptor().setEntityDescriptorArray(arrayEntities);

        // scrivo il nuovo file corrispondente alle entity ottenute
        try {
            Utils.writeSAML2MetadataToDisk(entities, resource.getFile().getAbsolutePath());
        } catch (Exception ex) {
            log.error(String.format("Errore durante la scrittura del file '%s' su disco", PROTECTEDAPP_GUARD_XML),
                    ex);
        }

        return entities;

    }

    private EntityDescriptorType[] loadAndCacheEntities(EntitiesDescriptorDocument entitiesDescriptorDocument) {
        Resource resourceCache = new ClassPathResource(METADATA_DIR + "/" + PROTECTEDAPP_GUARD_CACHED_XML);

        EntityDescriptorType[] entityDescriptors = entitiesDescriptorDocument.getEntitiesDescriptor()
                .getEntityDescriptorArray();

        // Cache the metadata locally
        try {
            Utils.writeSAML2MetadataToDisk(entitiesDescriptorDocument, resourceCache.getFile().getAbsolutePath());
        } catch (Exception ex) {
            log.error(String.format("Errore durante la scrittura del file di cache '%s' su disco",
                    PROTECTEDAPP_GUARD_CACHED_XML), ex);
        }

        return entityDescriptors;
    }

    private List<File> loadMetadataXml(File dir) {
        Collection<File> filesAndDirs = FileUtils.listFilesAndDirs(dir, FileFilterUtils.suffixFileFilter(".xml"),
                FileFilterUtils.suffixFileFilter("-guard"));

        return filesAndDirs.stream().filter(File::isFile).collect(Collectors.toList());
    }

}