Commit 2f7e1e77 authored by Matija Obreza's avatar Matija Obreza
Browse files

Basic BrAPI documentation

parent 9c0022fa
Genesys BrAPI reference manual
==============================
March 2017: Documentation commit {buildNumber}
:revnumber: {projectVersion}
:doctype: book
:toc: left
:toclevels: 5
:icons: font
:numbered:
:source-highlighter: pygments
:pygments-css: class
:pygments-linenums-mode: table
Genesys implements basic BrAPI v1 specification <<brapiv1>>
All API access is over HTTPS, and accessed from the https://www.genesys-pgr.org domain or
through https://sandbox.genesys-pgr.org for testing purposes. All data is sent and received as JSON.
In this manual, all URLs are pointing to the Genesys sandbox environment at https://sandbox.genesys-pgr.org.
include::brapi/auth.adoc[]
include::brapi/crops.adoc[]
include::brapi/germplasm.adoc[]
[bibliography]
- [[[brapiv1]]]: http://docs.brapi.apiary.io/
[[chAuth]]
== Authentication
All BrAPI requests can be made anonymously, without providing the OAuth2
*Bearer: <TOKEN>* authentication header.
=== Login
Genesys does not support the `/login` endpoint.
=== Logout
Genesys does not support the `/logout` endpoint.
[[chGermplasm]]
== Crops
*/brapi/v1/crops* endpoint allows for retrieving the list of
Genesys crops.
include::{snippets}/brapi-crops/curl-request.adoc[]
==== Path parameters
include::{snippets}/brapi-crops/path-parameters.adoc[]
==== Request parameters
include::{snippets}/brapi-crops/request-parameters.adoc[]
==== Server response
Genesys returns the standard BrAPI Germplasm response:
[source,json,linenums]
----
{
"content": [{
"uuid": "4422e87e-52fe-38ef-b04a-079e663dd3da",
"version": 0,
"instCode": "XXX001",
"instEmail": "institute@localhost",
"state": 0,
"createdDate": null,
"lastModifiedDate": null,
"lastReminderDate": null
}], <1>
"last": true,
"totalElements": 1, <2>
"totalPages": 1, <3>
"size": 10, <4>
"number": 0,
"sort": [{
"direction": "DESC",
"property": "createdDate",
"ignoreCase": false,
"nullHandling": "NATIVE",
"ascending": false
}],
"first": true,
"numberOfElements": 1 <5>
}
----
<1> Array containing request information
<2> Number of elements in the Genesys database
<3> Number of pages
<4> Page size
<5> Number of elements in the `content` array
include::{snippets}/brapi-crops/response-fields.adoc[]
[[chGermplasm]]
== Germplasm
=== Germplasm search
*/brapi/v1/germplasm-search* endpoint allows for retrieving accession data from
Genesys.
include::{snippets}/brapi-germplasm-search/curl-request.adoc[]
==== Path parameters
include::{snippets}/brapi-germplasm-search/path-parameters.adoc[]
==== Request parameters
include::{snippets}/brapi-germplasm-search/request-parameters.adoc[]
==== Server response
Genesys returns the standard BrAPI Germplasm response:
[source,json,linenums]
----
{
"content": [{
"uuid": "4422e87e-52fe-38ef-b04a-079e663dd3da",
"version": 0,
"instCode": "XXX001",
"instEmail": "institute@localhost",
"state": 0,
"createdDate": null,
"lastModifiedDate": null,
"lastReminderDate": null
}], <1>
"last": true,
"totalElements": 1, <2>
"totalPages": 1, <3>
"size": 10, <4>
"number": 0,
"sort": [{
"direction": "DESC",
"property": "createdDate",
"ignoreCase": false,
"nullHandling": "NATIVE",
"ascending": false
}],
"first": true,
"numberOfElements": 1 <5>
}
----
<1> Array containing request information
<2> Number of elements in the Genesys database
<3> Number of pages
<4> Page size
<5> Number of elements in the `content` array
include::{snippets}/brapi-germplasm-search/response-fields.adoc[]
...@@ -109,6 +109,7 @@ menu.faq=Frequently asked questions ...@@ -109,6 +109,7 @@ menu.faq=Frequently asked questions
menu.news=News menu.news=News
menu.basics=Accession passport data menu.basics=Accession passport data
menu.apis=Genesys API menu.apis=Genesys API
menu.brapi=BrAPI v1 implementation
page.news.title=News page.news.title=News
page.news.intro=The latest from across the Genesys community – from details of the newest members to updates on accessions being conserved around the world. page.news.intro=The latest from across the Genesys community – from details of the newest members to updates on accessions being conserved around the world.
......
...@@ -67,6 +67,10 @@ ...@@ -67,6 +67,10 @@
<a href="<c:url value="/doc/0/apis" />"> <spring:message code="menu.apis" /> <a href="<c:url value="/doc/0/apis" />"> <spring:message code="menu.apis" />
</a> </a>
</li> </li>
<li class="pull-left">
<a href="<c:url value="/doc/0/brapi" />"> <spring:message code="menu.brapi" />
</a>
</li>
<%-- <li role="separator" class="divider"></li> <%-- <li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li> <li class="dropdown-header">Nav header</li>
<li> <li>
......
...@@ -18,8 +18,13 @@ package org.genesys2.tests.resttests; ...@@ -18,8 +18,13 @@ package org.genesys2.tests.resttests;
import java.io.File; import java.io.File;
import org.apache.http.impl.client.HttpClientBuilder; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IQueue;
import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.VelocityEngine;
import org.genesys2.brapi.service.impl.BrAPIServiceImpl;
import org.genesys2.server.aspect.AsAdminAspect; import org.genesys2.server.aspect.AsAdminAspect;
import org.genesys2.server.filerepository.service.BytesStorageService; import org.genesys2.server.filerepository.service.BytesStorageService;
import org.genesys2.server.filerepository.service.ImageGalleryService; import org.genesys2.server.filerepository.service.ImageGalleryService;
...@@ -148,6 +153,7 @@ import org.springframework.beans.factory.annotation.Qualifier; ...@@ -148,6 +153,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.support.NoOpCacheManager; import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean; import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
...@@ -166,11 +172,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ...@@ -166,11 +172,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IQueue;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextHierarchy(@ContextConfiguration(name = "this", classes = { AbstractRestTest.Config.class }, initializers = PropertyPlacholderInitializer.class)) @ContextHierarchy(@ContextConfiguration(name = "this", classes = { AbstractRestTest.Config.class }, initializers = PropertyPlacholderInitializer.class))
@EnableAspectJAutoProxy @EnableAspectJAutoProxy
...@@ -181,9 +182,10 @@ public abstract class AbstractRestTest extends BaseSpringTest { ...@@ -181,9 +182,10 @@ public abstract class AbstractRestTest extends BaseSpringTest {
@Configuration @Configuration
@EnableWebMvc @EnableWebMvc
@EnableAspectJAutoProxy @EnableAspectJAutoProxy
@ComponentScan(basePackages = { "org.genesys2.server.servlet.controller.brapi" })
@DirtiesContext(hierarchyMode = HierarchyMode.CURRENT_LEVEL, classMode = DirtiesContext.ClassMode.AFTER_CLASS) @DirtiesContext(hierarchyMode = HierarchyMode.CURRENT_LEVEL, classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public static class Config { public static class Config {
@Bean @Bean
public ImageGalleryAspects imageGalleryAspects() { public ImageGalleryAspects imageGalleryAspects() {
// This thing makes galleries auto-fill with images // This thing makes galleries auto-fill with images
...@@ -517,6 +519,12 @@ public abstract class AbstractRestTest extends BaseSpringTest { ...@@ -517,6 +519,12 @@ public abstract class AbstractRestTest extends BaseSpringTest {
public IQueue<Object> elasticUpdateQueue(HazelcastInstance hazelcast) { public IQueue<Object> elasticUpdateQueue(HazelcastInstance hazelcast) {
return hazelcast.getQueue("es-update"); return hazelcast.getQueue("es-update");
} }
@Bean
public BrAPIServiceImpl brapiService() {
return new BrAPIServiceImpl();
}
} }
@Autowired @Autowired
......
/*
* Copyright 2016 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.tests.resttests.docs;
import static org.hamcrest.Matchers.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.CropRule;
import org.genesys2.tests.resttests.AbstractRestTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentation;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
@Transactional(transactionManager = "transactionManager")
public class BrAPITest extends AbstractRestTest {
private static final Log LOG = LogFactory.getLog(BrAPITest.class);
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
@Autowired
WebApplicationContext webApplicationContext;
MockMvc mockMvc;
private static final ObjectMapper objectMapper;
private Crop crop;
private CropRule cropRule;
static {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
objectMapper.setSerializationInclusion(Include.NON_EMPTY);
}
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(this.restDocumentation).uris().withScheme("https").withHost("sandbox.genesys-pgr.org").withPort(443)).build();
crop = cropService.addCrop("maize", "Maize", "Crop description in EN", null);
cropRule = cropService.addCropRule(crop, "Zea", "mays", true);
List<CropRule> cropRules = new ArrayList<>();
cropRules.add(cropRule);
crop.setCropRules(cropRules);
}
@After
public void tearDown() {
cropRepository.deleteAll();
}
@Test
public void listCropsTest() throws Exception {
LOG.info("Start test-method listCropsTest");
mockMvc.perform(get("/brapi/v1/crops").contentType(MediaType.APPLICATION_JSON))
//
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON))
//
.andDo(r -> {
System.err.println(r.getResponse().getContentAsString());
})
//
.andExpect(jsonPath("$.result", hasSize(greaterThan(0)))).andExpect(jsonPath("$.result[0]", is("maize")))
//
.andExpect(jsonPath("$.metadata", is(notNullValue()))).andExpect(jsonPath("$.metadata.status", hasSize(0)))
.andExpect(jsonPath("$.metadata.datafiles", hasSize(0)))
//
.andExpect(jsonPath("$.metadata.pagination", is(not(nullValue()))))
// .andExpect(jsonPath("$[0].i18n", is(nullValue()))).andExpect(jsonPath("$[0].name", is("Maize"))).andExpect(jsonPath("$[0].description", is("Crop description in EN")))
.andDo(document("brapi-crops"));
LOG.info("Test listCropsTest passed");
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment