Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update REST API #264

Merged
merged 19 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[![vitrivr - cineast](https://img.shields.io/static/v1?label=vitrivr&message=cineast&color=blue&logo=github)](https://github.com/vitrivr/cineast)
[![GitHub release](https://img.shields.io/github/release/vitrivr/cineast?include_prereleases=&sort=semver&color=2ea44f)](https://github.com/vitrivr/cineast/releases/)
[![License](https://img.shields.io/badge/License-MIT-blueviolet)](#license)
[![License](https://img.shields.io/badge/License-MIT-blueviolet)](LICENSE)
[![swagger-editor](https://img.shields.io/badge/open--API-in--editor-green.svg?style=flat&label=Open-Api%20(Release))](https://editor.swagger.io/?url=https://raw.githubusercontent.com/vitrivr/cineast/master/docs/openapi.json)
[![swagger-editor](https://img.shields.io/badge/open--API-in--editor-green.svg?style=flat&label=Open-Api%20(Dev))](https://editor.swagger.io/?url=https://raw.githubusercontent.com/vitrivr/cineast/master/docs/openapi.json)
[![swagger-editor](https://img.shields.io/badge/open--API-in--editor-green.svg?style=flat&label=Open-Api%20(Dev))](https://editor.swagger.io/?url=https://raw.githubusercontent.com/vitrivr/cineast/dev/docs/openapi.json)
silvanheller marked this conversation as resolved.
Show resolved Hide resolved
[![Java CI with Gradle](https://github.com/vitrivr/cineast/workflows/Java%20CI%20with%20Gradle/badge.svg)](https://github.com/vitrivr/cineast/actions?query=workflow:"Java+CI+with+Gradle")

# Cineast
Expand Down Expand Up @@ -47,7 +47,7 @@ $> ./gradlew -PcineastConfig=<path/to/your/config> generateOpenApiSpecs
```

You can omit `-PcineastConfig`, then the default config (`cineast.json`) is used.
As a result, the OAS is stored at `docs/swagger.json`
As a result, the OAS is stored at `docs/openapi.json`


## Prerequisites
Expand Down
20 changes: 8 additions & 12 deletions cineast-api/src/main/java/org/vitrivr/cineast/api/APIEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.vitrivr.cineast.api.rest.handlers.actions.metadata.FindSegmentMetadataGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentByIdPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentSimilarPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentSimilarStagedPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentSimilarTemporalPostHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentsByIdGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.segment.FindSegmentsByObjectIdGetHandler;
import org.vitrivr.cineast.api.rest.handlers.actions.session.EndExtractionHandler;
Expand Down Expand Up @@ -290,21 +292,13 @@ public Javalin dispatchService(boolean secure) {
this.webSocketApi = new WebsocketAPI();

service.ws(String.format("%s/websocket", namespace()), handler -> {
handler.onConnect(ctx -> {
webSocketApi.connected(ctx.session);
});
handler.onConnect(ctx -> webSocketApi.connected(ctx.session));

handler.onClose(ctx -> {
webSocketApi.closed(ctx.session, ctx.status(), ctx.reason());
});
handler.onClose(ctx -> webSocketApi.closed(ctx.session, ctx.status(), ctx.reason()));

handler.onError(ctx -> {
webSocketApi.onWebSocketException(ctx.session, ctx.error());
});
handler.onError(ctx -> webSocketApi.onWebSocketException(ctx.session, ctx.error()));

handler.onMessage(ctx -> {
webSocketApi.message(ctx.session, ctx.message());
});
handler.onMessage(ctx -> webSocketApi.message(ctx.session, ctx.message()));
});
}

Expand Down Expand Up @@ -412,6 +406,8 @@ private void registerRestOperations() {
new FindSegmentsByIdGetHandler(),
new FindSegmentsByObjectIdGetHandler(),
new FindSegmentSimilarPostHandler(retrievalLogic),
new FindSegmentSimilarStagedPostHandler(retrievalLogic),
new FindSegmentSimilarTemporalPostHandler(retrievalLogic),
new FindSegmentFeaturesGetHandler(),
new FindFeaturesByCategoryGetHandler(),
new FindFeaturesByEntityGetHandler(),
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.util.List;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.vitrivr.cineast.core.config.QueryConfig;

/**
* A {@link QueryStage} contains a list of {@link QueryTerm}s. This object represents a stage in a {@link StagedSimilarityQuery}.
Expand All @@ -17,21 +16,14 @@ public class QueryStage {
*/
public final List<QueryTerm> terms;

/**
* The {@link QueryConfig} that should be used to configure the query. May be null!
*/
public final QueryConfig config;

/**
* Constructor for the QueryStage object.
*
* @param terms List of {@link QueryTerm}s.
* @param config The {@link QueryConfig}. May be null!
*/
@JsonCreator
public QueryStage(@JsonProperty(value = "terms", required = true) List<QueryTerm> terms, @JsonProperty(value = "config", required = false) QueryConfig config) {
public QueryStage(@JsonProperty(value = "terms", required = true) List<QueryTerm> terms) {
this.terms = terms;
this.config = config;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,32 @@
import org.vitrivr.cineast.core.config.ReadableQueryConfig;

/**
* A {@link SimilarityQuery} contains a list of {@link QueryComponent}s. This object represents a similarity-query message, i.e. a request for a similarity-search.
* A {@link SimilarityQuery} contains a list of {@link QueryTerm}s. This object represents a similarity-query message, i.e. a request for a similarity-search.
*/
public class SimilarityQuery extends Query {

/**
* List of {@link QueryComponent}s that are part of this {@link SimilarityQuery}.
* List of {@link QueryTerm}s that are part of this {@link SimilarityQuery}.
*/
private final List<QueryComponent> components;
private final List<QueryTerm> terms;

/**
* Constructor for the SimilarityQuery object.
*
* @param components List of {@link QueryComponent}s.
* @param terms List of {@link QueryTerm}s.
* @param config The {@link ReadableQueryConfig}. May be null!
*/
@JsonCreator
public SimilarityQuery(@JsonProperty(value = "containers", required = true) List<QueryComponent> components,
@JsonProperty(value = "config", required = false) QueryConfig config) {
public SimilarityQuery(@JsonProperty(value = "terms", required = true) List<QueryTerm> terms, @JsonProperty(value = "config") QueryConfig config) {
super(config);
this.components = components;
this.terms = terms;
}

/**
* Getter for containers.
*/
public List<QueryComponent> getComponents() {
return this.components;
public List<QueryTerm> getTerms() {
return this.terms;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.vitrivr.cineast.api.rest;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
Expand All @@ -21,12 +20,11 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.vitrivr.cineast.api.APIEndpoint;
import org.vitrivr.cineast.api.messages.interfaces.MessageType;
import org.vitrivr.cineast.standalone.config.APIConfig;

/**
Expand All @@ -41,7 +39,7 @@ public class OpenApiCompatHelper {
public static final String SEGMENT_OAS_TAG = "Segment";


public static final List<Tag> OAS_TAGS = Arrays.asList(
public static final List<Tag> OAS_TAGS = Collections.singletonList(
new Tag().name(METADATA_OAS_TAG).description("Metadata related operations")
);
private static final Logger LOGGER = LogManager.getLogger();
Expand Down Expand Up @@ -115,11 +113,11 @@ public static void writeOpenApiDocPersistently(APIEndpoint apiEndpoint, final St
apiEndpoint.getOpenApi().getOpenApiHandler().createOpenAPISchema());
File file = new File(path);
File folder = file.getParentFile();
if (folder != null) {
folder.mkdirs();
if (folder != null && !folder.exists() && !folder.mkdirs()) {
LOGGER.warn("Could not create OpenAPI documentation path: {}", folder.getAbsolutePath());
}
if (file.exists()) {
file.delete();
if (file.exists() && !file.delete()) {
LOGGER.warn("Could not delete existing OpenAPI documentation: {}", file.getAbsolutePath());
}
try (FileOutputStream stream = new FileOutputStream(
file); PrintWriter writer = new PrintWriter(stream)) {
Expand All @@ -132,10 +130,4 @@ public static void writeOpenApiDocPersistently(APIEndpoint apiEndpoint, final St
APIEndpoint.stop();
}
}

private static abstract class MediaObjectMetadataQueryResultMixin {

@JsonIgnore
public abstract MessageType getMessageType();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,10 @@
import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import org.vitrivr.cineast.api.messages.query.SimilarityQuery;
import org.vitrivr.cineast.api.messages.result.SimilarityQueryResultBatch;
import org.vitrivr.cineast.api.rest.handlers.interfaces.ParsingPostRestHandler;
import org.vitrivr.cineast.api.util.QueryUtil;
import org.vitrivr.cineast.core.config.QueryConfig;
import org.vitrivr.cineast.core.config.ReadableQueryConfig;
import org.vitrivr.cineast.core.data.Pair;
import org.vitrivr.cineast.core.data.StringDoublePair;
import org.vitrivr.cineast.core.data.query.containers.AbstractQueryTermContainer;
import org.vitrivr.cineast.standalone.config.Config;
import org.vitrivr.cineast.standalone.config.ConstrainedQueryConfig;
import org.vitrivr.cineast.standalone.util.ContinuousRetrievalLogic;

Expand All @@ -31,28 +21,11 @@ public FindSegmentSimilarPostHandler(ContinuousRetrievalLogic continuousRetrieva

@Override
public SimilarityQueryResultBatch performPost(SimilarityQuery query, Context ctx) {
ConstrainedQueryConfig config = ConstrainedQueryConfig.getApplyingConfig(query.getQueryConfig());

HashMap<String, List<StringDoublePair>> returnMap = new HashMap<>();
/*
* Prepare map that maps categories to QueryTerm components.
*/
HashMap<String, ArrayList<AbstractQueryTermContainer>> categoryMap = QueryUtil.groupComponentsByCategory(query.getComponents());
var returnMap = QueryUtil.findSegmentsSimilar(continuousRetrievalLogic, query.getTerms(), config);
silvanheller marked this conversation as resolved.
Show resolved Hide resolved

QueryConfig config = query.getQueryConfig();
ConstrainedQueryConfig qconf = new ConstrainedQueryConfig(config);
if (config == null) {
final int max = Math.min(qconf.getMaxResults().orElse(Config.sharedConfig().getRetriever().getMaxResults()), Config.sharedConfig().getRetriever().getMaxResults());
qconf.setMaxResults(max);
final int resultsPerModule = Math.min(qconf.getRawResultsPerModule() == -1 ? Config.sharedConfig().getRetriever().getMaxResultsPerModule() : qconf.getResultsPerModule(), Config.sharedConfig().getRetriever().getMaxResultsPerModule());
qconf.setResultsPerModule(resultsPerModule);
}

for (String category : categoryMap.keySet()) {
List<Pair<AbstractQueryTermContainer, ReadableQueryConfig>> containerList = categoryMap.get(category).stream().map(x -> new Pair<>(x, (ReadableQueryConfig) qconf)).collect(Collectors.toList());
returnMap.put(category, QueryUtil.retrieveCategory(continuousRetrievalLogic, containerList, category));
}

return new SimilarityQueryResultBatch(returnMap, qconf.getQueryId().toString());
return new SimilarityQueryResultBatch(returnMap, config.getQueryId().toString());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.vitrivr.cineast.api.rest.handlers.actions.segment;

import io.javalin.http.Context;
import io.javalin.plugin.openapi.dsl.OpenApiBuilder;
import io.javalin.plugin.openapi.dsl.OpenApiDocumentation;
import org.vitrivr.cineast.api.messages.query.StagedSimilarityQuery;
import org.vitrivr.cineast.api.messages.result.SimilarityQueryResultBatch;
import org.vitrivr.cineast.api.rest.handlers.interfaces.ParsingPostRestHandler;
import org.vitrivr.cineast.api.util.QueryUtil;
import org.vitrivr.cineast.standalone.config.ConstrainedQueryConfig;
import org.vitrivr.cineast.standalone.util.ContinuousRetrievalLogic;

public class FindSegmentSimilarStagedPostHandler implements ParsingPostRestHandler<StagedSimilarityQuery, SimilarityQueryResultBatch> {

public static final String ROUTE = "find/segments/similar/staged";
private final ContinuousRetrievalLogic continuousRetrievalLogic;

public FindSegmentSimilarStagedPostHandler(ContinuousRetrievalLogic continuousRetrievalLogic) {
this.continuousRetrievalLogic = continuousRetrievalLogic;
}


@Override
public OpenApiDocumentation docs() {
return OpenApiBuilder.document()
.operation(op -> {
op.summary("Find similar segments based on the given staged query");
op.description("Performs a similarity search based on the formulated query stages, executing each subsequent stage on the results of the previous stage");
op.operationId("findSegmentSimilarStaged");
op.addTagsItem("Segments");
})
.body(inClass())
.json("200", outClass());
}

@Override
public SimilarityQueryResultBatch performPost(StagedSimilarityQuery query, Context ctx) {
ConstrainedQueryConfig config = ConstrainedQueryConfig.getApplyingConfig(query.getConfig());

var results = QueryUtil.findSegmentsSimilarStaged(continuousRetrievalLogic, query.getStages(), config);
silvanheller marked this conversation as resolved.
Show resolved Hide resolved

return new SimilarityQueryResultBatch(results, config.getQueryId().toString());
}

@Override
public Class<StagedSimilarityQuery> inClass() {
return StagedSimilarityQuery.class;
}

@Override
public Class<SimilarityQueryResultBatch> outClass() {
return SimilarityQueryResultBatch.class;
}

@Override
public String route() {
return ROUTE;
}
}
Loading