在 Groovy 中使用一对多映射从 JSON 输出创建 CSV

问题描述 投票:0回答:1
我有一个请求,我想在第一个 Json 上运行一个循环,从中捕获一个项目和一个 url。然后,该 url 将检索另一个 json,其中包含与第一个 json 中的项目相对应的版本和阶段。 预期输出:-

项目版本相A1开发A2产品B1开发
以下是示例 json:- 第一个 Json,我们需要从中获取项目名称和版本 url。

{ "totalCount": 6884, "items": [ { "name": "$PROJECT_NAME", "description": "$PROJECT_DESCRIPTION", "projectLevelAdjustments": true, "cloneCategories": [ "DEEP_LICENSE", "LICENSE_TERM_FULFILLMENT", "COMPONENT_DATA", "VULN_DATA", "CUSTOM_FIELD_DATA", "VERSION_SETTINGS" ], "customSignatureEnabled": false, "customSignatureDepth": "5", "deepLicenseDataEnabled": false, "snippetAdjustmentApplied": false, "licenseConflictsEnabled": false, "projectGroup": "https://sample.test.com/api/project-groups/00000003-0003-0000-0000-000000000001", "createdAt": "2024-12-04T06:32:00.052Z", "createdBy": "MiSignetServer", "createdByUser": "https://sample.test.com/api/users/4c4ca1a7-bb08-4b41-b74c-4901c8bffa61", "updatedAt": "2024-12-04T06:32:00.052Z", "updatedBy": "MiSignetServer", "updatedByUser": "https://sample.test.com/api/users/4c4ca1a7-bb08-4b41-b74c-4901c8bffa61", "source": "CUSTOM", "_meta": { "allow": [ "DELETE", "GET", "PUT" ], "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5", "links": [ { "rel": "versions", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/versions" }, { "rel": "canonicalVersion", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/versions/85f8dfbb-0c83-4c17-ae62-1df5b422d036" }, { "rel": "assignable-users", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/assignable-users" }, { "rel": "assignable-usergroups", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/assignable-usergroups" }, { "rel": "users", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/users" }, { "rel": "usergroups", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/usergroups" }, { "rel": "tags", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/tags" }, { "rel": "project-mappings", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/project-mappings" }, { "rel": "project-journal", "href": "https://sample.test.com/api/journal/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5" }, { "rel": "custom-fields", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/custom-fields" }, { "rel": "sbom-fields", "href": "https://sample.test.com/api/projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/sbom-fields" }, { "rel": "lts-project-versions", "href": "https://sample.test.com/api/lts-projects/49cd7067-c29c-4df2-8b18-259b744a1ec5/lts-project-versions" } ] } }, { "name": "248_EMB_Mobile_App_OWHB_morelite_owhb_hk", "projectLevelAdjustments": true, "cloneCategories": [ "DEEP_LICENSE", "LICENSE_TERM_FULFILLMENT", "COMPONENT_DATA", "VULN_DATA", "CUSTOM_FIELD_DATA", "VERSION_SETTINGS" ], "customSignatureEnabled": false, "customSignatureDepth": "5", "deepLicenseDataEnabled": false, "snippetAdjustmentApplied": false, "licenseConflictsEnabled": false, "projectGroup": "https://sample.test.com/api/project-groups/00000003-0003-0000-0000-000000000001", "createdAt": "2021-07-12T09:17:58.774Z", "createdBy": "jenkinsuser", "createdByUser": "https://sample.test.com/api/users/ab4adeed-5b45-453e-946f-7850cfdb26bf", "updatedAt": "2024-01-08T09:27:37.369Z", "updatedBy": "blackduck_system", "updatedByUser": "https://sample.test.com/api/users/00000000-0000-0000-0004-000000000011", "source": "CUSTOM", "_meta": { "allow": [ "DELETE", "GET", "PUT" ], "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc", "links": [ { "rel": "versions", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/versions" }, { "rel": "canonicalVersion", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/versions/d59a3a1d-278d-4ead-a2af-d4026a88f1cc" }, { "rel": "assignable-users", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/assignable-users" }, { "rel": "assignable-usergroups", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/assignable-usergroups" }, { "rel": "users", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/users" }, { "rel": "usergroups", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/usergroups" }, { "rel": "tags", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/tags" }, { "rel": "project-mappings", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/project-mappings" }, { "rel": "project-journal", "href": "https://sample.test.com/api/journal/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc" }, { "rel": "custom-fields", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/custom-fields" }, { "rel": "sbom-fields", "href": "https://sample.test.com/api/projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/sbom-fields" }, { "rel": "lts-project-versions", "href": "https://sample.test.com/api/lts-projects/1a9a7d6c-89e0-4e6f-b3cb-76d047b6cadc/lts-project-versions" } ] } }, { "name": "540_ECM_-NS-_&_QA_Systems_-TM-____camunda-demo-fe_sg", "projectLevelAdjustments": true, "cloneCategories": [ "LICENSE_TERM_FULFILLMENT", "COMPONENT_DATA", "VULN_DATA", "CUSTOM_FIELD_DATA", "VERSION_SETTINGS" ], "customSignatureEnabled": false, "customSignatureDepth": "5", "deepLicenseDataEnabled": false, "snippetAdjustmentApplied": false, "licenseConflictsEnabled": false, "projectGroup": "https://sample.test.com/api/project-groups/00000003-0003-0000-0000-000000000001", "createdAt": "2022-06-28T01:51:57.761Z", "createdBy": "jenkinsuser", "createdByUser": "https://sample.test.com/api/users/ab4adeed-5b45-453e-946f-7850cfdb26bf", "updatedAt": "2022-06-28T02:22:32.994Z", "updatedBy": "jenkinsuser", "updatedByUser": "https://sample.test.com/api/users/ab4adeed-5b45-453e-946f-7850cfdb26bf", "source": "CUSTOM", "_meta": { "allow": [ "DELETE", "GET", "PUT" ], "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52", "links": [ { "rel": "versions", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions" }, { "rel": "canonicalVersion", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c" }, { "rel": "assignable-users", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/assignable-users" }, { "rel": "assignable-usergroups", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/assignable-usergroups" }, { "rel": "users", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/users" }, { "rel": "usergroups", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/usergroups" }, { "rel": "tags", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/tags" }, { "rel": "project-mappings", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/project-mappings" }, { "rel": "project-journal", "href": "https://sample.test.com/api/journal/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52" }, { "rel": "custom-fields", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/custom-fields" }, { "rel": "sbom-fields", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/sbom-fields" }, { "rel": "lts-project-versions", "href": "https://sample.test.com/api/lts-projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/lts-project-versions" } ] } },
从上面我们需要运行一个循环来获取所有及其相应版本的 url。

"name": "540_ECM_-NS-_&_QA_Systems_-TM-____camunda-demo-fe_sg", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions
现在我们需要curl上面的href并提取上面项目名称的版本并放入表中。
以下是来自版本 href 的示例 json。

{ "totalCount": 1, "items": [ { "versionName": "unnamed", "phase": "DEVELOPMENT", "distribution": "EXTERNAL", "license": { "type": "DISJUNCTIVE", "licenses": [ { "license": "https://sample.test.com/api/licenses/00000000-0010-0000-0000-000000000000", "licenses": [], "name": "Unknown License", "ownership": "UNKNOWN", "licenseDisplay": "Unknown License", "licenseFamilySummary": { "name": "Unknown", "href": "https://sample.test.com/api/license-families/5" } } ], "licenseDisplay": "Unknown License" }, "protectedFromDeletion": false, "codeLocationProtection": false, "autoUnmappingStatus": { "hasCodeLocationMarkedForUnmapping": false }, "bomState": "ACTIVE", "bomTransitionReason": "CREATED", "createdAt": "2022-06-28T02:22:21.094Z", "createdBy": "jenkinsuser", "createdByUser": "https://sample.test.com/api/users/ab4adeed-5b45-453e-946f-7850cfdb26bf", "settingUpdatedAt": "2022-06-28T02:22:21.094Z", "settingUpdatedBy": "jenkinsuser", "settingUpdatedByUser": "https://sample.test.com/api/users/ab4adeed-5b45-453e-946f-7850cfdb26bf", "scheduledDeletionDate": "2024-12-17T05:10:36.217Z", "source": "CUSTOM", "_meta": { "allow": [ "GET" ], "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c", "links": [ { "rel": "reports", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/reports" }, { "rel": "versionReport", "href": "https://sample.test.com/api/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/reports" }, { "rel": "licenseReports", "href": "https://sample.test.com/api/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/license-reports" }, { "rel": "riskProfile", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/risk-profile" }, { "rel": "version-risk-profile", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/risk-profile" }, { "rel": "origin-risk-profile", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/origin-risk-profile" }, { "rel": "components", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/components" }, { "rel": "vulnerable-components", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/vulnerable-bom-components" }, { "rel": "comparison", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/comparison" }, { "rel": "project", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52" }, { "rel": "policy-status", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/policy-status" }, { "rel": "codelocations", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/codelocations" }, { "rel": "custom-fields", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/custom-fields" }, { "rel": "issues", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/issues" }, { "rel": "project-version-journal", "href": "https://sample.test.com/api/journal/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c" }, { "rel": "bom-status", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/bom-status" }, { "rel": "active-policy-rules", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/policy-rules" }, { "rel": "bom-events", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/bom-events" }, { "rel": "unmatched-declared-component-count", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/unmatched-declared-component-count" }, { "rel": "annotations", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/annotations" }, { "rel": "containers", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions/fc6ba67a-ed66-4be4-8fcf-07b20631601c/containers" } ] } } ], "appliedFilters": [], "_meta": { "allow": [ "GET" ], "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions", "links": [ { "rel": "static-filter", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions-filters?filterKey=distribution", "name": "distribution", "label": "Distribution" }, { "rel": "dynamic-filter", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions-filters?filterKey=license", "name": "license", "label": "License" }, { "rel": "static-filter", "href": "https://sample.test.com/api/projects/e15228d2-b4aa-45e8-9ea0-2042fdadab52/versions-filters?filterKey=phase", "name": "phase", "label": "Release Phase" } ] } }
从上面我们可以提取以下信息并相应地放入表格中。

"versionName": "unnamed", "phase": "DEVELOPMENT",
在上面的示例中,它只有 1 个版本,但有些可能有更多版本。
有人可以帮忙编写groovy 脚本吗?

groovy jenkins-groovy
1个回答
0
投票
这就是我要做的。 这需要您添加依赖项,但这会将 JSON 数据结构转换为 CSV:

@Grab("com.github.chubbard:gratum:1.1.10") import gratum.source.JsonSource String json = """ <insert your json here> """ // parse the json string and iterate the array stored in the items property JsonSource.json( json ).path("items").into() .addStep("Reduce Dimensions") { row -> // this maps the item object into a smaller set of dimensions return [ Project: row["project"], // or whatever field this comes from Versions: row["versionName"], Phase: row["phase"] ] } .save( "report.csv", "," ) // write out a CSV .go() // execute the pipeline
    
© www.soinside.com 2019 - 2024. All rights reserved.