completed initial setup
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package zw.qantra.tm.domain.controllers;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/confirm/transaction")
|
||||
@RequiredArgsConstructor
|
||||
public class ConfirmationController {
|
||||
@PostMapping()
|
||||
public ResponseEntity post(@RequestBody Object transactionRequest) {
|
||||
return ResponseEntity.ok("Transaction endpoint is working");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package zw.qantra.tm.domain.controllers;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/integration/transaction")
|
||||
@RequiredArgsConstructor
|
||||
public class IntegrationController {
|
||||
@PostMapping()
|
||||
public ResponseEntity post(@RequestBody Object transactionRequest) {
|
||||
return ResponseEntity.ok("Transaction endpoint is working");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package zw.qantra.tm.domain.controllers;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/transaction")
|
||||
@RequiredArgsConstructor
|
||||
public class TransactonController {
|
||||
@PostMapping()
|
||||
public ResponseEntity post(@RequestBody Object transactionRequest) {
|
||||
return ResponseEntity.ok("Transaction endpoint is working");
|
||||
}
|
||||
}
|
||||
6
src/main/java/zw/qantra/tm/domain/enums/RequestType.java
Normal file
6
src/main/java/zw/qantra/tm/domain/enums/RequestType.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package zw.qantra.tm.domain.enums;
|
||||
|
||||
public enum RequestType {
|
||||
REQUEST,
|
||||
CONFIRM
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.*;
|
||||
import zw.qantra.tm.domain.enums.RequestType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ConfirmTransaction {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String trace;
|
||||
private BigDecimal amount;
|
||||
private String reference;
|
||||
private String providerUid;
|
||||
private String productUid;
|
||||
private String paymentProcessorLabel;
|
||||
private String integrationProcessorLabel;
|
||||
private String rrn;
|
||||
private String channelName;
|
||||
private String channel;
|
||||
private String debitPhone;
|
||||
private String debitAccount;
|
||||
private String debitCurrency;
|
||||
private String debitName;
|
||||
private String debitCard;
|
||||
private String debitRef;
|
||||
private String creditPhone;
|
||||
private String creditAccount;
|
||||
private String creditCurrency;
|
||||
private String creditName;
|
||||
private String creditCard;
|
||||
private String creditRef;
|
||||
private String billClientId;
|
||||
private String clientSecret;
|
||||
private String aggregatorId;
|
||||
private String billName;
|
||||
private String billProductName;
|
||||
private RequestType type;
|
||||
}
|
||||
25
src/main/java/zw/qantra/tm/domain/models/Currency.java
Normal file
25
src/main/java/zw/qantra/tm/domain/models/Currency.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Currency {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String isoCode;
|
||||
private String name;
|
||||
private String displayName;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.*;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class IntegrationProcessor {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private String type;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PaymentProcessor {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private String label;
|
||||
private String type;
|
||||
}
|
||||
25
src/main/java/zw/qantra/tm/domain/models/Provider.java
Normal file
25
src/main/java/zw/qantra/tm/domain/models/Provider.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Provider {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String clientId;
|
||||
private String name;
|
||||
private String description;
|
||||
}
|
||||
28
src/main/java/zw/qantra/tm/domain/models/Setting.java
Normal file
28
src/main/java/zw/qantra/tm/domain/models/Setting.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Setting {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
}
|
||||
49
src/main/java/zw/qantra/tm/domain/models/Transaction.java
Normal file
49
src/main/java/zw/qantra/tm/domain/models/Transaction.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package zw.qantra.tm.domain.models;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import zw.qantra.tm.domain.enums.RequestType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Transaction {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private UUID id;
|
||||
|
||||
private String trace;
|
||||
private BigDecimal amount;
|
||||
private String reference;
|
||||
private String providerUid;
|
||||
private String productUid;
|
||||
private String paymentProcessorLabel;
|
||||
private String integrationProcessorLabel;
|
||||
private String rrn;
|
||||
private String channelName;
|
||||
private String channel;
|
||||
private String debitPhone;
|
||||
private String debitAccount;
|
||||
private String debitCurrency;
|
||||
private String debitName;
|
||||
private String debitCard;
|
||||
private String debitRef;
|
||||
private String creditPhone;
|
||||
private String creditAccount;
|
||||
private String creditCurrency;
|
||||
private String creditName;
|
||||
private String creditCard;
|
||||
private String creditRef;
|
||||
private String billClientId;
|
||||
private String clientSecret;
|
||||
private String aggregatorId;
|
||||
private String billName;
|
||||
private String billProductName;
|
||||
private RequestType type;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.ConfirmTransaction;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface ConfirmTransactionRepository extends JpaRepository<ConfirmTransaction, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.Currency;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface CurrencyRepository extends JpaRepository<Currency, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.IntegrationProcessor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface IntegrationProcessorRepository extends JpaRepository<IntegrationProcessor, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.PaymentProcessor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface PaymentProcessorRepository extends JpaRepository<PaymentProcessor, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.Provider;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface ProviderRepository extends JpaRepository<Provider, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.Setting;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface SettingRepository extends JpaRepository<Setting, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.repositories;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import zw.qantra.tm.domain.models.Transaction;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface TransactionRepository extends JpaRepository<Transaction, UUID> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.repositories.ConfirmTransactionRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ConfirmTransactionService {
|
||||
private final ConfirmTransactionRepository confirmTransactionRepository;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.repositories.CurrencyRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CurrencyService {
|
||||
private final CurrencyRepository currencyRepository;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.repositories.IntegrationProcessorRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class IntegrationProcessorService {
|
||||
private final IntegrationProcessorRepository integrationProcessorRepository;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.repositories.PaymentProcessorRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentProcessorService {
|
||||
private final PaymentProcessorRepository paymentProcessorRepository;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.repositories.ProviderRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProviderService {
|
||||
private final ProviderRepository providerRepository;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.repositories.SettingRepository;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SettingService {
|
||||
private final SettingRepository settingRepository;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package zw.qantra.tm.domain.services;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.models.PaymentProcessor;
|
||||
import zw.qantra.tm.domain.models.Transaction;
|
||||
import zw.qantra.tm.domain.repositories.TransactionRepository;
|
||||
import zw.qantra.tm.domain.services.factories.PaymentProcessorFactory;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TransactionService {
|
||||
private final TransactionRepository transactionRepository;
|
||||
private final PaymentProcessorFactory paymentProcessorFactory;
|
||||
|
||||
private Transaction bootstrap(Transaction transaction) {
|
||||
String label = transaction.getType() + "_" + transaction.getPaymentProcessorLabel();
|
||||
// PaymentProcessor paymentProcessor = paymentProcessorFactory.getPaymentProcessor(label);
|
||||
return transaction;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package zw.qantra.tm.domain.services.factories;
|
||||
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentProcessorFactory implements ApplicationContextAware {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public Object getPaymentProcessor(String paymentProcessorName) {
|
||||
Object paymentProcessor;
|
||||
|
||||
try {
|
||||
paymentProcessor = applicationContext.getBean(paymentProcessorName);
|
||||
} catch (NoSuchBeanDefinitionException exception) {
|
||||
logger.error("Couldn't find payment processor: {}", exception.getMessage());
|
||||
return null;
|
||||
} catch (BeansException e) {
|
||||
logger.error("Error retrieving payment processor bean: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return paymentProcessor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package zw.qantra.tm.domain.services.processors;
|
||||
|
||||
import zw.qantra.tm.domain.models.Transaction;
|
||||
|
||||
public interface TransactionProcessorInterface {
|
||||
Object process(Transaction transaction);
|
||||
Object reverse(Transaction transaction);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package zw.qantra.tm.domain.services.processors.confirmations;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import zw.qantra.tm.domain.models.Transaction;
|
||||
import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
|
||||
import zw.qantra.tm.rest.RestService;
|
||||
|
||||
@Service("CONFIRM_POWERTEL_ZESA")
|
||||
@RequiredArgsConstructor
|
||||
public class ZesaConfirmationProcessor implements TransactionProcessorInterface {
|
||||
private final RestService restService;
|
||||
|
||||
|
||||
@Override
|
||||
public Object process(Transaction transaction) {
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object reverse(Transaction transaction) {
|
||||
return transaction;
|
||||
}
|
||||
}
|
||||
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