package ca.intelliware.ihtsdo.mlds.web.rest; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.annotation.Resource; import javax.annotation.security.RolesAllowed; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; 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.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.codahale.metrics.annotation.Timed; import ca.intelliware.ihtsdo.mlds.domain.Affiliate; import ca.intelliware.ihtsdo.mlds.domain.Member; import ca.intelliware.ihtsdo.mlds.repository.AffiliateRepository; import ca.intelliware.ihtsdo.mlds.repository.MemberRepository; import ca.intelliware.ihtsdo.mlds.security.AuthoritiesConstants; import ca.intelliware.ihtsdo.mlds.web.rest.dto.AffiliateCheckDTO; @RestController public class AffiliatePublicResource { private static final int ZERO_ONE_MANY_RESULTS_LENGTH = 3; private static final int MINIMUM_MATCH_LENGTH = 3; private final Logger log = LoggerFactory.getLogger(AffiliatePublicResource.class); @Resource AffiliateRepository affiliateRepository; @Resource MemberRepository memberRepository; @RequestMapping(value = Routes.AFFILIATES_CHECK, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @Timed @RolesAllowed({ AuthoritiesConstants.ANONYMOUS }) public @ResponseBody ResponseEntity<AffiliateCheckDTO> getAffiliates( @RequestParam(value="member", defaultValue="") String memberKey, @RequestParam(value="affiliateId", defaultValue="", required=false) String affiliateId, @RequestParam(value="match", defaultValue="") String match) { AffiliateCheckDTO response = new AffiliateCheckDTO(); if (StringUtils.isBlank(memberKey)) { return badRequest(response, "Missing mandatory parameter: member"); } if (StringUtils.isBlank(match)) { return badRequest(response, "Missing mandatory parameter: match"); } if (match.trim().length() < MINIMUM_MATCH_LENGTH) { return badRequest(response, "Match parameter value: '"+match+"' was shorter than the minimum length: "+MINIMUM_MATCH_LENGTH); } Member member = memberRepository.findOneByKey(memberKey); if (member == null) { return badRequest(response, "Unknown member: '"+memberKey+"'. Valid options: "+memberOptions()); } long affilateIdOptional = AffiliateRepository.AFFILIATE_ID_OPTIONAL_VALUE; if (StringUtils.isNotBlank(affiliateId)) { try { // Do not try to check affiliateId to not leak valid ids affilateIdOptional = Long.valueOf(affiliateId); } catch (NumberFormatException e) { response.setMatched(false); return new ResponseEntity<AffiliateCheckDTO>(response, HttpStatus.OK); } } Page<Affiliate> matchingAffiliates = affiliateRepository.findForCheck(affilateIdOptional, member, match, createZeroOneManyPageRequest()); response.setMatched(isSingleAffiliateMatch(matchingAffiliates)); return new ResponseEntity<AffiliateCheckDTO>(response, HttpStatus.OK); } private boolean isSingleAffiliateMatch(Page<Affiliate> resultPage) { return resultPage.getNumberOfElements() == 1; } private PageRequest createZeroOneManyPageRequest() { // Limit number of results to tell difference between 0, 1, many results PageRequest pageRequest = new PageRequest(0, ZERO_ONE_MANY_RESULTS_LENGTH); return pageRequest; } private ResponseEntity<AffiliateCheckDTO> badRequest(AffiliateCheckDTO response, String errorMessage) { HttpStatus status = HttpStatus.BAD_REQUEST; response.setError(status.getReasonPhrase()); response.setStatus(status.value()); response.setMessage(errorMessage); return new ResponseEntity<AffiliateCheckDTO>(response, status); } private String memberOptions() { List<String> options = new ArrayList<String>(); for (Member member : memberRepository.findAll()) { options.add(member.getKey()); } Collections.sort(options); StringBuilder builder = new StringBuilder(); for (String memberKey : options) { builder.append(memberKey); builder.append(' '); } return builder.toString(); } }