/** * Copyright 2015 StreamSets Inc. * * Licensed under the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.streamsets.datacollector.el; import com.codahale.metrics.MetricRegistry; import com.google.common.collect.ImmutableSet; import com.streamsets.datacollector.http.WebServerTask; import com.streamsets.datacollector.main.RuntimeInfo; import com.streamsets.datacollector.main.RuntimeModule; import com.streamsets.datacollector.main.StandaloneRuntimeInfo; import com.streamsets.datacollector.util.Configuration; import com.streamsets.lib.security.http.RemoteSSOService; import dagger.ObjectGraph; import org.apache.commons.io.IOUtils; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.Mockito; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; import java.util.Arrays; import java.util.Properties; import java.util.UUID; public class TestRuntimeEL { private static final String SDC_HOME_KEY = "SDC_HOME"; private static final String EMBEDDED_SDC_HOME_VALUE = "../sdc-embedded"; private static final String REMOTE_SDC_HOME_VALUE = "../sdc-remote"; private static File resourcesDir; private static File dataDir; private static File configDir; private static RuntimeInfo runtimeInfo; @BeforeClass public static void beforeClass() throws IOException { configDir = new File("target", UUID.randomUUID().toString()).getAbsoluteFile(); Assert.assertTrue(configDir.mkdirs()); resourcesDir = new File("target", UUID.randomUUID().toString()).getAbsoluteFile(); Assert.assertTrue(resourcesDir.mkdirs()); dataDir = new File("target", UUID.randomUUID().toString()).getAbsoluteFile(); Assert.assertTrue(dataDir.mkdirs()); System.setProperty(RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.CONFIG_DIR, configDir.getPath()); System.setProperty(RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.RESOURCES_DIR, resourcesDir.getPath()); System.setProperty(RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.DATA_DIR, dataDir.getPath()); } @AfterClass public static void afterClass() throws IOException { System.getProperties().remove(RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.CONFIG_DIR); System.getProperties().remove(RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.RESOURCES_DIR); System.getProperties().remove(RuntimeModule.SDC_PROPERTY_PREFIX + RuntimeInfo.DATA_DIR); } @Before() public void setUp() { runtimeInfo = new StandaloneRuntimeInfo(RuntimeModule.SDC_PROPERTY_PREFIX,new MetricRegistry(), Arrays.asList(getClass().getClassLoader())); } @Test public void testRuntimeELEmbedded() throws IOException { createSDCFile("sdc-embedded-runtime-conf.properties"); RuntimeEL.loadRuntimeConfiguration(runtimeInfo); Assert.assertEquals(EMBEDDED_SDC_HOME_VALUE, RuntimeEL.conf(SDC_HOME_KEY)); } @Test public void testRuntimeELExternal() throws IOException { File configDir = new File("target", UUID.randomUUID().toString()).getAbsoluteFile(); Assert.assertTrue(configDir.mkdirs()); try (OutputStream os = new FileOutputStream(new File(configDir, "sdc.properties"))) { Properties props = new Properties(); props.setProperty("runtime.conf.location", "foo.properties"); props.store(os, ""); } try (OutputStream os = new FileOutputStream(new File(configDir, "foo.properties"))) { Properties props = new Properties(); props.setProperty("foo", "bar"); props.store(os, ""); } RuntimeInfo runtimeInfo = Mockito.mock(RuntimeInfo.class); Mockito.when(runtimeInfo.getConfigDir()).thenReturn(configDir.getAbsolutePath()); RuntimeEL.loadRuntimeConfiguration(runtimeInfo); Assert.assertEquals("bar", RuntimeEL.conf("foo")); } private void createSDCFile(String sdcFileName) throws IOException { String sdcFile = new File(runtimeInfo.getConfigDir(), "sdc.properties").getAbsolutePath(); OutputStream os = new FileOutputStream(sdcFile); InputStream is = Thread.currentThread().getContextClassLoader(). getResourceAsStream(sdcFileName); IOUtils.copy(is, os); is.close(); } @Test public void testLoadResource() throws Exception { Path fooFile = Paths.get(resourcesDir.getPath(), "foo.txt"); try { Files.write(fooFile, "Hello".getBytes(StandardCharsets.UTF_8)); RuntimeEL.loadRuntimeConfiguration(runtimeInfo); Assert.assertNull(RuntimeEL.loadResource("bar.txt", false)); Assert.assertNull(RuntimeEL.loadResource("bar.txt", true)); Assert.assertEquals("Hello", RuntimeEL.loadResource("foo.txt", false)); try { RuntimeEL.loadResource("foo.txt", true); Assert.fail(); } catch (IllegalArgumentException ex) { //nop } catch (Exception ex) { Assert.fail(); } Files.setPosixFilePermissions(fooFile, ImmutableSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)); Assert.assertEquals("Hello", RuntimeEL.loadResource("foo.txt", true)); try { Files.setPosixFilePermissions(fooFile, ImmutableSet.of(PosixFilePermission.OTHERS_READ)); Assert.assertEquals("Hello", RuntimeEL.loadResource("foo.txt", true)); Assert.fail(); } catch (IllegalArgumentException ex) { //NOP } try { Files.setPosixFilePermissions(fooFile, ImmutableSet.of(PosixFilePermission.OTHERS_WRITE)); Assert.assertEquals("Hello", RuntimeEL.loadResource("foo.txt", true)); Assert.fail(); } catch (IllegalArgumentException ex) { //NOP } } finally { Files.setPosixFilePermissions(fooFile, ImmutableSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)); } } @Test public void testAuthToken() throws IOException { Properties props = new Properties(); props.setProperty(RemoteSSOService.SECURITY_SERVICE_APP_AUTH_TOKEN_CONFIG, "AUTH_TOKEN"); Writer writer = new FileWriter(new File(configDir, "sdc.properties")); props.store(writer, ""); writer.close(); ObjectGraph og = ObjectGraph.create(RuntimeModule.class); og.get(Configuration.class); RuntimeInfo info = og.get(RuntimeInfo.class); RuntimeEL.loadRuntimeConfiguration(info); Assert.assertEquals("AUTH_TOKEN", RuntimeEL.authToken()); } @Test public void testAuthTokenNoFile() throws IOException { OutputStream sdcProps = new FileOutputStream(new File(runtimeInfo.getConfigDir(), "sdc.properties")); sdcProps.close(); RuntimeEL.loadRuntimeConfiguration(runtimeInfo); Assert.assertEquals(null, RuntimeEL.authToken()); } @Test public void testHostname() throws IOException { // No configuration, fetch hostname dynamically OutputStream sdcProps = new FileOutputStream(new File(runtimeInfo.getConfigDir(), "sdc.properties")); sdcProps.close(); RuntimeEL.loadRuntimeConfiguration(runtimeInfo); Assert.assertEquals(InetAddress.getLocalHost().getCanonicalHostName(), RuntimeEL.hostname()); // Hostname in configuration file sdcProps = new FileOutputStream(new File(runtimeInfo.getConfigDir(), "sdc.properties")); IOUtils.write(WebServerTask.HTTP_BIND_HOST + "=sdc.jarcec.net", sdcProps); sdcProps.close(); RuntimeEL.loadRuntimeConfiguration(runtimeInfo); Assert.assertEquals("sdc.jarcec.net", RuntimeEL.hostname()); } }