// Copyright 2006 Google Inc. // // 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 com.google.enterprise.connector.manager; import com.google.common.base.Strings; import com.google.enterprise.connector.instantiator.InstantiatorException; import com.google.enterprise.connector.pusher.GsaFeedConnection; import com.google.enterprise.connector.test.ConnectorTestUtils; import junit.framework.TestCase; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.util.Properties; /** * Tests for {@link Context#setConnectorManagerConfig(String, int)}. */ public class SetManagerConfigTest extends TestCase { private static final String APPLICATION_CONTEXT = "testdata/contextTests/SetManagerConfigTest.xml"; private static final String TEST_PROPERTIES = "testContext.properties"; private static final String TEST_DIR_NAME = "testdata/tmp/SetManagerConfigTest"; private final File baseDirectory = new File(TEST_DIR_NAME); private File propFile = new File(baseDirectory, TEST_PROPERTIES); private Context context; @Override protected void setUp() throws Exception { super.setUp(); ConnectorTestUtils.deleteAllFiles(baseDirectory); assertTrue(ConnectorTestUtils.mkdirs(baseDirectory)); // Create an original set of properties. Properties props = new Properties(); props.put(Context.GSA_FEED_HOST_PROPERTY_KEY, "fubar"); props.put(Context.GSA_FEED_PORT_PROPERTY_KEY, "25"); storeProperties(props, propFile, "Initial Props"); Context.refresh(); context = Context.getInstance(); context.setStandaloneContext(APPLICATION_CONTEXT, Context.DEFAULT_JUNIT_COMMON_DIR_PATH); context.setFeeding(false); } @Override protected void tearDown() throws Exception { ConnectorTestUtils.deleteAllFiles(baseDirectory); super.tearDown(); } public final void testGetConnectorManagerConfig() throws Exception { // Get the properties directly from the file. Properties props = loadProperties(propFile); String host = props.getProperty(Context.GSA_FEED_HOST_PROPERTY_KEY); int port = Integer.parseInt(props.getProperty( Context.GSA_FEED_PORT_PROPERTY_KEY, Context.GSA_FEED_PORT_DEFAULT)); // Now get them from the Context. Properties managerProps = context.getConnectorManagerConfig(); String ctxHost = managerProps.getProperty(Context.GSA_FEED_HOST_PROPERTY_KEY); int ctxPort = Integer.parseInt(managerProps.getProperty( Context.GSA_FEED_PORT_PROPERTY_KEY, Context.GSA_FEED_PORT_DEFAULT)); assertEquals("Correct host from context", host, ctxHost); assertEquals("Correct port from context", port, ctxPort); // Update the manager config and pull again. context.setConnectorManagerConfig("", "shme", 14, Context.GSA_FEED_SECURE_PORT_INVALID, null); managerProps = context.getConnectorManagerConfig(); ctxHost = managerProps.getProperty(Context.GSA_FEED_HOST_PROPERTY_KEY); ctxPort = Integer.parseInt(managerProps.getProperty( Context.GSA_FEED_PORT_PROPERTY_KEY, Context.GSA_FEED_PORT_DEFAULT)); assertEquals("Correct host from context", "shme", ctxHost); assertEquals("Correct port from context", 14, ctxPort); } public final void testSetConnectorManagerConfig() throws InstantiatorException, IOException { Properties props = loadProperties(propFile); String host = props.getProperty(Context.GSA_FEED_HOST_PROPERTY_KEY); int port = Integer.parseInt(props.getProperty( Context.GSA_FEED_PORT_PROPERTY_KEY, Context.GSA_FEED_PORT_DEFAULT)); String contentUrlPrefix = props.getProperty( Context.FEED_CONTENTURL_PREFIX_PROPERTY_KEY); assertEquals("fubar", host); assertEquals(25, port); assertNull(contentUrlPrefix); context.setConnectorManagerConfig("", "shme", 14, Context.GSA_FEED_SECURE_PORT_INVALID, "http://test:8080/connector-manager"); String expectedContentUrlPrefix = "http://test:8080/connector-manager/getDocumentContent"; verifyPropsValues("shme", 14, expectedContentUrlPrefix, propFile); context.setConnectorManagerConfig("", host, port, Context.GSA_FEED_SECURE_PORT_INVALID, null); verifyPropsValues(host, port, expectedContentUrlPrefix, propFile); // Verify that the contentUrlPrefix was also set in the Context. assertEquals(expectedContentUrlPrefix, context.getContentUrlPrefix()); } public final void testIsManagerLocked() throws Exception { // Check initial states. assertTrue("Manager with missing prop is locked", context.getIsManagerLocked()); setLockedProperty(Boolean.FALSE.toString()); assertFalse("Manager with prop set to false", context.getIsManagerLocked()); // Check state after updating the manager config. context.setConnectorManagerConfig("", "172.25.25.25", 19900, Context.GSA_FEED_SECURE_PORT_INVALID, null); assertTrue("Manager is locked after setting config", context.getIsManagerLocked()); } private void setLockedProperty(String isLocked) throws IOException { updateProperty(Context.MANAGER_LOCKED_PROPERTY_KEY, isLocked, "Updating lock"); } private void updateProperty(String key, String value, String comment) throws IOException { Properties props = loadProperties(propFile); props.setProperty(key, value); storeProperties(props, propFile, comment); } private void verifyPropsValues(String expectedHost, int expectedPort, String expectedContentUrlPrefix, File propFile) throws IOException { Properties props = loadProperties(propFile); String actualHost = props.getProperty(Context.GSA_FEED_HOST_PROPERTY_KEY); int actualPort = Integer.valueOf(props.getProperty( Context.GSA_FEED_PORT_PROPERTY_KEY, Context.GSA_FEED_PORT_DEFAULT)); String actualContentUrlPrefix = props.getProperty( Context.FEED_CONTENTURL_PREFIX_PROPERTY_KEY); assertEquals(expectedHost, actualHost); assertEquals(expectedPort, actualPort); assertEquals(expectedContentUrlPrefix, actualContentUrlPrefix); String isManagerLocked = props.getProperty(Context.MANAGER_LOCKED_PROPERTY_KEY); assertEquals("Manager is locked", Boolean.TRUE.toString(), isManagerLocked); } /** The field default is true, to make the code safer to use. */ public void testDefaultFieldValidateCertificate() throws Exception { GsaFeedConnection feeder = new GsaFeedConnection("", "fubar", 25, -1); assertTrue(feeder.getValidateCertificate()); } /** * The property default is false, so that the code will run without * certificates, and so that we can change this default to true when * the installer installs the GSA certificate. */ public void testDefaultPropertyValidateCertificate() throws Exception { GsaFeedConnection feeder = new GsaFeedConnection("", "fubar", 25, -1); context.setConnectorManagerConfig("", "shme", 14, Context.GSA_FEED_SECURE_PORT_INVALID, feeder, null); assertFalse(feeder.getValidateCertificate()); } public void testSetPropertyValidateCertificate() throws Exception { updateProperty(Context.GSA_FEED_VALIDATE_CERTIFICATE_PROPERTY_KEY, "true", "Updating validateCertificate"); GsaFeedConnection feeder = new GsaFeedConnection("", "fubar", 25, -1); context.setConnectorManagerConfig("", "shme", 14, Context.GSA_FEED_SECURE_PORT_INVALID, feeder, null); assertTrue(feeder.getValidateCertificate()); } public void testSecurePortSet() throws Exception { // Get the property directly from the file. Properties props = loadProperties(propFile); String securePort = props.getProperty( Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY); assertNull(securePort, securePort); // Now get them from the Context. Properties managerProps = context.getConnectorManagerConfig(); String ctxSecurePort = managerProps.getProperty( Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY); assertNull(ctxSecurePort, ctxSecurePort); // Update the manager config and pull again. setAndGetSecurePort(42, 42); } public void testSecurePortUnset() throws Exception { // Set the secure port. setAndGetSecurePort(42, 42); // Unset the secure port, which should not overwrite the configured port. // This is for backward compatibility when manually setting the securePort. setAndGetSecurePort(Context.GSA_FEED_SECURE_PORT_INVALID, 42); } public void testSecurePortReset() throws Exception { // Set the secure port. setAndGetSecurePort(42, 42); // Reset the secure port. setAndGetSecurePort(45, 45); } public void testSecurePortNeverSet() throws Exception { Properties managerProps = context.getConnectorManagerConfig(); String ctxSecurePort = managerProps.getProperty( Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY); assertNull(ctxSecurePort, ctxSecurePort); context.setConnectorManagerConfig("", "shme", 14, Context.GSA_FEED_SECURE_PORT_INVALID, null); managerProps = context.getConnectorManagerConfig(); ctxSecurePort = managerProps.getProperty( Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY); assertNull(ctxSecurePort, ctxSecurePort); } private void setAndGetSecurePort(int setPort, int expectedPort) throws MalformedURLException, InstantiatorException { GsaFeedConnection feeder = new GsaFeedConnection("", "fubar", 25, -1); context.setConnectorManagerConfig("", "shme", 14, setPort, feeder, null); Properties managerProps = context.getConnectorManagerConfig(); String ctxSecurePort = managerProps.getProperty( Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY); assertNotNull(ctxSecurePort); assertEquals("Correct secure port from context", expectedPort, Integer.parseInt(ctxSecurePort)); assertEquals(expectedPort, feeder.getFeedUrl().getPort()); } /** Represents the XML attributes from a GSA SetManagerConfig request. */ private static class Gsa { public Gsa(String protocolAttribute, int portAttribute, int securePortAttribute) { this.protocolAttribute = protocolAttribute; this.portAttribute = portAttribute; this.securePortAttribute = securePortAttribute; } private final String protocolAttribute; private final int portAttribute; private final int securePortAttribute; } /** Creates a properties object with the non-null arguments */ private Properties makeProps(String protocolProperty, String securePortProperty) { Properties props = new Properties(); if (protocolProperty != null) { props.put(Context.GSA_FEED_PROTOCOL_PROPERTY_KEY, protocolProperty); } if (securePortProperty != null) { props.put(Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY, securePortProperty); } return props; } /** * Tests variations in the inputs to setConnectorManager. * * @param gsa the GSA SetManagerConfig request * @param extraProps the stored properties * @param expectedProtocol the expected feed URL protocol * @param expectedPort the expected feed URL port */ private void setManagerConfig(Gsa gsa, Properties extraProps, String expectedProtocol, int expectedPort) throws IOException, InstantiatorException { Properties props = loadProperties(propFile); props.putAll(extraProps); storeProperties(props, propFile, "Extra Props"); // Make the call. GsaFeedConnection feeder = new GsaFeedConnection("", "fubar", 25, -1); context.setConnectorManagerConfig(gsa.protocolAttribute, "shme", gsa.portAttribute, gsa.securePortAttribute, feeder, null); // Check the feed URL. assertEquals(expectedProtocol, feeder.getFeedUrl().getProtocol()); assertEquals(expectedPort, feeder.getFeedUrl().getPort()); // Check for overwritten protocol and secure port properties. Properties managerProps = context.getConnectorManagerConfig(); assertProperty(!Strings.isNullOrEmpty(gsa.protocolAttribute), gsa.protocolAttribute, Context.GSA_FEED_PROTOCOL_PROPERTY_KEY, extraProps, managerProps); assertProperty(gsa.securePortAttribute >= 0, String.valueOf(gsa.securePortAttribute), Context.GSA_FEED_SECURE_PORT_PROPERTY_KEY, extraProps, managerProps); } /** * Asserts that a property value is either the value from the GSA or * the pre-existing property value. * * @param fromGsa whether the GSA supplied a value * @param gsaValue the value from the GSA (fromGsa != (gsaValue != null)) * @param key the property key * @param extraProps the pre-existing properties * @param managerProps the properties under test */ private void assertProperty(boolean fromGsa, String gsaValue, String key, Properties extraProps, Properties managerProps) { String expectedProperty = (fromGsa) ? gsaValue : extraProps.getProperty(key); assertEquals(expectedProperty, managerProps.getProperty(key)); } /** Represents a GSA request with only a host and port. */ private static final Gsa GSA_6_10 = new Gsa("", 80, -1); /** Represents a GSA request with a securePort attribute. */ private static final Gsa GSA_6_12 = new Gsa("", 80, 443); /** Represents a GSA request with securePort and protocol attributes. */ private static final Gsa GSA_7_0_HTTP = new Gsa("http", 80, 443); /** Represents a GSA request with securePort and protocol attributes. */ private static final Gsa GSA_7_0_HTTPS = new Gsa("https", 80, 443); /** * 1. No securePort from GSA, no gsa.feed.securePort, protocol * defaults to HTTP: non-SSL feeds. */ public void testGsa610Null() throws Exception { setManagerConfig(GSA_6_10, makeProps(null, null), "http", 80); } /** * 2. No securePort from GSA, no gsa.feed.securePort, HTTP: non-SSL * feeds. */ public void testGsa610Http() throws Exception { setManagerConfig(GSA_6_10, makeProps("http", null), "http", 80); } /** * 3. No securePort from GSA, no gsa.feed.securePort, HTTPS: SSL * feeds on gsa.feed.port. */ public void testGsa610Https() throws Exception { setManagerConfig(GSA_6_10, makeProps("https", null), "https", 19902); } /** * 4. No securePort from GSA, gsa.feed.securePort, protocol defaults * to HTTPS: SSL feeds. */ public void testGsa610NullSecurePort() throws Exception { setManagerConfig(GSA_6_10, makeProps(null, "443"), "https", 443); } /** * 5. No securePort from GSA, gsa.feed.securePort, HTTP: non-SSL feeds. */ public void testGsa610HttpSecurePort() throws Exception { setManagerConfig(GSA_6_10, makeProps("http", "443"), "http", 80); } /** * 6. No securePort from GSA, gsa.feed.securePort, HTTPS: SSL feeds. */ public void testGsa610HttpsSecurePort() throws Exception { setManagerConfig(GSA_6_10, makeProps("https", "443"), "https", 443); } /** * 7. securePort from GSA, gsa.feed.securePort is overwritten, * protocol defaults to HTTPS: SSL feeds */ public void testGsa612Null() throws Exception { setManagerConfig(GSA_6_12, makeProps(null, "777"), "https", 443); } /** * 8. securePort from GSA, gsa.feed.securePort is overwritten, * protocol is not overwritten: HTTP: non-SSL feeds. */ public void testGsa612Http() throws Exception { setManagerConfig(GSA_6_12, makeProps("http", "777"), "http", 80); } /** * 9. securePort from GSA, gsa.feed.securePort is overwritten, * protocol is not overwritten: HTTPS: SSL feeds. */ public void testGsa612Https() throws Exception { setManagerConfig(GSA_6_12, makeProps("https", "777"), "https", 443); } /** * 10. securePort and HTTP protocol from GSA, gsa.feed.securePort is * overwritten, protocol is overwritten: HTTP: non-SSL feeds. */ public void testGsa70Http() throws Exception { setManagerConfig(GSA_7_0_HTTP, makeProps("https", "777"), "http", 80); } /** * 11. securePort and HTTPS protocol from GSA, gsa.feed.securePort * is overwritten, protocol is overwritten: HTTPS: SSL feeds. */ public void testGsa70Https() throws Exception { setManagerConfig(GSA_7_0_HTTPS, makeProps("http", "777"), "https", 443); } private Properties loadProperties(File propFile) throws IOException { Properties props = new Properties(); InputStream inStream = new FileInputStream(propFile); try { props.load(inStream); } finally { inStream.close(); } return props; } private void storeProperties(Properties props, File propFile, String comments) throws IOException { OutputStream outStream = new FileOutputStream(propFile); try { props.store(outStream, comments); } finally { outStream.close(); } } }