/* * Copyright (c) Members of the EGEE Collaboration. 2006-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * 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 org.glite.authz.pep.server.config; import java.io.Reader; import java.io.StringReader; import java.util.List; import java.util.StringTokenizer; import javax.net.ssl.X509TrustManager; import net.jcip.annotations.ThreadSafe; import org.glite.authz.common.config.AbstractIniServiceConfigurationParser; import org.glite.authz.common.config.ConfigurationException; import org.glite.authz.common.config.IniConfigUtil; import org.glite.authz.pep.obligation.IniOHConfigurationParserHelper; import org.glite.authz.pep.obligation.ObligationService; import org.glite.authz.pep.pip.IniPIPConfigurationParserHelper; import org.glite.authz.pep.pip.PolicyInformationPoint; import org.glite.voms.VOMSTrustManager; import org.ini4j.Ini; import org.opensaml.ws.soap.client.http.HttpClientBuilder; import org.opensaml.ws.soap.client.http.HttpSOAPClient; import org.opensaml.xml.parse.BasicParserPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Parser for a {@link org.glite.authz.pep.server.PEPDaemon} configuration file. */ @ThreadSafe public class PEPDaemonIniConfigurationParser extends AbstractIniServiceConfigurationParser<PEPDaemonConfiguration> { /** The name of the {@value} INI header which contains the property for configuring the PDP interaction. */ public static final String PDP_SECTION_HEADER = "PDP"; /** The name of the {@value} property which gives the space-delimited PDP endpoint URLs. */ public static final String PDP_PROP = "pdps"; /** * The name of the {@value} property which gives the maximum number of responses that will be cached. A value of * zero will disable caching. */ public static final String MAX_CACHED_RESP_PROP = "maximumCachedResponses"; /** The name of the {@value} property which gives the time-to-live, in seconds, for a cached item. */ public static final String CACHED_RESP_TTL_PROP = "cachedResponseTTL"; /** Default value of the {@value AbstractIniServiceConfigurationParser#PORT_PROP} property, {@value} . */ public static final int DEFAULT_PORT = 8154; /** Default value of the {@value AbstractIniServiceConfigurationParser#ADMIN_PORT_PROP} property, {@value} . */ public static final int DEFAULT_ADMIN_PORT = 8155; /** Default value of the {@value #MAX_CACHED_RESP_PROP} property, {@value} . */ public static final int DEFAULT_MAX_CACHED_RESP = 500; /** Default value of the {@value #CACHED_RESP_TTL_PROP} property, {@value} . */ public static final int DEFAULT_CACHED_RESP_TTL = 10 * 60; /** Class logger. */ private final Logger log = LoggerFactory.getLogger(PEPDaemonIniConfigurationParser.class); /** Constructor. */ public PEPDaemonIniConfigurationParser() { super(); } /** {@inheritDoc} */ public PEPDaemonConfiguration parse(Reader iniReader) throws ConfigurationException { return parseIni(iniReader); } /** {@inheritDoc} */ public PEPDaemonConfiguration parse(String iniString) throws ConfigurationException { return parseIni(new StringReader(iniString)); } /** * {@inheritDoc} * * @return the port value, or the default port {@value #DEFAULT_PORT} if it is not set */ protected int getPort(Ini.Section configSection) { return IniConfigUtil.getInt(configSection, PORT_PROP, DEFAULT_PORT, 1, 65535); } /** * {@inheritDoc} * * @return the admin port value, or the default admin port {@value #DEFAULT_ADMIN_PORT} if it is not set */ protected int getAdminPort(Ini.Section configSection) { return IniConfigUtil.getInt(configSection, ADMIN_PORT_PROP, DEFAULT_ADMIN_PORT, 1, 65535); } /** * Gets the value of the {@value #CACHED_RESP_TTL_PROP} property from the configuration section. If the property is * not present or is not valid the default value of {@value #DEFAULT_CACHED_RESP_TTL} will be used. * * @param configSection configuration section from which to extract the value * * @return the value */ protected int getCacheResponseTTL(Ini.Section configSection) { return IniConfigUtil.getInt(configSection, CACHED_RESP_TTL_PROP, DEFAULT_CACHED_RESP_TTL, 1, Integer.MAX_VALUE); } /** * Gets the value of the {@value #MAX_CACHED_RESP_PROP} property from the configuration section. If the property is * not present or is not valid the default value of {@value #DEFAULT_MAX_CACHED_RESP} will be used. * * @param configSection configuration section from which to extract the value * * @return the value */ protected int getMaxCachedResponses(Ini.Section configSection) { return IniConfigUtil.getInt(configSection, MAX_CACHED_RESP_PROP, DEFAULT_MAX_CACHED_RESP, 0, Integer.MAX_VALUE); } /** * Parses a configuration. * * @param iniReader INI to parse * * @return the daemon configuration * * @throws ConfigurationException thrown if there is a problem configuring the system */ private PEPDaemonConfiguration parseIni(Reader iniReader) throws ConfigurationException { Ini iniFile = new Ini(); try { log.info("Loading and parsing INI configuration file"); iniFile.load(iniReader); } catch (Exception e) { log.error("Unable to load and parse the INI configuration file", e); throw new ConfigurationException("Unable to parse INI configuration file", e); } PEPDaemonConfigurationBuilder configBuilder = new PEPDaemonConfigurationBuilder(); log.info("Processing PEP Server {} configuration section", SECURITY_SECTION_HEADER); processSecuritySection(iniFile, configBuilder); log.info("Processing PEP Server {} configuration section", SERVICE_SECTION_HEADER); processServiceSection(iniFile, configBuilder); Ini.Section configSection = iniFile.get(SERVICE_SECTION_HEADER); List<PolicyInformationPoint> pips = IniPIPConfigurationParserHelper.processPolicyInformationPoints(iniFile, configSection, configBuilder); log.info("Total policy information points: {}", pips.size()); configBuilder.getPolicyInformationPoints().addAll(pips); ObligationService service = IniOHConfigurationParserHelper.processObligationHandlers(iniFile, configSection, configBuilder); log.info("Total obligation handlers: {}", service.getObligationHandlers().size()); configBuilder.setObligationService(service); log.info("Processing PEP Server {} configuration section", PDP_SECTION_HEADER); processPDPConfiguration(iniFile, configBuilder); return configBuilder.build(); } /** * Processes the PDP configuration section. * * @param iniFile the INI configuration file * @param configBuilder the daemon configuration builder * * @throws ConfigurationException thrown if the communication to the PDP can be configured */ private void processPDPConfiguration(Ini iniFile, PEPDaemonConfigurationBuilder configBuilder) throws ConfigurationException { Ini.Section configSection = iniFile.get(PDP_SECTION_HEADER); if (configSection == null) { String errorMsg = "INI configuration does not contain the required '" + PDP_SECTION_HEADER + "' INI section"; log.error(errorMsg); throw new ConfigurationException(errorMsg); } String name= configSection.getName(); String pdpEndpointStr = IniConfigUtil.getString(configSection, PDP_PROP); log.info("{}: endpoints: {}", name,pdpEndpointStr); StringTokenizer pdpEndpoints = new StringTokenizer(pdpEndpointStr, " "); while (pdpEndpoints.hasMoreTokens()) { configBuilder.getPDPEndpoints().add(pdpEndpoints.nextToken()); } int maxCachedResponses = getMaxCachedResponses(configSection); log.info("{}: max cached responses: {}", name,maxCachedResponses); configBuilder.setMaxCachedResponses(maxCachedResponses); int cachedResponseTTL = getCacheResponseTTL(configSection) * 1000; log.info("{}: cached response TTL: {}ms", name,cachedResponseTTL); configBuilder.setCachedResponseTTL(cachedResponseTTL); try { X509TrustManager trustManager = new VOMSTrustManager(configBuilder.getTrustMaterialStore()); HttpClientBuilder soapClientBuilder = buildSOAPClientBuilder(configSection, configBuilder.getKeyManager(), trustManager); BasicParserPool parserPool = new BasicParserPool(); parserPool.setMaxPoolSize(soapClientBuilder.getMaxTotalConnections()); configBuilder.setSoapClient(new HttpSOAPClient(soapClientBuilder.buildClient(), parserPool)); } catch (Exception e) { log.error("Unable to create PDP SOAP client",e); throw new ConfigurationException("Unable to create PDP SOAP client", e); } } }