Using Groovy collection to exactly match the string format - java

I have a question about matching the exact string format using the groovy collection.
def createPullRequest(projectSlug, repoSlug, title, description, sourceBranch, targetBranch) {
//this is reading in the array with the user names
def names = BitbutkcetUtil.getGroupUsers(teamName, activeOnly)
def prResponse = this.steps.httpRequest(
acceptType: 'APPLICATION_JSON',
authentication: this.userId,
contentType: 'APPLICATION_JSON',
httpMode: 'POST',
ignoreSslErrors: true,
quiet: true,
requestBody: """
{
"title": "${title}",
"description": "${description}",
"state": "OPEN",
"open": true,
"closed": false,
"fromRef": { "id": "${sourceBranch}" },
"toRef": { "id": "${targetBranch}" },
"locked": false,
"reviewers": [
//I want to replace this hardcoded names with the string values inside the array `names`
{ "user": { "name": "HardCoded1" } },
{ "user": { "name": "HardCoded2" } },
{ "user": { "name": "HardCoded3" } },
{ "user": { "name": "HardCoded4" } }
]
}
""",
responseHandle: 'STRING',
url: "https://bitbucket.absolute.com/rest/api/latest/projects/${projectSlug}/repos/${repoSlug}/pull-requests",
validResponseCodes: '200:299')
def pullRequest = this.steps.readJSON(text: prResponse.content)
prResponse.close()
return pullRequest['id']
}
What I want to do is I want to replace the hardcoded names inside the reviewers with the string elements inside the array names. I want to use the collection but I have to match the exact format
{ "user": { "name": "HardCoded1" } },
{ "user": { "name": "HardCoded2" } },
{ "user": { "name": "HardCoded3" } },
{ "user": { "name": "HardCoded4" } }
Right now, I have [reviewers: names.collect{ [user: [name: it]] }], and it is outputting the following:
[reviewers:[[user:[name:name1]],
[user:[name:name2]],
[user:[name:name3]],
[user:[name:name4]]]]
How can I make it so that the output is in the following format?
"reviewers": [
//I want to replace this hardcoded names with the string values inside the array `names`
{ "user": { "name": "HardCoded1" } },
{ "user": { "name": "HardCoded2" } },
{ "user": { "name": "HardCoded3" } },
{ "user": { "name": "HardCoded4" } }
]
Any help would be greatly appreciated!

What you see is a result of calling toString() method on a list of map elements. For a valid JSON representation, you may pass a result of the collect() method to a JsonOutput.toJSON(). Something like this:
requestBody: """
{
"title": "${title}",
"description": "${description}",
"state": "OPEN",
"open": true,
"closed": false,
"fromRef": { "id": "${sourceBranch}" },
"toRef": { "id": "${targetBranch}" },
"locked": false,
"reviewers": ${JsonOutput.toJson(names.collect{ [user: [name: it]] })}
}
"""
JsonOutput.toJSON() may need script approval when it gets used for the first time in Jenkins Pipeline.

Related

MongoDB Autocomplete index doesn't get result

I have a collection which name called 'airport' and i have Atlas Auto Complete index you can see JSON config below.
{
"mappings": {
"dynamic": false,
"fields": {
"name": [
{
"type": "string"
},
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 2,
"type": "autocomplete"
}
]
}
}
}
and this is my Document record
{
"_id": {
"$oid": "63de588c7154cc3ee5cbabb2"
},
"name": "Antalya Airport",
"code": "AYT",
"country": "TR",
"createdDate": {
"$date": {
"$numberLong": "1675516044323"
}
},
"updatedDate": {
"$date": {
"$numberLong": "1675516044323"
}
},
"updatedBy": "VISITOR",
"createdBy": "VISITOR",
}
And This is my MongoDB Query
public List<Document> autoCompleteAirports(AutoCompleteRequest autoCompleteRequest) {
return database.getCollection(AIRPORT).aggregate(
Arrays.asList(new Document("$search",
new Document("index", "airportAutoCompleteIndex")
.append("text",
new Document("query", autoCompleteRequest.getKeyword())
.append("path", "name")
)))
).into(new ArrayList<>());
}
So, when i type "antalya" or "Antalya", this works. But when i type "Antaly" or "antal" there is no result.
Any solution ?
i tried change min and max grams settings on index

Create N number of GCP compute instances using Rest api

How to create n number of instances in GCP using rest api.
in AWS java SDK, there is a method withMaxCount where we specify number of ec2 instances.
Similarly is there anything for GCP compute.
You can use REST API in loop to create instances.
Example request will look something like this:
{
"kind": "compute#instance",
"name": "INSTANCE-NAME",
"zone": "projects/PROJECT-NAME/zones/us-central1-a",
"machineType": "projects/PROJECT-NAME/zones/us-central1-a/machineTypes/e2-medium",
"displayDevice": {
"enableDisplay": false
},
"metadata": {
"kind": "compute#metadata",
"items": []
},
"tags": {
"items": []
},
"disks": [
{
"kind": "compute#attachedDisk",
"type": "PERSISTENT",
"boot": true,
"mode": "READ_WRITE",
"autoDelete": true,
"deviceName": "INSTANCE-NAME",
"initializeParams": {
"sourceImage": "projects/debian-cloud/global/images/debian-10-buster-v20210122",
"diskType": "projects/PROJECT-NAME/zones/us-central1-a/diskTypes/pd-standard",
"diskSizeGb": "10",
"labels": {}
},
"diskEncryptionKey": {}
}
],
"canIpForward": false,
"networkInterfaces": [
{
"kind": "compute#networkInterface",
"subnetwork": "regions/us-central1/subnetworks/default",
"accessConfigs": [
{
"kind": "compute#accessConfig",
"name": "External NAT",
"type": "ONE_TO_ONE_NAT",
"networkTier": "PREMIUM"
}
],
"aliasIpRanges": []
}
],
"description": "",
"labels": {},
"scheduling": {
"preemptible": false,
"onHostMaintenance": "MIGRATE",
"automaticRestart": true,
"nodeAffinities": []
},
"deletionProtection": false,
"reservationAffinity": {
"consumeReservationType": "ANY_RESERVATION"
},
"serviceAccounts": [
{
"email": "111111111111-compute#developer.gserviceaccount.com",
"scopes": [
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write",
"https://www.googleapis.com/auth/servicecontrol",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/trace.append"
]
}
],
"shieldedInstanceConfig": {
"enableSecureBoot": false,
"enableVtpm": true,
"enableIntegrityMonitoring": true
},
"confidentialInstanceConfig": {
"enableConfidentialCompute": false
}
}
Replace it with your own project name and service account, and you can test it here.

Extract specific data from json object and store them in a list

I´m new to the world of json format. I have Json info stored in a json object and I only want to extract name key values in a list. At least I have one user and sometimes more than one user. Extraction using Java or Groovy.
{
"reviewers": [
{
"user": {
"name": "name1.n1",
"emailAddress": "example#example.com"
},
"role": "REVIEWER"
},
{
"user": {
"name": "name2.n2",
"emailAddress": "example2#example.com"
},
"role": "REVIEWER"
}
]
}
basic groovy+json doc here: https://groovy-lang.org/json.html
import groovy.json.JsonSlurper
def json = '''{
"reviewers": [
{
"user": {
"name": "name1.n1",
"emailAddress": "example#example.com"
},
"role": "REVIEWER"
},
{
"user": {
"name": "name2.n2",
"emailAddress": "example2#example.com"
},
"role": "REVIEWER"
}
]
}
'''
def obj = new JsonSlurper().parseText(json)
println obj.reviewers.collect{ it.user.name } // v1
println obj.reviewers*.user.name // the same as above but shorter
Using Java with library org.json.JSONObject;
JSONObject json =new JSONObject(YOUR_JSON_HERE );
JSONArray array = json.getJSONArray("reviewers" );
for(int i=0;i<array.length();i++){
JSONObject user =array.getJSONObject(i);
System.out.println(user.getJSONObject("user").get("name"));
}
}
You can get a list of names like this, using just Groovy:
jason = '''{
"reviewers": [
{
"user": {
"name": "name1.n1",
"emailAddress": "example#example.com"
},
"role": "REVIEWER"
},
{
"user": {
"name": "name2.n2",
"emailAddress": "example2#example.com"
},
"role": "REVIEWER"
}
]
}
'''
import groovy.json.JsonSlurper
def jsonslurper = new JsonSlurper()
def object = jsonslurper.parseText(jason)
List names = object.findAll { it.value instanceof List }
.values()
.flatten()
.collect { it.user.name }
println names

Use different class name than JSON with Jackson deserialization

I'm trying to deserialize a JSON file with Jackson and I want to use different names for objects. I know how to set the #JsonProperty annotation but this doesn't work for class names. An example:
public class _my_class {
#JsonProperty("my_variable")
private String myVariable;
}
I want the class to be named MyClass. I also tried to use #JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "MyClass") but it doesn't work too. Is there a solution to this?
EDIT
This is my simplified JSON file:
{
"CVE_data_type": "CVE",
"CVE_data_format": "MITRE",
"CVE_data_version": "4.0",
"CVE_data_numberOfCVEs": "1",
"CVE_data_timestamp": "2018-10-26T07:00Z",
"CVE_Items": [
{
"cve": {
"data_type": "CVE",
"data_format": "MITRE",
"data_version": "4.0",
"CVE_data_meta": {
"ID": "CVE-2018-0001",
"ASSIGNER": "my#mail.com"
},
"affects": {
"vendor": {
"vendor_data": [
{
"vendor_name": "myVendorName",
"product": {
"product_data": [
{
"product_name": "myProductName",
"version": {
"version_data": [
{
"version_value": "myVersionValue",
"version_affected": "myVersionAffected"
}
]
}
}
]
}
}
]
}
},
"problemtype": {
"problemtype_data": [
{
"description": [
{
"lang": "en",
"value": "myProblemtypeDescription"
}
]
}
]
},
"references": {
"reference_data": [
{
"url": "http://www.myReferenceDataUrl.com/",
"name": "myReferenceDataName",
"refsource": "myReferenceDataRefsource",
"tags": [
"myReferenceDataTagOne",
"myReferenceDataTagTwo"
]
}
]
},
"description": {
"description_data": [
{
"lang": "en",
"value": "myDescription"
}
]
}
},
"configurations": {
"CVE_data_version": "4.0",
"nodes": [
{
"operator": "OR",
"cpe": [
{
"vulnerable": true,
"cpe22Uri": "cpe:/o:this:is:a:cpe",
"cpe23Uri": "cpe:2.3:o:this:is:a:cpe:*:*:*:*:*:*",
"versionStartIncluding": "myVersionStartIncluding",
"versionStartExcluding": "myVersionStartExcluding",
"versionEndIncluding": "myVersionEndIncluding",
"versionEndExcluding": "myVersionEndExcluding"
},
{
"vulnerable": true,
"cpe22Uri": "cpe:/o:this:is:another:cpe",
"cpe23Uri": "cpe:2.3:o:this:is:another:cpe:*:*:*:*:*:*"
}
]
}
]
},
"impact": {
"baseMetricV3": {
"cvssV3": {
"version": "3.0",
"vectorString": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"attackVector": "NETWORK",
"attackComplexity": "LOW",
"privilegesRequired": "NONE",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH",
"baseScore": 9.8,
"baseSeverity": "CRITICAL"
},
"exploitabilityScore": 3.9,
"impactScore": 5.9
},
"baseMetricV2": {
"cvssV2": {
"version": "2.0",
"vectorString": "(AV:N/AC:L/Au:N/C:P/I:P/A:P)",
"accessVector": "NETWORK",
"accessComplexity": "LOW",
"authentication": "NONE",
"confidentialityImpact": "PARTIAL",
"integrityImpact": "PARTIAL",
"availabilityImpact": "PARTIAL",
"baseScore": 7.5
},
"severity": "HIGH",
"exploitabilityScore": 10.0,
"impactScore": 6.4,
"obtainAllPrivilege": false,
"obtainUserPrivilege": false,
"obtainOtherPrivilege": false,
"userInteractionRequired": false
}
},
"publishedDate": "2018-01-10T22:29Z",
"lastModifiedDate": "2018-02-23T02:29Z"
}
]
}
Now in want the corresponding class for the CVE Meta Data like this:
public class CVEDataMeta /* currently it's CVE_Data_Meta */ {
private String id;
private String assigner;
// getter and setters
}
EDIT 2
That's how i read the json file:
public CVE_Data deserialize(InputStream jsonStream) {
CVE_Data cveData = null;
ObjectMapper mapper = new ObjectMapper();
try {
cveData = mapper.readValue(jsonStream, CVE_Data.class);
} catch (...) {
...
}
return cveData;
}

Elasticsearch Query String Query not working with synonym analyzer

I am trying to configure elastic search with synonyms.
These are my settings:
"analysis": {
"analyzer": {
"category_synonym": {
"tokenizer": "whitespace",
"filter": [
"synonym_filter"
]
}
},
"filter": {
"synonym_filter": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
}
}
Mappings config:
"category": {
"properties": {
"name": {
"type":"string",
"search_analyzer" : "category_synonym",
"index_analyzer" : "standard",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
And the list of my synonyms
film => video,
ooh => panels , poster,
commercial => advertisement,
print => magazine
I must say that I am using Elasticsearch Java API.
I am using QueryBuilders.queryStringQuery because this is the only way how I set analyzers to my request.
So, when I am making:
QueryBuilders.queryStringQuery("name:film").analyzer(analyzer)
It returns me
[
{
"id": 71,
"name": "Pitch video",
"description": "... ",
"parent": null
},
{
"id": 25,
"name": "Video",
"description": "... ",
"parent": null
}
]
That is perfect for me, but when I am calling something like this
QueryBuilders.queryStringQuery("name:vid").analyzer(analyzer)
I expect that it should return same objects, but there is nothing: []
So, I added asterisk to queryStringQuery:
QueryBuilders.queryStringQuery("name:vid*").analyzer(analyzer)
Works well, but now
QueryBuilders.queryStringQuery("name:film*").analyzer(analyzer)
returns me []
So, how can I configure my elastic search that it will return same objects when I am searching video, vid, film and fil?
Thanks in advance!
Hm, I don't think Elasticsearch will know to "translate" fil into vid :-). So, I think you need edgeNGrams for this, both at indexing and search time.
PUT test
{
"settings": {
"analysis": {
"analyzer": {
"category_synonym": {
"tokenizer": "whitespace",
"filter": [
"synonym_filter",
"my_edgeNGram_filter"
]
},
"standard_edgeNGram": {
"tokenizer": "standard",
"filter": [
"lowercase",
"synonym_filter",
"my_edgeNGram_filter"
]
}
},
"filter": {
"synonym_filter": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
},
"my_edgeNGram_filter": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 8
}
}
}
},
"mappings": {
"test": {
"properties": {
"name": {
"type": "string",
"analyzer": "category_synonym",
"index_analyzer": "standard_edgeNGram",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
POST test/test/1
{"name": "Pitch video"}
POST test/test/2
{"name": "Video"}
GET /test/test/_search
{
"query": {
"query_string": {
"query": "name:fil"
}
}
}

Categories

Resources