Goal: I have a YAML file that needed to remove some key: value properties from. Then I want to create a new YAML file with doesn't exist removed key: value properties. The required key should be removed from the whole YAML file.
Expected Result: Should Iterate through the YAML File and identify the required key: value to be removed and then remove and continue searching for such key: value properties.
Actual Result: Even though iterating through the YAML file desired key: value property won't' remove from the YAML File.
Errors: No Compile or Runtime errors, there seems to be a logical error.
What I have tried:
- Use Jackson ObjectMapper to read the YAML file.
- Put all the properties into LinkedHashMap such that I can preserve the order and I can remove items
My Logic: Implement two methods
- one is to iterate the LinkedHashMap and ArrayList object
- another one it to check whether a specific key is removable
- If a removable key is found and remove from the LinkedHashMap and continues searching the same key in other items in the YAML file.
for example I want to remove
"originalRef": "Conditions"
(the key is String data type) from the YAML file. This key can contain in a LinkedHashMap. Also, There could be ArrayLists which contains multiple LinkedHashMaps.
Code: Below are the YAML file I'm using for these purpose. api-test.yml this only contains a small portion of my big YAML file.
---
swagger: '2.0'
info:
description: |-
Planner application is a proposal system enables user to create, manage plan .
It also enables network user to publish plan
version: '1.0'
title: Planner API
contact:
name: API team
email: apiteam@test.com
license:
name: Copyright © 2020 test
host: aos-dev.test.com
basePath: /unifiedplanner
tags:
- name: Additional Fee APIs
description: Additional Fee Controller
- name: Condition APIs
description: Condition Controller
- name: Conditions Status APIs
paths:
'/v1/{apiKey}/entity/{entityId}':
post:
tags:
- Condition APIs
summary: Save New Conditions Entity
operationId: saveNewConditions
consumes:
- application/json
produces:
- application/json
parameters:
- name: Authorization
in: header
description: Authorization
required: true
type: string
- name: apiKey
in: path
description: API Key
required: true
type: string
- in: body
name: conditions
description: Conditions Entity that needs to be saved
required: true
schema:
$ref: '#/definitions/Conditions'
originalRef: Conditions
- name: entityId
in: path
description: Entity ID
required: true
type: string
responses:
'200':
description: OK
schema:
$ref: '#/definitions/Conditions'
originalRef: Conditions
deprecated: false
put:
tags:
- Condition APIs
summary: Modify / Overwrite existing Conditions Entity
operationId: modifyConditions
consumes:
- application/json
produces:
- application/json
parameters:
- name: Authorization
in: header
description: Authorization
required: true
type: string
- name: apiKey
in: path
description: API Key
required: true
type: string
- in: body
name: conditions
description: Conditions Entity that needs to be updated
required: true
schema:
$ref: '#/definitions/Conditions'
originalRef: Conditions
- name: entityId
in: path
description: Entity ID
required: true
type: string
responses:
'200':
description: OK
schema:
$ref: '#/definitions/Conditions'
originalRef: Conditions
deprecated: false
below is the Java class for parsing above the YAML file and doing the needful.
package com.aos.tools.aostool.yaml;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.util.*;
@Service
public class YamlProcessorGeneric {
Logger logger = LoggerFactory.getLogger(YamlProcessorGeneric.class);
public YamlProcessorGeneric() throws IOException {
process();
}
public void process() throws IOException {
final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
final Map<String, Object> api = objectMapper.readValue(new File("api-test.yaml"),
new TypeReference<Map<String, Object>>() {
});
final Map<String, Object> path = (Map<String, Object>) api.get("paths");
extractLinkedHashMap(path);
// write YAML file
final Date date = Calendar.getInstance().getTime();
objectMapper.writeValue(new File(date.toString() + "api-updated.yaml"), api);
}
private void extractLinkedHashMap(final Map<String,Object> itemMap) {
itemMap.entrySet().forEach(k -> {
// if k is a linkedhashmap and again iterate through
if(k.getValue() instanceof LinkedHashMap) {
extractLinkedHashMap((Map<String, Object>) k.getValue());
}
// if k is an arraylist then iterate through to till I find a linkedhashmap
// so that I can remove an item.
if(k.getValue() instanceof ArrayList) {
((ArrayList<?>) k.getValue()).forEach(singleItem -> {
if(!(singleItem instanceof String)) {
extractLinkedHashMap((Map<String, Object>) singleItem);
}
});
}
// check for a specific key , if found remove from the linkedhashmap
// but this doesn't work
if(isRemovable(k.getKey())) {
itemMap.remove(k);
}
});
}
private boolean isRemovable(final String key) {
// eg:- I want to remove key with originalRef
String removableString = "originalRef";
return key.equals(removableString);
}
}
for the demonstration process I will attach a screenshot when I was debugging the application.
All the values of itemMap
.
I'm currently out of options trying out. Please Can anyone give me direction where I'm doing wrong here. Any help would be very much appreciated. Good day!