Details
diff --git a/az-core/src/main/java/azkaban/Constants.java b/az-core/src/main/java/azkaban/Constants.java
index 820b041..9497ffe 100644
--- a/az-core/src/main/java/azkaban/Constants.java
+++ b/az-core/src/main/java/azkaban/Constants.java
@@ -205,6 +205,8 @@ public class Constants {
public static final String EXECUTOR_SELECTOR_COMPARATOR_PREFIX =
"azkaban.executorselector.comparator.";
public static final String QUEUEPROCESSING_ENABLED = "azkaban.queueprocessing.enabled";
+
+ public static final String SESSION_TIME_TO_LIVE = "session.time.to.live";
}
public static class FlowProperties {
diff --git a/az-core/src/main/java/azkaban/utils/Props.java b/az-core/src/main/java/azkaban/utils/Props.java
index 9ee0869..1b6c433 100644
--- a/az-core/src/main/java/azkaban/utils/Props.java
+++ b/az-core/src/main/java/azkaban/utils/Props.java
@@ -39,7 +39,7 @@ import java.util.TreeMap;
import org.apache.log4j.Logger;
/**
- * Hashmap implementation of a hierarchitical properties with helpful converter functions and
+ * Hashmap implementation of a hierarchical properties with helpful converter functions and
* Exception throwing. This class is not threadsafe.
*/
public class Props {
diff --git a/az-core/src/main/java/azkaban/utils/PropsUtils.java b/az-core/src/main/java/azkaban/utils/PropsUtils.java
index 6784f40..5caa30b 100644
--- a/az-core/src/main/java/azkaban/utils/PropsUtils.java
+++ b/az-core/src/main/java/azkaban/utils/PropsUtils.java
@@ -142,7 +142,7 @@ public class PropsUtils {
return false;
}
- public static boolean isVarialbeReplacementPattern(final String str) {
+ public static boolean isVariableReplacementPattern(final String str) {
final Matcher matcher = VARIABLE_REPLACEMENT_PATTERN.matcher(str);
return matcher.matches();
}
diff --git a/azkaban-common/src/main/java/azkaban/project/FlowLoaderUtils.java b/azkaban-common/src/main/java/azkaban/project/FlowLoaderUtils.java
index 1fa4ac3..eee2df3 100644
--- a/azkaban-common/src/main/java/azkaban/project/FlowLoaderUtils.java
+++ b/azkaban-common/src/main/java/azkaban/project/FlowLoaderUtils.java
@@ -263,14 +263,14 @@ public class FlowLoaderUtils {
for (final String jobName : jobPropsMap.keySet()) {
final Props jobProps = jobPropsMap.get(jobName);
final String xms = jobProps.getString(XMS, null);
- if (xms != null && !PropsUtils.isVarialbeReplacementPattern(xms)
+ if (xms != null && !PropsUtils.isVariableReplacementPattern(xms)
&& Utils.parseMemString(xms) > sizeMaxXms) {
errors.add(String.format(
"%s: Xms value has exceeded the allowed limit (max Xms = %s)",
jobName, maxXms));
}
final String xmx = jobProps.getString(XMX, null);
- if (xmx != null && !PropsUtils.isVarialbeReplacementPattern(xmx)
+ if (xmx != null && !PropsUtils.isVariableReplacementPattern(xmx)
&& Utils.parseMemString(xmx) > sizeMaxXmx) {
errors.add(String.format(
"%s: Xmx value has exceeded the allowed limit (max Xmx = %s)",
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 505a59d..49303ca 100644
--- a/azkaban-common/src/main/java/azkaban/server/session/SessionCache.java
+++ b/azkaban-common/src/main/java/azkaban/server/session/SessionCache.java
@@ -16,6 +16,7 @@
package azkaban.server.session;
+import azkaban.Constants.ConfigurationKeys;
import azkaban.utils.Props;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@@ -25,28 +26,32 @@ import java.util.concurrent.TimeUnit;
/**
* Cache for web session.
*
- * The following global azkaban properties can be used: max.num.sessions - used to determine the
- * number of live sessions that azkaban will handle. Default is 10000 session.time.to.live -Number
- * of seconds before session expires. Default set to 10 hours.
+ * The following global Azkaban properties are used:
+ * <ul>
+ * <li>{@code max.num.sessions} - number of live sessions that Azkaban handles, default is 10000
+ * <li>{@code session.time.to.live} - number of milliseconds before the session expires,
+ * default 36000000 ms, i.e. 10 hours.
+ * </ul>
*/
public class SessionCache {
private static final int MAX_NUM_SESSIONS = 10000;
- private static final long SESSION_TIME_TO_LIVE = 10 * 60 * 60 * 1000L;
+ private static final long DEFAULT_SESSION_TIME_TO_LIVE = 10 * 60 * 60 * 1000L; // 10 hours
- // private CacheManager manager = CacheManager.create();
private final Cache<String, Session> cache;
+ private final long effectiveSessionTimeToLive;
+
/**
* Constructor taking global props.
*/
@Inject
public SessionCache(final Props props) {
+ this.effectiveSessionTimeToLive = props.getLong(ConfigurationKeys.SESSION_TIME_TO_LIVE,
+ DEFAULT_SESSION_TIME_TO_LIVE);
this.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)
+ .expireAfterAccess(effectiveSessionTimeToLive, TimeUnit.MILLISECONDS)
.build();
}
@@ -58,6 +63,10 @@ public class SessionCache {
return elem;
}
+ public long getEffectiveSessionTimeToLive() {
+ return effectiveSessionTimeToLive;
+ }
+
/**
* Adds a session to the cache. Accessible through the session ID.
*/
diff --git a/azkaban-common/src/test/java/azkaban/server/session/SessionCacheTest.java b/azkaban-common/src/test/java/azkaban/server/session/SessionCacheTest.java
new file mode 100644
index 0000000..f205be3
--- /dev/null
+++ b/azkaban-common/src/test/java/azkaban/server/session/SessionCacheTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 LinkedIn Corp.
+ *
+ * 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.server.session;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import azkaban.user.User;
+import azkaban.utils.Props;
+import azkaban.utils.PropsUtils;
+import org.junit.Test;
+
+public final class SessionCacheTest {
+
+ final String propsString = "{ \"session.time.to.live\": \"100\" }";
+
+ SessionCache freshSessionCache() throws Exception {
+ final Props props = PropsUtils.fromJSONString(propsString);
+ return new SessionCache(props);
+ }
+
+ @Test
+ public void SessionCacheHit() throws Exception {
+ final SessionCache sessionCache = freshSessionCache();
+ final Session session = new Session("TEST_SESSION_ID", new User("TEST_USER_HIT"),
+ "123.12.12.123");
+ sessionCache.addSession(session);
+ assertThat(sessionCache.getSession("TEST_SESSION_ID")).isEqualTo(session);
+ }
+
+ @Test
+ public void SessionCacheMiss() throws Exception {
+ final SessionCache sessionCache = freshSessionCache();
+ final Session session = new Session("TEST_SESSION_ID", new User("TEST_USER_MISS"),
+ "123.12.12.123");
+ sessionCache.addSession(session);
+ Thread.sleep(200L);
+ assertThat(sessionCache.getSession("TEST_SESSION_ID")).isNull();
+ }
+
+}