I am facing a peculiar issue which I am not able to resolve. Not sure where I am going wrong.
Description – I have a JavaFX GUI. On GUI I have 2 input fields which accepts port number (string).
I have a java code which gets the data from the bean and creates yaml file with the configuration.
Code –
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;
@Service
public class GenerateYamlFileImpl implements GenerateYamlFile {
private static final Logger logger = LogManager.getLogger(GenerateYamlFileImpl.class);
public void writeYamlfile(Container container, File file) {
try (FileWriter writer = new FileWriter(file.getPath() + LocalDateTime.now() + FXMLPageConstants.FILE_TYPE)) {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options);
Map<String, Object> data = new LinkedHashMap<>();
data.put("name", container.getName());
Map<String, Object> topology = new LinkedHashMap<>();
Map<String, Object> nodes = new LinkedHashMap<>();
for (Map.Entry<String, NodesProperties> entry : container.getTopology().getNodes().entrySet()) {
Map<String, Object> nodeDetails = new LinkedHashMap<String, Object>();
NodesProperties nodeProps = entry.getValue();
nodeDetails.put("kind", nodeProps.getKind());
nodeDetails.put("image", nodeProps.getImage());
if (nodeProps.getGroup() != null && !nodeProps.getGroup().isBlank()) {
nodeDetails.put("group", nodeProps.getGroup());
}
if (nodeProps.getStartupConfig() != null && !nodeProps.getStartupConfig().isBlank()) {
nodeDetails.put("startup-config", nodeProps.getStartupConfig());
}
if (nodeProps.getPorts() != null && !nodeProps.getPorts().isEmpty()) {
String[] ports = nodeProps.getPorts().stream().map(port -> port+":"+"22").toArray(String[]::new);
nodeDetails.put("ports", ports);
}
nodes.put(entry.getKey(), nodeDetails);
}
topology.put("nodes", nodes);
StringBuilder linksYaml = new StringBuilder();
linksYaml.append(" links:n");
for (Link link : container.getTopology().getLinks()) {
linksYaml.append(" - endpoints: ["");
linksYaml.append(String.join("", "", link.getEndpoints()));
linksYaml.append(""]n");
}
topology.put("nodes", nodes);
data.put("topology", topology);
yaml.dump(data, writer);
writer.write(linksYaml.toString());
writer.flush();
logger.info("YAML file generated successfully: ");
} catch (IOException e) {
logger.error("Error while writing YAML file", e);
}
}
}
public class Container {
private String name;
private Topology topology;
}
public class Topology {
private Map<String, NodesProperties> nodes;
private List<Link> links;
}
public class NodesProperties {
private String kind;
private String image;
private List<String> ports;
private String group;
private String startupConfig;
}
public class Link {
private List<String> endpoints;
}
With the above code I am able to achieve below config-
name: srlceostopo
topology:
nodes:
srl1:
kind: nokia_srlinux
image: ghcr.io/nokia/srlinux
group: leaf
ports:
- '1000:22'
ceos1:
kind: ceos
image: ceos:4.32.0.1F
group: leaf
ports:
- '2000:22'
srl2:
kind: nokia_srlinux
image: ghcr.io/nokia/srlinux
group: leaf
ports:
- '3000:22'
links:
- endpoints: ["srl1:e1-1", "ceos1:eth1"]
- endpoints: ["srl2:e1-1", "srl1:e1-2"]
- endpoints: ["srl2:e1-2", "ceos1:eth3"]
Please note –
With one port, the config is generated fine.
ports:
– ‘2000:22’
But when I am trying to add 2 ports, the yaml file is breaking. Instead of reading it as string, it is reading it as numbers.
e.g.
ports:
- '2000:22
- 3000:80
This error causing issue while executing the yaml in other places.
Question – How can I update my code so that it can generate the configuration for ports in String i.e. with double quotes or single quotes
Please Note – Because of the issue, right now I have modified the GUI to accept only 1 port. I want to enable multiple ports and generate configurations accordingly.
I have alreaty tried with Representer, but I am not getting appropriate result with it.
`
Representer representer = new Representer(options) {
@Override
protected Node representScalar(Tag tag, String value) {
// Ensure all scalar values are double-quoted
return super.representScalar(tag, value, DumperOptions.ScalarStyle.DOUBLE_QUOTED);
}
};
`
...
`
if (nodeProps.getPorts() != null && !nodeProps.getPorts().isEmpty()) {
List<String> ports = nodeProps.getPorts().stream()
.map(port -> """ + port + """)
.collect(Collectors.toList());
nodeDetails.put("ports", ports);
}
`
I want the code to generate yaml file with multiple ports in string format
ports:
- "2000:22"
- "3000:80"
1