1 package org.imageconverter.config.health;
2
3 import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
4
5 import java.io.ByteArrayInputStream;
6 import java.io.IOException;
7 import java.util.HashMap;
8 import java.util.LinkedHashMap;
9 import java.util.Map;
10 import java.util.Objects;
11
12 import javax.imageio.ImageIO;
13
14 import org.apache.commons.collections4.MapUtils;
15 import org.imageconverter.util.BeanUtil;
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.beans.factory.annotation.Value;
18 import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
19 import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
20 import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
21 import org.springframework.cloud.endpoint.RefreshEndpoint;
22 import org.springframework.core.env.ConfigurableEnvironment;
23 import org.springframework.core.env.MapPropertySource;
24 import org.springframework.core.io.Resource;
25 import org.springframework.lang.Nullable;
26 import org.springframework.stereotype.Component;
27
28 import com.fasterxml.jackson.annotation.JsonAnyGetter;
29 import com.fasterxml.jackson.annotation.JsonInclude;
30
31 import net.sourceforge.tess4j.ITesseract;
32 import net.sourceforge.tess4j.TesseractException;
33
34
35
36
37
38
39 @Component
40 @Endpoint(id = "tesseract")
41
42 public class TesseractInfoService {
43
44 private final Resource imageFile;
45
46 private final RefreshEndpoint refreshEndpoint;
47
48
49
50
51
52
53
54 TesseractInfoService(
55 @Value("classpath:check-image.png")
56 final Resource newImageFile,
57
58 @Autowired
59 final RefreshEndpoint newRefreshEndpoint) {
60 super();
61 this.imageFile = newImageFile;
62 this.refreshEndpoint = newRefreshEndpoint;
63 }
64
65
66
67
68
69
70 @ReadOperation
71 public TesseractDetailsData read() {
72
73 final var details = new LinkedHashMap<String, Object>();
74
75 details.put("tesseractVersion", "4.11");
76 details.put("tesseractFolder", BeanUtil.getPropertyValue("tesseract.folder"));
77 details.put("tesseractLanguage", BeanUtil.getPropertyValue("tesseract.language"));
78 details.put("tesseractDpi", BeanUtil.getPropertyValue("tesseract.dpi"));
79
80 if (checkTesseract()) {
81 details.put("tesseractInit", "SUCCESSFUL");
82 } else {
83 details.put("tesseractInit", "FAIL");
84 }
85
86 return new TesseractDetailsData(details);
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101 @WriteOperation
102 public void writeOperation(@Nullable final String tesseractFolder, @Nullable final String tesseractLanguage, @Nullable final String tesseractDpi) {
103 final var env = (ConfigurableEnvironment) BeanUtil.getEnvironment();
104
105 final var propertySources = env.getPropertySources();
106 final var map = new HashMap<String, Object>();
107
108 if (Objects.nonNull(tesseractFolder)) {
109 map.put("tesseract.folder", tesseractFolder);
110 }
111
112 if (Objects.nonNull(tesseractLanguage)) {
113 map.put("tesseract.language", tesseractLanguage);
114 }
115
116 if (Objects.nonNull(tesseractDpi)) {
117 map.put("tesseract.dpi", tesseractDpi);
118 }
119
120 propertySources.addFirst(new MapPropertySource("newmap", map));
121
122 if (!map.isEmpty()) {
123 refreshEndpoint.refresh();
124 }
125
126 }
127
128
129
130
131
132
133 private boolean checkTesseract() {
134
135 final var tesseractBeanProvider = BeanUtil.getBeanProviderFrom(ITesseract.class);
136 final var tesseract = tesseractBeanProvider.getObject();
137
138 boolean result = false;
139
140 if (Objects.isNull(tesseract)) {
141
142 result = false;
143
144 } else {
145
146 try {
147
148 final var bufferedImage = ImageIO.read(new ByteArrayInputStream(imageFile.getInputStream().readAllBytes()));
149
150 final var numberOne = tesseract.doOCR(bufferedImage).replaceAll("\\D+", "");
151
152 if (equalsIgnoreCase(numberOne, "033")) {
153 result = true;
154 }
155
156 } catch (final TesseractException | IOException | IllegalArgumentException ex) {
157 result = false;
158 }
159 }
160
161 return result;
162 }
163
164 @JsonInclude(JsonInclude.Include.NON_EMPTY)
165 public static class TesseractDetailsData {
166
167 private final Map<String, Object> tesseractDetails;
168
169 TesseractDetailsData(final Map<String, Object> tesseractDetails) {
170 super();
171 this.tesseractDetails = tesseractDetails;
172 }
173
174 @JsonAnyGetter
175 public Map<String, Object> getTesseractDetails() {
176 return MapUtils.unmodifiableMap(tesseractDetails);
177 }
178 }
179 }