/**
* @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;
}
}