Skip to content

Commit

Permalink
OpenAPI doco
Browse files Browse the repository at this point in the history
removed redundant status

#1302
  • Loading branch information
djtfmartin committed Jun 27, 2024
1 parent 877fa7f commit 452e028
Show file tree
Hide file tree
Showing 22 changed files with 272 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import com.fasterxml.jackson.annotation.JsonProperty;

public class LinneanClassificationImpl implements LinneanClassification {
import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "A set of higher taxa references", title = "Classification", type = "object")
public class Classification implements LinneanClassification {

String kingdom;
String phylum;
String clazz;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.regex.Pattern;

public class CleanupUtils {

private static final Pattern NULL_PATTERN = Pattern.compile("^\\s*(\\\\N|\\\\?NULL|null)\\s*$");
private static final CharMatcher SPACE_MATCHER =
CharMatcher.whitespace().or(CharMatcher.javaIsoControl());
Expand All @@ -26,8 +27,8 @@ public static String clean(String x) {
}

/**
* @param classification
* @return
* @param classification the classification object to clean
* @return a new cleaned classification object
*/
public static LinneanClassification clean(LinneanClassification classification) {
classification.setKingdom(clean(classification.getKingdom()));
Expand Down
73 changes: 47 additions & 26 deletions matching-ws/src/main/java/life/catalogue/matching/DatasetIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
import jakarta.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

import life.catalogue.api.vocab.MatchType;
Expand All @@ -33,6 +34,9 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
* Represents an index of a dataset.
*/
@Service
public class DatasetIndex {

Expand All @@ -44,7 +48,7 @@ public class DatasetIndex {
String indexPath;

@Value("${working.dir}")
protected String workingDir = "/tmp/";
String workingDir = "/tmp/";

/** Attempts to read the index from disk if it exists. */
@PostConstruct
Expand All @@ -70,25 +74,33 @@ void initWithDir(Directory indexDir) {
}
}

/**
* Returns the metadata of the index. This includes the number of taxa, the size on disk, the
* dataset title and key, and the build information.
* @return IndexMetadata
*/
public IndexMetadata getIndexMetadata(){

IndexMetadata metadata = new IndexMetadata();
// get size on disk
Path directoryPath = Path.of(indexPath);
try {
BasicFileAttributes attributes = Files.readAttributes(directoryPath, BasicFileAttributes.class);
FileTime creationTime = attributes.creationTime();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
String formattedCreationTime = dateFormat.format(creationTime.toMillis());
Instant creationTime = attributes.creationTime().toInstant();
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
.withZone(ZoneId.systemDefault());
String formattedCreationTime = dateFormatter.format(creationTime);
metadata.setCreated(formattedCreationTime);

FileStore fileStore = Files.getFileStore(directoryPath);
long totalSpace = fileStore.getTotalSpace();
long usableSpace = fileStore.getUsableSpace();
long usedSpace = totalSpace - usableSpace;
if (usedSpace > 0) {
metadata.setSizeInMB((usedSpace / 1024) / 1024);
long totalSize = 0;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(directoryPath)) {
for (Path entry : stream) {
if (!Files.isDirectory(entry)) {
totalSize += Files.size(entry);
}
}
}
metadata.setSizeInMB((long) (totalSize / (1024.0 * 1024.0)));

} catch (IOException e) {
LOG.error("Cannot read index directory attributes", e);
}
Expand Down Expand Up @@ -118,13 +130,17 @@ public IndexMetadata getIndexMetadata(){
return metadata;
}

/**
* Reads the git information from the git.json file in the working directory.
* @return Map<String, Object>
*/
public Map<String, Object> readGitInfo() {
ObjectMapper mapper = new ObjectMapper();

final String filePath = workingDir + "/git.json";
try {
if (new File(workingDir + "/git.json").exists()) {
if (new File(filePath).exists()) {
// Read JSON file and parse to JsonNode
JsonNode rootNode = mapper.readTree(new File(workingDir + "/git.json"));
JsonNode rootNode = mapper.readTree(new File(filePath));

// Navigate to the author node
String sha = rootNode.path("sha").asText();
Expand All @@ -140,28 +156,34 @@ public Map<String, Object> readGitInfo() {

return Map.of("sha", sha, "url", url, "html_url", html_url, "name", name, "email", email, "date", date, "message", message);
} else {
LOG.warn("Git info not found at {}", workingDir + "/dataset.json");
LOG.warn("Git info not found at {}", filePath);
}
} catch (IOException e) {
LOG.error("Cannot read index git information", e);
}
return Map.of();
}

/**
* Reads the dataset information from the dataset.json file in the working directory.
* @return Map<String, Object>
*/
public Map<String, Object> readDatasetInfo() {
ObjectMapper mapper = new ObjectMapper();

String filePath = workingDir + "/dataset.json";

try {
if (new File(workingDir + "/dataset.json").exists()){
LOG.info("Loading dataset info from {}", workingDir + "/dataset.json");
if (new File(filePath).exists()){
LOG.info("Loading dataset info from {}", filePath);
// Read JSON file and parse to JsonNode
JsonNode rootNode = mapper.readTree(new File(workingDir + "/dataset.json"));
JsonNode rootNode = mapper.readTree(new File(filePath));
// Navigate to the author node
String datasetKey = rootNode.path("key").asText();
String datasetTitle = rootNode.path("title").asText();
return Map.of("datasetKey", datasetKey, "datasetTitle", datasetTitle);
} else {
LOG.warn("Dataset info not found at {}", workingDir + "/dataset.json");
LOG.warn("Dataset info not found at {}", filePath);
}
} catch (IOException e) {
LOG.error("Cannot read index dataset information", e);
Expand Down Expand Up @@ -228,7 +250,7 @@ public Optional<Document> getByUsageId(String usageKey) {
try {
TopDocs docs = getSearcher().search(query, 3);
if (docs.totalHits.value > 0) {
return Optional.of(getSearcher().doc(docs.scoreDocs[0].doc));
return Optional.of(getSearcher().storedFields().document(docs.scoreDocs[0].doc));
} else {
return Optional.empty();
}
Expand Down Expand Up @@ -334,8 +356,7 @@ private NameUsageMatch fromDoc(Document doc) {
u.setSynonym(synonym);

String status = doc.get(FIELD_STATUS);
u.setStatus(TaxonomicStatus.valueOf(status));
u.getDiagnostics().setStatus(status);
u.getDiagnostics().setStatus(TaxonomicStatus.valueOf(status));

return u;
}
Expand Down Expand Up @@ -389,7 +410,7 @@ private List<NameUsageMatch> search(Query q, String name, boolean fuzzySearch, i
TopDocs docs = searcher.search(q, maxMatches);
if (docs.totalHits.value > 0) {
for (ScoreDoc sdoc : docs.scoreDocs) {
NameUsageMatch match = fromDoc(searcher.doc(sdoc.doc));
NameUsageMatch match = fromDoc(searcher.storedFields().document(sdoc.doc));
if (name.equalsIgnoreCase(match.getUsage().getCanonicalName())) {
match.getDiagnostics().setMatchType(MatchType.EXACT);
results.add(match);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package life.catalogue.matching;

import life.catalogue.api.vocab.DatasetOrigin;

import org.apache.ibatis.annotations.Param;

import javax.annotation.Nullable;

import java.util.List;

public interface DatasetMapper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

import io.swagger.v3.oas.annotations.media.Schema;

import life.catalogue.api.vocab.MatchType;
import life.catalogue.api.vocab.TaxonomicStatus;

import lombok.Data;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@Schema(description = "Diagnostics for a name match including the type of match and confidence level", title = "Diagnostics", type = "object")
public class Diagnostics {
@Schema(description = "The match type, e.g. 'exact', 'fuzzy', 'partial', 'none'")
MatchType matchType;
@JsonIgnore MatchIssueType matchIssueType;
@Schema(description = "Confidence level in percent")
Integer confidence;
String status;
@Schema(description = "The status of the match e.g. ACCEPTED, SYNONYM, AMBIGUOUS, EXCLUDED, etc.")
TaxonomicStatus status;
@Schema(description = "Additional notes about the match")
String note;
}
Loading

0 comments on commit 452e028

Please sign in to comment.