/** * @author ishaikh * */ package com.transformuk.bdt.controller; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; 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.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; import com.transformuk.bdt.domain.Lep; import com.transformuk.bdt.mapit.domain.MapItPartialPostCode; import com.transformuk.bdt.model.ErrorResponse; import com.transformuk.bdt.model.Response; import com.transformuk.bdt.model.TCLep; import com.transformuk.bdt.service.LepServiceImpl; import com.transformuk.bdt.service.MapItServiceImpl; import com.transformuk.bdt.util.StaticReferences; @RestController @RequestMapping("/lep") public class HubLepController { @Autowired MapItServiceImpl mapItService; @Autowired LepServiceImpl lepService; private static final Logger logger = Logger .getLogger(HubLepController.class); @RequestMapping(value = "/lookup/v1/{postcode}", method = RequestMethod.GET, produces = "application/json; charset=utf-8") @ResponseBody public ResponseEntity<Response> getLepDataByFullPostCode( HttpServletRequest request, @PathVariable String postcode, HttpServletResponse response) { logger.debug("getting lep data for postcode: " + postcode); String client1Header = System.getProperty("clientTC"); String client2Header = System.getProperty("clientBIS"); if (StringUtils.isBlank(client1Header)) { logger.error("System property clientTC and clientBIS is required"); response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); return new ResponseEntity<Response>(HttpStatus.SERVICE_UNAVAILABLE); } Response resp = new Response(); String userAgent = request.getHeader("User-Agent"); if ( (StringUtils.isBlank(userAgent)) || (!userAgent.toLowerCase().startsWith(client1Header.toLowerCase()) && !userAgent.toLowerCase().startsWith(client2Header.toLowerCase()))) { logger.error("Unauthorised access userAgent:" + userAgent); return new ResponseEntity<Response>(HttpStatus.FORBIDDEN); } try { logger.warn("Got request from Authorised client with header:"+userAgent); ResponseEntity<String> mapItResponse = getMapItDataByCode(postcode, false); String jsonResponse = mapItResponse.getBody(); Map<String, List<String>> gssNameResponseMap = mapItService .getGssNamesFromPostCodeResponse(jsonResponse, false); // build lep names/phone data from gss codes List<String> gssList = gssNameResponseMap.get(StaticReferences.GSS); List<Lep> lepData = buildLepData(gssList); List<TCLep> tcLepDataList = convertToTC(lepData); resp.setData(tcLepDataList); resp.setStatus("success"); } catch (Exception e) { logger.error("Exception doing HubLep lookup: " + e.getMessage()); ErrorResponse errResp = handleMapItError(e, postcode, false); return new ResponseEntity<Response>(errResp, HttpStatus.SERVICE_UNAVAILABLE); } return new ResponseEntity<Response>(resp, HttpStatus.OK); } @RequestMapping(value = "/lookup/v1/partial/{postcode}", method = RequestMethod.GET, produces = "application/json; charset=utf-8") @ResponseBody public ResponseEntity<Response> getLepDataByPartialPostCode( HttpServletRequest request, @PathVariable String postcode, HttpServletResponse response) { logger.debug("getting question by id: " + postcode); String client1Header = System.getProperty("clientTC"); String client2Header = System.getProperty("clientBIS"); if (StringUtils.isBlank(client1Header)) { logger.error("System property clientTC and clientBIS is required"); response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); return new ResponseEntity<Response>(HttpStatus.SERVICE_UNAVAILABLE); } Response resp = new Response(); String userAgent = request.getHeader("User-Agent"); if (StringUtils.isBlank(userAgent) || !userAgent.toLowerCase().startsWith(client1Header.toLowerCase()) || !userAgent.toLowerCase().startsWith(client2Header.toLowerCase())) { logger.error("Unauthorised access userAgent:" + userAgent); return new ResponseEntity<Response>(HttpStatus.FORBIDDEN); } try { logger.warn("Got request for partial from Authorised client with header:"+userAgent); ResponseEntity<String> mapItResponse = getMapItDataByCode(postcode, true); String jsonResponse = mapItResponse.getBody(); // for partial post code use another API jsonResponse = getJsonResponseByPointAPI(jsonResponse); Map<String, List<String>> gssNameResponseMap = mapItService .getGssNamesFromPostCodeResponse(jsonResponse, true); // build lep names/phone data from gss codes List<String> gssList = gssNameResponseMap.get(StaticReferences.GSS); List<Lep> lepData = buildLepData(gssList); List<TCLep> tcLepDataList = convertToTC(lepData); resp.setData(tcLepDataList); resp.setStatus("success"); } catch (Exception e) { logger.error("Exception doing HubLep lookup: " + e.getMessage()); ErrorResponse errResp = handleMapItError(e, postcode, true); return new ResponseEntity<Response>(errResp, HttpStatus.SERVICE_UNAVAILABLE); } return new ResponseEntity<Response>(resp, HttpStatus.OK); } private ResponseEntity<String> getMapItDataByCode(String postCode, boolean isPartialPostCode) { ResponseEntity<String> mapItResponse = null; if (isPartialPostCode) { mapItResponse = mapItService .getMapItDataForPartialPostCode(postCode); } else { mapItResponse = mapItService.getMapItDataForFullPostCode(postCode); } if (mapItResponse.getStatusCode() != HttpStatus.OK) { logger.error("MapIt postcode lookup returned HttpResponse error code: " + mapItResponse.getStatusCode()); throw new RuntimeException("MapIt Service error,http code: " + mapItResponse.getStatusCode()); } return mapItResponse; } private String getJsonResponseByPointAPI(String jsonResponse) throws Exception { MapItPartialPostCode mapItPostCodeResponse = mapItService .convertDataFromPartialPostCode(jsonResponse); // make call to the point API ResponseEntity<String> jsonDataPointApi = mapItService .getDataFromPointApi(mapItPostCodeResponse); return jsonDataPointApi.getBody(); } private ErrorResponse handleMapItError(Exception e, String postcode, boolean isPartial) { logger.error(e.getMessage()); ErrorResponse errResp = new ErrorResponse(); errResp.setStatus("failure"); if (e instanceof HttpClientErrorException) { String msg = ((HttpClientErrorException) e) .getResponseBodyAsString(); logger.error(msg); HttpStatus statusCode = ((HttpClientErrorException) e) .getStatusCode(); if (statusCode == HttpStatus.BAD_REQUEST || statusCode == HttpStatus.NOT_FOUND) { errResp.setCode(HttpStatus.BAD_REQUEST.toString()); if (isPartial) { errResp.setError("Partial postcode '" + postcode + "' is not valid."); } else { errResp.setError("Postcode '" + postcode + "' is not valid."); } } } else { errResp.setCode(HttpStatus.SERVICE_UNAVAILABLE.toString()); errResp.setError("Service Unavailable"); } return errResp; } private List<TCLep> convertToTC(List<Lep> lepData) { List<TCLep> tcLepList = new ArrayList<TCLep>(); for (Lep lep : lepData) { TCLep tcLep = new TCLep(); tcLep.setName(lep.getName()); tcLep.setLep(lep.getLep()); tcLep.setUrl(lep.getUrl()); tcLep.setPhone(lep.getPhone()); tcLep.setEmail(lep.getEmail()); tcLep.setDistrict(lep.getDistrict()); tcLepList.add(tcLep); } return tcLepList; } private List<Lep> buildLepData(List<String> gssList) throws Exception { List<Lep> lepDataList = new ArrayList<Lep>(); for (String gssCode : gssList) { List<Lep> lepListForGSSCode = lepService .getMatchingLepFromGssCode(gssCode); // note for same gsscode we can get multiple LEPS therefore add all // list lepDataList.addAll(lepListForGSSCode); } return lepDataList; } }