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

refactor(cbir): cbir endpoints and tests #29

Merged
merged 23 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5ea945c
refactor: cbir index endpoint
bathienle Aug 9, 2024
66ab003
refactor: cbir delete index
bathienle Aug 9, 2024
3b32e00
refactor: cbir search
bathienle Aug 9, 2024
3fbba34
fix: remove query annotation from results
bathienle Aug 14, 2024
111809c
feat: convert distance to normalised similarity score
bathienle Aug 14, 2024
ce3d9f4
refactor: convert RestTemplate to bean
bathienle Aug 19, 2024
e992236
test: add delete index test
bathienle Aug 19, 2024
e18a2da
feat: return delete index response
bathienle Aug 19, 2024
0810ef7
test: change to correct response body
bathienle Aug 19, 2024
7593ff0
test: add index annotation test
bathienle Aug 19, 2024
eca2d8c
test: add test for retrieveSimilarImages()
bathienle Aug 20, 2024
5e60164
feat: add all args constructor annotation
bathienle Aug 20, 2024
1d14999
test: fix project creation tests
bathienle Aug 20, 2024
7626263
test: fix project resouce tests
bathienle Aug 20, 2024
5fb93a9
test: fix project service tests
bathienle Aug 20, 2024
4f3bfc0
test: fix annotation domain resource tests
bathienle Aug 20, 2024
2ee5d6d
test: fix user annotation resource tests
bathienle Aug 20, 2024
08e74a4
test: fix user annotation service tests
bathienle Aug 20, 2024
b723588
test: fix secuser service tests
bathienle Aug 20, 2024
d23ea22
test: fix ontology service tests
bathienle Aug 20, 2024
8a2dcc5
test: fix image instance service tests
bathienle Aug 20, 2024
ffa1bd0
test: fix user annotation authorization tests
bathienle Aug 20, 2024
8b458e8
test: fix project authorization tests
bathienle Aug 20, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
* limitations under the License.
*/

import be.cytomine.api.controller.RestCytomineController;
import be.cytomine.domain.ontology.AnnotationDomain;
import be.cytomine.service.dto.CropParameter;
import be.cytomine.service.search.RetrievalService;
import java.io.UnsupportedEncodingException;
import javax.persistence.EntityManager;

import com.vividsolutions.jts.io.ParseException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -29,12 +28,15 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.EntityManager;
import java.io.IOException;
import be.cytomine.api.controller.RestCytomineController;
import be.cytomine.domain.ontology.AnnotationDomain;
import be.cytomine.dto.search.SearchResponse;
import be.cytomine.service.dto.CropParameter;
import be.cytomine.service.search.RetrievalService;

@Slf4j
@RestController
@RequestMapping("/api")
@Slf4j
@RequiredArgsConstructor
public class RestRetrievalController extends RestCytomineController {

Expand All @@ -54,33 +56,33 @@ private CropParameter getParameters(String location) {
return parameters;
}

@GetMapping("/retrieval/index.json")
public ResponseEntity<String> indexAnnotation(@RequestParam(value = "annotation") Long id) throws IOException, ParseException, InterruptedException {
@GetMapping("/retrieval/index")
public ResponseEntity<String> indexAnnotation(
@RequestParam(value = "annotation") Long id
) throws ParseException, UnsupportedEncodingException {
log.debug("REST request to index an annotation");

AnnotationDomain annotation = AnnotationDomain.getAnnotationDomain(entityManager, id);
CropParameter parameters = getParameters(annotation.getWktLocation());

return responseSuccess(retrievalService.indexAnnotation(annotation, parameters, getRequestETag()));
return retrievalService.indexAnnotation(annotation, parameters, getRequestETag());
}

@GetMapping("/retrieval/retrieve.json")
public ResponseEntity<String> retrieveSimilarAnnotations(
@GetMapping("/retrieval/search")
public ResponseEntity<SearchResponse> retrieveSimilarAnnotations(
@RequestParam(value = "annotation") Long id,
@RequestParam(value = "nrt_neigh") Long nrt_neigh
) throws IOException, ParseException, InterruptedException {
) throws ParseException, UnsupportedEncodingException {
log.debug("REST request to retrieve similar annotations given a query annotation {}", id);

AnnotationDomain annotation = AnnotationDomain.getAnnotationDomain(entityManager, id);
CropParameter parameters = getParameters(annotation.getWktLocation());

return responseSuccess(
retrievalService.retrieveSimilarImages(
annotation,
parameters,
getRequestETag(),
nrt_neigh
)
return retrievalService.retrieveSimilarImages(
annotation,
parameters,
getRequestETag(),
nrt_neigh
);
}
}
14 changes: 14 additions & 0 deletions src/main/java/be/cytomine/config/RestTemplateConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package be.cytomine.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfiguration {

@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
18 changes: 18 additions & 0 deletions src/main/java/be/cytomine/dto/search/SearchResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package be.cytomine.dto.search;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SearchResponse {

private String query;
private String storage;
private String index;
private List<List<Object>> similarities;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -484,7 +485,7 @@ protected void afterAdd(CytomineDomain domain, CommandResponse response) {

try {
retrievalService.indexAnnotation(annotation, parameters, null);
} catch (IOException | ParseException | InterruptedException exception) {
} catch (ParseException | UnsupportedEncodingException exception) {
log.error(exception.getMessage());
}
}
Expand Down Expand Up @@ -591,11 +592,7 @@ protected void afterDelete(CytomineDomain domain, CommandResponse response) {
response.getData().remove("userannotation");

/* Delete the annotation from the CBIR database */
try {
retrievalService.deleteIndex((AnnotationDomain) domain);
} catch (IOException | InterruptedException exception) {
log.error(exception.getMessage());
}
retrievalService.deleteIndex((AnnotationDomain) domain);
}

public List<CommandResponse> repeat(UserAnnotation userAnnotation, Long baseSliceId, int repeat) {
Expand Down
38 changes: 34 additions & 4 deletions src/main/java/be/cytomine/service/project/ProjectService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* limitations under the License.
*/

import be.cytomine.config.properties.ApplicationProperties;
import be.cytomine.domain.CytomineDomain;
import be.cytomine.domain.command.*;
import be.cytomine.domain.image.ImageInstance;
Expand All @@ -27,7 +28,6 @@
import be.cytomine.domain.security.SecRole;
import be.cytomine.domain.security.SecUser;
import be.cytomine.domain.security.User;
import be.cytomine.domain.social.PersistentConnection;
import be.cytomine.dto.DatedCytomineDomain;
import be.cytomine.dto.NamedCytomineDomain;
import be.cytomine.exceptions.*;
Expand All @@ -41,7 +41,6 @@
import be.cytomine.repository.project.ProjectRepresentativeUserRepository;
import be.cytomine.repository.security.SecRoleRepository;
import be.cytomine.repository.security.UserRepository;
import be.cytomine.repositorynosql.social.PersistentConnectionRepository;
import be.cytomine.service.CurrentRoleService;
import be.cytomine.service.CurrentUserService;
import be.cytomine.service.ModelService;
Expand All @@ -53,7 +52,6 @@
import be.cytomine.service.ontology.OntologyService;
import be.cytomine.service.ontology.ReviewedAnnotationService;
import be.cytomine.service.search.ProjectSearchExtension;
import be.cytomine.service.security.SecRoleService;
import be.cytomine.service.security.SecUserSecRoleService;
import be.cytomine.service.security.SecUserService;
import be.cytomine.service.security.SecurityACLService;
Expand All @@ -72,8 +70,10 @@
import org.bson.conversions.Bson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.http.*;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.mail.MessagingException;
import javax.persistence.Query;
Expand All @@ -89,7 +89,6 @@
import static com.mongodb.client.model.Aggregates.sort;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.gte;
import static com.mongodb.client.model.Sorts.ascending;
import static com.mongodb.client.model.Sorts.descending;
import static org.springframework.security.acls.domain.BasePermission.*;

Expand All @@ -98,6 +97,9 @@
@Transactional
public class ProjectService extends ModelService {

@Autowired
private ApplicationProperties applicationProperties;

@Autowired
private CommandHistoryRepository commandHistoryRepository;

Expand Down Expand Up @@ -173,6 +175,9 @@ public class ProjectService extends ModelService {
@Autowired
private ProjectRepresentativeUserRepository projectRepresentativeUserRepository;

@Autowired
private RestTemplate restTemplate;

public Project get(Long id) {
return find(id).orElse(null);
}
Expand Down Expand Up @@ -599,6 +604,28 @@ public List<NamedCytomineDomain> listByUser(User user) {
return projectRepository.listByUser(user);
}

private void createStorage(String projectId) {
String url = this.applicationProperties.getRetrievalServerURL() + "/api/storages";
Map<String, String> payload = new HashMap<>();
payload.put("name", projectId);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(payload, headers);

log.debug("Sending POST request to {}, {}", url, projectId);
ResponseEntity<String> response = restTemplate.exchange(
url,
HttpMethod.POST,
requestEntity,
String.class
);

if (!response.getStatusCode().equals(HttpStatus.OK)) {
log.error("Failed to create storage for project {}", projectId);
}
}

@Override
public CommandResponse add(JsonObject jsonObject) {
return add(jsonObject, null);
Expand Down Expand Up @@ -649,6 +676,9 @@ public CommandResponse add(JsonObject jsonObject, Task task) {
}
}

// Create retrieval storage
createStorage(project.getId().toString());

return commandResponse;
}

Expand Down
Loading
Loading