Skip to content

Revert "chore: [revert] network spans #1394

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

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

- Add support for xCode 16. ([#1370](https://github.com/Instabug/Instabug-React-Native/pull/1370))

- Add support for network spans. ([#1394](https://github.com/Instabug/Instabug-React-Native/pull/1394))

## [14.3.0](https://github.com/Instabug/Instabug-React-Native/compare/v14.1.0...14.3.0)

### Added
Expand Down
3 changes: 2 additions & 1 deletion RNInstabug.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Pod::Spec.new do |s|
s.source_files = "ios/**/*.{h,m,mm}"

s.dependency 'React-Core'
use_instabug!(s)
# use_instabug!(s)
s.dependency 'Instabug'

end
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ final class Constants {
final static String IBG_ON_NEW_MESSAGE_HANDLER = "IBGonNewMessageHandler";
final static String IBG_ON_NEW_REPLY_RECEIVED_CALLBACK = "IBGOnNewReplyReceivedCallback";

final static String IBG_ON_FEATURES_UPDATED_CALLBACK = "IBGOnFeatureUpdatedCallback";
final static String IBG_NETWORK_LOGGER_HANDLER = "IBGNetworkLoggerHandler";

final static String IBG_ON_NEW_W3C_FLAGS_UPDATE_RECEIVED_CALLBACK = "IBGOnNewW3CFlagsUpdateReceivedCallback";

final static String IBG_SESSION_REPLAY_ON_SYNC_CALLBACK_INVOCATION = "IBGSessionReplayOnSyncCallback";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package com.instabug.reactlibrary;


import static com.instabug.apm.configuration.cp.APMFeature.APM_NETWORK_PLUGIN_INSTALLED;
import static com.instabug.apm.configuration.cp.APMFeature.CP_NATIVE_INTERCEPTION_ENABLED;

import android.util.Log;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.instabug.apm.InternalAPM;
import com.instabug.apm.sanitization.OnCompleteCallback;
import com.instabug.library.logging.listeners.networklogs.NetworkLogSnapshot;
import com.instabug.reactlibrary.utils.EventEmitterModule;
import com.instabug.reactlibrary.utils.MainThreadHandler;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class RNInstabugNetworkLoggerModule extends EventEmitterModule {

public final ConcurrentHashMap<String, OnCompleteCallback<NetworkLogSnapshot>> callbackMap = new ConcurrentHashMap<String, OnCompleteCallback<NetworkLogSnapshot>>();

public RNInstabugNetworkLoggerModule(ReactApplicationContext reactContext) {
super(reactContext);
}


@NonNull
@Override
public String getName() {
return "IBGNetworkLogger";
}


@ReactMethod
public void addListener(String event) {
super.addListener(event);
}

@ReactMethod
public void removeListeners(Integer count) {
super.removeListeners(count);
}

private boolean getFlagValue(String key) {
return InternalAPM._isFeatureEnabledCP(key, "");
}

private WritableMap convertFromMapToWritableMap(Map<String, Object> map) {
WritableMap writableMap = new WritableNativeMap();
for (String key : map.keySet()) {
Object value = map.get(key);
writableMap.putString(key, (String) value);
}
return writableMap;
}

private Map<String, Object> convertReadableMapToMap(ReadableMap readableMap) {
Map<String, Object> map = new HashMap<>();
if (readableMap != null) {
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
map.put(key, readableMap.getString(key));
}
}
return map;
}

/**
* Get first time Value of [cp_native_interception_enabled] flag
*/
@ReactMethod
public void isNativeInterceptionEnabled(Promise promise) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
promise.resolve(getFlagValue(CP_NATIVE_INTERCEPTION_ENABLED));
} catch (Exception e) {
e.printStackTrace();
promise.resolve(false); // Will rollback to JS interceptor
}

}
});
}

/**
* Indicate if user added APM Network plugin or not
* [true] means user added the APM plugin
* [false] means not
*/
@ReactMethod
public void hasAPMNetworkPlugin(Promise promise) {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
promise.resolve(getFlagValue(APM_NETWORK_PLUGIN_INSTALLED));
} catch (Exception e) {
e.printStackTrace();
promise.resolve(false); // Will rollback to JS interceptor
}

}
});
}


@ReactMethod
public void registerNetworkLogsListener() {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
InternalAPM._registerNetworkLogSanitizer((networkLogSnapshot, onCompleteCallback) -> {
final String id = String.valueOf(onCompleteCallback.hashCode());
callbackMap.put(id, onCompleteCallback);

WritableMap networkSnapshotParams = Arguments.createMap();
networkSnapshotParams.putString("id", id);
networkSnapshotParams.putString("url", networkLogSnapshot.getUrl());
networkSnapshotParams.putInt("responseCode", networkLogSnapshot.getResponseCode());
networkSnapshotParams.putString("requestBody", networkLogSnapshot.getRequestBody());
networkSnapshotParams.putString("response", networkLogSnapshot.getResponse());
final Map<String, Object> requestHeaders = networkLogSnapshot.getRequestHeaders();
if (requestHeaders != null) {
networkSnapshotParams.putMap("requestHeader", convertFromMapToWritableMap(requestHeaders));
}
final Map<String, Object> responseHeaders = networkLogSnapshot.getResponseHeaders();
if (responseHeaders != null) {
networkSnapshotParams.putMap("responseHeader", convertFromMapToWritableMap(responseHeaders));
}

sendEvent(Constants.IBG_NETWORK_LOGGER_HANDLER, networkSnapshotParams);
});
}
});
}

@ReactMethod
public void resetNetworkLogsListener() {
MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
InternalAPM._registerNetworkLogSanitizer(null);
}
});
}

@ReactMethod
public void updateNetworkLogSnapshot(
String url,
String callbackID,
String requestBody,
String responseBody,
int responseCode,
ReadableMap requestHeaders,
ReadableMap responseHeaders
) {
try {
// Convert ReadableMap to a Java Map for easier handling
Map<String, Object> requestHeadersMap = convertReadableMapToMap(requestHeaders);
Map<String, Object> responseHeadersMap = convertReadableMapToMap(responseHeaders);

NetworkLogSnapshot modifiedSnapshot = null;
if (!url.isEmpty()) {
modifiedSnapshot = new NetworkLogSnapshot(url, requestHeadersMap, requestBody, responseHeadersMap, responseBody, responseCode);
}

final OnCompleteCallback<NetworkLogSnapshot> callback = callbackMap.get(callbackID);
if (callback != null) {
callback.onComplete(modifiedSnapshot);
callbackMap.remove(callbackID);
}
} catch (Exception e) {
// Reject the promise to indicate an error occurred
Log.e("IB-CP-Bridge", "InstabugNetworkLogger.updateNetworkLogSnapshot failed to parse the network snapshot object.");
}
}
}
Loading