diff --git a/conf/example/Application.xml b/conf/example/Application.xml
index 728b42e..3ca9e6e 100755
--- a/conf/example/Application.xml
+++ b/conf/example/Application.xml
@@ -226,6 +226,16 @@
2
Integer
+
+ HONEYBADGER_API_KEY
+ zyx987
+ String
+
+
+ ENV
+ example-environment
+ String
+
diff --git a/src/edu/stanford/dlss/wowza/SulEnvironment.java b/src/edu/stanford/dlss/wowza/SulEnvironment.java
deleted file mode 100644
index 13123cc..0000000
--- a/src/edu/stanford/dlss/wowza/SulEnvironment.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package edu.stanford.dlss.wowza;
-
-public class SulEnvironment
-{
- public String getEnvironmentVariable(String var)
- {
- return System.getenv(var);
- }
-}
diff --git a/src/edu/stanford/dlss/wowza/SulWowza.java b/src/edu/stanford/dlss/wowza/SulWowza.java
index f736247..98dd1ea 100644
--- a/src/edu/stanford/dlss/wowza/SulWowza.java
+++ b/src/edu/stanford/dlss/wowza/SulWowza.java
@@ -34,33 +34,20 @@ public class SulWowza extends ModuleBase
{
static String stacksTokenVerificationBaseUrl;
static String stacksUrlErrorMsg = "rejecting due to invalid stacksURL property (" + stacksTokenVerificationBaseUrl + ")";
- static final String HONEYBADGER_API_KEY_ENV_VAR = "WOWZA_HONEYBADGER_API_KEY";
- static final String HONEYBADGER_ENV_NAME_ENV_VAR = "WOWZA_HONEYBADGER_ENV";
static int stacksConnectionTimeout;
static int stacksReadTimeout;
static NoticeReporter noticeReporter;
StandardConfigContext honeybadgerConfig;
- SulEnvironment environment;
/** configuration is invalid if the stacks url is malformed */
boolean invalidConfiguration = false;
- public SulWowza()
- {}
-
- public SulWowza(SulEnvironment se)
- {
- environment = se;
- }
-
/** invoked when a Wowza application instance is started;
* defined in the IModuleOnApp interface */
public void onAppStart(IApplicationInstance appInstance)
{
- initHoneybadger();
- registerUncaughtExceptionHandler();
- initNoticeReporter();
+ initHoneybadger(appInstance);
setStacksConnectionTimeout(appInstance);
setStacksReadTimeout(appInstance);
stacksTokenVerificationBaseUrl = getStacksUrl(appInstance);
@@ -147,34 +134,70 @@ public void play(IClient client, RequestFunction function, AMFDataList params)
}
}
+ public void setHoneybadgerConfigContext(StandardConfigContext configContext)
+ {
+ honeybadgerConfig = configContext;
+ }
+
+ // TODO: this approach expects the properties to be set in Application.xml
+ // maybe that's good, or maybe we want to load a java properties file from our plugin jar itself?
+ //
+ // TL;DR: Application.xml should contain the API key and the instance environment (e.g. stage, prod),
+ // in its section. the property names should be "HONEYBADGER_API_KEY" and "ENV", respective.
+ // see conf/example/Application.xml.
+ public void initDefaultHoneybadgerConfigContext(IApplicationInstance appInstance)
+ {
+ // this is maybe too much background for here and should prob go in a readme or devops doc, but for now...
+ // the StandardConfigContext constructor first initializes the instance with a DefaultsConfigContext
+ // by way of a super() call to its parent class constructor (BaseChainedConfigContext). that sets
+ // the honeybadger API URL. the StandardConfigContext constructor can also take a map of properties,
+ // from which it will override default property values based on expected field names. in particular,
+ // it'll look for the environment name first in the "ENV" field, then in the "JAVA_ENV" field. it'll
+ // look for the API key in the "HONEYBADGER_API_KEY" field, then in the "honeybadger.api_key"* field.
+ // since IApplicationInstance.getProperties() returns a subclass of Map (WMSProperties) containing properties
+ // set in Application.xml, we can just set the property names we care about in Application.xml and they'll get
+ // picked up automatically.
+ //
+ // see also:
+ // https://github.com/honeybadger-io/honeybadger-java#advanced-configuration
+ // https://github.com/honeybadger-io/honeybadger-java/blob/1.1.0/src/main/java/io/honeybadger/reporter/config/DefaultsConfigContext.java
+ // https://github.com/honeybadger-io/honeybadger-java/blob/1.1.0/src/main/java/io/honeybadger/reporter/config/BaseChainedConfigContext.java
+ // https://github.com/honeybadger-io/honeybadger-java/blob/1.1.0/src/main/java/io/honeybadger/reporter/config/StandardConfigContext.java
+ // https://github.com/honeybadger-io/honeybadger-java/blob/1.1.0/src/main/java/io/honeybadger/reporter/config/MapConfigContext.java
+ // http://www.wowza.com/resources/serverapi/com/wowza/wms/application/IApplicationInstance.html#getProperties()
+ // http://www.wowza.com/resources/serverapi/com/wowza/wms/application/WMSProperties.html
+ //
+ // * note: i suspect we shouldn't use "honeybadger.api_key", because it appears that
+ // MapConfigContext.getHoneybadgerUrl() erroneously looks there first for the URL, so we
+ // should avoid confusing it, to be safe:
+ // https://github.com/honeybadger-io/honeybadger-java/blob/1.1.0/src/main/java/io/honeybadger/reporter/config/MapConfigContext.java#L113
+ setHoneybadgerConfigContext(new StandardConfigContext(appInstance.getProperties()));
+ }
+
/**
* Initalizes the Honeybadger error reporting tool. This is a public method so we can call
* it from the tests. It's outside the constructor, since testing constructors with Mockito is a pain.
*/
- public void initHoneybadger()
+ public void initHoneybadger(IApplicationInstance appInstance)
{
- if(environment == null)
- environment = new SulEnvironment();
+ initDefaultHoneybadgerConfigContext(appInstance);
- String apiKey = environment.getEnvironmentVariable(HONEYBADGER_API_KEY_ENV_VAR);
- String honeybadgerEnv = environment.getEnvironmentVariable(HONEYBADGER_ENV_NAME_ENV_VAR);
- if(apiKey == null)
+ if (honeybadgerConfig.getApiKey() == null)
{
- getLogger().error(this.getClass().getSimpleName() + " unable to set up Honeybadger error reporting (missing API key environment variable?)");
+ getLogger().error(this.getClass().getSimpleName() + " unable to set up Honeybadger error reporting (missing API key property in Application.xml?)");
invalidConfiguration = true;
}
- else if (honeybadgerEnv == null)
+ else if (honeybadgerConfig.getEnvironment() == null)
{
- getLogger().error(this.getClass().getSimpleName() + " unable to set up Honeybadger error reporting (missing Honeybadger environment specification?)");
+ getLogger().error(this.getClass().getSimpleName() + " unable to set up Honeybadger error reporting (missing Honeybadger environment property in Application.xml?)");
invalidConfiguration = true;
}
- else
- {
- honeybadgerConfig = new StandardConfigContext();
- honeybadgerConfig.setApiKey(apiKey)
- .setEnvironment(honeybadgerEnv)
- .setApplicationPackage(this.getClass().getPackage().getName());
- }
+
+ if (invalidConfiguration)
+ return;
+
+ honeybadgerConfig.setApplicationPackage(this.getClass().getPackage().getName());
+ registerUncaughtExceptionHandler();
}
@@ -568,9 +591,14 @@ void registerUncaughtExceptionHandler()
HoneybadgerUncaughtExceptionHandler.registerAsUncaughtExceptionHandler(honeybadgerConfig);
}
+ void setNoticeReporter(NoticeReporter noticeReporter)
+ {
+ this.noticeReporter = noticeReporter;
+ }
+
void initNoticeReporter()
{
- noticeReporter = new HoneybadgerReporter(honeybadgerConfig);
+ setNoticeReporter(new HoneybadgerReporter(honeybadgerConfig));
}
NoticeReporter getNoticeReporter()
diff --git a/test/edu/stanford/dlss/wowza/TestParsingFromRequestInfo.java b/test/edu/stanford/dlss/wowza/TestParsingFromRequestInfo.java
index 56084f2..c0fcb01 100644
--- a/test/edu/stanford/dlss/wowza/TestParsingFromRequestInfo.java
+++ b/test/edu/stanford/dlss/wowza/TestParsingFromRequestInfo.java
@@ -17,7 +17,6 @@ public class TestParsingFromRequestInfo
public void setUp()
{
testModule = new SulWowza();
- testModule.initHoneybadger();
}
@Test
diff --git a/test/edu/stanford/dlss/wowza/TestSulWowza.java b/test/edu/stanford/dlss/wowza/TestSulWowza.java
index 8679ff8..8a66769 100644
--- a/test/edu/stanford/dlss/wowza/TestSulWowza.java
+++ b/test/edu/stanford/dlss/wowza/TestSulWowza.java
@@ -8,7 +8,10 @@
import org.apache.log4j.*;
+import io.honeybadger.reporter.NoticeReporter;
+import io.honeybadger.reporter.HoneybadgerReporter;
import io.honeybadger.reporter.HoneybadgerUncaughtExceptionHandler;
+import io.honeybadger.reporter.config.StandardConfigContext;
import com.wowza.wms.amf.AMFDataList;
import com.wowza.wms.application.ApplicationInstance;
@@ -22,12 +25,16 @@
import java.io.ByteArrayOutputStream;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
public class TestSulWowza
{
SulWowza testModule;
+ NoticeReporter mockNoticeReporter;
+
final static String stacksToken = "encryptedStacksMediaToken";
final static String queryStr = "stacks_token=" + stacksToken;
@@ -35,7 +42,8 @@ public class TestSulWowza
public void setUp()
{
testModule = new SulWowza();
- testModule.initHoneybadger();
+ mockNoticeReporter = mock(HoneybadgerReporter.class);
+ testModule.setNoticeReporter(mockNoticeReporter);
}
@Test
@@ -43,8 +51,9 @@ public void onAppStart_calls_setStacksConnectionTimeout()
{
SulWowza spyModule = spy(testModule);
IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
- spyModule.onAppStart(appInstanceMock);
+ doNothing().when(spyModule).initHoneybadger(appInstanceMock);
+ spyModule.onAppStart(appInstanceMock);
verify(spyModule).setStacksConnectionTimeout(appInstanceMock);
}
@@ -53,8 +62,9 @@ public void onAppStart_calls_setStacksReadTimeout()
{
SulWowza spyModule = spy(testModule);
IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
- spyModule.onAppStart(appInstanceMock);
+ doNothing().when(spyModule).initHoneybadger(appInstanceMock);
+ spyModule.onAppStart(appInstanceMock);
verify(spyModule).setStacksReadTimeout(appInstanceMock);
}
@@ -63,8 +73,9 @@ public void onAppStart_calls_getStacksUrl()
{
SulWowza spyModule = spy(testModule);
IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
- spyModule.onAppStart(appInstanceMock);
+ doNothing().when(spyModule).initHoneybadger(appInstanceMock);
+ spyModule.onAppStart(appInstanceMock);
verify(spyModule).getStacksUrl(appInstanceMock);
}
@@ -180,12 +191,38 @@ public void onAppStart_badUrl_callsHoneybadger()
}
@Test
- public void onAppStart_setsUpUncaughtExceptionHandler()
+ public void initHoneybadger_setsApplicationPackage()
+ {
+ SulWowza spyModule = spy(testModule);
+ IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
+
+ StandardConfigContext spyHoneybadgerConfig = spy(new StandardConfigContext());
+ doReturn("zyx987").when(spyHoneybadgerConfig).getApiKey();
+ doReturn("unit_test_env").when(spyHoneybadgerConfig).getEnvironment();
+
+ spyModule.setHoneybadgerConfigContext(spyHoneybadgerConfig);
+ doNothing().when(spyModule).initDefaultHoneybadgerConfigContext(appInstanceMock);
+ doNothing().when(spyModule).registerUncaughtExceptionHandler();
+
+ spyModule.initHoneybadger(appInstanceMock);
+ verify(spyHoneybadgerConfig).setApplicationPackage(spyModule.getClass().getPackage().getName());
+ }
+
+ @Test
+ public void initHoneybadger_setsUpUncaughtExceptionHandler()
{
SulWowza spyModule = spy(testModule);
IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
- spyModule.onAppStart(appInstanceMock);
+ StandardConfigContext mockHoneybadgerConfig = mock(StandardConfigContext.class);
+ doReturn("zyx987").when(mockHoneybadgerConfig).getApiKey();
+ doReturn("unit_test_env").when(mockHoneybadgerConfig).getEnvironment();
+
+ spyModule.setHoneybadgerConfigContext(mockHoneybadgerConfig);
+ doNothing().when(spyModule).initDefaultHoneybadgerConfigContext(appInstanceMock);
+ doNothing().when(spyModule).registerUncaughtExceptionHandler();
+
+ spyModule.initHoneybadger(appInstanceMock);
verify(spyModule).registerUncaughtExceptionHandler();
}
@@ -194,52 +231,79 @@ public void onAppStart_initializesHoneybadger()
{
SulWowza spyModule = spy(testModule);
IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
- spyModule.onAppStart(appInstanceMock);
+ doNothing().when(spyModule).initHoneybadger(appInstanceMock);
- verify(spyModule).initHoneybadger();
+ spyModule.onAppStart(appInstanceMock);
+ verify(spyModule).initHoneybadger(appInstanceMock);
}
@Test
public void initHoneybadger_failsWithoutAPIKey()
{
- SulEnvironment mockSystem = mock(SulEnvironment.class);
- when(mockSystem.getEnvironmentVariable(SulWowza.HONEYBADGER_API_KEY_ENV_VAR)).thenReturn(null);
- when(mockSystem.getEnvironmentVariable(SulWowza.HONEYBADGER_ENV_NAME_ENV_VAR)).thenReturn("test_env");
+ StandardConfigContext mockHoneybadgerConfig = mock(StandardConfigContext.class);
+ doReturn(null).when(mockHoneybadgerConfig).getApiKey();
+ doReturn("unit_test_env").when(mockHoneybadgerConfig).getEnvironment();
- SulWowza localTestModule = new SulWowza(mockSystem);
- localTestModule.initHoneybadger();
- assertTrue(localTestModule.invalidConfiguration);
+ SulWowza spyModule = spy(testModule);
+ IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
+ spyModule.setHoneybadgerConfigContext(mockHoneybadgerConfig);
+ doNothing().when(spyModule).initDefaultHoneybadgerConfigContext(appInstanceMock);
+ doNothing().when(spyModule).registerUncaughtExceptionHandler();
+
+ spyModule.initHoneybadger(appInstanceMock);
+ assertTrue(spyModule.invalidConfiguration);
}
@Test
public void initHoneybadger_failsWithoutHoneybadgerEnv()
{
- SulEnvironment mockSystem = mock(SulEnvironment.class);
- when(mockSystem.getEnvironmentVariable(SulWowza.HONEYBADGER_API_KEY_ENV_VAR)).thenReturn("abcd");
- when(mockSystem.getEnvironmentVariable(SulWowza.HONEYBADGER_ENV_NAME_ENV_VAR)).thenReturn(null);
+ StandardConfigContext mockHoneybadgerConfig = mock(StandardConfigContext.class);
+ doReturn("zyx987").when(mockHoneybadgerConfig).getApiKey();
+ doReturn(null).when(mockHoneybadgerConfig).getEnvironment();
- SulWowza localTestModule = new SulWowza(mockSystem);
- localTestModule.initHoneybadger();
- assertTrue(localTestModule.invalidConfiguration);
+ SulWowza spyModule = spy(testModule);
+ IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
+ spyModule.setHoneybadgerConfigContext(mockHoneybadgerConfig);
+ doNothing().when(spyModule).initDefaultHoneybadgerConfigContext(appInstanceMock);
+ doNothing().when(spyModule).registerUncaughtExceptionHandler();
+
+ spyModule.initHoneybadger(appInstanceMock);
+ assertTrue(spyModule.invalidConfiguration);
}
@Test
public void initHoneybadger_succeedsWithAPIKeyAndHoneybadgerEnv()
{
- SulEnvironment mockSystem = mock(SulEnvironment.class);
- when(mockSystem.getEnvironmentVariable(SulWowza.HONEYBADGER_API_KEY_ENV_VAR)).thenReturn("abcd");
- when(mockSystem.getEnvironmentVariable(SulWowza.HONEYBADGER_ENV_NAME_ENV_VAR)).thenReturn("test_env");
+ StandardConfigContext mockHoneybadgerConfig = mock(StandardConfigContext.class);
+ doReturn("zyx987").when(mockHoneybadgerConfig).getApiKey();
+ doReturn("unit_test_env").when(mockHoneybadgerConfig).getEnvironment();
+
+ SulWowza spyModule = spy(testModule);
+ IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
+ spyModule.setHoneybadgerConfigContext(mockHoneybadgerConfig);
+ doNothing().when(spyModule).initDefaultHoneybadgerConfigContext(appInstanceMock);
+ doNothing().when(spyModule).registerUncaughtExceptionHandler();
- SulWowza localTestModule = new SulWowza(mockSystem);
- localTestModule.initHoneybadger();
- assertFalse(localTestModule.invalidConfiguration);
+ spyModule.initHoneybadger(appInstanceMock);
+ assertFalse(spyModule.invalidConfiguration);
}
@Test
- public void registerUncaughtExceptionHandler_registersHoneybadger()
+ public void registerUncaughtExceptionHandler_registersHoneybadger() throws URISyntaxException
{
- testModule.registerUncaughtExceptionHandler();
+ StandardConfigContext mockHoneybadgerConfig = mock(StandardConfigContext.class);
+ doReturn("zyx987").when(mockHoneybadgerConfig).getApiKey();
+ doReturn("unit_test_env").when(mockHoneybadgerConfig).getEnvironment();
+ doReturn(new URI("https://honey.badger")).when(mockHoneybadgerConfig).getHoneybadgerUrl();
+
+ SulWowza spyModule = spy(testModule);
+ IApplicationInstance appInstanceMock = mock(IApplicationInstance.class);
+ spyModule.setHoneybadgerConfigContext(mockHoneybadgerConfig);
+ doNothing().when(spyModule).initDefaultHoneybadgerConfigContext(appInstanceMock);
+
+ spyModule.initHoneybadger(appInstanceMock);
+ spyModule.registerUncaughtExceptionHandler();
HoneybadgerUncaughtExceptionHandler curThreadUncaughtExceptionHandler =
(HoneybadgerUncaughtExceptionHandler) (Thread.getDefaultUncaughtExceptionHandler());
@@ -525,7 +589,7 @@ public void authorizeSession_acceptsIfAuthorized()
when(sessionMock.getQueryStr()).thenReturn(queryStr);
when(sessionMock.getStreamName()).thenReturn(streamName);
SulWowza spyModule = spy(testModule);
- when(spyModule.verifyStacksToken(stacksToken, druid, filename, userIp)).thenReturn(true);
+ doReturn(true).when(spyModule).verifyStacksToken(stacksToken, druid, filename, userIp);
spyModule.authorizeSession(sessionMock);
verify(sessionMock).acceptSession();
@@ -545,7 +609,7 @@ public void authorizeSession_rejectsIfNotAuthorized()
when(sessionMock.getQueryStr()).thenReturn(queryStr);
when(sessionMock.getStreamName()).thenReturn(streamName);
SulWowza spyModule = spy(testModule);
- when(spyModule.verifyStacksToken(stacksToken, druid, filename, userIp)).thenReturn(false);
+ doReturn(false).when(spyModule).verifyStacksToken(stacksToken, druid, filename, userIp);
spyModule.authorizeSession(sessionMock);
verify(sessionMock).rejectSession();
@@ -702,7 +766,7 @@ public void authorizePlay_trueIfAuthorized()
when(spyModule.validateStreamName(streamName)).thenReturn(true);
when(spyModule.getDruid(streamName)).thenReturn(druid);
when(spyModule.getFilename(streamName)).thenReturn(filename);
- when(spyModule.verifyStacksToken(token, druid, filename, userIp)).thenReturn(true);
+ doReturn(true).when(spyModule).verifyStacksToken(token, druid, filename, userIp);
assertEquals(true, spyModule.authorizePlay(queryString, userIp, streamName));
}
@@ -724,7 +788,7 @@ public void authorizePlay_falseIfNotAuthorized()
when(spyModule.validateStreamName(streamName)).thenReturn(true);
when(spyModule.getDruid(streamName)).thenReturn(druid);
when(spyModule.getFilename(streamName)).thenReturn(filename);
- when(spyModule.verifyStacksToken(token, druid, filename, userIp)).thenReturn(false);
+ doReturn(false).when(spyModule).verifyStacksToken(token, druid, filename, userIp);
assertEquals(false, spyModule.authorizePlay(queryString, userIp, streamName));
}
@@ -739,7 +803,7 @@ public void authorizePlay_validatesStacksToken()
SulWowza spyModule = spy(testModule);
when(spyModule.getStacksToken(queryString)).thenReturn(token);
- when(spyModule.validateUserIp("1")).thenReturn(true);
+ doReturn(true).when(spyModule).validateUserIp("1");
spyModule.authorizePlay(queryString, userIp, streamName);
verify(spyModule).validateStacksToken(token);
diff --git a/test/edu/stanford/dlss/wowza/TestValidationMethods.java b/test/edu/stanford/dlss/wowza/TestValidationMethods.java
index a531de5..216ab7a 100644
--- a/test/edu/stanford/dlss/wowza/TestValidationMethods.java
+++ b/test/edu/stanford/dlss/wowza/TestValidationMethods.java
@@ -17,7 +17,6 @@ public class TestValidationMethods
public void setUp()
{
testModule = new SulWowza();
- testModule.initHoneybadger();
}
@Test
diff --git a/test/edu/stanford/dlss/wowza/TestVerifyStacksToken.java b/test/edu/stanford/dlss/wowza/TestVerifyStacksToken.java
index 334042f..b0f84ed 100644
--- a/test/edu/stanford/dlss/wowza/TestVerifyStacksToken.java
+++ b/test/edu/stanford/dlss/wowza/TestVerifyStacksToken.java
@@ -26,7 +26,6 @@ public class TestVerifyStacksToken
public void setUp()
{
testModule = new SulWowza();
- testModule.initHoneybadger();
}
@Test