All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.internet2.middleware.subject.config.SubjectConfig Maven / Gradle / Ivy

There is a newer version: 5.13.5
Show newest version
/**
 * Copyright 2014 Internet2
 *
 * 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 edu.internet2.middleware.subject.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute;
import edu.internet2.middleware.grouper.app.subectSource.SubjectSourceConfiguration;
import edu.internet2.middleware.grouper.cfg.GrouperConfig;
import edu.internet2.middleware.grouper.externalSubjects.ExternalSubject;
import edu.internet2.middleware.grouper.externalSubjects.ExternalSubjectAutoSourceAdapter;
import edu.internet2.middleware.grouper.util.GrouperUtil;
import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase;
import edu.internet2.middleware.subject.Source;
import edu.internet2.middleware.subject.SubjectUtils;
import edu.internet2.middleware.subject.provider.BaseSourceAdapter;
import edu.internet2.middleware.subject.provider.Search;

/**
 * hierarchical config class for subject.properties
 * @author mchyzer
 *
 */
public class SubjectConfig extends ConfigPropertiesCascadeBase {

  /**
   * use the factory
   */
  private SubjectConfig() {
    
  }

  /**
   * retrieve a config from the config file or from cache
   * @return the config object
   */
  public static SubjectConfig retrieveConfig() {
    return retrieveConfig(SubjectConfig.class);
  }

  /**
   * @see ConfigPropertiesCascadeBase#clearCachedCalculatedValues()
   */
  @Override
  public void clearCachedCalculatedValues() {
    
  }

  /**
   * @see ConfigPropertiesCascadeBase#getHierarchyConfigKey
   */
  @Override
  protected String getHierarchyConfigKey() {
    return "subject.config.hierarchy";
  }

  /**
   * @see ConfigPropertiesCascadeBase#getMainConfigClasspath
   */
  @Override
  protected String getMainConfigClasspath() {
    return "subject.properties";
  }
  
  /**
   * @see ConfigPropertiesCascadeBase#getMainExampleConfigClasspath
   */
  @Override
  protected String getMainExampleConfigClasspath() {
    return "subject.base.properties";
  }

  /**
   * @see ConfigPropertiesCascadeBase#getSecondsToCheckConfigKey
   */
  @Override
  protected String getSecondsToCheckConfigKey() {
    return "subject.config.secondsBetweenUpdateChecks";
  }

  /**
   * exclude these sourceIds from the subject cache
   */
  private Set subjectCacheExcludeSourceIds = null;
  
  /**
   * @return the cache
   */
  public Set subjectCacheExcludeSourceIds() {
    if (subjectCacheExcludeSourceIds == null) {
      subjectCacheExcludeSourceIds = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(this.propertyValueString("subject.cache.excludeSourceIds"), ","));
    }
    return subjectCacheExcludeSourceIds;
  }
  
  /**
   * cache the sources by source config id (which might not be source id)
   */
  private Map sources;

  /**
   * pattern for source
   * subjectApi.source..id
   */
  private static Pattern sourceIdConfigPattern = Pattern.compile("^subjectApi\\.source\\.([^.]+)\\.id$");
  
  /**
   * pattern for param value
   * subjectApi.source..param.throwErrorOnFindAllFailure.value
   */
  private static Pattern paramValueConfigPattern = Pattern.compile("^subjectApi\\.source\\.[^.]+\\.param\\.([^.]+)\\.value$");
  
  /**
   * pattern for param value
   * subjectApi.source..search..param..value = something
   */
  private static Pattern searchParamValueConfigPattern = Pattern.compile("^subjectApi\\.source\\.[^.]+\\.search\\.[^.]+\\.param\\.([^.]+)\\.value$");
  
  public Source reloadSourceConfigs(String sourceId) {
    if (this.sources == null) {
      retrieveSourceConfigs();
      for (Source source : this.sources.values()) {
        if (sourceId.equals(source.getId())) {
          return source;
        }
      }
    } else {
      for (String configName : this.propertyNames()) {
        Matcher matcher = sourceIdConfigPattern.matcher(configName);
        if (matcher.matches()) {
          String sourceConfigId = matcher.group(1);
          String thisSourceId = propertyValueStringRequired("subjectApi.source." + sourceConfigId + ".id");
          if (sourceId.equals(thisSourceId)) {
            Source source = loadSourceConfigs(sourceConfigId);
            this.sources.put(sourceConfigId, source);
            return source;
          }
        }
      }
    }
    //didnt find source, is it grouper external?
    if (StringUtils.equals(sourceId, ExternalSubject.sourceId()) 
        && GrouperConfig.retrieveConfig().propertyValueBoolean("externalSubjects.autoCreateSource", true)) {
      return ExternalSubjectAutoSourceAdapter.instance();

    }
    
    return null;
  }
  
  private Source loadSourceConfigs(String sourceConfigId) {

    try {
      //  # the adapter class implements the interface: edu.internet2.middleware.subject.Source
      //  # generally the adapter class should extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter
      //  # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2  :  if doing JDBC this should be used if possible.  All subject data in one table/view.
      //  # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter   :  oldest JDBC source.  Put freeform queries in here
      //  # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter   :  used for LDAP
      //  # subjectApi.source..adapterClass = 
  
      BaseSourceAdapter source = null;
      
      {
      
        String adapterClassName = propertyValueString("subjectApi.source." + sourceConfigId + ".adapterClass");
        
        Class adapterClassClass = SubjectUtils.forName(adapterClassName);
        source = (BaseSourceAdapter)SubjectUtils.newInstance(adapterClassClass);
      }              
  
      source.setConfigId(sourceConfigId);
      
      {
        //  # generally the  is the same as the source id.  Generally this should not have special characters
        //  # subjectApi.source..id = sourceId
        String sourceId = propertyValueStringRequired("subjectApi.source." + sourceConfigId + ".id");
        source.setId(sourceId);
      }
  
      {
        //  # this is a friendly name for the source
        //  # subjectApi.source..name = sourceName
        String sourceName = propertyValueStringRequired("subjectApi.source." + sourceConfigId + ".name");
        source.setName(sourceName);
      }
  
      {
        //  # type is not used all that much 
        //  # subjectApi.source..types = person, application
        String sourceTypes = propertyValueString("subjectApi.source." + sourceConfigId + ".types");
        if (!StringUtils.isEmpty(sourceTypes)) {
          for (String sourceType : SubjectUtils.splitTrim(sourceTypes, ",")) {
            source.addSubjectType(sourceType);
          }
        }
      }
  
      {
        //params (note, name is optional and generally not there)
        //  # subjectApi.source..param.throwErrorOnFindAllFailure.value = true
        for (String paramValueKey : this.propertyNames()) {
          
          if (paramValueKey.startsWith("subjectApi.source." + sourceConfigId + ".param") 
              && paramValueKey.endsWith(".value") ) {
            String paramValue = propertyValueString(paramValueKey);
            Matcher paramValueMatcher = paramValueConfigPattern.matcher(paramValueKey);
            paramValueMatcher.matches();
            String paramConfigId = paramValueMatcher.group(1);
            String paramName = propertyValueString("subjectApi.source." + sourceConfigId + ".param." + paramConfigId + ".name");
            if (StringUtils.isBlank(paramName)) {
              paramName = paramConfigId;
            }
            source.addInitParam(paramName, paramValue);
          }
        }
      }
      
      {
        List subjectSourceConfigurations = SubjectSourceConfiguration.retrieveAllSubjectSourceConfigurations();
        SubjectSourceConfiguration subjectSourceConfiguration = null;
        for (SubjectSourceConfiguration subjectSourceConfig: subjectSourceConfigurations) {
          
          if (StringUtils.equals(subjectSourceConfig.getConfigId(), sourceConfigId)) {
            subjectSourceConfiguration = subjectSourceConfig;
            break;
          }
        }
  
        if (subjectSourceConfiguration != null) {
          String sqlAttribute = propertyValueString("subjectApi.source." + sourceConfigId + ".param.jdbcConfigId.value");
          if (sqlAttribute != null) {
            
  //          source.addInitParam("jdbcConnectionProvider", GrouperJdbcConnectionProvider.class.getName());
            
            String subjectIdAttributeName = propertyValueString("subjectApi.source." + sourceConfigId + ".param.SubjectID_AttributeType.value");
            
            String subjectNameAttributeName = propertyValueString("subjectApi.source." + sourceConfigId + ".param.Name_AttributeType.value");
            
            String subjectDescriptionAttributeName = propertyValueString("subjectApi.source." + sourceConfigId + ".param.Description_AttributeType.value");
            
            String subjectEmailAttributeName = propertyValueString("subjectApi.source." + sourceConfigId + ".param.emailAttributeName.value");
            
            String subjectNetIdAttributeName = propertyValueString("subjectApi.source." + sourceConfigId + ".param.netId.value");
            
            String numberOfAttributes = propertyValueString("subjectApi.source." + sourceConfigId + ".numberOfAttributes");
                  
            if (StringUtils.isNotBlank(numberOfAttributes)) {
              
              int numberOfAttrs = Integer.parseInt(numberOfAttributes);
              for (int i=0; i.internalAttributes = someName, anotherName
        String internalAttributes = propertyValueString("subjectApi.source." + sourceConfigId + ".internalAttributes");
        if (!StringUtils.isEmpty(internalAttributes)) {
          for (String internalAttribute : SubjectUtils.splitTrim(internalAttributes, ",")) {
            source.addInternalAttribute(internalAttribute);
          }
        }
        
        String numberOfAttributes = propertyValueString("subjectApi.source." + sourceConfigId + ".numberOfAttributes");
        if (StringUtils.isNotBlank(numberOfAttributes)) {
          
          int numberOfAttrs = Integer.parseInt(numberOfAttributes);
          for (int i=0; i subjectIdentifiers = new TreeSet();
          for (int i=0; i.attributes = cn, sn, uid, department, exampleEduRegId
        String attributes = propertyValueString("subjectApi.source." + sourceConfigId + ".attributes");
        if (!StringUtils.isEmpty(attributes)) {
          for (String attribute : SubjectUtils.splitTrim(attributes, ",")) {
            source.addAttribute(attribute);
          }
        }
        
        String extraAttributesFromSource = propertyValueString("subjectApi.source." + sourceConfigId + ".extraAttributesFromSource");
        if (!StringUtils.isEmpty(extraAttributesFromSource)) {
          for (String extraAttribute : SubjectUtils.splitTrim(extraAttributesFromSource, ",")) {
            source.addAttribute(extraAttribute);
          }
        }
        
        String numberOfAttributes = propertyValueString("subjectApi.source." + sourceConfigId + ".numberOfAttributes");
        if (StringUtils.isNotBlank(numberOfAttributes)) {
          
          int numberOfAttrs = Integer.parseInt(numberOfAttributes);
          for (int i=0; i.search..param..value = something
      {
        //params (note, name is optional and generally not there)
        //  # subjectApi.source..param.throwErrorOnFindAllFailure.value = true
        for (String searchType : new String[] {"searchSubject", "searchSubjectByIdentifier", "search"}) {
          
          Search search = new Search();
          search.setSearchType(searchType);
          
          for (String paramValueKey : this.propertyNames()) {
            
            //all search params has a value
            if (paramValueKey.startsWith("subjectApi.source." + sourceConfigId + ".search." + searchType + ".param.") 
                && paramValueKey.endsWith(".value") ) {
              String paramValue = propertyValueString(paramValueKey);
              Matcher paramValueMatcher = searchParamValueConfigPattern.matcher(paramValueKey);
              paramValueMatcher.matches();
              String paramConfigId = paramValueMatcher.group(1);
              String paramName = propertyValueString("subjectApi.source." + sourceConfigId + ".search." + searchType + ".param." + paramConfigId + ".name");
              
              //if name is not specified used the config id (most arent specified)
              if (StringUtils.isBlank(paramName)) {
                paramName = paramConfigId;
              }
              search.addParam(paramName, paramValue);
            }
          }
          
          if (StringUtils.isBlank(search.getParam("base"))) {
            String searchSubjectBase = propertyValueString("subjectApi.source." + sourceConfigId + ".search.searchSubject.param.base.value");
            if (StringUtils.isNotBlank(searchSubjectBase)) {
              search.addParam("base", searchSubjectBase);
            }
          }
          
          if (StringUtils.isBlank(search.getParam("scope"))) {
            String searchSubjectScope = propertyValueString("subjectApi.source." + sourceConfigId + ".search.searchSubject.param.scope.value");
            if (StringUtils.isNotBlank(searchSubjectScope)) {
              search.addParam("scope", searchSubjectScope);
            } else {
              search.addParam("scope", "SUBTREE_SCOPE");
            }
          }
          
          source.loadSearch(search);
        }
      }
      
      return source;
    } catch (RuntimeException re) {
      GrouperUtil.injectInException(re, "Problem with subject source '" + sourceConfigId + "'");
      throw re;
    }
  }
  
  /**
   * process configs for sources and return the map 
   * @return the configs
   */
  public Map retrieveSourceConfigs() {
    if (this.sources == null) {
      synchronized (SubjectConfig.class) {
        if (this.sources == null) {
          Map theSources = new HashMap();
          
          for (String configName : this.propertyNames()) {
            
            //  # generally the  is the same as the source id.  Generally this should not have special characters
            //  # subjectApi.source..id = sourceId

            Matcher matcher = sourceIdConfigPattern.matcher(configName);
            if (matcher.matches()) {
              String sourceConfigId = matcher.group(1);
              Source source = loadSourceConfigs(sourceConfigId);
              theSources.put(sourceConfigId, source);
            }
          }
          
          this.sources = theSources;
        }
      }
    }
    return this.sources;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy