Skip to content

Commit

Permalink
NR-267244 changed the way watchOS determines offline (#244)
Browse files Browse the repository at this point in the history
* NR-267244 changed the way watchOS determines offline

* Added unit tests for currentReachabilityStatusTo

* Changed the url defines to use the Constants.h file
  • Loading branch information
mbruin-NR authored May 22, 2024
1 parent 9eda379 commit 5225a2c
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 10 deletions.
5 changes: 5 additions & 0 deletions Agent/Analytics/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ extern NSString *const kNRMA_Attrib_file_private;
extern NSString *const kNRMA_EventStoreFilename;

extern NSString *const kNRMA_Offline_folder;

extern NSString *const kNRMA_Collector_connect_url;
extern NSString *const kNRMA_Collector_data_url;
extern NSString *const kNRMA_Collector_hex_url;

// Integer Analytics Constants
static int kNRMA_Attrib_Max_Name_Length = 256;
static int kNRMA_Attrib_Max_Value_Size_Bytes = 4096;
Expand Down
4 changes: 4 additions & 0 deletions Agent/Analytics/Constants.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,7 @@
NSString * const kNRMA_EventStoreFilename = @"eventsStore.txt";

NSString * const kNRMA_Offline_folder = @"offlineStorage";

NSString * const kNRMA_Collector_connect_url = @"/mobile/v4/connect";
NSString * const kNRMA_Collector_data_url = @"/mobile/v3/data";
NSString * const kNRMA_Collector_hex_url = @"/mobile/f";
4 changes: 4 additions & 0 deletions Agent/Analytics/Events/NRMAMobileEvent.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ - (nonnull instancetype) initWithTimestamp:(NSTimeInterval)timestamp
if([NRMAFlags shouldEnableOfflineStorage]) {
NRMAReachability* r = [NewRelicInternalUtils reachability];
@synchronized(r) {
#if TARGET_OS_WATCH
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostDataURL]]];
#else
NRMANetworkStatus status = [r currentReachabilityStatus];
#endif
if (status == NotReachable) {
[self addAttribute:kNRMA_Attrib_offline value:@YES];
}
Expand Down
4 changes: 4 additions & 0 deletions Agent/Analytics/NRMAAnalytics.mm
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,11 @@ - (BOOL) checkOfflineStatus {
if([NRMAFlags shouldEnableOfflineStorage]) {
NRMAReachability* r = [NewRelicInternalUtils reachability];
@synchronized(r) {
#if TARGET_OS_WATCH
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostDataURL]]];
#else
NRMANetworkStatus status = [r currentReachabilityStatus];
#endif
return (status == NotReachable);
}
}
Expand Down
4 changes: 4 additions & 0 deletions Agent/General/NewRelicAgentInternal.m
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,11 @@ - (void) onSessionStart {
NRMAReachability* r = [NewRelicInternalUtils reachability];
NRMANetworkStatus status;
@synchronized(r) {
#if TARGET_OS_WATCH
status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostHexURL]]];
#else
status = [r currentReachabilityStatus];
#endif
}
if ([NRMAFlags shouldEnableHandledExceptionEvents]) {
self.handledExceptionsController = [[NRMAHandledExceptions alloc] initWithAnalyticsController:self.analyticsController
Expand Down
12 changes: 10 additions & 2 deletions Agent/HandledException/NRMAHandledExceptions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <Analytics/AnalyticsController.hpp>
#import "NRMABool.h"
#import "NRMASupportMetricHelper.h"
#import "Constants.h"

@interface NRMAAnalytics(Protected)
// Because the NRMAAnalytics class interfaces with non Objective-C++ files, we cannot expose the API on the header. Therefore, we must use this reference.
Expand Down Expand Up @@ -76,11 +77,10 @@ - (instancetype) initWithAnalyticsController:(NRMAAnalytics*)analytics
std::vector<std::shared_ptr<NewRelic::Hex::Report::Library>> libs;
NSString* appToken = agentConfiguration.applicationToken.value;
NSString* protocol = agentConfiguration.useSSL?@"https://":@"http://";
NSString* hexCollectorPath = @"/mobile/f";
NSString* collectorHost = [NSString stringWithFormat:@"%@%@%@",
protocol,
agentConfiguration.collectorHost,
hexCollectorPath];
kNRMA_Collector_hex_url];

NSString* version = [NRMAAgentConfiguration connectionInformation].applicationInformation.appVersion;

Expand Down Expand Up @@ -135,7 +135,11 @@ - (void) onHarvest {
if([NRMAFlags shouldEnableOfflineStorage]) {
NRMAReachability* r = [NewRelicInternalUtils reachability];
@synchronized(r) {
#if TARGET_OS_WATCH
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostHexURL]]];
#else
NRMANetworkStatus status = [r currentReachabilityStatus];
#endif
if (status != NotReachable) {
[self processAndPublishPersistedReports]; // When using offline we always want to send from persisted because the keyContext doesn't persist.
_controller->resetKeyContext();
Expand All @@ -161,7 +165,11 @@ - (void) checkOffline:(std::shared_ptr<NewRelic::Hex::Report::HexReport>) report
if([NRMAFlags shouldEnableOfflineStorage]) {
NRMAReachability* r = [NewRelicInternalUtils reachability];
@synchronized(r) {
#if TARGET_OS_WATCH
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostHexURL]]];
#else
NRMANetworkStatus status = [r currentReachabilityStatus];
#endif
if (status == NotReachable) {
report->setAttributeNoValidation(__kNRMA_Attrib_offline, true);
}
Expand Down
2 changes: 0 additions & 2 deletions Agent/Harvester/NRMAHarvesterConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
#import "NRMAConnection.h"
#import "NRMAOfflineStorage.h"

#define kCOLLECTOR_CONNECT_URI @"/mobile/v4/connect"
#define kCOLLECTOR_DATA_URL @"/mobile/v3/data"
#define kAPPLICATION_TOKEN_HEADER @"X-App-License-Key"
#define kCONNECT_TIME_HEADER @"X-NewRelic-Connect-Time"

Expand Down
5 changes: 3 additions & 2 deletions Agent/Harvester/NRMAHarvesterConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "NRMAMeasurements.h"
#import <zlib.h>
#import "NRMATaskQueue.h"
#import "Constants.h"
#import <time.h>
#import "NRMAHarvesterConnection+GZip.h"
#import "NRMASupportMetricHelper.h"
Expand Down Expand Up @@ -230,12 +231,12 @@ - (NSURLRequest*) createDataPost:(NSString *)message
}
- (NSString*) collectorConnectURL
{
return [self collectorHostURL:(NSString*)kCOLLECTOR_CONNECT_URI];
return [self collectorHostURL:(NSString*)kNRMA_Collector_connect_url];
}

- (NSString*) collectorHostDataURL
{
return [self collectorHostURL:(NSString*)kCOLLECTOR_DATA_URL];
return [self collectorHostURL:(NSString*)kNRMA_Collector_data_url];
}

- (NSString*) collectorHostURL:(NSString*)resource
Expand Down
9 changes: 9 additions & 0 deletions Agent/Utilities/NewRelicInternalUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ NSTimeInterval NRMAMillisecondTimestamp(void);
// Returns the connection type, wifi, ethernet, or cellular.
+ (NSString*) connectionType;

// Determines if a url is reachable.
+ (NRMANetworkStatus)currentReachabilityStatusTo:(NSURL*)url;

// Returns the url for the data endpoint.
+ (NSString*) collectorHostDataURL;

// Returns the url for the hex endpoint.
+ (NSString*) collectorHostHexURL;

// Returns the NRMANetworkStatus
+ (NRMANetworkStatus) networkStatus;

Expand Down
37 changes: 37 additions & 0 deletions Agent/Utilities/NewRelicInternalUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#import "NRLogger.h"
#import "NRConstants.h"
#import "NRTimer.h"
#import "Constants.h"
#import "NewRelicAgentInternal.h"
#import <netdb.h>

#if !TARGET_OS_TV && !TARGET_OS_WATCH

Expand All @@ -36,6 +39,7 @@
#import "NRMADEBUG_Reachability.h"
#endif


// This gets autogenerated into a _vers file using the "Current Project Version" from the project file.
NSTimeInterval NRMAMillisecondTimestamp(void) {
return (NSTimeInterval)(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) * 1000;
Expand Down Expand Up @@ -196,6 +200,35 @@ + (NSString*) connectionType {
}
}

+ (NRMANetworkStatus)currentReachabilityStatusTo:(NSURL*)url {
if([self checkReachablityTo:url]) return ReachableViaUnknown;
return NotReachable;
}

+ (BOOL) checkReachablityTo:(NSURL*)url {
struct hostent *remoteHostEnt = gethostbyname([[url host] UTF8String]);
if(remoteHostEnt == NULL) return false;
return [[url host] isEqualToString:[NSString stringWithUTF8String:*remoteHostEnt->h_aliases]];
}

+ (NSString*) collectorHostDataURL
{
return [self collectorHostURL:(NSString*)kNRMA_Collector_data_url];
}

+ (NSString*) collectorHostHexURL
{
return [self collectorHostURL:(NSString*)kNRMA_Collector_hex_url];
}

+ (NSString*) collectorHostURL:(NSString*)resource
{
NSString* protocol = [[NewRelicAgentInternal sharedInstance] agentConfiguration].useSSL ? @"https://":@"http://";
NSString* collectorHost = [[NewRelicAgentInternal sharedInstance] agentConfiguration].collectorHost;
if(collectorHost == NULL) collectorHost = kNRMA_DEFAULT_COLLECTOR_HOST;
return [NSString stringWithFormat:@"%@%@%@",protocol, collectorHost,resource];
}

// Returns the carrier name, or 'wifi' if the device is on a wifi network.
+ (NSString*) carrierName {
#if TARGET_OS_TV
Expand Down Expand Up @@ -319,6 +352,9 @@ + (NSString*) deviceOrientation {
}

+ (NRMANetworkStatus) networkStatus {
#if TARGET_OS_WATCH
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostDataURL]]];
#else
#ifdef NRMA_REACHABILITY_DEBUG
static NRMADEBUG_Reachability* debugLog;
static dispatch_once_t onceToken;
Expand Down Expand Up @@ -371,6 +407,7 @@ + (NRMANetworkStatus) networkStatus {
if (debugLog.total % 1000 == 0){
NRLOG_INFO(@"DEBUG UPDATE: %@",debugLog);
}
#endif
#endif
return status;
}
Expand Down
5 changes: 4 additions & 1 deletion Agent/Vendor/NRMAReachability.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@
typedef enum {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
ReachableViaWWAN,
ReachableViaUnknown
} NRMANetworkStatus;

@interface NRMAReachability: NSObject
Expand All @@ -84,7 +85,9 @@ typedef enum {

+ (NRMAReachability*)reachability;

#if !TARGET_OS_WATCH
- (NRMANetworkStatus)currentReachabilityStatus;
#endif
- (BOOL) connectionRequired;

@end
Expand Down
8 changes: 5 additions & 3 deletions Agent/Vendor/NRMAReachability.m
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ - (void)setCurrentWanNetworkType:(NSString *)radioAccessTech {

- (NSString *)getCurrentWanNetworkType:(NRMANetworkStatus)networkStatus
{
#if TARGET_OS_TV || TARGET_OS_WATCH
#if TARGET_OS_TV
return NRMA_CARRIER_WIFI;
#elif TARGET_OS_WATCH
return NRMA_CARRIER_OTHER;
#else
@synchronized (_wanNetworkType) {
if (networkStatus != ReachableViaWWAN) {
Expand Down Expand Up @@ -243,15 +245,15 @@ - (NRMANetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags {
}
#endif

#if !TARGET_OS_WATCH
- (NRMANetworkStatus)currentReachabilityStatus {
NRMANetworkStatus retVal = NotReachable;
#if !TARGET_OS_WATCH
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
retVal = [self networkStatusForFlags:flags];
}
#endif
return retVal;
}
#endif

@end
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,18 @@ - (void) testDeviceModeViaSysCtrlNil
[mockNewRelicUtils stopMocking];
}

- (void) testCurrentReachabilityStatusToData
{
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostDataURL]]];

XCTAssertEqual(status, ReachableViaUnknown);
}

- (void) testCurrentReachabilityStatusToHex
{
NRMANetworkStatus status = [NewRelicInternalUtils currentReachabilityStatusTo:[NSURL URLWithString:[NewRelicInternalUtils collectorHostHexURL]]];

XCTAssertEqual(status, ReachableViaUnknown);
}

@end

0 comments on commit 5225a2c

Please sign in to comment.