Skip to content

Commit

Permalink
Merge pull request #13 from TAMULib/simple-resolver-api
Browse files Browse the repository at this point in the history
Simple entity resolver API
  • Loading branch information
wwelling committed Jul 20, 2020
2 parents dcea951 + 40edfec commit 71ac54a
Show file tree
Hide file tree
Showing 28 changed files with 598 additions and 135 deletions.
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<description>Ecosystem Identifier Service</description>

<properties>
<java.version>11</java.version>
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
</properties>

Expand Down
50 changes: 50 additions & 0 deletions src/docs/asciidocs/resolver.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
== Simple Entity Resolver API

Endpoints for basic Entity resolving

=== Create with URL

==== Request
include::{snippets}/create-with-url/http-request.adoc[]

==== Query Parameters
include::{snippets}/create-with-url/request-parameters.adoc[]

==== Response
include::{snippets}/create-with-url/http-response.adoc[]


=== Resolve Id

==== Request
include::{snippets}/resolve-id/http-request.adoc[]

==== Path Parameters
include::{snippets}/resolve-id/path-parameters.adoc[]

==== Response
include::{snippets}/resolve-id/http-response.adoc[]


=== Resolve URL

==== Request
include::{snippets}/resolve-url/http-request.adoc[]

==== Query Parameters
include::{snippets}/resolve-url/request-parameters.adoc[]

==== Response
include::{snippets}/resolve-url/http-response.adoc[]


=== Delete by Id

==== Request
include::{snippets}/delete-by-id/http-request.adoc[]

==== Path Parameters
include::{snippets}/delete-by-id/path-parameters.adoc[]

==== Response
include::{snippets}/delete-by-id/http-response.adoc[]
31 changes: 31 additions & 0 deletions src/main/java/edu/tamu/eider/app/config/AppRepositoryConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package edu.tamu.eider.app.config;

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.http.converter.HttpMessageConverter;

import edu.tamu.eider.app.model.Entity;
import edu.tamu.eider.app.model.Identifier;
import edu.tamu.eider.app.model.IdentifierType;
import edu.tamu.eider.app.model.Name;
import edu.tamu.eider.app.web.converter.PlainTextHttpMessageConverter;

@Configuration
public class AppRepositoryConfig implements RepositoryRestConfigurer {

@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(Entity.class, Identifier.class, IdentifierType.class, Name.class);
RepositoryRestConfigurer.super.configureRepositoryRestConfiguration(config);
}

@Override
public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(0, new PlainTextHttpMessageConverter());
RepositoryRestConfigurer.super.configureHttpMessageConverters(messageConverters);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ public void addCorsMappings(CorsRegistry registry) {
.allowedMethods("GET", "DELETE", "PUT", "POST")
.allowedHeaders("Origin", "Content-Type", "Access-Control-Allow-Origin", "x-requested-with", "data", "x-forwarded-for");
}

}
22 changes: 0 additions & 22 deletions src/main/java/edu/tamu/eider/app/config/RepositoryConfig.java

This file was deleted.

1 change: 1 addition & 0 deletions src/main/java/edu/tamu/eider/app/model/IdentifierType.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ public class IdentifierType {

@Size(max = 250)
private String name;

}
1 change: 1 addition & 0 deletions src/main/java/edu/tamu/eider/app/model/Name.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ public Name(String name, String notes, Entity entity) {
this.notes = notes;
this.entity = entity;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ public interface NameRepository extends PagingAndSortingRepository<Name, UUID> {

@RestResource(exported = false)
public List<Name> findByName(String name);

}
51 changes: 10 additions & 41 deletions src/main/java/edu/tamu/eider/app/web/EntityController.java
Original file line number Diff line number Diff line change
@@ -1,73 +1,52 @@
package edu.tamu.eider.app.web;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.HEAD;

import java.net.URL;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.JsonProcessingException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.data.rest.webmvc.PersistentEntityResource;
import org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.hateoas.CollectionModel;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.view.RedirectView;

import edu.tamu.eider.app.model.Entity;
import edu.tamu.eider.app.model.Identifier;
import edu.tamu.eider.app.model.repo.EntityRepository;
import edu.tamu.eider.app.model.repo.IdentifierRepository;
import edu.tamu.eider.app.model.repo.NameRepository;

@BasePathAwareController
@RepositoryRestController
public class EntityController {

@Autowired
private EntityRepository entityRepo;
private NameRepository nameRepo;

@Autowired
private IdentifierRepository identifierRepo;
private EntityRepository entityRepo;

@Autowired
private NameRepository nameRepo;

@RequestMapping(path = "/entity/{uuid}", method = HEAD)
public RedirectView redirectHeadToEntity(@PathVariable("uuid") UUID uuid) {
Optional<Entity> entityOption = entityRepo.findById(uuid);
if (entityOption.isPresent()) {
return new RedirectView(entityOption.get().getUrl().toString());
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Unable to find Entity for provided id");
}
}
private IdentifierRepository identifierRepo;

@ResponseBody
@GetMapping("/entity/name")
public CollectionModel<PersistentEntityResource> findByAssociatedName(@RequestParam("name") String nameValue, PersistentEntityResourceAssembler assembler)
throws JsonProcessingException {

Set<PersistentEntityResource> entities = nameRepo.findByName(nameValue).stream()
.map(name -> name.getEntity())
.map(ent -> assembler.toFullResource(ent))
public @ResponseBody CollectionModel<PersistentEntityResource> findByAssociatedName(@RequestParam(required = true) String name, PersistentEntityResourceAssembler assembler) throws JsonProcessingException {
Set<PersistentEntityResource> entities = nameRepo.findByName(name).stream()
.map(n -> n.getEntity())
.map(e -> assembler.toFullResource(e))
.collect(Collectors.toSet());
return CollectionModel.of(entities);
}

@ResponseBody
@GetMapping("/entity/url")
public PersistentEntityResource findByUrl(@RequestParam(name = "url") URL url, PersistentEntityResourceAssembler assembler) {
public @ResponseBody PersistentEntityResource findByUrl(@RequestParam(required = true) URL url, PersistentEntityResourceAssembler assembler) {
Optional<Entity> entityOption;
Optional<Identifier> identifierOption = identifierRepo.findByIdentifier(url.toString());
if (identifierOption.isPresent()) {
Expand All @@ -78,14 +57,4 @@ public PersistentEntityResource findByUrl(@RequestParam(name = "url") URL url, P
return assembler.toFullResource(entityOption.get());
}

@RequestMapping(path = "/entity/{uuid}/redirect", method = GET)
public RedirectView redirectGetToEntity(@PathVariable("uuid") UUID uuid) {
Optional<Entity> entityOption = entityRepo.findById(uuid);
if (entityOption.isPresent()) {
return new RedirectView(entityOption.get().getUrl().toString());
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Unable to find Entity for provided id");
}
}

}
45 changes: 45 additions & 0 deletions src/main/java/edu/tamu/eider/app/web/EntityRedirectController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package edu.tamu.eider.app.web;

import static org.springframework.web.bind.annotation.RequestMethod.HEAD;

import java.util.Optional;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.view.RedirectView;

import edu.tamu.eider.app.model.Entity;
import edu.tamu.eider.app.model.repo.EntityRepository;

@RepositoryRestController
public class EntityRedirectController {

@Autowired
private EntityRepository entityRepo;

@RequestMapping(method = HEAD, path = "/entity/{uuid}")
public RedirectView headRedirectEntity(@PathVariable(required = true) final UUID uuid) {
return redirectEntity(uuid);
}

@GetMapping("/entity/{uuid}/redirect")
public RedirectView getRedirectEntity(@PathVariable(required = true) final UUID uuid) {
return redirectEntity(uuid);
}

private RedirectView redirectEntity(final UUID uuid) {
Optional<Entity> entityOption = entityRepo.findById(uuid);
if (entityOption.isPresent()) {
return new RedirectView(entityOption.get().getUrl().toString());
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Unable to find Entity for provided id");
}
}

}
74 changes: 74 additions & 0 deletions src/main/java/edu/tamu/eider/app/web/EntityResolverController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package edu.tamu.eider.app.web;

import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

import java.net.URISyntaxException;
import java.net.URL;
import java.util.Optional;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.RepositoryRestController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ResponseStatusException;

import edu.tamu.eider.app.model.Entity;
import edu.tamu.eider.app.model.repo.EntityRepository;

@RepositoryRestController
public class EntityResolverController {

@Autowired
private EntityRepository entityRepo;

@RequestMapping(method = POST, path = "/entity", produces = MediaType.TEXT_PLAIN_VALUE)
public @ResponseBody ResponseEntity<String> createWithUrl(@RequestParam(required = true) URL url) throws URISyntaxException {
Optional<Entity> existingEntity = entityRepo.findByUrl(url);
if (existingEntity.isPresent()) {
return ResponseEntity.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(existingEntity.get().getId().toString());
}
Entity entity = new Entity();
entity.setUrl(url);
entity = entityRepo.save(entity);
return ResponseEntity.created(url.toURI())
.contentType(MediaType.TEXT_PLAIN)
.body(entity.getId().toString());
}

@RequestMapping(method = GET, path = "/entity/{uuid}", produces = MediaType.TEXT_PLAIN_VALUE)
public @ResponseBody ResponseEntity<String> resolveId(@PathVariable(required = true) String uuid) {
return ResponseEntity.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(entityRepo.findById(UUID.fromString(uuid))
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Entity with id {} not found", uuid)))
.getUrl().toString());
}

@RequestMapping(method = GET, path = "/entity", produces = MediaType.TEXT_PLAIN_VALUE)
public @ResponseBody ResponseEntity<String> resolveUrl(@RequestParam(required = true) URL url) {
return ResponseEntity.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(entityRepo.findByUrl(url)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Entity with url {} not found", url)))
.getId().toString());
}

@RequestMapping(method = DELETE, path = "/entity/{uuid}", produces = MediaType.TEXT_PLAIN_VALUE)
public @ResponseBody ResponseEntity<Void> deleteById(@PathVariable(required = true) String uuid) {
Entity entity = entityRepo.findById(UUID.fromString(uuid))
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Entity with id {} not found", uuid)));
entityRepo.delete(entity);
return ResponseEntity.noContent().build();
}

}

0 comments on commit 71ac54a

Please sign in to comment.