azkaban-developers

merge with azkaban3

11/13/2015 5:49:40 PM

Changes

.travis.yml 6(+6 -0)

azkaban-common/src/main/java/azkaban/utils/cache/Cache.java 193(+0 -193)

azkaban-common/src/main/java/azkaban/utils/cache/CacheManager.java 132(+0 -132)

azkaban-common/src/main/java/azkaban/utils/cache/Element.java 48(+0 -48)

azkaban-common/src/test/java/azkaban/utils/cache/CacheTest.java 159(+0 -159)

build.gradle 5(+5 -0)

Details

.travis.yml 6(+6 -0)

diff --git a/.travis.yml b/.travis.yml
index 09aad73..d7354f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,2 +1,8 @@
 languages: java
+# TODO(dzc): Add openjdk8 once it is available in Travis.
+jdk:
+  - openjdk7
+  - oraclejdk7
+  - oraclejdk8
+sudo: false
 script: ./gradlew distTar
diff --git a/azkaban-common/src/main/java/azkaban/jobExecutor/JavaProcessJob.java b/azkaban-common/src/main/java/azkaban/jobExecutor/JavaProcessJob.java
index e8e2dac..d3ab3f1 100644
--- a/azkaban-common/src/main/java/azkaban/jobExecutor/JavaProcessJob.java
+++ b/azkaban-common/src/main/java/azkaban/jobExecutor/JavaProcessJob.java
@@ -22,8 +22,8 @@ import java.util.List;
 
 import org.apache.log4j.Logger;
 
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.server.AzkabanServer;
-import azkaban.utils.DirectoryFlowLoader;
 import azkaban.utils.Pair;
 import azkaban.utils.Props;
 import azkaban.utils.Utils;
diff --git a/azkaban-common/src/main/java/azkaban/project/ProjectManager.java b/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
index 0f09b9c..18582bd 100644
--- a/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
+++ b/azkaban-common/src/main/java/azkaban/project/ProjectManager.java
@@ -32,6 +32,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.log4j.Logger;
 
 import azkaban.flow.Flow;
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.project.ProjectLogEvent.EventType;
 import azkaban.project.ProjectWhitelist.WhitelistType;
 import azkaban.project.validator.ValidationReport;
@@ -42,7 +43,6 @@ import azkaban.project.validator.XmlValidatorManager;
 import azkaban.user.Permission;
 import azkaban.user.Permission.Type;
 import azkaban.user.User;
-import azkaban.utils.DirectoryFlowLoader;
 import azkaban.utils.Props;
 import azkaban.utils.Utils;
 
diff --git a/azkaban-common/src/main/java/azkaban/project/validator/XmlValidatorManager.java b/azkaban-common/src/main/java/azkaban/project/validator/XmlValidatorManager.java
index 0f240da..cc6d005 100644
--- a/azkaban-common/src/main/java/azkaban/project/validator/XmlValidatorManager.java
+++ b/azkaban-common/src/main/java/azkaban/project/validator/XmlValidatorManager.java
@@ -24,7 +24,7 @@ import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
 import azkaban.project.Project;
-import azkaban.utils.DirectoryFlowLoader;
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.utils.Props;
 
 /**
diff --git a/azkaban-common/src/main/java/azkaban/server/session/SessionCache.java b/azkaban-common/src/main/java/azkaban/server/session/SessionCache.java
index fc4d64f..20f4496 100644
--- a/azkaban-common/src/main/java/azkaban/server/session/SessionCache.java
+++ b/azkaban-common/src/main/java/azkaban/server/session/SessionCache.java
@@ -16,10 +16,12 @@
 
 package azkaban.server.session;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.Cache;
+
+import java.util.concurrent.TimeUnit;
+
 import azkaban.utils.Props;
-import azkaban.utils.cache.Cache;
-import azkaban.utils.cache.CacheManager;
-import azkaban.utils.cache.Cache.EjectionPolicy;
 
 /**
  * Cache for web session.
@@ -34,7 +36,7 @@ public class SessionCache {
   private static final long SESSION_TIME_TO_LIVE = 24 * 60 * 60 * 1000L;
 
   // private CacheManager manager = CacheManager.create();
-  private Cache cache;
+  private Cache<String, Session> cache;
 
   /**
    * Constructor taking global props.
@@ -42,13 +44,12 @@ public class SessionCache {
    * @param props
    */
   public SessionCache(Props props) {
-    CacheManager manager = CacheManager.getInstance();
-
-    cache = manager.createCache();
-    cache.setEjectionPolicy(EjectionPolicy.LRU);
-    cache.setMaxCacheSize(props.getInt("max.num.sessions", MAX_NUM_SESSIONS));
-    cache.setExpiryTimeToLiveMs(props.getLong("session.time.to.live",
-        SESSION_TIME_TO_LIVE));
+    cache = CacheBuilder.newBuilder()
+        .maximumSize(props.getInt("max.num.sessions", MAX_NUM_SESSIONS))
+        .expireAfterAccess(
+            props.getLong("session.time.to.live", SESSION_TIME_TO_LIVE),
+            TimeUnit.MILLISECONDS)
+        .build();
   }
 
   /**
@@ -58,8 +59,7 @@ public class SessionCache {
    * @return
    */
   public Session getSession(String sessionId) {
-    Session elem = cache.<Session> get(sessionId);
-
+    Session elem = cache.getIfPresent(sessionId);
     return elem;
   }
 
@@ -79,7 +79,7 @@ public class SessionCache {
    * @param id
    * @return
    */
-  public boolean removeSession(String id) {
-    return cache.remove(id);
+  public void removeSession(String id) {
+    cache.invalidate(id);
   }
 }
diff --git a/azkaban-common/src/test/java/azkaban/executor/ExecutableFlowTest.java b/azkaban-common/src/test/java/azkaban/executor/ExecutableFlowTest.java
index 91a4290..c6400f8 100644
--- a/azkaban-common/src/test/java/azkaban/executor/ExecutableFlowTest.java
+++ b/azkaban-common/src/test/java/azkaban/executor/ExecutableFlowTest.java
@@ -28,13 +28,13 @@ import org.apache.log4j.Logger;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import azkaban.executor.ExecutionOptions.FailureAction;
 import azkaban.flow.Flow;
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.project.Project;
-import azkaban.utils.DirectoryFlowLoader;
+import azkaban.test.executions.TestExecutions;
 import azkaban.utils.JSONUtils;
 import azkaban.utils.Props;
 
@@ -47,7 +47,8 @@ public class ExecutableFlowTest {
 
     Logger logger = Logger.getLogger(this.getClass());
     DirectoryFlowLoader loader = new DirectoryFlowLoader(new Props(), logger);
-    loader.loadProjectFlow(project, new File("unit/executions/embedded"));
+
+    loader.loadProjectFlow(project, TestExecutions.getFlowDir("embedded"));
     Assert.assertEquals(0, loader.getErrors().size());
 
     project.setFlows(loader.getFlowMap());
@@ -58,7 +59,7 @@ public class ExecutableFlowTest {
   public void tearDown() throws Exception {
   }
 
-  @Ignore @Test
+  @Test
   public void testExecutorFlowCreation() throws Exception {
     Flow flow = project.getFlow("jobe");
     Assert.assertNotNull(flow);
@@ -96,7 +97,7 @@ public class ExecutableFlowTest {
     Assert.assertEquals(4, jobdFlow.getExecutableNodes().size());
   }
 
-  @Ignore @Test
+  @Test
   public void testExecutorFlowJson() throws Exception {
     Flow flow = project.getFlow("jobe");
     Assert.assertNotNull(flow);
@@ -114,7 +115,7 @@ public class ExecutableFlowTest {
     testEquals(exFlow, parsedExFlow);
   }
 
-  @Ignore @Test
+  @Test
   public void testExecutorFlowJson2() throws Exception {
     Flow flow = project.getFlow("jobe");
     Assert.assertNotNull(flow);
@@ -154,7 +155,7 @@ public class ExecutableFlowTest {
   }
 
   @SuppressWarnings("rawtypes")
-  @Ignore @Test
+  @Test
   public void testExecutorFlowUpdates() throws Exception {
     Flow flow = project.getFlow("jobe");
     ExecutableFlow exFlow = new ExecutableFlow(project, flow);
@@ -250,7 +251,7 @@ public class ExecutableFlowTest {
     }
   }
 
-  public static void testEquals(ExecutableNode a, ExecutableNode b) {
+  private static void testEquals(ExecutableNode a, ExecutableNode b) {
     if (a instanceof ExecutableFlow) {
       if (b instanceof ExecutableFlow) {
         ExecutableFlow exA = (ExecutableFlow) a;
@@ -304,7 +305,7 @@ public class ExecutableFlowTest {
     Assert.assertEquals(a.getOutNodes(), a.getOutNodes());
   }
 
-  public static void testEquals(ExecutionOptions optionsA,
+  private static void testEquals(ExecutionOptions optionsA,
       ExecutionOptions optionsB) {
     Assert.assertEquals(optionsA.getConcurrentOption(),
         optionsB.getConcurrentOption());
@@ -329,7 +330,7 @@ public class ExecutableFlowTest {
     testEquals(optionsA.getFlowParameters(), optionsB.getFlowParameters());
   }
 
-  public static void testEquals(Set<String> a, Set<String> b) {
+  private static void testEquals(Set<String> a, Set<String> b) {
     if (a == b) {
       return;
     }
@@ -348,7 +349,7 @@ public class ExecutableFlowTest {
     }
   }
 
-  public static void testEquals(List<String> a, List<String> b) {
+  private static void testEquals(List<String> a, List<String> b) {
     if (a == b) {
       return;
     }
@@ -370,7 +371,7 @@ public class ExecutableFlowTest {
   }
 
   @SuppressWarnings("unchecked")
-  public static void testDisabledEquals(List<Object> a, List<Object> b) {
+  private static void testDisabledEquals(List<Object> a, List<Object> b) {
     if (a == b) {
       return;
     }
@@ -401,7 +402,7 @@ public class ExecutableFlowTest {
     }
   }
 
-  public static void testEquals(Map<String, String> a, Map<String, String> b) {
+  private static void testEquals(Map<String, String> a, Map<String, String> b) {
     if (a == b) {
       return;
     }
diff --git a/azkaban-common/src/test/java/azkaban/executor/QueuedExecutionsTest.java b/azkaban-common/src/test/java/azkaban/executor/QueuedExecutionsTest.java
index 94bbd7e..b938b56 100644
--- a/azkaban-common/src/test/java/azkaban/executor/QueuedExecutionsTest.java
+++ b/azkaban-common/src/test/java/azkaban/executor/QueuedExecutionsTest.java
@@ -13,14 +13,12 @@ import azkaban.flow.Flow;
 import azkaban.project.Project;
 import azkaban.utils.JSONUtils;
 import azkaban.utils.Pair;
+import azkaban.utils.TestUtils;
 
 public class QueuedExecutionsTest {
-  /* Directory with serialized description of test flows */
-  private static final String UNIT_BASE_DIR =
-    "../azkaban-test/src/test/resources/executions/exectest1/";
 
   private File getFlowDir(String flow) {
-    return new File(UNIT_BASE_DIR + flow + ".flow");
+    return TestUtils.getFlowDir("exectest1", flow);
   }
 
   /*
@@ -205,4 +203,4 @@ public class QueuedExecutionsTest {
         queue.getReference(pair.getFirst().getExecId()));
     }
   }
-}
\ No newline at end of file
+}
diff --git a/azkaban-common/src/test/java/azkaban/utils/TestUtils.java b/azkaban-common/src/test/java/azkaban/utils/TestUtils.java
index 68b10ee..3eff490 100644
--- a/azkaban-common/src/test/java/azkaban/utils/TestUtils.java
+++ b/azkaban-common/src/test/java/azkaban/utils/TestUtils.java
@@ -33,7 +33,7 @@ import azkaban.user.XmlUserManager;
 public class TestUtils {
   /* Base  resource direcotyr for unit tests */
   private static final String UNIT_RESOURCE_DIR =
-      "../azkaban-test/src/test/resources";
+      "../azkaban-test/src/test/resources/azkaban/test";
   /* Directory with serialized description of test flows */
   private static final String UNIT_EXECUTION_DIR =
       UNIT_RESOURCE_DIR + "/executions";
diff --git a/azkaban-execserver/src/main/java/azkaban/execapp/ServerStatisticsServlet.java b/azkaban-execserver/src/main/java/azkaban/execapp/ServerStatisticsServlet.java
index e07eac5..17ba6e9 100644
--- a/azkaban-execserver/src/main/java/azkaban/execapp/ServerStatisticsServlet.java
+++ b/azkaban-execserver/src/main/java/azkaban/execapp/ServerStatisticsServlet.java
@@ -168,7 +168,7 @@ public class ServerStatisticsServlet extends HttpServlet {
         returnResult = Long.parseLong(result.split("\\s+")[1]);
         logger.debug(field + ":" + returnResult);
       } catch (NumberFormatException e) {
-        returnResult = 0l;
+        returnResult = 0L;
         logger.error(String.format("yielding 0 for %s as output is invalid - %s", field, result));
       }
     }
diff --git a/azkaban-execserver/src/package/bin/azkaban-executor-start.sh b/azkaban-execserver/src/package/bin/azkaban-executor-start.sh
index c281890..446571b 100755
--- a/azkaban-execserver/src/package/bin/azkaban-executor-start.sh
+++ b/azkaban-execserver/src/package/bin/azkaban-executor-start.sh
@@ -44,7 +44,7 @@ serverpath=`pwd`
 if [ -z $AZKABAN_OPTS ]; then
   AZKABAN_OPTS="-Xmx3G"
 fi
-AZKABAN_OPTS="$AZKABAN_OPTS -server -Dcom.sun.management.jmxremote -Djava.io.tmpdir=$tmpdir -Dexecutorport=$executorport -Dserverpath=$serverpath"
+AZKABAN_OPTS="$AZKABAN_OPTS -server -Dcom.sun.management.jmxremote -Djava.io.tmpdir=$tmpdir -Dexecutorport=$executorport -Dserverpath=$serverpath -Dlog4j.log.dir=$azkaban_dir/logs"
 
 java $AZKABAN_OPTS $JAVA_LIB_PATH -cp $CLASSPATH azkaban.execapp.AzkabanExecutorServer -conf $azkaban_dir/conf $@ &
 
diff --git a/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPipelineTest.java b/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPipelineTest.java
index 360d4f4..e29e973 100644
--- a/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPipelineTest.java
+++ b/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPipelineTest.java
@@ -43,11 +43,11 @@ import azkaban.executor.Status;
 import azkaban.flow.Flow;
 import azkaban.jobtype.JobTypeManager;
 import azkaban.jobtype.JobTypePluginSet;
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.project.Project;
 import azkaban.project.ProjectLoader;
 import azkaban.project.ProjectManagerException;
 import azkaban.project.MockProjectLoader;
-import azkaban.utils.DirectoryFlowLoader;
 import azkaban.utils.Props;
 
 /**
diff --git a/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPropertyResolutionTest.java b/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPropertyResolutionTest.java
index d5988bb..422f622 100644
--- a/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPropertyResolutionTest.java
+++ b/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerPropertyResolutionTest.java
@@ -39,11 +39,11 @@ import azkaban.executor.JavaJob;
 import azkaban.executor.MockExecutorLoader;
 import azkaban.flow.Flow;
 import azkaban.jobtype.JobTypeManager;
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.project.Project;
 import azkaban.project.ProjectLoader;
 import azkaban.project.ProjectManagerException;
 import azkaban.project.MockProjectLoader;
-import azkaban.utils.DirectoryFlowLoader;
 import azkaban.utils.Props;
 
 /**
diff --git a/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerTest2.java b/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerTest2.java
index c78abaa..84416de 100644
--- a/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerTest2.java
+++ b/azkaban-execserver/src/test/java/azkaban/execapp/FlowRunnerTest2.java
@@ -42,11 +42,11 @@ import azkaban.executor.Status;
 import azkaban.flow.Flow;
 import azkaban.jobtype.JobTypeManager;
 import azkaban.jobtype.JobTypePluginSet;
+import azkaban.project.DirectoryFlowLoader;
 import azkaban.project.Project;
 import azkaban.project.ProjectLoader;
 import azkaban.project.ProjectManagerException;
 import azkaban.project.MockProjectLoader;
-import azkaban.utils.DirectoryFlowLoader;
 import azkaban.utils.Props;
 
 /**
diff --git a/azkaban-test/src/test/java/azkaban/test/executions/TestExecutions.java b/azkaban-test/src/test/java/azkaban/test/executions/TestExecutions.java
new file mode 100644
index 0000000..56cf0c6
--- /dev/null
+++ b/azkaban-test/src/test/java/azkaban/test/executions/TestExecutions.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Azkaban Authors
+ *
+ * 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 azkaban.test.executions;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URISyntaxException;
+
+import org.junit.Assert;
+
+public class TestExecutions {
+  public static File getFlowDir(final String path) throws URISyntaxException {
+    URL url = TestExecutions.class.getResource(path);
+    Assert.assertNotNull(url);
+    return new File(url.toURI());
+  }
+}
diff --git a/azkaban-webserver/src/main/java/azkaban/webapp/AzkabanWebServer.java b/azkaban-webserver/src/main/java/azkaban/webapp/AzkabanWebServer.java
index b5b8d0e..89dea03 100644
--- a/azkaban-webserver/src/main/java/azkaban/webapp/AzkabanWebServer.java
+++ b/azkaban-webserver/src/main/java/azkaban/webapp/AzkabanWebServer.java
@@ -709,6 +709,13 @@ public class AzkabanWebServer extends AzkabanServer {
           .getString("jetty.trustpassword"));
       secureConnector.setHeaderBufferSize(MAX_HEADER_BUFFER_SIZE);
 
+      // set up vulnerable cipher suites to exclude
+      List<String> cipherSuitesToExclude = azkabanSettings.getStringList("jetty.excludeCipherSuites");
+      logger.info("Excluded Cipher Suites: " + String.valueOf(cipherSuitesToExclude));
+      if (cipherSuitesToExclude != null && !cipherSuitesToExclude.isEmpty()) {
+        secureConnector.setExcludeCipherSuites(cipherSuitesToExclude.toArray(new String[0]));
+      }
+
       server.addConnector(secureConnector);
     } else {
       ssl = false;
diff --git a/azkaban-webserver/src/package/bin/azkaban-web-start.sh b/azkaban-webserver/src/package/bin/azkaban-web-start.sh
index 744320a..f0cc3c8 100755
--- a/azkaban-webserver/src/package/bin/azkaban-web-start.sh
+++ b/azkaban-webserver/src/package/bin/azkaban-web-start.sh
@@ -43,7 +43,7 @@ serverpath=`pwd`
 if [ -z $AZKABAN_OPTS ]; then
   AZKABAN_OPTS="-Xmx4G"
 fi
-AZKABAN_OPTS="$AZKABAN_OPTS -server -Dcom.sun.management.jmxremote -Djava.io.tmpdir=$tmpdir -Dexecutorport=$executorport -Dserverpath=$serverpath"
+AZKABAN_OPTS="$AZKABAN_OPTS -server -Dcom.sun.management.jmxremote -Djava.io.tmpdir=$tmpdir -Dexecutorport=$executorport -Dserverpath=$serverpath -Dlog4j.log.dir=$azkaban_dir/logs"
 
 java $AZKABAN_OPTS $JAVA_LIB_PATH -cp $CLASSPATH azkaban.webapp.AzkabanWebServer -conf $azkaban_dir/conf $@ &
 
diff --git a/azkaban-webserver/src/package/conf/azkaban.properties b/azkaban-webserver/src/package/conf/azkaban.properties
index 609a917..a89a46a 100644
--- a/azkaban-webserver/src/package/conf/azkaban.properties
+++ b/azkaban-webserver/src/package/conf/azkaban.properties
@@ -34,6 +34,7 @@ jetty.password=password
 jetty.keypassword=password
 jetty.truststore=keystore
 jetty.trustpassword=password
+jetty.excludeCipherSuites=SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,SSL_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA
 
 # Azkaban Executor settings
 executor.port=12321

build.gradle 5(+5 -0)

diff --git a/build.gradle b/build.gradle
index d19ad19..914f014 100644
--- a/build.gradle
+++ b/build.gradle
@@ -127,6 +127,7 @@ project(':azkaban-common') {
     compile('org.mortbay.jetty:jetty-util:6.1.26')
     compile('org.slf4j:slf4j-api:1.6.1')
 
+    testCompile(project(':azkaban-test').sourceSets.test.output)
     testCompile('junit:junit:4.11')
     testCompile('org.hamcrest:hamcrest-all:1.3')
   }
@@ -429,6 +430,10 @@ project(':azkaban-sql') {
 project(':azkaban-test') {
   apply plugin: 'distribution'
 
+  dependencies {
+    testCompile('junit:junit:4.11')
+  }
+
   distributions {
     animal {
       baseName = 'test-animal'