1 package org.kuali.common.devops.metadata.function;
2
3 import static com.google.common.base.Optional.absent;
4 import static com.google.common.base.Optional.fromNullable;
5 import static org.apache.commons.lang.StringUtils.substringAfter;
6 import static org.apache.commons.lang.StringUtils.substringBefore;
7 import static org.apache.commons.lang.StringUtils.substringBetween;
8 import static org.apache.commons.lang.StringUtils.substringsBetween;
9 import static org.kuali.common.util.base.Exceptions.illegalArgument;
10 import static org.kuali.common.util.base.Precondition.checkNotBlank;
11 import static org.kuali.common.util.base.Precondition.checkNotNull;
12
13 import java.text.ParseException;
14 import java.text.SimpleDateFormat;
15 import java.util.Date;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Properties;
19
20 import org.kuali.common.devops.metadata.model.Memory;
21 import org.kuali.common.devops.metadata.model.RemoteEnvironment;
22 import org.kuali.common.util.FormatUtils;
23 import org.kuali.common.util.property.ImmutableProperties;
24
25 import com.google.common.base.Function;
26 import com.google.common.base.Optional;
27 import com.google.common.base.Splitter;
28 import com.google.common.collect.Maps;
29
30 public final class RemoteEnvironmentFunction implements Function<String, RemoteEnvironment> {
31
32 public RemoteEnvironmentFunction() {
33 this("yyyy-MM-dd HH:mm:ss.S z");
34 }
35
36 public RemoteEnvironmentFunction(String timestampFormat) {
37 this.timestampFormat = checkNotBlank(timestampFormat, "timestampFormat");
38 }
39
40 private final String timestampFormat;
41
42 @Override
43 public RemoteEnvironment apply(String html) {
44 checkNotNull(html, "html");
45 Properties system = getProperties("System Property", html);
46 Properties environment = getProperties("Environment Variable", html);
47 Optional<Long> millis = getCurrentTimeMillis(html);
48 Optional<Integer> processors = getProcessors(html);
49 Optional<Memory> memory = getMemory(html);
50 return RemoteEnvironment.builder().system(system).environment(environment).currentTimeMillis(millis).processors(processors).memory(memory).build();
51 }
52
53 protected Optional<Memory> getMemory(String html) {
54
55 Optional<String> token = fromNullable(substringBetween(html, "<li>mem: [", "]</li>"));
56 if (token.isPresent()) {
57 List<String> tokens = Splitter.on(',').splitToList(token.get());
58 Map<String, Long> map = Maps.newHashMap();
59 for (String element : tokens) {
60 String key = substringBefore(element.trim(), "=");
61 Long value = FormatUtils.getBytes(substringAfter(element.trim(), "="));
62 map.put(key, value);
63 }
64 Memory memory = Memory.builder().used(map.get("used")).free(map.get("free")).allocated(map.get("allocated")).max(map.get("max")).build();
65 return Optional.of(memory);
66 }
67 return absent();
68 }
69
70 protected Optional<Integer> getProcessors(String html) {
71
72 Optional<String> token = getToken(html, "processors");
73 if (token.isPresent()) {
74 return Optional.of(Integer.parseInt(token.get()));
75 }
76 return absent();
77 }
78
79 protected Optional<Long> getCurrentTimeMillis(String html) {
80
81 Optional<String> token = getToken(html, "time");
82 return token.isPresent() ? getTime(token.get()) : Optional.<Long> absent();
83 }
84
85 protected Optional<Long> getTime(String token) {
86 try {
87 SimpleDateFormat parser = new SimpleDateFormat(timestampFormat);
88 Date date = parser.parse(token);
89 return Optional.of(date.getTime());
90 } catch (ParseException e) {
91 throw illegalArgument(e, "unexpected parse error -> [%s]", token);
92 }
93 }
94
95 protected Properties getProperties(String title, String html) {
96 Optional<String> content = fromNullable(substringBetween(html, "<th>" + title + "</th>", "</table>"));
97 if (!content.isPresent()) {
98 return ImmutableProperties.of();
99 }
100 Optional<String[]> rows = fromNullable(substringsBetween(content.get(), "<tr>", "</tr>"));
101 if (!rows.isPresent()) {
102 return ImmutableProperties.of();
103 }
104 Properties properties = new Properties();
105 for (String row : rows.get()) {
106 Optional<String[]> data = fromNullable(substringsBetween(row, "<td>", "</td>"));
107 if (data.isPresent() && data.get().length == 2) {
108 String[] tokens = data.get();
109 String key = tokens[0];
110 String value = tokens[1].replace("<br>", "").replace(" ", "");
111 properties.setProperty(key, value);
112 }
113 }
114 return ImmutableProperties.copyOf(properties);
115 }
116
117 protected Optional<String> getToken(String html, String item) {
118 String token = substringBetween(html, "<li>" + item + ":", "</li>");
119 if (token == null) {
120 return absent();
121 } else {
122 return Optional.of(token.trim());
123 }
124 }
125
126 }