-
Notifications
You must be signed in to change notification settings - Fork 268
Add trace filter support, custom headers and add opentelemetry to dataservices #4520
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
base: master
Are you sure you want to change the base?
Conversation
WalkthroughThis pull request introduces OpenTelemetry tracing support to WSO2 Data Services by adding a centralized tracing collector and instrumenting key message receivers, request processors, and OData handlers with entry/exit tracing events. It updates method signatures in request dispatch classes to accept MessageContext parameters for context propagation. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| ", Operation - " + msgContext.getSoapAction() + ", Request body - " + | ||
| msgContext.getEnvelope().getText() + ", ThreadID - " + Thread.currentThread().getId()); | ||
| } | ||
| DataServicesTracingCollector.reportEntryEvent(msgContext); |
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.
Log Improvement Suggestion No: 1
| DataServicesTracingCollector.reportEntryEvent(msgContext); | |
| DataServicesTracingCollector.reportEntryEvent(msgContext); | |
| log.info("Processing in-only message for Data Service: " + msgContext.getServiceContext().getName() + ", Operation: " + msgContext.getSoapAction()); |
| DataServicesTracingCollector.reportEntryEvent(msgContext); | ||
| DataServiceProcessor.dispatch(msgContext); | ||
| msgContext.setProperty(DBConstants.TENANT_IN_ONLY_MESSAGE, Boolean.TRUE); | ||
| DataServicesTracingCollector.closeEntryEvent(msgContext, null); |
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.
Log Improvement Suggestion No: 2
| DataServicesTracingCollector.closeEntryEvent(msgContext, null); | |
| DataServicesTracingCollector.closeEntryEvent(msgContext, null); | |
| log.info("Successfully completed in-only message processing for Data Service: " + msgContext.getServiceContext().getName()); |
| newMsgContext.setProperty(Constants.Configuration.MESSAGE_TYPE, | ||
| HTTPConstants.MEDIA_TYPE_APPLICATION_JSON); | ||
| } | ||
| DataServicesTracingCollector.closeEntryEvent(msgContext, result); |
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.
Log Improvement Suggestion No: 4
| newMsgContext.setProperty(Constants.Configuration.MESSAGE_TYPE, | |
| HTTPConstants.MEDIA_TYPE_APPLICATION_JSON); | |
| } | |
| DataServicesTracingCollector.closeEntryEvent(msgContext, result); | |
| newMsgContext.setProperty(Constants.Configuration.MESSAGE_TYPE, | |
| HTTPConstants.MEDIA_TYPE_APPLICATION_JSON); | |
| } | |
| log.info("Data service request completed successfully - MessageID: " + msgContext.getMessageID()); |
| DataServiceRequest request = DataServiceRequest.createDataServiceRequest(msgContext); | ||
| OMElement result = request.dispatch(); | ||
| DataServicesTracingCollector.reportQueryExecutionEvent(msgContext, request); |
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.
Log Improvement Suggestion No: 5
| DataServiceRequest request = DataServiceRequest.createDataServiceRequest(msgContext); | |
| OMElement result = request.dispatch(); | |
| DataServicesTracingCollector.reportQueryExecutionEvent(msgContext, request); | |
| DataServiceRequest request = DataServiceRequest.createDataServiceRequest(msgContext); | |
| log.info("Processing data service request: " + request.getRequestName()); | |
| DataServicesTracingCollector.reportQueryExecutionEvent(msgContext, request); |
| public synchronized OMElement execute(MessageContext messageContext) throws DataServiceFault { | ||
| OMElement result; |
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.
Log Improvement Suggestion No: 7
| public synchronized OMElement execute(MessageContext messageContext) throws DataServiceFault { | |
| OMElement result; | |
| public synchronized OMElement execute(MessageContext messageContext) throws DataServiceFault { | |
| log.info("Starting boxcarring session execution with " + this.getRequests().size() + " requests"); | |
| OMElement result; |
| for (int i = 0; i < n; i++) { | ||
| result = reqList.get(i).dispatch(); | ||
| DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i)); |
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.
Log Improvement Suggestion No: 8
| for (int i = 0; i < n; i++) { | |
| result = reqList.get(i).dispatch(); | |
| DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i)); | |
| for (int i = 0; i < n; i++) { | |
| if (log.isDebugEnabled()) { | |
| log.debug("Executing request " + (i + 1) + " of " + n + " in boxcarring session"); | |
| } | |
| DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i)); |
| if (!this.getDataService().isInDTX()) { | ||
| this.getDataService().getDSSTxManager().begin(); | ||
| } | ||
| OMElement lastRequestResult = DSSessionManager.getCurrentRequestBox().execute(); | ||
| OMElement lastRequestResult = DSSessionManager.getCurrentRequestBox().execute(messageContext); | ||
| error = 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.
Log Improvement Suggestion No: 12
| if (!this.getDataService().isInDTX()) { | |
| this.getDataService().getDSSTxManager().begin(); | |
| } | |
| OMElement lastRequestResult = DSSessionManager.getCurrentRequestBox().execute(); | |
| OMElement lastRequestResult = DSSessionManager.getCurrentRequestBox().execute(messageContext); | |
| error = false; | |
| if (!this.getDataService().isInDTX()) { | |
| this.getDataService().getDSSTxManager().begin(); | |
| } | |
| if (log.isDebugEnabled()) { | |
| log.debug("Executing boxcarring requests for session"); | |
| } | |
| OMElement lastRequestResult = DSSessionManager.getCurrentRequestBox().execute(messageContext); | |
| error = false; | |
| log.info("Successfully executed boxcarring session"); |
| */ | ||
| public OMElement dispatch() throws DataServiceFault { | ||
| public OMElement dispatch(MessageContext messageContext) throws DataServiceFault { |
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.
Log Improvement Suggestion No: 13
| */ | |
| public OMElement dispatch() throws DataServiceFault { | |
| public OMElement dispatch(MessageContext messageContext) throws DataServiceFault { | |
| public OMElement dispatch(MessageContext messageContext) throws DataServiceFault { | |
| log.debug("Dispatching data service request: " + this.requestName); | |
| /* set user */ |
| OMElement result = this.processRequest(messageContext); | ||
| /* check disable streaming */ |
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.
Log Improvement Suggestion No: 14
| OMElement result = this.processRequest(messageContext); | |
| /* check disable streaming */ | |
| OMElement result = this.processRequest(messageContext); | |
| if (log.isDebugEnabled()) { | |
| log.debug("Request processed successfully for: " + this.requestName); | |
| } | |
| /* check disable streaming */ |
| public OMElement processRequest(MessageContext messageContext) throws DataServiceFault { | ||
|
|
||
| boolean error = true; | ||
| try { |
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.
Log Improvement Suggestion No: 15
| try { | |
| DispatchStatus.setBoxcarringRequest(); | |
| log.info("Processing request box with " + this.requestBox.getRequestCount() + " requests"); |
| this.getDataService().getDSSTxManager().begin(); | ||
| } | ||
| OMElement lastRequestResult = this.requestBox.execute(); | ||
| OMElement lastRequestResult = this.requestBox.execute(messageContext); |
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.
Log Improvement Suggestion No: 16
| OMElement lastRequestResult = this.requestBox.execute(messageContext); | |
| OMElement lastRequestResult = this.requestBox.execute(messageContext); | |
| log.debug("Request box execution completed successfully"); |
| @Override | ||
| public OMElement processRequest() throws DataServiceFault { | ||
| public OMElement processRequest(MessageContext messageContext) throws DataServiceFault { |
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.
Log Improvement Suggestion No: 17
| @Override | |
| public OMElement processRequest() throws DataServiceFault { | |
| public OMElement processRequest(MessageContext messageContext) throws DataServiceFault { | |
| @Override | |
| public OMElement processRequest(MessageContext messageContext) throws DataServiceFault { | |
| log.info("Processing single data service request"); |
| * Report entry event for data service invocation. | ||
| * @param messageContext Axis2 message context | ||
| */ | ||
| public static void reportEntryEvent(MessageContext messageContext) { |
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.
Log Improvement Suggestion No: 18
| * Report entry event for data service invocation. | |
| * @param messageContext Axis2 message context | |
| */ | |
| public static void reportEntryEvent(MessageContext messageContext) { | |
| public static void reportEntryEvent(MessageContext messageContext) { | |
| if (isOpenTelemetryEnabled() && messageContext != null) { | |
| String componentName = messageContext.getAxisService().getName(); | |
| log.info("Starting data service invocation for service: " + componentName); |
| private static void setPayload(OMElement payload, StatisticDataUnit dataUnit) { | ||
| try { | ||
| if (payload != null) { | ||
| dataUnit.setPayload(payload.toString()); |
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.
Log Improvement Suggestion No: 19
| private static void setPayload(OMElement payload, StatisticDataUnit dataUnit) { | |
| try { | |
| if (payload != null) { | |
| dataUnit.setPayload(payload.toString()); | |
| } catch (Exception e) { | |
| // We are catching exception to avoid any issues with toString() and | |
| // We should not fail the main flow due to tracing issues | |
| log.error("Error while setting payload for tracing span: " + e.getMessage()); |
| try { | ||
| DataServicesTracingCollector.reportOdataQueryExecutionEvent(request.getAxis2MessageContext()); | ||
| oDataServiceHandler.process(request, response, serviceRootPath); |
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.
Log Improvement Suggestion No: 20
| try { | |
| DataServicesTracingCollector.reportOdataQueryExecutionEvent(request.getAxis2MessageContext()); | |
| oDataServiceHandler.process(request, response, serviceRootPath); | |
| try { | |
| log.info("Processing OData request for service: " + request.getRawODataPath()); | |
| DataServicesTracingCollector.reportOdataQueryExecutionEvent(request.getAxis2MessageContext()); | |
| oDataServiceHandler.process(request, response, serviceRootPath); |
| } catch (Exception e) { | ||
| if (log.isDebugEnabled()) { | ||
| log.debug("Failed to process the servlet request. " + e); | ||
| } |
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.
Log Improvement Suggestion No: 21
| } catch (Exception e) { | |
| if (log.isDebugEnabled()) { | |
| log.debug("Failed to process the servlet request. " + e); | |
| } | |
| } catch (Exception e) { | |
| log.error("Failed to process OData request: " + e.getMessage()); | |
| if (log.isDebugEnabled()) { | |
| log.debug("Failed to process the servlet request. " + e); | |
| } |
| if (axis2MessageContext.getProperty(TRANSPORT_IN_URL) != null && isODataService != null) { | ||
| // Marking the message to skip the main sequence in Synapse Axis2 Environment. | ||
| messageContext.setProperty(SynapseConstants.SKIP_MAIN_SEQUENCE, Boolean.TRUE); |
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.
Log Improvement Suggestion No: 22
| if (axis2MessageContext.getProperty(TRANSPORT_IN_URL) != null && isODataService != null) { | |
| // Marking the message to skip the main sequence in Synapse Axis2 Environment. | |
| messageContext.setProperty(SynapseConstants.SKIP_MAIN_SEQUENCE, Boolean.TRUE); | |
| if (axis2MessageContext.getProperty(TRANSPORT_IN_URL) != null && isODataService != null) { | |
| // Marking the message to skip the main sequence in Synapse Axis2 Environment. | |
| messageContext.setProperty(SynapseConstants.SKIP_MAIN_SEQUENCE, Boolean.TRUE); | |
| LOG.info("Processing OData service request for URL: " + axis2MessageContext.getProperty(TRANSPORT_IN_URL)); |
| streamResponseBack(response, messageContext, axis2MessageContext); | ||
| } | ||
| DataServicesTracingCollector.closeOdataEntryEvent(axis2MessageContext, |
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.
Log Improvement Suggestion No: 23
| streamResponseBack(response, messageContext, axis2MessageContext); | |
| } | |
| DataServicesTracingCollector.closeOdataEntryEvent(axis2MessageContext, | |
| } | |
| DataServicesTracingCollector.closeOdataEntryEvent(axis2MessageContext, | |
| axis2MessageContext.getEnvelope()); | |
| LOG.debug("Successfully processed OData service request"); |
| public MessageContext getAxis2MessageContext() { | ||
| return axis2MessageContext; | ||
| } |
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.
Log Improvement Suggestion No: 24
| public MessageContext getAxis2MessageContext() { | |
| return axis2MessageContext; | |
| } | |
| public MessageContext getAxis2MessageContext() { | |
| log.debug("Retrieving Axis2 message context"); | |
| return axis2MessageContext; | |
| } |
| try { | ||
| DataServicesTracingCollector.reportEntryEvent(axis2MessageContext); |
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.
Log Improvement Suggestion No: 25
| try { | |
| DataServicesTracingCollector.reportEntryEvent(axis2MessageContext); | |
| try { | |
| log.info("Starting data service dispatch for operation: " + axis2MessageContext.getOperationContext().getOperationName()); | |
| DataServicesTracingCollector.reportEntryEvent(axis2MessageContext); |
| } catch (DataServiceFault dataServiceFault) { | ||
| DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, dataServiceFault); |
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.
Log Improvement Suggestion No: 26
| } catch (DataServiceFault dataServiceFault) { | |
| DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, dataServiceFault); | |
| } catch (DataServiceFault dataServiceFault) { | |
| log.error("Data service fault occurred: " + dataServiceFault.getMessage()); | |
| DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, dataServiceFault); |
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.
AI Agent Log Improvement Checklist
- The log-related comments and suggestions in this review were generated by an AI tool to assist with identifying potential improvements. Purpose of reviewing the code for log improvements is to improve the troubleshooting capabilities of our products.
- Please make sure to manually review and validate all suggestions before applying any changes. Not every code suggestion would make sense or add value to our purpose. Therefore, you have the freedom to decide which of the suggestions are helpful.
✅ Before merging this pull request:
- Review all AI-generated comments for accuracy and relevance.
- Complete and verify the table below. We need your feedback to measure the accuracy of these suggestions and the value they add. If you are rejecting a certain code suggestion, please mention the reason briefly in the suggestion for us to capture 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.
Actionable comments posted: 6
🧹 Nitpick comments (4)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOnlyMessageReceiver.java (1)
48-71: Tracing lifecycle is wired correctly; consider minor @OverRide annotation improvementThe try/catch/finally now cleanly wraps the whole flow: entry event before dispatch, normal close on success, and
closeFlowForcefullyon any exception, while preserving the original logging, fault-name setting, andAxisFaultwrapping. Semantics of the in-only receiver look unchanged apart from tracing.As a small improvement, you could add
@OverrideaboveinvokeBusinessLogicto make the override explicit and catch signature drift at compile time.- public void invokeBusinessLogic(MessageContext msgContext) throws AxisFault { + @Override + public void invokeBusinessLogic(MessageContext msgContext) throws AxisFault {components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/RequestBoxRequest.java (1)
27-27: Unused import.
DataServicesTracingCollectoris imported but not used in this file.-import org.wso2.micro.integrator.dataservices.core.opentelemetry.DataServicesTracingCollector;components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/DataServiceRequest.java (1)
393-397: Document nullable parameter in Javadoc.The
messageContextparameter can benull(as shown bydispatch()callingdispatch(null)). Consider updating the Javadoc to explicitly document this:/** * This method must implement the request specific request processing logic. - * @param messageContext Axis2 message context of the request + * @param messageContext Axis2 message context of the request, may be null if tracing is not required * @return The result of the request invocation * @throws DataServiceFault */ public abstract OMElement processRequest(MessageContext messageContext) throws DataServiceFault;components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingConstants.java (1)
21-37: Consider making this a utility/constants class.Constants-only classes are typically made
finalwith a private constructor to prevent instantiation and inheritance, following Java best practices.-public class DataServicesTracingConstants { +public final class DataServicesTracingConstants { + + private DataServicesTracingConstants() { + // Prevent instantiation + } + public static final int DEFAULT_PARENT_INDEX = -1; public static final int DATA_SERVICE_INDEX = 0;This follows the same pattern used in
DBConstants.FaultCodesshown in the relevant snippets.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOnlyMessageReceiver.java(2 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOutMessageReceiver.java(3 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DataServiceProcessor.java(3 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/boxcarring/RequestBox.java(2 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/BatchDataServiceRequest.java(3 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/BoxcarringDataServiceRequest.java(3 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/DataServiceRequest.java(4 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/RequestBoxRequest.java(2 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/SingleDataServiceRequest.java(2 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java(1 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingConstants.java(1 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.odata.endpoint/src/main/java/org/wso2/micro/integrator/dataservices/odata/endpoint/ODataEndpoint.java(3 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.odata.endpoint/src/main/java/org/wso2/micro/integrator/dataservices/odata/endpoint/ODataPassThroughHandler.java(2 hunks)components/data/data-services/org.wso2.micro.integrator.dataservices.odata.endpoint/src/main/java/org/wso2/micro/integrator/dataservices/odata/endpoint/ODataServletRequest.java(1 hunks)components/mediation/mediators/dataservices-mediator/org.wso2.micro.integrator.mediator.dataservice/src/main/java/org/wso2/micro/integrator/mediator/dataservice/DataServiceCallMediator.java(4 hunks)distribution/src/resources/config-tool/key-mappings.json(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOutMessageReceiver.java (2)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (1)
DataServicesTracingCollector(57-370)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingConstants.java (1)
DataServicesTracingConstants(21-37)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/boxcarring/RequestBox.java (3)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/DataServiceRequest.java (1)
DataServiceRequest(48-398)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (1)
DataServicesTracingCollector(57-370)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingConstants.java (1)
DataServicesTracingConstants(21-37)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DataServiceProcessor.java (1)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (1)
DataServicesTracingCollector(57-370)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/RequestBoxRequest.java (2)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/boxcarring/RequestBox.java (1)
RequestBox(38-96)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (1)
DataServicesTracingCollector(57-370)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (2)
components/data/data-services/org.wso2.micro.integrator.dataservices.common/src/main/java/org/wso2/micro/integrator/dataservices/common/DBConstants.java (2)
DBConstants(27-1108)FaultCodes(92-103)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingConstants.java (1)
DataServicesTracingConstants(21-37)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOnlyMessageReceiver.java (2)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (1)
DataServicesTracingCollector(57-370)components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingConstants.java (1)
DataServicesTracingConstants(21-37)
🔇 Additional comments (18)
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOnlyMessageReceiver.java (1)
27-29: Tracing imports look consistent with the new OpenTelemetry infrastructureStatic import of
DATA_SERVICE_INDEXand the addition ofDataServicesTracingCollectormatch the patterns used elsewhere in the PR and keep the call sites readable. No issues here.components/mediation/mediators/dataservices-mediator/org.wso2.micro.integrator.mediator.dataservice/src/main/java/org/wso2/micro/integrator/mediator/dataservice/DataServiceCallMediator.java (1)
48-48: LGTM!The imports for OpenTelemetry tracing support are correctly added.
Also applies to: 60-60
distribution/src/resources/config-tool/key-mappings.json (1)
119-120: Naming inconsistency:'oltp'vs'opentelemetry'prefix requires verification.Lines 119-120 map OpenTelemetry properties using the
'oltp'prefix, while the established OpenTelemetry mappings on lines 113-117 use the'opentelemetry'prefix. This inconsistency warrants verification, as'oltp'may be a typo (the standard term in OpenTelemetry ecosystem is OTLP, not oltp), or these property names may need to be confirmed against actual Synapse property definitions.Verify whether the target Synapse property names are:
synapse_properties.'opentelemetry.filtered.mediator.names'andsynapse_properties.'opentelemetry.custom.span.header.tags'(consistent with lines 113-117), or- The
'oltp'prefix is intentional for a different configuration namespacecomponents/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/BoxcarringDataServiceRequest.java (1)
24-24: LGTM! Clean integration of MessageContext for tracing support.The method signature update and parameter threading to
DSSessionManager.getCurrentRequestBox().execute(messageContext)correctly propagates the context needed for OpenTelemetry tracing downstream.Also applies to: 52-55, 69-69
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DataServiceProcessor.java (1)
41-51: LGTM! Tracing correctly wraps the dispatch operation.The tracing calls appropriately bracket the dispatch operation, and the
closeQueryExecutionEventreceives the final result after any request status generation. Exception handling is correctly delegated to the caller (DBInOutMessageReceiver) which callscloseFlowForcefullyon errors.components/data/data-services/org.wso2.micro.integrator.dataservices.odata.endpoint/src/main/java/org/wso2/micro/integrator/dataservices/odata/endpoint/ODataServletRequest.java (1)
444-448: LGTM! Simple accessor for tracing context propagation.The getter enables OData components to access the underlying Axis2 MessageContext for OpenTelemetry tracing purposes, as noted in the AI summary.
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/DBInOutMessageReceiver.java (1)
65-65: LGTM! Proper tracing lifecycle management.The tracing integration correctly:
- Reports entry event before business logic processing
- Closes the entry event on the success path with the result
- Closes the flow forcefully on the exception path with error details
This ensures spans are properly closed in all execution paths.
Also applies to: 98-98, 102-102
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/BatchDataServiceRequest.java (1)
110-113: Verify method namecloserMultiEvent- possible typo.The method name
closerMultiEventon line 113 appears inconsistent with the naming pattern used elsewhere (e.g.,closeEntryEvent,closeQueryExecutionEvent). Confirm whether this should becloseMultiEvent.components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/SingleDataServiceRequest.java (1)
59-62: Method signature updated for interface consistency.The
messageContextparameter is added to align with the updatedDataServiceRequestcontract but is not used within this implementation. This is acceptable since this class handles single requests that don't require per-request tracing context propagation—the parentdispatch(MessageContext)method inDataServiceRequestalready handles the outer tracing context.components/data/data-services/org.wso2.micro.integrator.dataservices.odata.endpoint/src/main/java/org/wso2/micro/integrator/dataservices/odata/endpoint/ODataPassThroughHandler.java (2)
53-66: OpenTelemetry tracing integration for OData requests looks correct.The tracing lifecycle follows the proper pattern: entry event is reported before processing (line 56), and closed after successful completion (lines 65-66). The
SKIP_MAIN_SEQUENCEproperty ensures OData requests bypass the normal Synapse flow.
69-74: Proper trace finalization on error path.The
closeFlowForcefullycall ensures OpenTelemetry spans are properly closed with error details when an exception occurs, preventing orphaned spans.components/data/data-services/org.wso2.micro.integrator.dataservices.odata.endpoint/src/main/java/org/wso2/micro/integrator/dataservices/odata/endpoint/ODataEndpoint.java (2)
131-131: Visibility change fromprivatetopublic.This method is now exposed publicly. Ensure this is intentional and that all callers handle the
ODataServiceFaultexception appropriately.
105-122: Verify OpenTelemetry context propagation to the spawned thread.Tracing events are reported inside
streamThread, but OpenTelemetry context propagation across thread boundaries requires explicit handling. When Axis2MessageContext is passed to the thread, the OpenTelemetry trace context associated with the incoming request must be made current on the new thread to ensure spans are correctly linked to the parent.Confirm that either:
- The framework (or
OpenTelemetryManagerHolder) automatically propagates and activates context whenrequest.getAxis2MessageContext()is passed to the thread, or- The tracing implementation explicitly calls
context.makeCurrent()or equivalent within the thread to activate the extracted context for downstream span creation.Without this, spans created in
streamThreadmay not be properly correlated with the parent trace.components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/RequestBoxRequest.java (1)
59-70: Method signature and context propagation updated correctly.The
MessageContextis properly propagated torequestBox.execute(), enabling the tracing instrumentation added inRequestBox.java.components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java (3)
64-85: LGTM! Well-structured entry event reporting.The method properly checks
isOpenTelemetryEnabled()and nullmessageContextbefore proceeding, sets up theStatisticDataUnitwith appropriate properties, and uses helper methods for HTTP properties. Good defensive approach withsetPayloadwrapped in try-catch.
264-288: Good error handling incloseFlowForcefully.The method appropriately handles both
DataServiceFaultand generic exceptions, extracting error codes and messages accordingly. The adjustment for multi-request indices is well-documented.
356-369: Good defensive coding insetPayload.The try-catch block prevents tracing failures from impacting the main flow. Setting a fallback payload and error message provides useful debugging information while maintaining resilience.
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/dispatch/DataServiceRequest.java (1)
360-389: LGTM! Good backward-compatible design for MessageContext propagation.The overloaded
dispatch()method that delegates todispatch(null)maintains backward compatibility while enabling tracing support. This allows existing callers to continue working without modification.However, verification of null-handling in all
processRequestimplementations could not be completed due to repository access limitations. The design pattern shown in the provided code snippet appears sound, but complete validation requires examining all implementing classes to ensure they properly handle the nullableMessageContextparameter.
| public synchronized OMElement execute(MessageContext messageContext) throws DataServiceFault { | ||
| OMElement result; | ||
| List<DataServiceRequest> reqList = this.getRequests(); | ||
| int n = reqList.size(); | ||
| OMElement resultElement = null; | ||
| for (int i = 0; i < n; i++) { | ||
| result = reqList.get(i).dispatch(); | ||
| DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i)); | ||
| messageContext.setProperty(MULTI_REQUEST_LAST_INDEX_PROPERTY, i); | ||
| result = reqList.get(i).dispatch(messageContext); | ||
| DataServicesTracingCollector.closerMultiEvent(messageContext, i, result); |
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.
Potential NullPointerException if messageContext is null.
Line 70 calls messageContext.setProperty(...) without a null check. While DataServicesTracingCollector methods internally check for null, this direct property access will throw NPE if messageContext is null. The DataServiceRequest.dispatch() no-arg method calls dispatch(null), making this a possible code path.
Consider adding a null guard:
for (int i = 0; i < n; i++) {
DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i));
- messageContext.setProperty(MULTI_REQUEST_LAST_INDEX_PROPERTY, i);
+ if (messageContext != null) {
+ messageContext.setProperty(MULTI_REQUEST_LAST_INDEX_PROPERTY, i);
+ }
result = reqList.get(i).dispatch(messageContext);
DataServicesTracingCollector.closerMultiEvent(messageContext, i, result);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public synchronized OMElement execute(MessageContext messageContext) throws DataServiceFault { | |
| OMElement result; | |
| List<DataServiceRequest> reqList = this.getRequests(); | |
| int n = reqList.size(); | |
| OMElement resultElement = null; | |
| for (int i = 0; i < n; i++) { | |
| result = reqList.get(i).dispatch(); | |
| DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i)); | |
| messageContext.setProperty(MULTI_REQUEST_LAST_INDEX_PROPERTY, i); | |
| result = reqList.get(i).dispatch(messageContext); | |
| DataServicesTracingCollector.closerMultiEvent(messageContext, i, result); | |
| public synchronized OMElement execute(MessageContext messageContext) throws DataServiceFault { | |
| OMElement result; | |
| List<DataServiceRequest> reqList = this.getRequests(); | |
| int n = reqList.size(); | |
| OMElement resultElement = null; | |
| for (int i = 0; i < n; i++) { | |
| DataServicesTracingCollector.reportMultiEvent(messageContext, i, reqList.get(i)); | |
| if (messageContext != null) { | |
| messageContext.setProperty(MULTI_REQUEST_LAST_INDEX_PROPERTY, i); | |
| } | |
| result = reqList.get(i).dispatch(messageContext); | |
| DataServicesTracingCollector.closerMultiEvent(messageContext, i, result); |
🤖 Prompt for AI Agents
In
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/boxcarring/RequestBox.java
around lines 63 to 72, the code calls messageContext.setProperty(...) and
DataServicesTracingCollector methods without checking if messageContext is null
which can cause a NullPointerException (dispatch may be called with null). Add a
null guard: if messageContext is non-null, perform the tracing/reporting and
setProperty calls as written; otherwise skip those calls and invoke
reqList.get(i).dispatch(null) (or dispatch with the existing null) so dispatch
still runs but no property access or tracing occurs on a null messageContext.
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.
Check this suggestion
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.
@AmilaSamith, I've reviewed the suggestion. The concern is valid based on the code flow:
Tracing the null path:
- In
DataServiceRequest.java, the no-argdispatch()method delegates todispatch(null)(lines visible in the AI summary) - This null
MessageContextis then passed toprocessRequest(messageContext) - For
BoxcarringDataServiceRequest,processRequest()callsexecute(messageContext)inRequestBox - At line 70 in
RequestBox.execute(),messageContext.setProperty(...)is called without a null check
Result: If the no-arg dispatch() is called anywhere in the codebase, it will cause a NullPointerException at line 70.
The suggested null guard is appropriate since:
DataServicesTracingCollectormethods already handle null messageContext internally (based on the pattern)- The
setPropertycall is purely for tracing infrastructure and shouldn't break the core boxcarring flow - The
dispatch(messageContext)call on line 71 should work fine with null (delegates back to no-arg version)
Would you like to apply this fix, or is there a guarantee that execute() will never receive a null messageContext in your deployment?
| public static void closerMultiEvent(MessageContext messageContext, int currentIndex, OMElement result) { | ||
| handleCloseEvents(messageContext, result, currentIndex + MULTI_REQUEST_BASE_INDEX); | ||
| } |
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.
Typo in method name: closerMultiEvent should be closeMultiEvent.
This appears to be a typo. All other close methods follow the pattern close*Event.
- public static void closerMultiEvent(MessageContext messageContext, int currentIndex, OMElement result) {
+ public static void closeMultiEvent(MessageContext messageContext, int currentIndex, OMElement result) {
handleCloseEvents(messageContext, result, currentIndex + MULTI_REQUEST_BASE_INDEX);
}🤖 Prompt for AI Agents
In
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java
around lines 253-255, the method name closerMultiEvent is a typo and should be
renamed to closeMultiEvent; change the method declaration to public static void
closeMultiEvent(MessageContext messageContext, int currentIndex, OMElement
result) and update all internal references/usages (and any tests or javadocs) to
call closeMultiEvent instead of closerMultiEvent to keep naming consistent.
| private static String[] getOdataServiceDetails(MessageContext messageContext) { | ||
| String odataServiceName; | ||
| String odataServiceUri; | ||
| String configID; | ||
| Object transportInURL = messageContext.getProperty(TRANSPORT_IN_URL); | ||
| String uri = transportInURL != null ? transportInURL.toString() : ""; | ||
| int index = uri.indexOf(ODATA_SERVICE); | ||
| if (-1 != index) { | ||
| int serviceStart = index + ODATA_SERVICE.length(); | ||
| if (uri.length() > serviceStart + 1) { | ||
| odataServiceUri = uri.substring(serviceStart); | ||
| if (-1 != odataServiceUri.indexOf(URL_SEPARATOR_CHAR)) { | ||
| String[] params = odataServiceUri.split(URL_SEPARATOR); | ||
| odataServiceName = params[0]; | ||
| configID = params[1]; | ||
| return new String[] {odataServiceName, configID}; | ||
| } | ||
| } | ||
| } | ||
| return new String[] {DEFAULT_ODATA_SERVICE_NAME, null}; | ||
| } |
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.
Potential ArrayIndexOutOfBoundsException when parsing OData service URI.
If the URI contains only one segment after splitting (e.g., odata/serviceName without a config ID), accessing params[1] at Line 316 will throw an exception.
private static String[] getOdataServiceDetails(MessageContext messageContext) {
String odataServiceName;
String odataServiceUri;
String configID;
Object transportInURL = messageContext.getProperty(TRANSPORT_IN_URL);
String uri = transportInURL != null ? transportInURL.toString() : "";
int index = uri.indexOf(ODATA_SERVICE);
if (-1 != index) {
int serviceStart = index + ODATA_SERVICE.length();
if (uri.length() > serviceStart + 1) {
odataServiceUri = uri.substring(serviceStart);
if (-1 != odataServiceUri.indexOf(URL_SEPARATOR_CHAR)) {
String[] params = odataServiceUri.split(URL_SEPARATOR);
- odataServiceName = params[0];
- configID = params[1];
- return new String[] {odataServiceName, configID};
+ if (params.length >= 2) {
+ odataServiceName = params[0];
+ configID = params[1];
+ return new String[] {odataServiceName, configID};
+ } else if (params.length == 1) {
+ return new String[] {params[0], null};
+ }
}
}
}
return new String[] {DEFAULT_ODATA_SERVICE_NAME, null};
}🤖 Prompt for AI Agents
In
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java
around lines 302 to 322, the code assumes params[1] exists after splitting the
OData URI which can throw ArrayIndexOutOfBoundsException; change the parsing to
validate params length (or filter out empty segments) before accessing
params[1], assign configID = null if there is no second segment (and still set
odataServiceName = params[0] when present), and return appropriately so a
missing config ID is handled safely instead of throwing.
| private static Map<String, Object> getDataServiceProperties(DataServiceRequest request) { | ||
| DataService dataService = request.getDataService(); | ||
| String requestName = request.getRequestName(); | ||
| CallQuery callQuery = dataService.getCallableRequest(requestName).getCallQuery(); | ||
| Map<String, Object> customProperties = new HashMap<>(); | ||
| if (callQuery != null) { | ||
| Query query = callQuery.getQuery(); | ||
| String queryId = query.getQueryId(); | ||
| String configId = query.getConfigId(); | ||
| if (queryId != null) { | ||
| customProperties.put(DB_QUERY_ID, queryId); | ||
| } | ||
| if (configId != null) { | ||
| customProperties.put(DB_CONFIG_ID, configId); | ||
| } | ||
| } | ||
| return customProperties; | ||
| } |
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.
Potential NullPointerException if getCallableRequest returns null or getCallQuery returns null.
The code assumes getCallableRequest(requestName) returns a non-null value and that getCallQuery() is also non-null. If either is null, an NPE will occur.
private static Map<String, Object> getDataServiceProperties(DataServiceRequest request) {
DataService dataService = request.getDataService();
String requestName = request.getRequestName();
- CallQuery callQuery = dataService.getCallableRequest(requestName).getCallQuery();
Map<String, Object> customProperties = new HashMap<>();
- if (callQuery != null) {
+ var callableRequest = dataService.getCallableRequest(requestName);
+ if (callableRequest != null) {
+ CallQuery callQuery = callableRequest.getCallQuery();
+ if (callQuery == null) {
+ return customProperties;
+ }
Query query = callQuery.getQuery();
String queryId = query.getQueryId();
String configId = query.getConfigId();
if (queryId != null) {
customProperties.put(DB_QUERY_ID, queryId);
}
if (configId != null) {
customProperties.put(DB_CONFIG_ID, configId);
}
}
return customProperties;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private static Map<String, Object> getDataServiceProperties(DataServiceRequest request) { | |
| DataService dataService = request.getDataService(); | |
| String requestName = request.getRequestName(); | |
| CallQuery callQuery = dataService.getCallableRequest(requestName).getCallQuery(); | |
| Map<String, Object> customProperties = new HashMap<>(); | |
| if (callQuery != null) { | |
| Query query = callQuery.getQuery(); | |
| String queryId = query.getQueryId(); | |
| String configId = query.getConfigId(); | |
| if (queryId != null) { | |
| customProperties.put(DB_QUERY_ID, queryId); | |
| } | |
| if (configId != null) { | |
| customProperties.put(DB_CONFIG_ID, configId); | |
| } | |
| } | |
| return customProperties; | |
| } | |
| private static Map<String, Object> getDataServiceProperties(DataServiceRequest request) { | |
| DataService dataService = request.getDataService(); | |
| String requestName = request.getRequestName(); | |
| Map<String, Object> customProperties = new HashMap<>(); | |
| var callableRequest = dataService.getCallableRequest(requestName); | |
| if (callableRequest != null) { | |
| CallQuery callQuery = callableRequest.getCallQuery(); | |
| if (callQuery == null) { | |
| return customProperties; | |
| } | |
| Query query = callQuery.getQuery(); | |
| String queryId = query.getQueryId(); | |
| String configId = query.getConfigId(); | |
| if (queryId != null) { | |
| customProperties.put(DB_QUERY_ID, queryId); | |
| } | |
| if (configId != null) { | |
| customProperties.put(DB_CONFIG_ID, configId); | |
| } | |
| } | |
| return customProperties; | |
| } |
🤖 Prompt for AI Agents
In
components/data/data-services/org.wso2.micro.integrator.dataservices.core/src/main/java/org/wso2/micro/integrator/dataservices/core/opentelemetry/DataServicesTracingCollector.java
around lines 337 to 354, the code dereferences
request.getDataService().getCallableRequest(requestName) and then getCallQuery()
without null checks which can cause NPEs; guard against null by first retrieving
the callableRequest into a local variable, verify callableRequest != null before
calling getCallQuery(), then verify callQuery != null (and Query != null) before
accessing queryId/configId, and if any are null simply skip adding those
properties (optionally log a debug/warn) and return the customProperties map.
| DataServicesTracingCollector.reportEntryEvent(axis2MessageContext); | ||
| OMElement omElement = DataServiceProcessor.dispatch(axis2MessageContext); | ||
| DataServicesTracingCollector.closeEntryEvent(axis2MessageContext, omElement); |
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.
Tracing instrumentation looks good, but exception handling is incomplete.
The entry/exit tracing pattern around the dispatch call is implemented correctly. However, there's a critical gap in exception handling: if an AxisFault is thrown after reportEntryEvent is called (line 211), the tracing flow won't be closed because the AxisFault catch block (lines 255-260) doesn't call closeFlowForcefully.
This issue is addressed in the next comment on line 247.
🤖 Prompt for AI Agents
In
components/mediation/mediators/dataservices-mediator/org.wso2/micro/integrator/mediator/dataservice/DataServiceCallMediator.java
around lines 211-213 (and the AxisFault catch at 255-260), ensure tracing is
always closed when reportEntryEvent has been called: either wrap the dispatch
call and subsequent closeEntryEvent in a try/finally so closeEntryEvent or
closeFlowForcefully runs on all exits, or explicitly invoke
DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext) inside the
AxisFault catch (and any other exception paths) before rethrowing/handling the
fault; keep the existing closeEntryEvent for normal flow and use
closeFlowForcefully only for error paths to guarantee the tracing flow is
terminated.
| axisMsgCtx.setEnvelope(createDefaultSOAPEnvelope(messageContext)); | ||
| } | ||
| } catch (DataServiceFault dataServiceFault) { | ||
| DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, dataServiceFault); |
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.
Critical: Add tracing cleanup to the AxisFault catch block.
The DataServiceFault catch block correctly calls closeFlowForcefully, but the AxisFault catch block (lines 255-260) doesn't. If an AxisFault is thrown after reportEntryEvent is called on line 211, the tracing flow will remain open, leading to incomplete traces and potential resource leaks.
Apply this diff to add tracing cleanup to the AxisFault handler:
} catch (AxisFault axisFault) {
+ DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, axisFault);
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug(axisFault.getMessage());
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, dataServiceFault); | |
| } catch (AxisFault axisFault) { | |
| DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext, DATA_SERVICE_INDEX, axisFault); | |
| if (synLog.isTraceOrDebugEnabled()) { | |
| synLog.traceOrDebug(axisFault.getMessage()); | |
| } |
🤖 Prompt for AI Agents
In
components/mediation/mediators/dataservices-mediator/org.wso2/micro/integrator/mediator/dataservice/src/main/java/org/wso2/micro/integrator/mediator/dataservice/DataServiceCallMediator.java
around line 247, the AxisFault catch block does not perform tracing cleanup
which can leave the tracing flow open; update the AxisFault handler to call
DataServicesTracingCollector.closeFlowForcefully(axis2MessageContext,
DATA_SERVICE_INDEX, dataServiceFault) just like the DataServiceFault handler —
if dataServiceFault is not in scope create one from the AxisFault (or pass null
only if safe) before calling closeFlowForcefully, and keep the existing
exception handling/logging intact.
fixes: #4496
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.