completed initial setup
This commit is contained in:
195
src/main/java/zw/qantra/tm/rest/RestService.java
Executable file
195
src/main/java/zw/qantra/tm/rest/RestService.java
Executable file
@@ -0,0 +1,195 @@
|
||||
package zw.qantra.tm.rest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import zw.qantra.tm.exceptions.RestTemplateResponseErrorHandler;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Rest service that facilitates communication between services. Authentication
|
||||
* is either based on client credentials, user credentials or is open. User credentials
|
||||
* are only available for registered users
|
||||
* */
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RestService {
|
||||
Logger logger = LoggerFactory.getLogger(this.getClass().toString());
|
||||
|
||||
@Autowired
|
||||
private Gson gson;
|
||||
|
||||
public final RestTemplate restTemplate;
|
||||
|
||||
public RestService() {
|
||||
this.restTemplate = new RestTemplate(
|
||||
new BufferingClientHttpRequestFactory(
|
||||
new SimpleClientHttpRequestFactory()
|
||||
)
|
||||
);
|
||||
|
||||
this.restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler());
|
||||
|
||||
// bootstrap rest template
|
||||
List<ClientHttpRequestInterceptor> interceptors
|
||||
= this.restTemplate.getInterceptors();
|
||||
if (CollectionUtils.isEmpty(interceptors)) {
|
||||
interceptors = new ArrayList<>();
|
||||
}
|
||||
interceptors.add(new RestTemplateInterceptor(gson));
|
||||
this.restTemplate.setInterceptors(interceptors);
|
||||
}
|
||||
|
||||
public String getUserToken(){
|
||||
String token = "Utils.getToken()";
|
||||
logger.info(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
// client token is retrieved from open ID identity provider and
|
||||
// cached for 20 days for easy reuse.
|
||||
|
||||
// todo: definitely not the best way to do this, tried implementing caching but
|
||||
// that needs a bit of time to do correctly
|
||||
public String getClientToken(){
|
||||
logger.info("Getting client token");
|
||||
MultiValueMap<String, String> payload = new LinkedMultiValueMap<>();
|
||||
payload.add("grant_type", "client_credentials");
|
||||
Map tokenResponse = getToken(payload);
|
||||
assert tokenResponse != null;
|
||||
|
||||
String clientToken = (String) tokenResponse.get("access_token");
|
||||
logger.info("client access token", "log", clientToken);
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
public Map getToken(MultiValueMap payload){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
return this.restTemplate.postForObject("tokenUrl", entity, Map.class);
|
||||
}
|
||||
|
||||
public <T> T getAsClient(String path, Class<T> clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(getClientToken());
|
||||
HttpEntity entity = new HttpEntity<>(headers);
|
||||
return this.restTemplate.getForObject(path, clazz, entity);
|
||||
}
|
||||
|
||||
public <T> ResponseEntity<T> getExchangeAsClient(String path, Class<T> clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(getClientToken());
|
||||
HttpEntity entity = new HttpEntity<>(headers);
|
||||
return this.restTemplate.exchange(path, HttpMethod.GET, entity, clazz);
|
||||
}
|
||||
|
||||
public <T> ResponseEntity<T> postAsClient(String path, Object payload, Class<T> clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
headers.setBearerAuth(getClientToken());
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
ResponseEntity responseEntity = this.restTemplate.postForEntity(path, entity, clazz);
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
public <T> T postAs(String path, Object payload, HttpHeaders headers, Class<T> clazz){
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
return this.restTemplate.postForObject(path, entity, clazz);
|
||||
}
|
||||
|
||||
public <T> T post(String path, Object payload, Class<T> clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
headers.setBearerAuth(getUserToken());
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
T t = this.restTemplate.postForObject(path, entity, clazz);
|
||||
return t;
|
||||
}
|
||||
|
||||
public <T> T postWithToken(String token , String path, Object payload, Class<T> clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
headers.setBearerAuth(token);
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
T t = this.restTemplate.postForObject(path, entity, clazz);
|
||||
return t;
|
||||
}
|
||||
|
||||
public <T> T postFormData(String path, MultiValueMap<String, Object> payload, Class<T> clazz)
|
||||
{
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
|
||||
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(payload, headers);
|
||||
|
||||
return this.restTemplate.postForEntity(path, request, clazz).getBody();
|
||||
}
|
||||
|
||||
public <T> T get(String path, Type clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(getUserToken());
|
||||
HttpEntity entity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<String> responseEntity = this.restTemplate.exchange(path, HttpMethod.GET, entity, String.class);
|
||||
T response = gson.fromJson(responseEntity.getBody(), clazz);
|
||||
return response;
|
||||
}
|
||||
|
||||
// make post request to endpoint without bearer auth
|
||||
public <T> T postNoAuth(String path, Object payload, Class<T> clazz){
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
T t = this.restTemplate.postForObject(path, entity, clazz);
|
||||
return t;
|
||||
}
|
||||
|
||||
// make post request to endpoint without bearer auth
|
||||
public <T> T postWithExternalAuth(String path, Object payload, HttpHeaders headers, Class<T> clazz){
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
// build the request
|
||||
HttpEntity entity = new HttpEntity<>(payload, headers);
|
||||
T t = this.restTemplate.postForObject(path, entity, clazz);
|
||||
return t;
|
||||
}
|
||||
|
||||
// make get request to endpoint without bearer auth
|
||||
public <T> T getNoAuth(String path, Class<T> clazz){
|
||||
return this.restTemplate.getForObject(path, clazz);
|
||||
}
|
||||
|
||||
public <T> ResponseEntity<?> exchangeGetNoAuth(String path, HttpEntity<?> httpEntity, Class<?> clazz, String pathVariable) {
|
||||
return this.restTemplate.exchange(path, HttpMethod.GET, httpEntity, clazz, pathVariable);
|
||||
}
|
||||
}
|
||||
72
src/main/java/zw/qantra/tm/rest/RestTemplateInterceptor.java
Executable file
72
src/main/java/zw/qantra/tm/rest/RestTemplateInterceptor.java
Executable file
@@ -0,0 +1,72 @@
|
||||
package zw.qantra.tm.rest;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class RestTemplateInterceptor
|
||||
implements ClientHttpRequestInterceptor {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass().getName());
|
||||
private final Gson gson;
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(
|
||||
HttpRequest request,
|
||||
byte[] reqBody,
|
||||
ClientHttpRequestExecution execution) throws IOException {
|
||||
String requestBody = new String(reqBody, StandardCharsets.UTF_8);
|
||||
if(!isJSONValid(requestBody)) requestBody = toBasicJson(requestBody);
|
||||
|
||||
// we don't log file data
|
||||
if(request.getHeaders().getContentLength() < 10000){
|
||||
logger.info("Request: "
|
||||
+ request.getMethod() + ": "
|
||||
+ request.getURI(), "http", gson.fromJson(requestBody, HashMap.class));
|
||||
}
|
||||
ClientHttpResponse response = execution.execute(request, reqBody);
|
||||
InputStreamReader isr = new InputStreamReader(response.getBody());
|
||||
String body = new BufferedReader(isr).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
try{
|
||||
logger.info("Response body: {}", "http", gson.fromJson(body, HashMap.class));
|
||||
}catch (Exception exception){
|
||||
logger.info("Problem serializing resp: {}", "http", exception.getMessage());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
public String toBasicJson(String string){
|
||||
HashMap map = new HashMap();
|
||||
map.put("log", string);
|
||||
return gson.toJson(map);
|
||||
}
|
||||
|
||||
public boolean isJSONValid(String test) {
|
||||
try {
|
||||
new JSONObject(test);
|
||||
} catch (JSONException ex) {
|
||||
try {
|
||||
new JSONArray(test);
|
||||
} catch (JSONException ex1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user