Adjust communication with OneAgent SDK for Android
After instrumentation is complete, check the following aspects regarding communication with OneAgent.
Network security configuration
If your Android app has network security configured, ensure that the HTTP traffic to the beaconUrl
endpoint is not blocked by the network security configuration.
Firewall
Ensure that the GET and POST requests to the beaconUrl
endpoint are not blocked by a firewall.
Include certificates
For HTTPS communication, OneAgent verifies the server certificate and the hostname. OneAgent communication fails if the verification steps aren't completed.
If your Cluster ActiveGate doesn't have a certificate issued by a trusted intermediate or root Certificate Authority (CA), provide the server certificate for SSL communication in the Network Security Configuration file (for Android API level 24+).
To use the Network Security Configuration feature, add a domain-config
section to your network_security_config.xml
file.
<domain-config>
<domain includeSubdomains="true">your.domain.com</domain>
<trust-anchors>
<certificates src="@raw/your_server_certificate" />
</trust-anchors>
</domain-config>
Certificate pinning
To use certificate pinning, follow the instructions provided by Android at Network security configuration > Pin certificates.
Custom HTTP headers
If HTTP requests of OneAgent don't fulfill the security requirements of your server infrastructure, you can modify the HTTP headers of OneAgent with the Dynatrace.setBeaconHeaders(Map<String, String>)
method. This feature allows you to add an Authorization
header to the HTTP requests and immediately reconnect to the Cluster ActiveGate when the token has expired.
To delete the old headers, call Dynatrace.setBeaconHeaders(null)
.
Basic authorization
When the authorization information is already available at the app start, call the Dynatrace.setBeaconHeaders
method before the starting up Dynatrace.startup
method. Every HTTP request of the OneAgent will then have the correct headers.
Map<String, String> headers = new HashMap<>();
headers.put("Cookie", "n1=v1; n2=v2");
headers.put("ExampleHeader", "ExampleValue");
headers.put("Authorization", basicAuthorization(username, password));
Dynatrace.setBeaconHeaders(headers);
Dynatrace.startup(this, new DynatraceConfigurationBuilder("<YourApplicationID>", "<ProvidedBeaconURL>")
.buildConfiguration());
val headers = HashMap<String, String>()
headers["Cookie"] = "n1=v1; n2=v2"
headers["ExampleHeader"] = "ExampleValue"
headers["Authorization"] = basicAuthorization(username, password)
Dynatrace.setBeaconHeaders(headers)
Dynatrace.startup(this, DynatraceConfigurationBuilder("<YourApplicationID>", "<ProvidedBeaconURL>")
.buildConfiguration()
)
If the authorization information is not available at the app start, call the Dynatrace.setBeaconHeaders
method when the information is available. The startup Dynatrace.startup
method should still be called in the Application.onCreate
method to track the correct start time. OneAgent will be automatically deactivated when the server sends an invalid status code response. The Dynatrace.setBeaconHeaders
method will activate OneAgent and will immediately reconnect to the Cluster ActiveGate.
Authorization with a token
If you use an authorization procedure, which requires you to regularly update a token, then you should add a CommunicationProblemListener
. The listener must be added via the DynatraceConfigurationBuilder
in the Dynatrace.startup
method.
Dynatrace.startup(this, new DynatraceConfigurationBuilder("<YourApplicationID>", "<ProvidedBeaconURL>")
.withCommunicationProblemListener(new YourDynatraceListener())
.buildConfiguration());
Dynatrace.startup(this, DynatraceConfigurationBuilder("<YourApplicationID>", "<ProvidedBeaconURL>")
.withCommunicationProblemListener(YourDynatraceListener())
.buildConfiguration())
When you use a CommunicationProblemListener
, OneAgent communication behavior is slightly different from the normal behavior. If the Cluster ActiveGate reacts with an invalid status code, like 403 Forbidden
, OneAgent won't reconnect to the server. Instead, OneAgent will wait until you have specified the correct headers with the method Dynatrace.setBeaconHeaders
. In this case, OneAgent will notify the CommunicationProblemListener
asynchronously in a background thread via the onFailure(int, String, String)
interface method. The following code snippet shows a sample implementation for the CommunicationProblemListener
interface:
public class YourDynatraceListener implements CommunicationProblemListener {
@Override
public void onFailure(int responseCode, String responseMessage, String body) {
String token = refreshToken();
Dynatrace.setBeaconHeaders(generateAuthorizationHeader(token));
}
@Override
public void onError(Throwable throwable) {
//do nothing
}
}
class YourDynatraceListener : CommunicationProblemListener {
override fun onFailure(responseCode: Int, responseMessage: String?, body: String?) {
String token = refreshToken()
Dynatrace.setBeaconHeaders(generateAuthorizationHeader(token))
}
override fun onError(throwable: Throwable?) {
//do nothing
}
}
The interface method onError(Throwable)
is asynchronously called when a communication problem occurs, such as a connection timeout or an SSL handshake error. In this case, OneAgent waits for a certain time and then reconnects to the Cluster ActiveGate. Normally you don't have to react on this callback method.
Offline monitoring
For efficiency, Dynatrace does not accept monitoring data older than 10 minutes. If the app is not connected to the internet for a longer period, OneAgent discards the old monitoring data and stops monitoring the app until the device establishes a new network connection.