From 0435e0ab18feb81174d02c6514e79b3f669fad50 Mon Sep 17 00:00:00 2001 From: jpmcmu Date: Fri, 4 Oct 2024 14:08:05 -0400 Subject: [PATCH 1/7] HPCC-32688 Add JirabotMerge Github Action - Added a Github action to update Jira issues upon PR merger Signed-off-by: James McMullan James.McMullan@lexisnexis.com --- .github/workflows/jirabot-merge.yml | 299 ++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 .github/workflows/jirabot-merge.yml diff --git a/.github/workflows/jirabot-merge.yml b/.github/workflows/jirabot-merge.yml new file mode 100644 index 00000000000..57aa9b02879 --- /dev/null +++ b/.github/workflows/jirabot-merge.yml @@ -0,0 +1,299 @@ +name: Jirabot - Merge + +on: + pull_request_target: + types: [closed] + branches: + - "master" + - "candidate-*" + +jobs: + jirabot: + runs-on: ubuntu-latest + if: github.event.pull_request.merged == true + steps: + - name: "Debug Vars" + env: + JIRA_URL : ${{ vars.JIRA_URL }} + PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }} + PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }} + PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }} + PULL_URL: ${{ github.event.pull_request.html_url }} + COMMENTS_URL: ${{ github.event.pull_request.comments_url }} + BRANCH_NAME: ${{ github.ref_name }} + run: | + echo "JIRA_URL: $JIRA_URL" + echo "Pull Request Number: $PULL_REQUEST_NUMBER" + echo "Pull Request Title: $PULL_REQUEST_TITLE" + echo "Pull Request Author Name: $PULL_REQUEST_AUTHOR_NAME" + echo "Pull Request URL: $PULL_URL" + echo "Comments URL: $COMMENTS_URL" + echo "Branch Name: $BRANCH_NAME" + - uses: "actions/setup-python@v5" + with: + python-version: "3.8" + - name: "Install dependencies" + run: | + set -xe + python -VV + python -m site + python -m pip install --upgrade pip setuptools wheel + python -m pip install --upgrade atlassian-python-api + python -m pip install --upgrade jira + - name: "Checkout" + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.base.ref }} + fetch-depth: 0 + fetch-tags: true + - name: "Run" + env: + JIRABOT_USERNAME : ${{ secrets.JIRABOT_USERNAME }} + JIRABOT_PASSWORD : ${{ secrets.JIRABOT_PASSWORD }} + JIRA_URL : ${{ vars.JIRA_URL }} + PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }} + PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }} + PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }} + PULL_URL: ${{ github.event.pull_request.html_url }} + PROJECT_CONFIG: ${{ vars.PROJECT_CONFIG}} + COMMENTS_URL: ${{ github.event.pull_request.comments_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH_NAME: ${{ github.ref_name }} + shell: python + run: | + import os + import re + import subprocess + import time + import sys + import json + from atlassian.jira import Jira + + def extractVersion(versionStr): + parts = versionStr.split('.') + if len(parts) != 3: + print('Invalid version: ' + versionStr) + sys.exit(1) + if parts[2].lower() == 'x': + parts[2] = '0' + + major, minor, point = map(int, parts) + return [major, minor, point] + + def getTagVersionForCmd(cmd): + versionPattern = re.compile(r".*([0-9]+\.[0-9]+\.[0-9]+).*") + + # Get latest release version + gitTagProcess = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) + (output, err) = gitTagProcess.communicate() + gitTagProcessStatus = gitTagProcess.wait() + + if gitTagProcessStatus != 0: + print('Unable to retrieve latest git tag.') + sys.exit(1) + + latestGitTag = str(output) + + versionMatch = versionPattern.match(latestGitTag) + if versionMatch: + return extractVersion(versionMatch.group(1)) + else: + print('Unable to extract version from git tag.') + sys.exit(2) + + def buildVersionString(version): + major, minor, point = map(int, version) + return f"{major}.{minor}.{point}" + + def createReleaseTagPattern(projectConfig, major = None, minor = None, point = None): + releaseTagPrefix = projectConfig.get('tagPrefix') + releaseTagPostfix = projectConfig.get('tagPostfix') + + if releaseTagPrefix is None or releaseTagPostfix is None: + print('Error: PROJECT_CONFIG is missing required fields: tagPrefix and/or tagPostfix') + sys.exit(1) + + releaseTagPattern = releaseTagPrefix + if major is not None: + releaseTagPattern += str(major) + '\\.' + else: + releaseTagPattern += '[0-9]+\\.' + + if minor is not None: + releaseTagPattern += str(minor) + '\\.' + else: + releaseTagPattern += '[0-9]+\\.' + + if point is not None: + releaseTagPattern += str(point) + '(-[0-9]+)?' + else: + releaseTagPattern += '[0-9]+(-[0-9]+)?' + + releaseTagPattern += releaseTagPostfix + '$' + + return releaseTagPattern + + def getLatestSemVer(projectConfig, major = None, minor = None, point = None): + cmd = "git tag --list --sort=-v:refname | grep -E '" + createReleaseTagPattern(projectConfig, major, minor, point) + "' | head -n 1" + return getTagVersionForCmd(cmd) + + def generateFixVersionList(jira, projectConfig, projectName, branchName): + latestVersion = getLatestSemVer(projectConfig) + + # If we are merging into master we assume it is going into the next minor release + fixVersions = [] + if branchName == "master": + fixVersions = [buildVersionString([latestVersion[0], latestVersion[1] + 2, 0])] + else: + # Extract candidate branch major / minor version + candidateBranchPattern = re.compile(r"candidate-([0-9]+\.[0-9]+\.([0-9]+|x)).*") + branchVersionMatch = candidateBranchPattern.match(branchName) + branchVersion = extractVersion(branchVersionMatch.group(1)) + + # Get latest release in branch + latestBranchVer = getLatestSemVer(projectConfig, branchVersion[0], branchVersion[1]) + + curMajor = branchVersion[0] + latestMajor = latestVersion[0] + while curMajor <= latestMajor: + latestVersionInMajor = getLatestSemVer(projectConfig, curMajor) + + curMinor = 0 + if curMajor == branchVersion[0]: + curMinor = branchVersion[1] + + latestMinor = latestVersionInMajor[1] + + while curMinor <= latestMinor: + latestPointInMinor = getLatestSemVer(projectConfig, curMajor, curMinor) + fixVersions.append(buildVersionString([latestPointInMinor[0], latestPointInMinor[1], latestPointInMinor[2] + 2])) + curMinor += 2 + curMajor += 1 + + for fixVersion in fixVersions: + try: + alreadyHasFixVersion = False + versions = jira.get_project_versions(projectName) + for v in versions: + if v['name'] == fixVersion: + alreadyHasFixVersion = True + + if not alreadyHasFixVersion: + project = jira.get_project(projectName) + projectId = project['id'] + jira.add_version(projectName, projectId, fixVersion) + except Exception as error: + print('Error: Unable to add fix version: ' + fixVersion + ' with: ' + str(error)) + sys.exit(1) + + return fixVersions + + def resolveIssue(jira, projectName, issue, fixVersions) -> str: + result = '' + + versionsToAdd = [] + + issueName = issue['key'] + issueFields = issue['fields'] + + for addedVersion in fixVersions: + alreadyHasFixVersion = False + for v in issueFields['fixVersions']: + if v['name'] == addedVersion: + alreadyHasFixVersion = True + break + if not alreadyHasFixVersion: + versionsToAdd.append(addedVersion) + + versions = jira.get_project_versions(projectName) + updatedVersionList = [] + for v in issueFields['fixVersions']: + updatedVersionList.append({'id' : v['id']}) + + for fixVersionName in versionsToAdd: + fixVersion = None + for v in versions: + if v['name'] == fixVersionName: + fixVersion = v + break + + if fixVersion: + updatedVersionList.append({'id' : fixVersion['id']}) + result += "Added fix version: " + fixVersionName + "\n" + else: + result += "Error: Unable to find fix version: " + fixVersionName + "\n" + + if len(versionsToAdd) > 0: + try: + jira.update_issue_field(issueName, {'fixVersions': updatedVersionList}) + except Exception as error: + result += 'Error: Updating fix versions failed with: "' + str(error) + '\n' + else: + result += "Fix versions already added.\n" + + statusName = str(issueFields['status']['name']) + if statusName != 'Resolved': + try: + transitionId = jira.get_transition_id_to_status_name(issueName, 'Resolved') + jira.set_issue_status_by_transition_id(issueName, transitionId) + result += "Workflow Transition: 'Resolve issue'\n" + except Exception as error: + result += 'Error: Transitioning to: "Resolved" failed with: "' + str(error) + '\n' + + return result + + jirabot_user = os.environ['JIRABOT_USERNAME'] + jirabot_pass = os.environ['JIRABOT_PASSWORD'] + jira_url = os.environ['JIRA_URL'] + + pr = os.environ['PULL_REQUEST_NUMBER'] + title = os.environ['PULL_REQUEST_TITLE'] + user = os.environ['PULL_REQUEST_AUTHOR_NAME'] + pull_url = os.environ['PULL_URL'] + github_token = os.environ['GITHUB_TOKEN'] + branch_name = os.environ['BRANCH_NAME'] + comments_url = os.environ['COMMENTS_URL'] + + projectConfig = json.loads(os.environ['PROJECT_CONFIG']) + if not isinstance(projectConfig, dict): + print('Error: PROJECT_CONFIG is not a valid JSON object, aborting.') + sys.exit(1) + + if 'tagPrefix' not in projectConfig or 'tagPostfix' not in projectConfig: + print('Error: PROJECT_CONFIG is missing required fields: tagPrefix and/or tagPostfix') + sys.exit(1) + + project_prefixes = projectConfig.get('projectPrefixes') + if project_prefixes is None: + print('Error: PROJECT_CONFIG is missing required field: projectPrefixes') + sys.exit(1) + + project_list_regex = '|'.join(project_prefixes) + + result = '' + issuem = re.search("(" + project_list_regex + ")-[0-9]+", title, re.IGNORECASE) + if issuem: + project_name = issuem.group(1) + issue_name = issuem.group() + + jira = Jira(url=jira_url, username=jirabot_user, password=jirabot_pass, cloud=True) + + if not jira.issue_exists(issue_name): + sys.exit('Error: Unable to find Jira issue: ' + issue_name) + else: + issue = jira.issue(issue_name) + + result = 'Jirabot Action Result:\n' + + fixVersions = generateFixVersionList(jira, projectConfig, project_name, branch_name) + result += resolveIssue(jira, project_name, issue, fixVersions) + jira.issue_add_comment(issue_name, result) + + # Escape the result for JSON + result = json.dumps(result) + + subprocess.run(['curl', '-X', 'POST', comments_url, '-H', 'Content-Type: application/json', '-H', f'Authorization: token {github_token}', '--data', f'{{ "body": {result} }}'], check=True) + else: + print('Unable to find Jira issue name in title') + + print(result) From 09d82ed8fa6f53aaef716d73a81445b036153088 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Mon, 14 Oct 2024 16:45:14 +0100 Subject: [PATCH 2/7] Split off 9.8.30 Signed-off-by: Gordon Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index 24f39d1d0ab..169009c09d3 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.8.29-closedown0 +version: 9.8.31-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.8.29-closedown0 +appVersion: 9.8.31-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 4b7c13034ee..bbeb58d63f3 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1477,7 +1477,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.8.29-closedown0 +helmVersion: 9.8.31-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 2bbb6ddc179..972d069e4b6 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 8 ) -set ( HPCC_POINT 29 ) +set ( HPCC_POINT 31 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-10-03T16:48:15Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-10-14T15:45:14Z" ) ### From f138e1267b4768885ca17f141ac3a20b205561f8 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Mon, 14 Oct 2024 16:46:30 +0100 Subject: [PATCH 3/7] Split off 9.6.56 Signed-off-by: Gordon Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index 36f4a90e113..2bb4aa0f3d1 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.6.55-closedown0 +version: 9.6.57-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.6.55-closedown0 +appVersion: 9.6.57-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 4b163f43aa5..1e04212ec7f 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1477,7 +1477,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.6.55-closedown0 +helmVersion: 9.6.57-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index e7cd9014923..1def3293376 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 6 ) -set ( HPCC_POINT 55 ) +set ( HPCC_POINT 57 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-10-03T16:47:27Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-10-14T15:46:30Z" ) ### From 1c24b22a43b65f96eb349608ba4ff67037de2c1d Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Mon, 14 Oct 2024 16:47:43 +0100 Subject: [PATCH 4/7] Split off 9.4.104 Signed-off-by: Gordon Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index 36d2e25e73d..5574efcd95b 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.4.103-closedown0 +version: 9.4.105-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.4.103-closedown0 +appVersion: 9.4.105-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 7676de2ad68..f29cbccc8d4 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1473,7 +1473,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.4.103-closedown0 +helmVersion: 9.4.105-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index c050f7b2826..81be0842570 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 4 ) -set ( HPCC_POINT 103 ) +set ( HPCC_POINT 105 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-10-03T16:46:08Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-10-14T15:47:43Z" ) ### From 93685b486b91aa8a0d28866da2a7ce41d1776f67 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Mon, 14 Oct 2024 16:48:48 +0100 Subject: [PATCH 5/7] Split off 9.2.130 Signed-off-by: Gordon Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index 55b71a45818..f22b2a933cf 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.2.129-closedown0 +version: 9.2.131-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.2.129-closedown0 +appVersion: 9.2.131-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 0dd032a0298..aec2e179876 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1361,7 +1361,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.2.129-closedown0 +helmVersion: 9.2.131-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index e39e59c893a..322310289e1 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 2 ) -set ( HPCC_POINT 129 ) +set ( HPCC_POINT 131 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-10-03T16:44:57Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-10-14T15:48:48Z" ) ### From 9293ae5af6279e3e4cf00fb944a23e9dd153b7c5 Mon Sep 17 00:00:00 2001 From: Terrence Asselin Date: Thu, 26 Sep 2024 10:29:00 -0500 Subject: [PATCH 6/7] HPCC-32639 Prevent ECLWatch file rename from mangling path Ensure a path separator is added between two components of the new path as it is used to update metadata and rename a file. Signed-off-by: Terrence Asselin --- dali/base/dadfs.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/dali/base/dadfs.cpp b/dali/base/dadfs.cpp index faa42e68a9e..e22e5c7b487 100644 --- a/dali/base/dadfs.cpp +++ b/dali/base/dadfs.cpp @@ -118,6 +118,19 @@ inline unsigned groupDistance(IGroup *grp1,IGroup *grp2) return grp1->distance(grp2); } +inline StringBuffer &appendEnsurePathSepChar(StringBuffer &dest, StringBuffer &newPart, char psc) +{ + addPathSepChar(dest, psc); + if (newPart.length() > 0) + { + if (isPathSepChar(newPart.charAt(0))) + dest.append(newPart.str()+1); + else + dest.append(newPart); + } + return dest; +} + static StringBuffer &normalizeFormat(StringBuffer &in) { @@ -4474,7 +4487,8 @@ protected: friend class CDistributedFilePart; if (isPathSepChar(newPath.charAt(newPath.length()-1))) newPath.setLength(newPath.length()-1); newPath.remove(0, myBase.length()); - newdir.append(baseDir).append(newPath); + newdir.append(baseDir); + appendEnsurePathSepChar(newdir, newPath, psc); StringBuffer fullname; CIArrayOf newNames; unsigned i; @@ -4493,7 +4507,8 @@ protected: friend class CDistributedFilePart; StringBuffer copyDir(baseDir); adjustClusterDir(i, copy, copyDir); - fullname.clear().append(copyDir).append(newPath); + fullname.clear().append(copyDir); + appendEnsurePathSepChar(fullname, newPath, psc); newNames.item(i).append(fullname); } } From 3d658e72c0f0763bc515e77f0baa5dae6934f5f9 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:10:41 -0400 Subject: [PATCH 7/7] HPCC-32751 ECL Watch v9 log viewer dynamic columns changes the way the ECL Watch v9 log viewer component defines its grid columns and filter fields, relying on the meta-data describing the engine returned by /WsLogaccess/GetLogAccessInfo Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/Logs.tsx | 35 +++++++++++++++++++++++---- esp/src/src-react/hooks/platform.ts | 23 ++++++++++++++++-- esp/src/src/Utility.ts | 8 ++++++ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/esp/src/src-react/components/Logs.tsx b/esp/src/src-react/components/Logs.tsx index 675bfca7b9b..40e65d0fc1a 100644 --- a/esp/src/src-react/components/Logs.tsx +++ b/esp/src/src-react/components/Logs.tsx @@ -1,9 +1,10 @@ import * as React from "react"; import { CommandBar, ContextualMenuItemType, ICommandBarItemProps } from "@fluentui/react"; -import { GetLogsExRequest, LogaccessService, TargetAudience, LogType } from "@hpcc-js/comms"; +import { GetLogsExRequest, LogaccessService, LogType, TargetAudience, WsLogaccess } from "@hpcc-js/comms"; import { Level, scopedLogger } from "@hpcc-js/util"; import nlsHPCC from "src/nlsHPCC"; -import { logColor, wuidToDate, wuidToTime } from "src/Utility"; +import { logColor, removeAllExcept, wuidToDate, wuidToTime } from "src/Utility"; +import { useLogAccessInfo } from "../hooks/platform"; import { HolyGrail } from "../layouts/HolyGrail"; import { pushParams } from "../util/history"; import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid"; @@ -92,6 +93,8 @@ const levelMap = (level) => { } }; +const columnOrder: string[] = [WsLogaccess.LogColumnType.timestamp, WsLogaccess.LogColumnType.message]; + export const Logs: React.FunctionComponent = ({ wuid, filter = defaultFilter, @@ -109,9 +112,26 @@ export const Logs: React.FunctionComponent = ({ const now = React.useMemo(() => new Date(), []); + const { columns: logColumns } = useLogAccessInfo(); + // Grid --- const columns = React.useMemo((): FluentColumns => { - return { + // we've defined the columnOrder array above to ensure specific columns will + // appear on the left-most side of the grid, eg timestamps and log messages + const cols = logColumns?.sort((a, b) => { + const logTypeA = columnOrder.indexOf(a.LogType); + const logTypeB = columnOrder.indexOf(b.LogType); + + if (logTypeA >= 0) { + if (logTypeB >= 0) { return logTypeA - logTypeB; } + return -1; + } else if (logTypeB >= 0) { + return 1; + } else { + return 0; + } + }); + const retVal = { timestamp: { label: nlsHPCC.TimeStamp, width: 140, sortable: false, }, message: { label: nlsHPCC.Message, width: 600, sortable: false, }, components: { label: nlsHPCC.ContainerName, width: 150, sortable: false }, @@ -129,7 +149,10 @@ export const Logs: React.FunctionComponent = ({ logid: { label: nlsHPCC.Sequence, width: 70, sortable: false, }, threadid: { label: nlsHPCC.ThreadID, width: 60, sortable: false, }, }; - }, [wuid]); + const colTypes = cols?.map(c => c.LogType.toString()) ?? []; + removeAllExcept(retVal, colTypes); + return retVal; + }, [logColumns, wuid]); const copyButtons = useCopyButtons(columns, selection, "logaccess"); @@ -194,8 +217,10 @@ export const Logs: React.FunctionComponent = ({ delete retVal.jobId; } } + const colTypes = logColumns?.map(c => c.LogType.toString()) ?? []; + removeAllExcept(retVal, colTypes); return retVal; - }, [filter, wuid]); + }, [filter, logColumns, wuid]); return } diff --git a/esp/src/src-react/hooks/platform.ts b/esp/src/src-react/hooks/platform.ts index 66dac5d9487..33f2089c260 100644 --- a/esp/src/src-react/hooks/platform.ts +++ b/esp/src/src-react/hooks/platform.ts @@ -2,7 +2,7 @@ import * as React from "react"; import { Octokit } from "octokit"; import { useConst } from "@fluentui/react-hooks"; import { scopedLogger } from "@hpcc-js/util"; -import { Topology, WsTopology, WorkunitsServiceEx } from "@hpcc-js/comms"; +import { LogaccessService, Topology, WsLogaccess, WsTopology, WorkunitsServiceEx } from "@hpcc-js/comms"; import { getBuildInfo, BuildInfo, fetchModernMode } from "src/Session"; import { cmake_build_type, containerized, ModernMode } from "src/BuildInfo"; import { sessionKeyValStore, userKeyValStore } from "src/KeyValStore"; @@ -10,6 +10,8 @@ import { Palette } from "@hpcc-js/common"; const logger = scopedLogger("src-react/hooks/platform.ts"); +export const service = new LogaccessService({ baseUrl: "" }); + declare const dojoConfig; export function useBuildInfo(): [BuildInfo, { isContainer: boolean, currencyCode: string, opsCategory: string }] { @@ -205,4 +207,21 @@ export function useModernMode(): { }, [modernMode, sessionStore, userStore]); return { modernMode, setModernMode }; -} \ No newline at end of file +} + +export function useLogAccessInfo(): { + managerType: string; + columns: WsLogaccess.Column[] +} { + const [managerType, setManagerType] = React.useState(""); + const [columns, setColumns] = React.useState(); + + React.useEffect(() => { + service.GetLogAccessInfo({}).then(response => { + setManagerType(response.RemoteLogManagerType ?? ""); + setColumns(response?.Columns?.Column); + }); + }, []); + + return { managerType, columns }; +} \ No newline at end of file diff --git a/esp/src/src/Utility.ts b/esp/src/src/Utility.ts index cc78350ed6d..32c0a912f59 100644 --- a/esp/src/src/Utility.ts +++ b/esp/src/src/Utility.ts @@ -1307,4 +1307,12 @@ export function wuidToTime(wuid: string): string { export function wuidToDateTime(wuid: string): Date { return new Date(`${wuidToDate(wuid)}T${wuidToTime(wuid)}Z`); +} + +export function removeAllExcept(arr: any, keysToKeep: string[]): void { + for (const key of Object.keys(arr)) { + if (keysToKeep.indexOf(key) < 0) { + delete arr[key]; + } + } } \ No newline at end of file