Skip to content
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

Added workbook for Logic Apps B2B tracking dashboard #2862

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

pravagar
Copy link

Summary

Logic Apps B2B tracking dashboard is a workbook that provides insights into B2B transactions. Customers can view which transactions are successful, which are failing, and the reasons for failure as well as the volume of transactions over time.
The dashboard also provides comprehensive insights into the transactions and corresponding acknowledgements.

Screenshots

image

image

Validation

End to end validation is not done yet.

  • Validate your changes using one or more of the testing methods.

    Make sure you've tested your template content. Fixing things while in PR is trivial. Hotfixing it later is very expensive; at the current time at least 3 teams are involved in a hotfix!

Checklist

  • If you are adding a new template, gallery, or folder, add your team and folder/file(s) to the CODEOWNERS file at the root of the repo. CODEOWNERS entries should be teams, not individuals.
    When done correctly, this means that from then on your team does reviews of your things, not the workbooks team.
  • Ensure all steps in your template have meaningful names.
  • Ensure all parameters and grid columns have display names set so they can be localized.

@@ -0,0 +1,1069 @@
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Pascal casing, acronyms like B2B are generally capitalized in their entirety because they are treated as distinct entities and retain their original capitalization. Thus, B2B remains unchanged in Pascal casing.

If you're following a convention where acronyms longer than two letters are capitalized but those with two letters are only capitalized for the first letter (e.g., IoTService for "Internet of Things Service"), you might adjust this. However, B2B is most commonly kept fully capitalized due to its unique meaning and recognition as an acronym, resulting in B2BIntegration or similar usages.

"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"let queryResult = (AS2TrackRecords\\r\\n| where EventTime {TimeRange}\\r\\n| where RecordType == \\\"AS2Message\\\"\\r\\n| where isnotempty(CorrelationMessageId)\\r\\n| project \\r\\n AgreementName,\\r\\n MessageId,\\r\\n CorrelationMessageId,\\r\\n SenderPartnerName,\\r\\n ReceiverPartnerName, \\r\\n MessageTime = EventTime,\\r\\n MessageClientTrackingId = ClientRequestId,\\r\\n MessageSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n MessageResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n MessageActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n MessageLogicAppName = WorkflowRunOperationInfo.Workflow.Name,\\r\\n MessageStatus = iff (IsMessageFailed, \\\"Failed\\\", \\\"Successful\\\"), \\r\\n MessageDirection = Direction,\\r\\n IsMdnExpected,\\r\\n DirectionBasedCorrelationId = iff (Direction == \\\"Receive\\\", strcat_delim(\\\"/\\\", WorkflowRunOperationInfo.RunInstance.OperationName, WorkflowRunOperationInfo.Workflow.Name, IntegrationAccountResourceGroup, IntegrationAccountSubscriptionId), \\\"\\\")\\r\\n| join kind=leftouter (\\r\\nAS2TrackRecords\\r\\n| where EventTime {TimeRange}\\r\\n| where RecordType == \\\"AS2MDN\\\"\\r\\n| project \\r\\n MdnStatusCode = MessageProperties.StatusCode,\\r\\n CorrelationMessageId, \\r\\n AckDirection = Direction, \\r\\n AckTime = EventTime,\\r\\n AckClientTrackingId = ClientRequestId,\\r\\n AckSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n AckResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n AckActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n AckLogicAppName = WorkflowRunOperationInfo.Workflow.Name,\\r\\n DirectionBasedCorrelationId = iff (Direction == \\\"Send\\\", strcat_delim(\\\"/\\\", WorkflowRunOperationInfo.RunInstance.OperationName, WorkflowRunOperationInfo.Workflow.Name, IntegrationAccountResourceGroup, IntegrationAccountSubscriptionId), \\\"\\\")\\r\\n| extend MdnStatus = iff (MdnStatusCode ==\\\"1\\\", \\\"Successful\\\", \\\"Failed\\\")\\r\\n) on CorrelationMessageId, DirectionBasedCorrelationId\\r\\n| extend IsAckValid = AckTime > MessageTime\\r\\n| extend\\r\\n MessageStatus = iff(MessageStatus == \\\"Successful\\\" and IsMdnExpected,\\r\\n iff(isnotempty(MdnStatusCode) and IsAckValid, \\r\\n MdnStatus, \\r\\n \\\"Pending\\\"), \\r\\n MessageStatus), \\r\\n AckStatus = iff(IsMdnExpected,\\r\\n iff(isnotempty(MdnStatusCode) and IsAckValid, \\r\\n iff (MdnStatusCode ==\\\"1\\\", \\\"Successful\\\", \\\"Failed\\\"), \\\"Pending\\\"), \\r\\n \\\"NotRequired\\\")\\r\\n)\\r\\n| union \\r\\n(AS2TrackRecords\\r\\n| where EventTime {TimeRange}\\r\\n| where RecordType == \\\"AS2Message\\\"\\r\\n| where isempty(CorrelationMessageId)\\r\\n| project \\r\\n AgreementName,\\r\\n SenderPartnerName,\\r\\n ReceiverPartnerName,\\r\\n MessageTime = EventTime,\\r\\n MessageStatus = iff (IsMessageFailed, \\\"Failed\\\", \\\"Successful\\\"), \\r\\n MessageId,\\r\\n CorrelationMessageId, \\r\\n MessageClientTrackingId = ClientRequestId,\\r\\n MessageSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n MessageResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n MessageActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n MessageLogicAppName = WorkflowRunOperationInfo.Workflow.Name,\\r\\n MessageDirection = Direction,\\r\\n IsMdnExpected,\\r\\n DirectionBasedCorrelationId = iff (Direction == \\\"Receive\\\", strcat_delim(\\\"/\\\", WorkflowRunOperationInfo.RunInstance.OperationName, WorkflowRunOperationInfo.Workflow.Name, IntegrationAccountResourceGroup, IntegrationAccountSubscriptionId), \\\"\\\"))\\r\\n | union\\r\\n (EdiTrackRecords\\r\\n| where EventTime {TimeRange}\\r\\n| where RecordType == \\\"X12TransactionSet\\\"\\r\\n| where isnotempty(TransactionSetControlNumber)\\r\\n| where MessageProperties.MessageType !in (\\\"997\\\", \\\"999\\\")\\r\\n| project \\r\\n AgreementName,\\r\\n TransactionSetControlNumber,\\r\\n FunctionalGroupControlNumber,\\r\\n InterchangeControlNumber,\\r\\n SenderPartnerName,\\r\\n ReceiverPartnerName,\\r\\n MessageTime = EventTime,\\r\\n MessageClientTrackingId = ClientRequestId,\\r\\n MessageSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n MessageResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n MessageActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n MessageLogicAppName = WorkflowRunOperationInfo.Workflow.Name,\\r\\n MessageDirection = Direction,\\r\\n IsFunctionalAckExpected = MessageProperties.IsFunctionalAcknowledgmentExpected,\\r\\n TransactionSetStatus = iff (IsMessageFailed == \\\"false\\\", \\\"Successful\\\", \\\"Failed\\\")\\r\\n| join kind = leftouter (\\r\\nEdiTrackRecords \\r\\n| where EventTime {TimeRange}\\r\\n| where RecordType == \\\"X12TransactionSetAcknowledgment\\\"\\r\\n| where MessageProperties.ProcessingStatus != \\\"2\\\" // 1 - received, 2 generated, 3 sent\\r\\n| project\\r\\n AgreementName,\\r\\n TransactionSetControlNumber = RespondingTransactionSetControlNumber,\\r\\n FunctionalGroupControlNumber = RespondingFunctionalGroupControlNumber,\\r\\n TransactionSetAckStatusCode = iff(MessageProperties.StatusCode == \\\"1\\\", \\\"Accepted\\\", iff(MessageProperties.StatusCode == \\\"2\\\", \\\"Rejected\\\", \\\"AcceptedWithError\\\")) , // 1 Accepted, 2 AcceptedWithError, 3 Rejected\\r\\n TransactionSetAckDirection = iff(MessageProperties.Direction == 0, \\\"Send\\\", \\\"Receive\\\"), // 0 Send, 1 Receive \\r\\n TransactionSetAckTime = EventTime,\\r\\n TransactionSetAckClientTrackingId = ClientRequestId,\\r\\n TransactionSetAckSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n TransactionSetAckResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n TransactionSetAckActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n TransactionSetAckLogicAppName = WorkflowRunOperationInfo.Workflow.Name\\r\\n) on AgreementName, TransactionSetControlNumber, FunctionalGroupControlNumber \\r\\n| project \\r\\n AgreementName,\\r\\n SenderPartnerName,\\r\\n ReceiverPartnerName,\\r\\n MessageClientTrackingId,\\r\\n InterchangeControlNumber,\\r\\n FunctionalGroupControlNumber,\\r\\n TransactionSetControlNumber,\\r\\n TransactionSetStatus,\\r\\n MessageTime,\\r\\n MessageSubscriptionId,\\r\\n MessageResourceGroup,\\r\\n MessageActionName,\\r\\n MessageLogicAppName,\\r\\n IsFunctionalAckExpected,\\r\\n TransactionSetAckStatusCode,\\r\\n TransactionSetAckDirection,\\r\\n TransactionSetAckTime,\\r\\n TransactionSetAckClientTrackingId,\\r\\n TransactionSetAckSubscriptionId,\\r\\n TransactionSetAckResourceGroup,\\r\\n TransactionSetAckActionName,\\r\\n TransactionSetAckLogicAppName\\r\\n| join kind = leftouter (\\r\\nEdiTrackRecords \\r\\n| where EventTime {TimeRange}\\r\\n| where RecordType == \\\"X12FunctionalGroupAcknowledgment\\\"\\r\\n| where MessageProperties.ProcessingStatus != \\\"2\\\" // 1 - received, 2 generated, 3 sent\\r\\n| project\\r\\n AgreementName,\\r\\n FunctionalGroupControlNumber = RespondingFunctionalGroupControlNumber,\\r\\n FunctionalAckStatusCode = iff(MessageProperties.StatusCode == \\\"1\\\", \\\"Accepted\\\", iff(MessageProperties.StatusCode == \\\"2\\\", \\\"Rejected\\\", \\\"AcceptedWithError\\\")) , // 1 Accepted, 2 AcceptedWithError, 3 Rejected\\r\\n FunctionalAckDirection = iff(MessageProperties.Direction == 0, \\\"Send\\\", \\\"Receive\\\"), // 0 Send, 1 Receive \\r\\n FunctionalAckTime = EventTime,\\r\\n FunctionalAckClientTrackingId = ClientRequestId,\\r\\n FunctionalAckSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n FunctionalAckResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n FunctionalAckActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n FunctionalAckLogicAppName = WorkflowRunOperationInfo.Workflow.Name\\r\\n ) on AgreementName, FunctionalGroupControlNumber\\r\\n| project \\r\\n AgreementName,\\r\\n SenderPartnerName,\\r\\n ReceiverPartnerName,\\r\\n MessageClientTrackingId,\\r\\n InterchangeControlNumber,\\r\\n FunctionalGroupControlNumber,\\r\\n TransactionSetControlNumber,\\r\\n TransactionSetStatus,\\r\\n MessageTime,\\r\\n MessageSubscriptionId,\\r\\n MessageResourceGroup,\\r\\n MessageActionName,\\r\\n MessageLogicAppName,\\r\\n IsFunctionalAckExpected,\\r\\n TransactionSetAckStatusCode,\\r\\n TransactionSetAckStatus = iff(TransactionSetAckStatusCode == \\\"Accepted\\\", \\\"Successful\\\",\\\"Failed\\\"),\\r\\n TransactionSetAckDirection,\\r\\n TransactionSetAckTime,\\r\\n TransactionSetAckActionName,\\r\\n TransactionSetAckSubscriptionId,\\r\\n TransactionSetAckResourceGroup,\\r\\n TransactionSetAckLogicAppName,\\r\\n FunctionalAckStatusCode, // 1 Accepted, 2 AcceptedWithError, 3 Rejected\\r\\n FunctionalAckStatus = iff(FunctionalAckStatusCode == \\\"Accepted\\\", \\\"Successful\\\",\\\"Failed\\\"),\\r\\n FunctionalAckDirection , // 0 Send, 1 Receive \\r\\n FunctionalAckTime,\\r\\n FunctionalAckClientTrackingId,\\r\\n FunctionalAckSubscriptionId,\\r\\n FunctionalAckResourceGroup,\\r\\n FunctionalAckActionName,\\r\\n FunctionalAckLogicAppName,\\r\\n AckActionName = iff(isnotempty( TransactionSetAckActionName), TransactionSetAckActionName, FunctionalAckActionName),\\r\\n AckLogicAppName = iff(isnotempty( TransactionSetAckLogicAppName), TransactionSetAckLogicAppName, FunctionalAckLogicAppName),\\r\\n AckDirection = iff(isnotempty(TransactionSetAckDirection), TransactionSetAckDirection, FunctionalAckDirection),\\r\\n AckTime = iff(isnotempty(TransactionSetAckTime), TransactionSetAckTime, FunctionalAckTime)\\r\\n | extend IsAckValid = AckTime > MessageTime\\r\\n | extend MessageStatus = iff(TransactionSetStatus == \\\"Successful\\\" and IsFunctionalAckExpected ,\\r\\n iff(isnotempty(TransactionSetAckStatusCode) and IsAckValid, TransactionSetAckStatus, iff(isnotempty(FunctionalAckStatusCode) and IsAckValid, FunctionalAckStatus, \\\"Pending\\\")),\\r\\n TransactionSetStatus)\\r\\n | extend AckStatus = iff(IsFunctionalAckExpected == true , iff(isnotempty( TransactionSetAckStatusCode) and IsAckValid, TransactionSetAckStatusCode,\\r\\n iff (isnotempty( FunctionalAckStatusCode) and IsAckValid, FunctionalAckStatusCode, \\\"Pending\\\")), \\\"NotRequired\\\"))\\r\\n | union \\r\\n (EdiTrackRecords\\r\\n | where EventTime {TimeRange}\\r\\n | where RecordType == \\\"X12TransactionSet\\\"\\r\\n | where isempty(TransactionSetControlNumber)\\r\\n | where MessageProperties.MessageType !in (\\\"997\\\", \\\"999\\\")\\r\\n |project \\r\\n AgreementName,\\r\\n SenderPartnerName,\\r\\n ReceiverPartnerName,\\r\\n MessageClientTrackingId = ClientRequestId,\\r\\n InterchangeControlNumber,\\r\\n FunctionalGroupControlNumber,\\r\\n TransactionSetControlNumber,\\r\\n MessageTime = EventTime,\\r\\n MessageSubscriptionId = WorkflowRunOperationInfo.Workflow.SubscriptionId,\\r\\n MessageResourceGroup = WorkflowRunOperationInfo.Workflow.ResourceGroup,\\r\\n MessageActionName = WorkflowRunOperationInfo.Operation.OperationName,\\r\\n MssageLogicAppName = WorkflowRunOperationInfo.Workflow.Name,\\r\\n MessageDirection = Direction,\\r\\n IsFunctionalAckExpected = MessageProperties.IsFunctionalAcknowledgmentExpected\\r\\n | extend MessageStatus = \\\"Failed\\\")\\r\\n | summarize count() by MessageStatus;\\r\\n let NameColumn = datatable(MessageStatus:string)[\\\"Successful\\\", \\\"Pending\\\", \\\"Failed\\\"];\\r\\nNameColumn\\r\\n| lookup queryResult on MessageStatus \\r\\n| extend count = coalesce(['count_'], 0)\",\"clusterName\":\"{KustoCluster}\",\"databaseName\":\"{Database}\"}",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very difficult to review queries like this. Does the repo has no mean to keep the query separated from the json file so it may be formatted more traditionally and easily reviewed in a suitable IDE?

"content": {
"version": "NotebookGroup/1.0",
"groupType": "editable",
"title": "Partners",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are the workbooks text resources localized for non-English customers?

"id": "10f09616-dddf-41b0-8bdf-5d2676911c69",
"version": "KqlParameterItem/1.0",
"name": "X12AcknowledgementStatus",
"label": "Acknowledgement Status",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check with our content writer Esther, IIRC we do not capitalize the labels.

}
},
"name": "AllMessagesStatus",
"styleSettings": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any UX styling guidelines to follow for consistency?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants