1 package net.avcompris.status.core.impl;
2
3 import static com.google.common.base.Preconditions.checkNotNull;
4 import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
5
6 import java.io.File;
7 import java.io.IOException;
8 import java.util.Arrays;
9 import java.util.Map;
10 import java.util.Set;
11 import java.util.TreeMap;
12 import java.util.TreeSet;
13
14 import org.apache.commons.lang3.NotImplementedException;
15
16 import com.google.common.collect.Iterables;
17
18 import net.avcompris.commons3.yaml.Yaml;
19 import net.avcompris.commons3.yaml.YamlUtils;
20 import net.avcompris.status.api.StatusConfig;
21 import net.avcompris.status.api.StatusConfig.Expect;
22 import net.avcompris.status.api.StatusConfig.ServiceConfig;
23
24 abstract class ConfigLoader {
25
26 public static StatusConfig loadConfig(final File yamlFile) throws IOException {
27
28 final Yaml yaml = YamlUtils.loadYaml(yamlFile);
29
30 return new StatusConfigImpl(yaml);
31 }
32
33 private static final class StatusConfigImpl implements StatusConfig {
34
35 private final Map<String, ServiceConfig> services = new TreeMap<>();
36
37 public StatusConfigImpl(final Yaml yaml) {
38
39 checkNotNull(yaml, "yaml");
40
41 final Yaml servicesSection = yaml.get("services");
42
43 for (final Object key : servicesSection.keys()) {
44
45 final String serviceId = (String) key;
46
47 final Yaml serviceSection = servicesSection.get(key);
48
49 final String endpoint = serviceSection.get("endpoint").asString();
50
51 final int statusCode = serviceSection.get("expect").get("statusCode").asInt();
52
53 final int timeOutMs = parseMs(serviceSection.get("timeOut").asString());
54
55 final int everyMs = parseMs(serviceSection.get("every").asString());
56
57 final Set<String> labels = new TreeSet<>();
58
59 if (serviceSection.has("labels")) {
60
61 if (serviceSection.get("labels").isArray()) {
62
63 for (final Yaml label : serviceSection.get("labels").items()) {
64
65 labels.add(label.asString());
66 }
67
68 } else {
69
70 labels.add(serviceSection.get("labels").asString());
71 }
72 }
73
74 services.put(serviceId, new ServiceImpl(
75 serviceId,
76 endpoint,
77 Iterables.toArray(labels, String.class),
78 timeOutMs,
79 everyMs,
80 new ExpectImpl(statusCode)));
81 }
82 }
83
84 @Override
85 public ServiceConfig[] getServices() {
86
87 return Iterables.toArray(services.values(), ServiceConfig.class);
88 }
89 }
90
91 private static int parseMs(final String s) {
92
93 if (s.endsWith("ms")) {
94
95 return Integer.parseInt(substringBeforeLast(s, "ms").trim());
96
97 } else if (s.endsWith("min")) {
98
99 return 60_000 * Integer.parseInt(substringBeforeLast(s, "min").trim());
100
101 } else {
102
103 throw new NotImplementedException("s: " + s);
104 }
105 }
106
107 private static final class ServiceImpl implements ServiceConfig {
108
109 private final String id;
110 private final String endpoint;
111 private final String[] labels;
112 private final int timeOutMs;
113 private final int everyMs;
114 private final Expect expect;
115
116 public ServiceImpl(
117 final String id,
118 final String endpoint,
119 final String[] labels,
120 final int timeOutMs,
121 final int everyMs,
122 final Expect expect) {
123
124 this.id = checkNotNull(id, "id");
125 this.endpoint = checkNotNull(endpoint, "endpoint");
126 checkNotNull(labels, "endpoint");
127 this.labels = Arrays.copyOf(labels, labels.length);
128 this.timeOutMs = timeOutMs;
129 this.everyMs = everyMs;
130 this.expect = checkNotNull(expect, "expect");
131 }
132
133 @Override
134 public String getId() {
135 return id;
136 }
137
138 @Override
139 public String getEndpoint() {
140 return endpoint;
141 }
142
143 @Override
144 public String[] getLabels() {
145 return Arrays.copyOf(labels, labels.length);
146 }
147
148 @Override
149 public Integer getTimeOutMs() {
150 return timeOutMs;
151 }
152
153 @Override
154 public Integer getEveryMs() {
155 return everyMs;
156 }
157
158 @Override
159 public Expect getExpect() {
160 return expect;
161 }
162 }
163
164 private static final class ExpectImpl implements Expect {
165
166 private final int statusCode;
167
168 public ExpectImpl(final int statusCode) {
169
170 this.statusCode = statusCode;
171 }
172
173 @Override
174 public Integer getStatusCode() {
175 return statusCode;
176 }
177 }
178 }