Skip to content

Commit

Permalink
Merge pull request #6156 from ant-media/fix/appCreation
Browse files Browse the repository at this point in the history
Handle exception in App Creation
  • Loading branch information
mekya authored Mar 5, 2024
2 parents b792079 + 583a755 commit 4479da2
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 30 deletions.
3 changes: 1 addition & 2 deletions src/main/java/io/antmedia/AppSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -1535,8 +1535,7 @@ public class AppSettings implements Serializable{
private String rtspPullTransportType = "3";

/**
* Specify the rtsp transport type in pulling IP Camera or RTSP sources
* It can be tcp or udp
* Specify the rtspTimeoutDurationMs in pulling IP Camera or RTSP sources
*/
@Value("${rtspTimeoutDurationMs:${" + SETTINGS_RTSP_TIMEOUT_DURATION_MS+ ":5000}}")
private int rtspTimeoutDurationMs = 5000;
Expand Down
59 changes: 31 additions & 28 deletions src/main/java/org/red5/server/tomcat/TomcatLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -576,33 +576,36 @@ public boolean startWebApplication(String applicationName) throws ServletExcepti
boolean result = false;
//get a reference to the current threads classloader
final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
log.debug("Webapp root: {}", webappFolder);
if (webappFolder == null) {
// Use default webapps directory
webappFolder = System.getProperty("red5.root") + "/webapps";
}
System.setProperty("red5.webapp.root", webappFolder);
log.info("Application root: {}", webappFolder);
// application directory
String contextName = '/' + applicationName;
Container ctx = null;
// Root applications directory
File appDirBase = new File(webappFolder);
// check if the context already exists for the host
if ((ctx = host.findChild(contextName)) == null) {
log.debug("Context did not exist in host");
String webappContextDir = FileUtil.formatPath(appDirBase.getAbsolutePath(), applicationName);
log.debug("Webapp context directory (full path): {}", webappContextDir);
// set the newly created context as the current container
ctx = addContext(contextName, webappContextDir);
} else {
log.debug("Context already exists in host");
}
final ServletContext servletContext = ((Context) ctx).getServletContext();
log.debug("Context initialized: {}", servletContext.getContextPath());
String prefix = servletContext.getRealPath("/");
log.debug("Path: {}", prefix);

try {
log.debug("Webapp root: {}", webappFolder);
if (webappFolder == null) {
// Use default webapps directory
webappFolder = System.getProperty("red5.root") + "/webapps";
}
System.setProperty("red5.webapp.root", webappFolder);
log.info("Application root: {}", webappFolder);
// application directory
String contextName = '/' + applicationName;
Container ctx = null;
// Root applications directory
File appDirBase = new File(webappFolder);
// check if the context already exists for the host
if ((ctx = host.findChild(contextName)) == null) {
log.debug("Context did not exist in host");
String webappContextDir = FileUtil.formatPath(appDirBase.getAbsolutePath(), applicationName);
log.debug("Webapp context directory (full path): {}", webappContextDir);
// set the newly created context as the current container
ctx = addContext(contextName, webappContextDir);
} else {
log.debug("Context already exists in host");
}
final ServletContext servletContext = ((Context) ctx).getServletContext();
log.debug("Context initialized: {}", servletContext.getContextPath());
String prefix = servletContext.getRealPath("/");

log.debug("Path: {}", prefix);

Loader cldr = ((Context) ctx).getLoader();
log.debug("Loader delegate: {} type: {}", cldr.getDelegate(), cldr.getClass().getName());
if (cldr instanceof WebappLoader) {
Expand Down Expand Up @@ -661,7 +664,7 @@ public void run() {
}
}
}

// add the servlet context
appctx.setServletContext(servletContext);
// set the root webapp ctx attr on the each servlet context so spring can find it later
Expand All @@ -675,7 +678,7 @@ public void run() {
thread.start();
result = true;
} catch (Throwable t) {
log.error("Error setting up context: {} due to: {}", servletContext.getContextPath(), t.getMessage());
log.error("Error setting up context: {} due to: {}", applicationName, t.getMessage());
log.error(ExceptionUtils.getStackTrace(t));
} finally {
//reset the classloader
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/io/antmedia/test/StreamSchedularUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,7 @@ public void testBandwidth() {

boolean deleteHLSFilesOnExit = getAppSettings().isDeleteHLSFilesOnEnded();
getAppSettings().setDeleteHLSFilesOnEnded(false);
getAppSettings().setRtspTimeoutDurationMs(15000);

File f = new File("target/test.db");
if (f.exists()) {
Expand Down Expand Up @@ -1135,6 +1136,8 @@ public void testBandwidth() {
Application.enableSourceHealthUpdate = false;

getAppSettings().setDeleteHLSFilesOnEnded(deleteHLSFilesOnExit);
getAppSettings().setRtspTimeoutDurationMs(5000);


stopCameraEmulator();

Expand Down
51 changes: 51 additions & 0 deletions src/test/java/org/red5/server/tomcat/TomcatLoaderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.red5.server.tomcat;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.*;

public class TomcatLoaderTest {

/**
* This Test checks handling of parse exception while creation
* Previously if there is a parse exception while creating tomcat, it was not handled
* and it cannot create any application after that exception
*/
@Test
public void testHandleParseException() {
TomcatLoader tomcatLoader = spy(new TomcatLoader());
Host host = mock(Host.class);
when(host.getName()).thenReturn("localhost");

Context context = mock(Context.class);
try {
doReturn(context).when(tomcatLoader).addContext(any(), any());
} catch (ServletException e) {
throw new RuntimeException(e);
}

ServletContext servletContext = mock(ServletContext.class);
when(context.getServletContext()).thenReturn(servletContext);

when(servletContext.getRealPath("/")).thenThrow(new IllegalStateException("Parse Exception"));

tomcatLoader.setBaseHost(host);

final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();

try {
//normally it didn't return in the bug case
assertFalse(tomcatLoader.startWebApplication("test"));
assertEquals(originalClassLoader, Thread.currentThread().getContextClassLoader());
} catch (ServletException e) {
throw new RuntimeException(e);
}
}
}

0 comments on commit 4479da2

Please sign in to comment.