diff --git a/TODO.md b/TODO.md index e69de29bb..be24a8fd3 100644 --- a/TODO.md +++ b/TODO.md @@ -0,0 +1,15 @@ +* [x] Criar vo que serve para parsear do json e yaml ao mesmo tempo +* [ ] Criar os parsers + * [x] YAML + * [x] JSON + * [ ] ENV +* [ ] Testar o merge dos 3 parsers no `ConfigParseService` +* [ ] Parsers precisam saber ler arquivo do diretorio de configuração e só ler se a versão for 3, senão retornar nulo +* [ ] Testar que ConfigService vai tentar ler a v1,v2,v3 e usar o que achar primeiro nessa ordem +* [ ] Criar a config na v3 se não encontrar nenhuma, caso encontre, mantém na versão encontrada +* [ ] Update the docs + * [ ] Env + * [ ] JSON + * [ ] Yaml support + +. diff --git a/build.gradle b/build.gradle index 14352e17c..1c8ad9150 100644 --- a/build.gradle +++ b/build.gradle @@ -72,7 +72,8 @@ dependencies { implementation('com.github.docker-java:docker-java-transport-httpclient5:3.3.4') implementation('info.picocli:picocli:4.7.6') - implementation('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1') + implementation('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.3') + implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.3') implementation('com.github.ben-manes.caffeine:caffeine:3.1.8') diff --git a/src/main/java/com/mageddo/dataformat/yaml/YamlUtils.java b/src/main/java/com/mageddo/dataformat/yaml/YamlUtils.java new file mode 100644 index 000000000..8b7de4171 --- /dev/null +++ b/src/main/java/com/mageddo/dataformat/yaml/YamlUtils.java @@ -0,0 +1,39 @@ +package com.mageddo.dataformat.yaml; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; + +import java.io.UncheckedIOException; + +public class YamlUtils { + + public static final YAMLMapper mapper = YAMLMapper + .builder() + .enable(SerializationFeature.INDENT_OUTPUT) + .build(); + + public static String format(String yaml) { + try { + return mapper.writeValueAsString(mapper.readTree(yaml)); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + } + + public static String writeValueAsString(Object o) { + try { + return mapper.writeValueAsString(o); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + } + + public static T readValue(String yaml, Class clazz) { + try { + return mapper.readValue(yaml, clazz); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigDAODataFormatV3.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigDAODataFormatV3.java new file mode 100644 index 000000000..888a412e3 --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigDAODataFormatV3.java @@ -0,0 +1,16 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3; + +import com.mageddo.dnsproxyserver.config.Config; +import com.mageddo.dnsproxyserver.config.dataprovider.ConfigDAO; + +public class ConfigDAODataFormatV3 implements ConfigDAO { + @Override + public Config find() { + return null; + } + + @Override + public int priority() { + return 0; + } +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigParseService.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigParseService.java new file mode 100644 index 000000000..bddceb852 --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigParseService.java @@ -0,0 +1,37 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3; + +import com.mageddo.dnsproxyserver.config.Config; +import com.mageddo.dnsproxyserver.config.mapper.ConfigMapper; +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.mapper.ConfigV3Mapper; +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser.Converter; +import lombok.RequiredArgsConstructor; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.List; + +@Singleton +@RequiredArgsConstructor(onConstructor_ = @Inject) +public class ConfigParseService { + + private final List unorderedConverters; + private final ConfigMapper configMapper; + + public Config parseMerging(){ + final var parsers = this.findParsersInOrder(); + final var configs = this.findConfigs(parsers); + return this.configMapper.mapFrom(configs); + } + + private List findConfigs(List converters) { + return converters.stream() + .map(Converter::parse) + .map(ConfigV3Mapper::toConfig) + .toList(); + } + + public List findParsersInOrder() { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigV3.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigV3.java new file mode 100644 index 000000000..0505b7302 --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/ConfigV3.java @@ -0,0 +1,126 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3; + +import lombok.Data; + +import java.util.List; + +@Data +public class ConfigV3 { + + public int version; + public Server server; + public Solver solver; + public DefaultDns defaultDns; + public Log log; + + @Data + public static class CircuitBreaker { + public String name; + } + + @Data + public static class DefaultDns { + public Boolean active; + public ResolvConf resolvConf; + } + + @Data + public static class Dns { + public Integer port; + public Integer noEntriesResponseCode; + } + + @Data + public static class Docker { + public Boolean registerContainerNames; + public String domain; + public Boolean hostMachineFallback; + public DpsNetwork dpsNetwork; + // public Networks networks; + public String dockerDaemonUri; + } + + @Data + public static class DpsNetwork { + public String name; + public Boolean autoCreate; + public Boolean autoConnect; + } + + @Data + public static class Env { + public String name; + public List hostnames; + } + + @Data + public static class Hostname { + public String type; + public String hostname; + public String ip; + public Integer ttl; + } + + @Data + public static class Local { + public String activeEnv; + public List envs; + } + + @Data + public static class Log { + public String level; + public String file; + } + + @Data + public static class Networks { + public List preferredNetworkNames; + } + + @Data + public static class Remote { + public Boolean active; + public List dnsServers; + public CircuitBreaker circuitBreaker; + } + + @Data + public static class ResolvConf { + public String paths; + public Boolean overrideNameServers; + } + + @Data + public static class Server { + public Dns dns; + public Web web; + public String protocol; + } + + @Data + public static class Solver { + public Remote remote; + public Docker docker; + public System system; + public Local local; + public Stub stub; + } + + @Data + public static class Stub { + public String domainName; + } + + @Data + public static class System { + public String hostMachineHostname; + } + + @Data + public static class Web { + public Integer port; + } + + +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/mapper/ConfigV3Mapper.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/mapper/ConfigV3Mapper.java new file mode 100644 index 000000000..c740cc5a6 --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/mapper/ConfigV3Mapper.java @@ -0,0 +1,10 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.mapper; + +import com.mageddo.dnsproxyserver.config.Config; +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.ConfigV3; + +public class ConfigV3Mapper { + public static Config toConfig(ConfigV3 configV3) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/Converter.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/Converter.java new file mode 100644 index 000000000..ee09a445a --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/Converter.java @@ -0,0 +1,13 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.ConfigV3; + +public interface Converter { + + ConfigV3 parse(); + + String serialize(ConfigV3 config); + + int priority(); + +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/EnvConverter.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/EnvConverter.java new file mode 100644 index 000000000..77691f3c0 --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/EnvConverter.java @@ -0,0 +1,20 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.ConfigV3; + +public class EnvConverter implements Converter { + @Override + public ConfigV3 parse() { + return null; + } + + @Override + public String serialize(ConfigV3 config) { + return ""; + } + + @Override + public int priority() { + return 0; + } +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/JsonConverter.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/JsonConverter.java new file mode 100644 index 000000000..9d45e2c8c --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/JsonConverter.java @@ -0,0 +1,32 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.ConfigV3; +import com.mageddo.json.JsonUtils; +import lombok.NoArgsConstructor; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +@NoArgsConstructor(onConstructor_ = @Inject) +public class JsonConverter implements Converter { + + @Override + public ConfigV3 parse() { + return parse(""); + } + + public ConfigV3 parse(String json) { + return JsonUtils.readValue(json, ConfigV3.class); + } + + @Override + public String serialize(ConfigV3 config) { + return JsonUtils.prettyWriteValueAsString(config); + } + + @Override + public int priority() { + return 1; + } +} diff --git a/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/YamlConverter.java b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/YamlConverter.java new file mode 100644 index 000000000..f331320fe --- /dev/null +++ b/src/main/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/YamlConverter.java @@ -0,0 +1,27 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dataformat.yaml.YamlUtils; +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.ConfigV3; + +public class YamlConverter implements Converter { + + @Override + public ConfigV3 parse() { + return null; + } + + public ConfigV3 parse(String yaml) { + return YamlUtils.readValue(yaml, ConfigV3.class); + } + + @Override + public String serialize(ConfigV3 config) { + return YamlUtils.writeValueAsString(config); + } + + @Override + public int priority() { + return 2; + } + +} diff --git a/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/ConverterTest.java b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/ConverterTest.java new file mode 100644 index 000000000..66c2360d9 --- /dev/null +++ b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/ConverterTest.java @@ -0,0 +1,26 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.templates.ConfigV3Templates; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ConverterTest { + + private final JsonConverter jsonParser = new JsonConverter(); + private final YamlConverter yamlParser = new YamlConverter(); + + @Test + void yamlAndJsonParsingMustGenerateSameVo(){ + + final var json = ConfigV3Templates.buildJson(); + final var yaml = ConfigV3Templates.buildYaml(); + + final var jsonParsed = this.jsonParser.parse(json); + final var yamlParsed = this.yamlParser.parse(yaml); + + assertEquals(jsonParsed, yamlParsed); + + } + +} diff --git a/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/JsonConverterTest.java b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/JsonConverterTest.java new file mode 100644 index 000000000..4d190ab11 --- /dev/null +++ b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/JsonConverterTest.java @@ -0,0 +1,25 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.templates.ConfigV3Templates; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JsonConverterTest { + + JsonConverter parser = new JsonConverter(); + + @Test + void mustParseAndSerializeWithTheExactSameContent() { + + final var json = ConfigV3Templates.buildJson(); + + final var parsed = parser.parse(json); + final var marshalled = parser.serialize(parsed); + final var marshalledParsed = parser.parse(json); + + assertEquals(json, marshalled); + assertEquals(parsed, marshalledParsed); + + } +} diff --git a/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/YamlConverterTest.java b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/YamlConverterTest.java new file mode 100644 index 000000000..946f29d29 --- /dev/null +++ b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/parser/YamlConverterTest.java @@ -0,0 +1,25 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.parser; + +import com.mageddo.dnsproxyserver.config.provider.dataformatv3.templates.ConfigV3Templates; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class YamlConverterTest { + + YamlConverter parser = new YamlConverter(); + + @Test + void mustParseAndSerializeWithTheExactSameContent() { + + final var yaml = ConfigV3Templates.buildYaml(); + + final var parsed = parser.parse(yaml); + final var marshalled = parser.serialize(parsed); + final var marshalledParsed = parser.parse(yaml); + + assertEquals(yaml, marshalled); + assertEquals(parsed, marshalledParsed); + + } +} diff --git a/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/templates/ConfigV3Templates.java b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/templates/ConfigV3Templates.java new file mode 100644 index 000000000..cbfd7fc73 --- /dev/null +++ b/src/test/java/com/mageddo/dnsproxyserver/config/provider/dataformatv3/templates/ConfigV3Templates.java @@ -0,0 +1,133 @@ +package com.mageddo.dnsproxyserver.config.provider.dataformatv3.templates; + +import com.mageddo.dataformat.yaml.YamlUtils; +import com.mageddo.json.JsonUtils; + +public class ConfigV3Templates { + + public static String buildYaml(){ + return YamlUtils.format(""" + --- + version: 3 + server: + dns: + port: 53 + noEntriesResponseCode: 3 + web: + port: 5380 + protocol: UDP_TCP + solver: + remote: + active: true + dnsServers: + - 8.8.8.8 + - 4.4.4.4:53 + circuitBreaker: + name: STATIC_THRESHOLD + docker: + registerContainerNames: false + domain: docker + hostMachineFallback: true + dpsNetwork: + name: dps + autoCreate: false + autoConnect: false + dockerDaemonUri:\s + system: + hostMachineHostname: host.docker + local: + activeEnv: '' + envs: + - name: '' + hostnames: + - type: A + hostname: github.com + ip: 192.168.0.1 + ttl: 255 + stub: + domainName: stub + defaultDns: + active: true + resolvConf: + paths: "/host/etc/systemd/resolved.conf,/host/etc/resolv.conf,/etc/systemd/resolved.conf,/etc/resolv.conf" + overrideNameServers: true + log: + level: DEBUG + file: console + """); + } + + public static String buildJson(){ + return JsonUtils.prettify(""" + { + "version": 3, + "server": { + "dns": { + "port": 53, + "noEntriesResponseCode": 3 + }, + "web": { + "port": 5380 + }, + "protocol": "UDP_TCP" + }, + "solver": { + "remote": { + "active": true, + "dnsServers": [ + "8.8.8.8", "4.4.4.4:53" + ], + "circuitBreaker": { + "name": "STATIC_THRESHOLD" + } + }, + "docker": { + "registerContainerNames": false, + "domain": "docker", + "hostMachineFallback": true, + "dpsNetwork": { + "name": "dps", + "autoCreate": false, + "autoConnect": false + }, + "dockerDaemonUri": null + }, + "system": { + "hostMachineHostname": "host.docker" + }, + "local": { + "activeEnv": "", + "envs": [ + { + "name": "", + "hostnames": [ + { + "type": "A", + "hostname": "github.com", + "ip": "192.168.0.1", + "ttl": 255 + } + ] + } + ] + }, + "stub": { + "domainName": "stub" + } + }, + "defaultDns": { + "active": true, + "resolvConf": { + "paths": "/host/etc/systemd/resolved.conf,/host/etc/resolv.conf,/etc/systemd/resolved.conf,/etc/resolv.conf", + "overrideNameServers": true + } + }, + "log": { + "level": "DEBUG", + "file": "console" + } + } + """); + } + +}