-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dhdoshi/spring boot name bug #411
Changes from all commits
c51b53a
11516bf
37b6fc8
16dda62
cf59793
544b0ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,29 +21,31 @@ | |
|
||
package com.microsoft.applicationinsights.web.internal; | ||
|
||
import java.io.IOException; | ||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
import java.util.Date; | ||
import java.util.LinkedList; | ||
import com.microsoft.applicationinsights.TelemetryClient; | ||
import com.microsoft.applicationinsights.TelemetryConfiguration; | ||
import com.microsoft.applicationinsights.agent.internal.coresync.impl.AgentTLS; | ||
import com.microsoft.applicationinsights.common.CommonUtils; | ||
import com.microsoft.applicationinsights.internal.agent.AgentConnector; | ||
import com.microsoft.applicationinsights.internal.logger.InternalLogger; | ||
import com.microsoft.applicationinsights.internal.schemav2.Internal; | ||
import com.microsoft.applicationinsights.internal.util.ThreadLocalCleaner; | ||
|
||
import javax.servlet.Filter; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
import javax.servlet.FilterChain; | ||
import javax.servlet.FilterConfig; | ||
import javax.servlet.ServletContext; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.ServletRequest; | ||
import javax.servlet.ServletResponse; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import com.microsoft.applicationinsights.common.CommonUtils; | ||
import com.microsoft.applicationinsights.TelemetryClient; | ||
import com.microsoft.applicationinsights.TelemetryConfiguration; | ||
import com.microsoft.applicationinsights.agent.internal.coresync.impl.AgentTLS; | ||
import com.microsoft.applicationinsights.internal.agent.AgentConnector; | ||
import com.microsoft.applicationinsights.internal.logger.InternalLogger; | ||
import com.microsoft.applicationinsights.internal.util.ThreadLocalCleaner; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
import java.util.Date; | ||
import java.util.LinkedList; | ||
import java.util.Properties; | ||
|
||
/** | ||
* Created by yonisha on 2/2/2015. | ||
|
@@ -59,20 +61,24 @@ public final class WebRequestTrackingFilter implements Filter { | |
private boolean agentIsUp = false; | ||
private final LinkedList<ThreadLocalCleaner> cleaners = new LinkedList<ThreadLocalCleaner>(); | ||
|
||
//For External Name Setting | ||
private String applicationName; | ||
|
||
// endregion Members | ||
|
||
// region Public | ||
|
||
/** | ||
* Processing the given request and response. | ||
* @param req The servlet request. | ||
* @param res The servlet response. | ||
* | ||
* @param req The servlet request. | ||
* @param res The servlet response. | ||
* @param chain The filters chain | ||
* @throws IOException Exception that can be thrown from invoking the filters chain. | ||
* @throws IOException Exception that can be thrown from invoking the filters chain. | ||
* @throws ServletException Exception that can be thrown from invoking the filters chain. | ||
*/ | ||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { | ||
ApplicationInsightsHttpResponseWrapper response = new ApplicationInsightsHttpResponseWrapper((HttpServletResponse)res); | ||
ApplicationInsightsHttpResponseWrapper response = new ApplicationInsightsHttpResponseWrapper((HttpServletResponse) res); | ||
setKeyOnTLS(key); | ||
|
||
boolean isRequestProcessedSuccessfully = invokeSafeOnBeginRequest(req, response); | ||
|
@@ -81,7 +87,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) | |
chain.doFilter(req, response); | ||
invokeSafeOnEndRequest(req, response, isRequestProcessedSuccessfully); | ||
} catch (ServletException se) { | ||
onException(se, req, response,isRequestProcessedSuccessfully); | ||
onException(se, req, response, isRequestProcessedSuccessfully); | ||
throw se; | ||
} catch (IOException ioe) { | ||
onException(ioe, req, response, isRequestProcessedSuccessfully); | ||
|
@@ -118,9 +124,10 @@ private void onException(Exception e, ServletRequest req, ServletResponse res, b | |
|
||
/** | ||
* Initializes the filter from the given config. | ||
* | ||
* @param config The filter configuration. | ||
*/ | ||
public void init(FilterConfig config){ | ||
public void init(FilterConfig config) { | ||
try { | ||
initialize(config); | ||
|
||
|
@@ -162,7 +169,7 @@ private boolean invokeSafeOnBeginRequest(ServletRequest req, ServletResponse res | |
boolean success = true; | ||
|
||
try { | ||
RequestTelemetryContext context = new RequestTelemetryContext(new Date().getTime(), (HttpServletRequest)req); | ||
RequestTelemetryContext context = new RequestTelemetryContext(new Date().getTime(), (HttpServletRequest) req); | ||
ThreadContext.setRequestTelemetryContext(context); | ||
|
||
webModulesContainer.invokeOnBeginRequest(req, res); | ||
|
@@ -212,18 +219,14 @@ private synchronized void initialize(FilterConfig filterConfig) { | |
//if agent is not installed (jar not loaded), can skip the entire registration process | ||
try { | ||
AgentConnector test = AgentConnector.INSTANCE; | ||
} catch(Throwable t) { | ||
} catch (Throwable t) { | ||
InternalLogger.INSTANCE.logAlways(InternalLogger.LoggingLevel.INFO, "Agent was not found. Skipping the agent registration"); | ||
return; | ||
} | ||
|
||
ServletContext context = filterConfig.getServletContext(); | ||
|
||
String name = getName(context); | ||
|
||
String key = registerWebApp(name); | ||
applicationName = getName(context); | ||
String key = registerWebApp(applicationName); | ||
setKey(key); | ||
|
||
InternalLogger.INSTANCE.logAlways(InternalLogger.LoggingLevel.INFO, "Successfully registered the filter '%s'", FILTER_NAME); | ||
} catch (Throwable t) { | ||
InternalLogger.INSTANCE.logAlways(InternalLogger.LoggingLevel.ERROR, "Failed to register '%s', exception: '%s'", FILTER_NAME, t.getMessage()); | ||
|
@@ -257,7 +260,13 @@ private String registerWebApp(String name) { | |
} | ||
|
||
private String getName(ServletContext context) { | ||
String name = null; | ||
|
||
String name = getApplicatioNameFromProperties(); | ||
|
||
if (name != null) { | ||
return name; | ||
} | ||
|
||
try { | ||
String contextPath = context.getContextPath(); | ||
if (CommonUtils.isNullOrEmpty(contextPath)) { | ||
|
@@ -284,6 +293,38 @@ private String getName(ServletContext context) { | |
return name; | ||
} | ||
|
||
/*This method is used to parse application name from the properties file*/ | ||
private String getApplicatioNameFromProperties() { | ||
|
||
Properties properties = new Properties(); | ||
InputStream input = null; | ||
String name = null; | ||
try { | ||
String fileName = "application.properties"; | ||
input = WebRequestTrackingFilter.class.getClassLoader().getResourceAsStream(fileName); | ||
if (input == null) { | ||
return null; | ||
} | ||
|
||
properties.load(input); | ||
name = properties.getProperty("spring.application.name"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it the way we're going to use for spring only or the name should be more generic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Dmitry-Matveev yes as of now I am not aware of any other framework that reads the value from the properties file though this is through a very preliminary research. There can be places where this is the only way but not in my knowledge. For all other cases we are already reading from application context. Also just pushed the corrected version where the public constructor has been removed which was accidentally present in the previous commit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This property is going to be our public interface to configure application name that something can take dependency on, so changing it once released is not an easy task. |
||
} | ||
catch (IOException ex) { | ||
InternalLogger.INSTANCE.logAlways(InternalLogger.LoggingLevel.ERROR, "Exception in loading properties file: '%s'",ex.getMessage()); | ||
} | ||
finally { | ||
if (input != null) { | ||
try { | ||
input.close(); | ||
} | ||
catch (IOException e) { | ||
InternalLogger.INSTANCE.logAlways(InternalLogger.LoggingLevel.WARN, "Error while closing properties file '%s'",e.getMessage()); | ||
} | ||
} | ||
} | ||
return name; | ||
} | ||
|
||
private void setKey(String key) { | ||
if (CommonUtils.isNullOrEmpty(key)) { | ||
agentIsUp = false; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to add a unit test for this new behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Dmitry-Matveev I agree that there should be test to test this behavior. However the WebRequestTrackingFilter does not implement any interface that we can mock using Mockito framework. The only way that we can write a testcase for this using JUnit can be actually reading from the file and doing the verification. Now that comes with a caveat. We need to store that file into our source code somewhere. If you have any other ideas on testing let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can make
WebRequestTrackingFilter
implement an interface if it's required for tests since you control the code. Storing file within test project for test purposes is perfectly fine - you can consider such a file a 'test resource'.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Dmitry-Matveev interface will not help here, mocking interface makes only interface methods available for mocking. Better to make class not final and Mockito will be able to mock it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gavlyukovskiy, makes sense. @dhaval24, could you please take a look at this approach?