Skip to content

Commit

Permalink
refactor(cbir): cbir endpoints and tests (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
bathienle authored Aug 20, 2024
1 parent 186204a commit f9d6699
Show file tree
Hide file tree
Showing 18 changed files with 1,616 additions and 802 deletions.
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 @@ -503,7 +504,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 @@ -613,11 +614,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

0 comments on commit f9d6699

Please sign in to comment.