TesseractInfoService.java
package org.imageconverter.config.health;
import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import javax.imageio.ImageIO;
import org.apache.commons.collections4.MapUtils;
import org.imageconverter.util.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.cloud.endpoint.RefreshEndpoint;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.TesseractException;
/**
* Component to show informations about tesseract configs.
*
* @author Fernando Romulo da Silva
*/
@Component
@Endpoint(id = "tesseract")
// @Endpoint, @JmxEndpoint, and @WebEndpoint
public class TesseractInfoService {
private final Resource imageFile;
private final RefreshEndpoint refreshEndpoint;
/**
* Default constructor.
*
* @param newImageFile Image to check if the tesseract works
* @param newRefreshEndpoint Represh point to update infos
*/
TesseractInfoService( //
@Value("classpath:check-image.png") //
final Resource newImageFile, //
//
@Autowired //
final RefreshEndpoint newRefreshEndpoint) {
super();
this.imageFile = newImageFile;
this.refreshEndpoint = newRefreshEndpoint;
}
/**
* Read data about tesseract configs.
*
* @return A {@link TesseractDetailsData} with the data
*/
@ReadOperation
public TesseractDetailsData read() {
final var details = new LinkedHashMap<String, Object>();
details.put("tesseractVersion", "4.11");
details.put("tesseractFolder", BeanUtil.getPropertyValue("tesseract.folder"));
details.put("tesseractLanguage", BeanUtil.getPropertyValue("tesseract.language"));
details.put("tesseractDpi", BeanUtil.getPropertyValue("tesseract.dpi"));
if (checkTesseract()) {
details.put("tesseractInit", "SUCCESSFUL");
} else {
details.put("tesseractInit", "FAIL");
}
return new TesseractDetailsData(details);
}
// @ReadOperation
// public String health(@Selector String name) {
// return "custom-end-point";
// }
/**
* Update values from request http, JMX, etc.
*
* @param tesseractFolder The tesseract intalled dictionary
* @param tesseractLanguage The tesseract language
* @param tesseractDpi The resolution quality
*/
@WriteOperation
public void writeOperation(@Nullable final String tesseractFolder, @Nullable final String tesseractLanguage, @Nullable final String tesseractDpi) {
final var env = (ConfigurableEnvironment) BeanUtil.getEnvironment();
final var propertySources = env.getPropertySources();
final var map = new HashMap<String, Object>();
if (Objects.nonNull(tesseractFolder)) {
map.put("tesseract.folder", tesseractFolder);
}
if (Objects.nonNull(tesseractLanguage)) {
map.put("tesseract.language", tesseractLanguage);
}
if (Objects.nonNull(tesseractDpi)) {
map.put("tesseract.dpi", tesseractDpi);
}
propertySources.addFirst(new MapPropertySource("newmap", map));
if (!map.isEmpty()) {
refreshEndpoint.refresh();
}
}
// @DeleteOperation
// public void deleteOperation(@Selector final String name) {
// // delete operation
// }
private boolean checkTesseract() {
final var tesseractBeanProvider = BeanUtil.getBeanProviderFrom(ITesseract.class);
final var tesseract = tesseractBeanProvider.getObject();
boolean result = false;
if (Objects.isNull(tesseract)) {
result = false;
} else {
try {
final var bufferedImage = ImageIO.read(new ByteArrayInputStream(imageFile.getInputStream().readAllBytes()));
final var numberOne = tesseract.doOCR(bufferedImage).replaceAll("\\D+", "");
if (equalsIgnoreCase(numberOne, "033")) {
result = true;
}
} catch (final TesseractException | IOException | IllegalArgumentException ex) {
result = false;
}
}
return result;
}
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public static class TesseractDetailsData {
private final Map<String, Object> tesseractDetails;
TesseractDetailsData(final Map<String, Object> tesseractDetails) {
super();
this.tesseractDetails = tesseractDetails;
}
@JsonAnyGetter
public Map<String, Object> getTesseractDetails() {
return MapUtils.unmodifiableMap(tesseractDetails);
}
}
}