Commit 7ecce711 authored by Viacheslav Pavlov's avatar Viacheslav Pavlov

Merge branch 'ui-244-network-routes' into 'master'

Added v1 api for Networks (Organizations)

See merge request genesys-pgr/genesys-server!371
parents 10faa4c0 2a51923b
......@@ -38,16 +38,16 @@ public interface ServiceEndpoints {
/* =============== Service endpoint /organizations =============== */
/* =============================================================== */
// Lists all Traits associated with Organization $O
// Lists all Traits associated with Network $O
String ORGANIZATION_TRAITS = "/organizations/{organizationId}/traits";
// Lists all DataSets associated with Organization $O
// Lists all DataSets associated with Network $O
String ORGANIZATION_DATA_SETS = "/organizations/{organizationId}/datasets";
// List all Licenses associated with Organization $O
// List all Licenses associated with Network $O
String ORGANIZATION_LICENSES = "/organizations/{organizationId}/licenses";
// Issue a request for current User to join Organization $O
// Issue a request for current User to join Network $O
String JOIN_ORGANIZATION = "/organizations/{organizationId}/join";
/* =============================================================== */
......
......@@ -30,9 +30,9 @@ import org.genesys2.server.exception.AuthorizationException;
import org.genesys2.server.exception.NotFoundElement;
import org.genesys2.server.model.impl.Article;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.Organization;
import org.genesys2.server.model.impl.PGRFANetwork;
import org.genesys2.server.service.CRMException;
import org.genesys2.server.service.OrganizationService;
import org.genesys2.server.service.PGRFANetworkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
......@@ -61,7 +61,7 @@ public class OrganizationController extends ApiBaseController {
protected static final String CONTROLLER_URL = ApiBaseController.APIv0_BASE + "/org";
@Autowired
private OrganizationService organizationService;
private PGRFANetworkService networkService;
/**
* List organizations
......@@ -73,8 +73,8 @@ public class OrganizationController extends ApiBaseController {
*/
@RequestMapping(value = "", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
List<Organization> listOrganizations(@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
return organizationService.list(new PageRequest(page - 1, 50)).getContent();
List<PGRFANetwork> listOrganizations(@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
return networkService.list(new PageRequest(page - 1, 50)).getContent();
}
/**
......@@ -85,19 +85,19 @@ public class OrganizationController extends ApiBaseController {
*/
@RequestMapping(value = "", method = { RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object updateOrganization(@RequestBody Organization organizationJson) throws ValidationException {
PGRFANetwork updateOrganization(@RequestBody PGRFANetwork organizationJson) throws ValidationException {
final Validator validator = new Validator();
final List<ConstraintViolation> violations = validator.validate(organizationJson);
if (violations.size() > 0) {
// TODO We could do better messages on validation error
throw new ModelValidationException("Validation failed", violations);
}
Organization organization = organizationService.getOrganization(organizationJson.getSlug());
PGRFANetwork network = networkService.getNetwork(organizationJson.getSlug());
if (organization == null) {
organization = organizationService.create(organizationJson.getSlug(), organizationJson.getTitle());
if (network == null) {
network = networkService.create(organizationJson.getSlug(), organizationJson.getTitle());
}
return organizationService.update(organization.getId(), organization.getSlug(), organizationJson.getTitle());
return networkService.update(network.getId(), network.getSlug(), organizationJson.getTitle());
}
/**
......@@ -108,36 +108,36 @@ public class OrganizationController extends ApiBaseController {
*/
@RequestMapping(value = "/{shortName}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Organization getOrganization(@PathVariable("shortName") String shortName) throws AuthorizationException {
return organizationService.getOrganization(shortName);
PGRFANetwork getOrganization(@PathVariable("shortName") String shortName) throws AuthorizationException {
return networkService.getNetwork(shortName);
}
/**
* Get organization blurp
* Get organization blurb
*
* @return
* @throws AuthorizationException
*/
@RequestMapping(value = "/{shortName}/blurp/{language}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
@RequestMapping(value = "/{shortName}/blurb/{language}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
String getBlurp(@PathVariable("shortName") String shortName, @PathVariable("language") String language) throws AuthorizationException {
Organization org = organizationService.getOrganization(shortName);
Article article = organizationService.getBlurp(org, new Locale(language));
String getBlurb(@PathVariable("shortName") String shortName, @PathVariable("language") String language) throws AuthorizationException {
PGRFANetwork org = networkService.getNetwork(shortName);
Article article = networkService.getBlurb(org, new Locale(language));
return article == null ? null : article.getBody();
}
/**
* Update blurp
* Update blurb
*
* @return
* @throws AuthorizationException
* @throws CRMException
*/
@RequestMapping(value = "/{shortName}/blurp", method = RequestMethod.PUT, produces = { MediaType.APPLICATION_JSON_VALUE })
@RequestMapping(value = "/{shortName}/blurb", method = RequestMethod.PUT, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Article updateBlurp(@PathVariable("shortName") String shortName, @RequestBody OrganizationBlurpJson blurp) throws AuthorizationException, CRMException {
Organization org = organizationService.getOrganization(shortName);
return organizationService.updateAbout(org, blurp.blurp, blurp.summary, blurp.getLocale());
Article updateBlurb(@PathVariable("shortName") String shortName, @RequestBody OrganizationBlurbJson blurb) throws AuthorizationException, CRMException {
PGRFANetwork org = networkService.getNetwork(shortName);
return networkService.updateAbout(org, blurb.blurb, blurb.summary, blurb.getLocale());
}
/**
......@@ -148,8 +148,8 @@ public class OrganizationController extends ApiBaseController {
*/
@RequestMapping(value = "/{shortName}", method = RequestMethod.DELETE, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Organization deleteOrganization(@PathVariable("shortName") String shortName) throws AuthorizationException {
return organizationService.deleteOrganization(organizationService.getOrganization(shortName));
PGRFANetwork deleteOrganization(@PathVariable("shortName") String shortName) throws AuthorizationException {
return networkService.delete(networkService.getNetwork(shortName));
}
/**
......@@ -162,14 +162,14 @@ public class OrganizationController extends ApiBaseController {
public @ResponseBody
Set<String> getOrganizationMembers(@PathVariable("shortName") String shortName) throws AuthorizationException {
Set<String> instCodes = new HashSet<String>();
for (FaoInstitute inst : organizationService.getMembers(organizationService.getOrganization(shortName))) {
for (FaoInstitute inst : networkService.getInstitutes(networkService.getNetwork(shortName))) {
instCodes.add(inst.getCode());
}
return instCodes;
}
/**
* Add Institutes to Organization
* Add Institutes to Network
*
* @return
* @throws IOException
......@@ -177,19 +177,19 @@ public class OrganizationController extends ApiBaseController {
*/
@RequestMapping(value = "/{slug}/add-institutes", method = { RequestMethod.POST, RequestMethod.PUT }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
boolean addOrganizationInstitutes(@PathVariable(value = "slug") String slug, @RequestBody List<String> instituteList) throws JsonProcessingException,
PGRFANetwork addOrganizationInstitutes(@PathVariable(value = "slug") String slug, @RequestBody List<String> instituteList) throws JsonProcessingException,
IOException {
// TODO Check user's permissions to update this organization.
final Organization organization = organizationService.getOrganization(slug);
if (organization == null) {
final PGRFANetwork network = networkService.getNetwork(slug);
if (network == null) {
throw new NotFoundElement();
}
return organizationService.addOrganizationInstitutes(organization, instituteList);
return networkService.addInstitutes(network, instituteList);
}
/**
* Set Institutes of Organization
* Set Institutes of Network
*
* @return
* @throws IOException
......@@ -197,20 +197,20 @@ public class OrganizationController extends ApiBaseController {
*/
@RequestMapping(value = "/{slug}/set-institutes", method = { RequestMethod.POST, RequestMethod.PUT }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
boolean setOrganizationInstitutes(@PathVariable(value = "slug") String slug, @RequestBody List<String> instituteList) throws JsonProcessingException,
PGRFANetwork setOrganizationInstitutes(@PathVariable(value = "slug") String slug, @RequestBody List<String> instituteList) throws JsonProcessingException,
IOException {
// TODO Check user's permissions to update this organization.
final Organization organization = organizationService.getOrganization(slug);
if (organization == null) {
final PGRFANetwork network = networkService.getNetwork(slug);
if (network == null) {
throw new NotFoundElement();
}
return organizationService.setOrganizationInstitutes(organization, instituteList);
return networkService.setInstitutes(network, instituteList);
}
public static class OrganizationBlurpJson {
public static class OrganizationBlurbJson {
public String summary;
public String blurp;
public String blurb;
public String locale;
public Locale getLocale() {
......
......@@ -141,7 +141,7 @@ public class InstituteController {
InstituteDetails details = new InstituteDetails();
details.details = faoInstitute;
details.blurb = contentService.getArticle(faoInstitute, "blurp", getLocale());
details.blurb = contentService.getArticle(faoInstitute, ContentService.ENTITY_BLURB_SLUG, getLocale());
details.pdciStats = faoInstitute.getStatisticsPDCI();
details.lastUpdates = genesysService.getLastUpdatedStatistics(faoInstitute);
details.overview = getOverviewData(byInstituteFilter);
......
/**
* Copyright 2019 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.server.api.v1;
import io.swagger.annotations.Api;
import org.genesys2.server.api.ApiBaseController;
import org.genesys2.server.exception.NotFoundElement;
import org.genesys2.server.model.impl.Article;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.PGRFANetwork;
import org.genesys2.server.service.CRMException;
import org.genesys2.server.service.PGRFANetworkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
@RestController("networkApi1")
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = { NetworkController.CONTROLLER_URL, "/json/v1/network" })
@Api(tags = { "network" })
public class NetworkController extends ApiBaseController {
// Rest controller base URL
public static final String CONTROLLER_URL = ApiBaseController.APIv1_BASE + "/network";
@Autowired
private PGRFANetworkService networkService;
/**
* List organizations
*
* @return
*/
@GetMapping(value = "", produces = { MediaType.APPLICATION_JSON_VALUE })
public List<PGRFANetwork> listNetworks(@RequestParam(value = "page", required = false, defaultValue = "1") int page) {
return networkService.list(new PageRequest(page - 1, 50)).getContent();
}
/**
* Create or update network
*
* @return
*/
@PostMapping(value = "", produces = { MediaType.APPLICATION_JSON_VALUE })
public PGRFANetwork updateNetwork(@RequestBody PGRFANetwork organizationJson) {
PGRFANetwork network = networkService.getNetwork(organizationJson.getSlug());
if (network == null) {
return networkService.create(organizationJson.getSlug(), organizationJson.getTitle());
}
return networkService.update(network.getId(), network.getSlug(), organizationJson.getTitle());
}
/**
* Get network
*
* @return
*/
@GetMapping(value = "/{shortName}", produces = { MediaType.APPLICATION_JSON_VALUE })
public PGRFANetwork getNetwork(@PathVariable("shortName") String shortName) {
PGRFANetwork network = networkService.getNetwork(shortName);
if (network == null)
throw new NotFoundElement("Network not found");
return network;
}
/**
* Get network details
*
* @return
*/
@GetMapping(value = "/{shortName}/details", produces = { MediaType.APPLICATION_JSON_VALUE })
public NetworkDetails getNetworkDetails(@PathVariable("shortName") String shortName, @RequestParam(value = "language", defaultValue = "en") String language) {
PGRFANetwork network = networkService.getNetwork(shortName);
if (network == null) {
throw new NotFoundElement("Network not found");
}
Page<FaoInstitute> members = networkService.getInstitutes(network, new PageRequest(0, 50));
Article blurb = networkService.getBlurb(network, new Locale(language));
return NetworkDetails.from(network, blurb, members);
}
/**
* Get network blurb
*
* @return
*/
@GetMapping(value = "/{shortName}/blurb/{language}", produces = { MediaType.APPLICATION_JSON_VALUE })
public Article getBlurb(@PathVariable("shortName") String shortName, @PathVariable("language") String language) {
PGRFANetwork network = networkService.getNetwork(shortName);
if (network == null) {
throw new NotFoundElement("Network not found");
}
return networkService.getBlurb(network, new Locale(language));
}
/**
* Update blurb
*
*/
@PutMapping(value = "/{shortName}/blurb", produces = { MediaType.APPLICATION_JSON_VALUE })
public Article updateBlurb(@PathVariable("shortName") String shortName, @RequestBody Article blurb) throws CRMException {
PGRFANetwork network = networkService.getNetwork(shortName);
if (network == null) {
throw new NotFoundElement("Network not found");
}
return networkService.updateAbout(network, blurb.getBody(), blurb.getSummary(), blurb.getLang() == null ? Locale.ENGLISH : new Locale(blurb.getLang()));
}
/**
* Get network details
*
* @return
*/
@DeleteMapping(value = "/{shortName}", produces = { MediaType.APPLICATION_JSON_VALUE })
public PGRFANetwork deleteNetwork(@PathVariable("shortName") String shortName) {
return networkService.delete(networkService.getNetwork(shortName));
}
/**
* Get network institutes' codes
*
* @return
*/
@GetMapping(value = "/{shortName}/institutes/codes", produces = { MediaType.APPLICATION_JSON_VALUE })
public Set<String> getNetworkInstitutesCodes(@PathVariable("shortName") String shortName) {
PGRFANetwork org = networkService.getNetwork(shortName);
return networkService.getInstitutes(org).stream().map(FaoInstitute::getCode).collect(Collectors.toSet());
}
/**
* Get network details
*
* @return
*/
@GetMapping(value = "/{shortName}/institutes", produces = { MediaType.APPLICATION_JSON_VALUE })
public Page<FaoInstitute> getNetworkInstitutes(@PathVariable("shortName") String shortName, @RequestParam Integer page) {
PGRFANetwork org = networkService.getNetwork(shortName);
return networkService.getInstitutes(org, new PageRequest(page, 50));
}
/**
* Add Institutes to Network
*
* @return
*/
@RequestMapping(value = "/{slug}/add-institutes", method = { RequestMethod.POST, RequestMethod.PUT }, produces = { MediaType.APPLICATION_JSON_VALUE })
public PGRFANetwork addNetworkInstitutes(@PathVariable(value = "slug") String slug, @RequestBody List<String> instituteList) {
final PGRFANetwork network = networkService.getNetwork(slug);
if (network == null) {
throw new NotFoundElement("Network cannot be found");
}
return networkService.addInstitutes(network, instituteList);
}
/**
* Set Institutes of Network
*
* @return
*/
@RequestMapping(value = "/{slug}/set-institutes", method = { RequestMethod.POST, RequestMethod.PUT }, produces = { MediaType.APPLICATION_JSON_VALUE })
public PGRFANetwork setNetworkInstitutes(@PathVariable(value = "slug") String slug, @RequestBody List<String> instituteList) {
final PGRFANetwork network = networkService.getNetwork(slug);
if (network == null) {
throw new NotFoundElement();
}
return networkService.setInstitutes(network, instituteList);
}
public static class NetworkDetails {
public PGRFANetwork network;
public Article blurb;
public Page<FaoInstitute> institutes;
public static NetworkDetails from(PGRFANetwork network, Article blurb, Page<FaoInstitute> institutes) {
NetworkDetails details = new NetworkDetails();
details.network = network;
details.blurb = blurb;
details.institutes = institutes;
return details;
}
}
}
......@@ -18,7 +18,7 @@ import org.genesys2.server.model.genesys.AccessionList;
import org.genesys2.server.model.genesys.AccessionRemark;
import org.genesys2.server.model.genesys.SvalbardDeposit;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.Organization;
import org.genesys2.server.model.impl.PGRFANetwork;
import org.genesys2.server.service.IndexAliasConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -474,19 +474,19 @@ public class AccessionDetails {
this.historic = historic;
}
public void networks(List<Organization> organizations) {
if (organizations == null || organizations.isEmpty())
public void networks(List<PGRFANetwork> networks) {
if (networks == null || networks.isEmpty())
return;
Set<String> networks = new HashSet<String>();
for (Organization org : organizations) {
networks.add(org.getSlug());
Set<String> nets = new HashSet<String>();
for (PGRFANetwork org : networks) {
nets.add(org.getSlug());
}
if (institute == null)
institute = new Institute();
institute.setNetworks(networks);
institute.setNetworks(nets);
}
public String getAcceUrl() {
......
......@@ -134,7 +134,7 @@ public class FaoInstitute extends BasicModel implements GeoReferencedEntity, Acl
@JsonIdentityReference(alwaysAsId = true)
@Field(index = FieldIndex.not_analyzed, type = FieldType.String)
@JsonProperty(access = Access.READ_ONLY)
private List<Organization> networks;
private List<PGRFANetwork> networks;
@ManyToOne(cascade = {})
......@@ -332,11 +332,11 @@ public class FaoInstitute extends BasicModel implements GeoReferencedEntity, Acl
this.codeSGSV = codeSGSV;
}
public List<Organization> getNetworks() {
public List<PGRFANetwork> getNetworks() {
return networks;
}
public void setNetworks(List<Organization> networks) {
public void setNetworks(List<PGRFANetwork> networks) {
this.networks = networks;
}
......
......@@ -28,6 +28,8 @@ import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.genesys.blocks.model.AuditedVersionedModel;
import org.hibernate.annotations.Type;
......@@ -36,10 +38,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "organization")
public class Organization extends AuditedVersionedModel {
public class PGRFANetwork extends AuditedVersionedModel {
private static final long serialVersionUID = 2710908645431936666L;
@NotNull
@Size(max = 150)
@Column(nullable = false, length = 150, unique = true)
private String slug;
......
......@@ -91,7 +91,7 @@ public class CountryController extends BaseController {
model.addAttribute("region", geoRegionService.getRegion(country));
model.addAttribute("itpgrfa", geoService.getITPGRFAStatus(country));
model.addAttribute("blurp", contentService.getArticle(country, "blurp", getLocale()));
model.addAttribute("blurb", contentService.getArticle(country, ContentService.ENTITY_BLURB_SLUG, getLocale()));
// All institutes
model.addAttribute("faoInstitutes", instituteService.listByCountry(country));
......@@ -143,14 +143,14 @@ public class CountryController extends BaseController {
@PreAuthorize("hasRole('ADMINISTRATOR')")
@RequestMapping("/{country}/update")
public String update(ModelMap model, @PathVariable(value = "country") String countryStr, @RequestParam("blurp") String blurp) throws CRMException {
public String update(ModelMap model, @PathVariable(value = "country") String countryStr, @RequestParam("blurb") String blurb) throws CRMException {
LOG.debug("Editing country {}", countryStr);
final Country country = geoService.getCountry(countryStr);
if (country == null) {
throw new NotFoundElement();
}
geoService.updateBlurp(country, blurp, getLocale());
geoService.updateBlurb(country, blurb, getLocale());
return "redirect:/geo/" + country.getCode3();
}
......
......@@ -136,7 +136,7 @@ public class CropController extends BaseController {
model.addAttribute("jsonFilter", appliedFilters.toString());
model.addAttribute("cropRules", cropService.getCropRules(crop));
model.addAttribute("cropTaxonomies", cropService.getCropTaxonomies(crop, new PageRequest(0, 21, new Sort("taxonomy.genus", "taxonomy.species"))));
model.addAttribute("blurp", contentService.getArticle(crop, "blurp", getLocale()));
model.addAttribute("blurb", contentService.getArticle(crop, ContentService.ENTITY_BLURB_SLUG, getLocale()));
// model.addAttribute("statsGenus",
// elasticService.termStatisticsAuto(appliedFilters,
......@@ -185,7 +185,7 @@ public class CropController extends BaseController {
@RequestMapping(value = "/{shortName}/update", method = RequestMethod.POST)
public String update(ModelMap model, @PathVariable(value = "shortName") String shortName, @RequestParam(value = "cropName", required = false) String cropName,
@RequestParam("blurp") String aboutBody, @RequestParam(value = "summary", required = false) String summary) throws CRMException {
@RequestParam("blurb") String aboutBody, @RequestParam(value = "summary", required = false) String summary) throws CRMException {
Crop crop = cropService.getCrop(shortName);
if (crop == null) {
......@@ -194,7 +194,7 @@ public class CropController extends BaseController {
}
LOG.debug("Updating crop blurb {}", shortName);
cropService.updateBlurp(crop, aboutBody, summary, getLocale());
cropService.updateBlurb(crop, aboutBody, summary, getLocale());