Bump ancient OkHTTP & Retrofit in Hooks (FINERACT-1252) (#1486)
This commit is contained in:
+1
-4
@@ -21,7 +21,7 @@ buildscript {
|
|||||||
ext {
|
ext {
|
||||||
jacocoVersion = '0.8.6'
|
jacocoVersion = '0.8.6'
|
||||||
retrofitVersion = '2.9.0'
|
retrofitVersion = '2.9.0'
|
||||||
okhttpVersion = '4.7.2'
|
okhttpVersion = '4.9.0'
|
||||||
oltuVersion = '1.0.1'
|
oltuVersion = '1.0.1'
|
||||||
fineractJavaProjects = subprojects.findAll{
|
fineractJavaProjects = subprojects.findAll{
|
||||||
[
|
[
|
||||||
@@ -107,9 +107,6 @@ allprojects {
|
|||||||
|
|
||||||
dependency 'org.springframework.security.oauth:spring-security-oauth2:2.5.0.RELEASE'
|
dependency 'org.springframework.security.oauth:spring-security-oauth2:2.5.0.RELEASE'
|
||||||
dependency 'org.apache.openjpa:openjpa:3.1.2' // when upgrading, also change OpenJPA version repeated above in buildscript!
|
dependency 'org.apache.openjpa:openjpa:3.1.2' // when upgrading, also change OpenJPA version repeated above in buildscript!
|
||||||
dependency 'com.squareup.retrofit:retrofit:1.9.0'
|
|
||||||
dependency 'com.squareup.okhttp:okhttp:2.7.5'
|
|
||||||
dependency 'com.squareup.okhttp:okhttp-urlconnection:2.7.5'
|
|
||||||
dependency 'com.google.guava:guava:30.0-jre'
|
dependency 'com.google.guava:guava:30.0-jre'
|
||||||
dependency 'com.google.code.gson:gson:2.8.6'
|
dependency 'com.google.code.gson:gson:2.8.6'
|
||||||
dependency 'org.apache.commons:commons-email:1.5'
|
dependency 'org.apache.commons:commons-email:1.5'
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ public final class FineractClient {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SSLContext sslContext = SSLContext.getInstance("SSL");
|
SSLContext sslContext = SSLContext.getInstance("SSL"); // TODO "SSL" or "TLS" as in hooks.processor.ProcessorHelper?
|
||||||
sslContext.init(null, new TrustManager[] { insecureX509TrustManager }, new SecureRandom());
|
sslContext.init(null, new TrustManager[] { insecureX509TrustManager }, new SecureRandom());
|
||||||
SSLSocketFactory insecureSslSocketFactory = sslContext.getSocketFactory();
|
SSLSocketFactory insecureSslSocketFactory = sslContext.getSocketFactory();
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,13 @@ dependencies {
|
|||||||
'com.google.guava:guava',
|
'com.google.guava:guava',
|
||||||
'com.google.code.gson:gson',
|
'com.google.code.gson:gson',
|
||||||
'com.sun.jersey:jersey-core',
|
'com.sun.jersey:jersey-core',
|
||||||
'com.squareup.retrofit:retrofit',
|
|
||||||
'jakarta.jms:jakarta.jms-api',
|
'jakarta.jms:jakarta.jms-api',
|
||||||
'jakarta.management.j2ee:jakarta.management.j2ee-api',
|
'jakarta.management.j2ee:jakarta.management.j2ee-api',
|
||||||
'jakarta.validation:jakarta.validation-api',
|
'jakarta.validation:jakarta.validation-api',
|
||||||
'com.squareup.okhttp:okhttp',
|
|
||||||
'com.squareup.okhttp:okhttp-urlconnection',
|
'com.squareup.retrofit2:retrofit',
|
||||||
|
'com.squareup.okhttp3:okhttp',
|
||||||
|
'com.squareup.okhttp3:okhttp-urlconnection',
|
||||||
|
|
||||||
'org.apache.commons:commons-email',
|
'org.apache.commons:commons-email',
|
||||||
'org.apache.commons:commons-lang3',
|
'org.apache.commons:commons-lang3',
|
||||||
|
|||||||
+10
-3
@@ -29,12 +29,16 @@ import org.apache.fineract.infrastructure.hooks.processor.HookProcessorProvider;
|
|||||||
import org.apache.fineract.infrastructure.hooks.service.HookReadPlatformService;
|
import org.apache.fineract.infrastructure.hooks.service.HookReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class FineractHookListener implements HookListener {
|
public class FineractHookListener implements HookListener {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(FineractHookListener.class);
|
||||||
|
|
||||||
private final HookProcessorProvider hookProcessorProvider;
|
private final HookProcessorProvider hookProcessorProvider;
|
||||||
private final HookReadPlatformService hookReadPlatformService;
|
private final HookReadPlatformService hookReadPlatformService;
|
||||||
private final TenantDetailsService tenantDetailsService;
|
private final TenantDetailsService tenantDetailsService;
|
||||||
@@ -49,7 +53,6 @@ public class FineractHookListener implements HookListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(final HookEvent event) {
|
public void onApplicationEvent(final HookEvent event) {
|
||||||
|
|
||||||
final String tenantIdentifier = event.getTenantIdentifier();
|
final String tenantIdentifier = event.getTenantIdentifier();
|
||||||
final FineractPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantIdentifier);
|
final FineractPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantIdentifier);
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
@@ -67,8 +70,12 @@ public class FineractHookListener implements HookListener {
|
|||||||
|
|
||||||
for (final Hook hook : hooks) {
|
for (final Hook hook : hooks) {
|
||||||
final HookProcessor processor = this.hookProcessorProvider.getProcessor(hook);
|
final HookProcessor processor = this.hookProcessorProvider.getProcessor(hook);
|
||||||
processor.process(hook, appUser, payload, entityName, actionName, tenantIdentifier, authToken);
|
try {
|
||||||
|
processor.process(hook, appUser, payload, entityName, actionName, tenantIdentifier, authToken);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LOG.error("Hook {} failed in HookProcessor {} for tenantIdentifier/user {}/{}, entityName: {}, actionName: {}, payload {} ",
|
||||||
|
hook.getId(), processor.getClass().getSimpleName(), tenantIdentifier, appUser, entityName, actionName, payload, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -24,6 +24,6 @@ import org.apache.fineract.useradministration.domain.AppUser;
|
|||||||
public interface HookProcessor {
|
public interface HookProcessor {
|
||||||
|
|
||||||
void process(Hook hook, AppUser appUser, String payload, String entityName, String actionName, String tenantIdentifier,
|
void process(Hook hook, AppUser appUser, String payload, String entityName, String actionName, String tenantIdentifier,
|
||||||
String authToken);
|
String authToken) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-43
@@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.hooks.processor;
|
package org.apache.fineract.infrastructure.hooks.processor;
|
||||||
|
|
||||||
import com.squareup.okhttp.OkHttpClient;
|
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
@@ -26,23 +25,39 @@ import java.security.cert.CertificateException;
|
|||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSession;
|
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import retrofit.Callback;
|
import retrofit2.Call;
|
||||||
import retrofit.RestAdapter;
|
import retrofit2.Callback;
|
||||||
import retrofit.RetrofitError;
|
import retrofit2.Retrofit;
|
||||||
import retrofit.client.OkClient;
|
|
||||||
import retrofit.client.Response;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public final class ProcessorHelper {
|
public final class ProcessorHelper {
|
||||||
|
|
||||||
|
// Nota bene: Similar code to insecure HTTPS is also in Fineract Client's
|
||||||
|
// org.apache.fineract.client.util.FineractClient.Builder.insecure()
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ProcessorHelper.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ProcessorHelper.class);
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static final X509TrustManager insecureX509TrustManager = new X509TrustManager() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[] {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure HTTP client to be "insecure", as in skipping host SSL certificate verification. While this can be
|
* Configure HTTP client to be "insecure", as in skipping host SSL certificate verification. While this can be
|
||||||
* useful during development e.g. when using self-signed certificates, it should never be enabled in production (due
|
* useful during development e.g. when using self-signed certificates, it should never be enabled in production (due
|
||||||
@@ -60,43 +75,23 @@ public final class ProcessorHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private OkHttpClient createClient() {
|
private OkHttpClient createClient() {
|
||||||
final OkHttpClient client = new OkHttpClient();
|
var okBuilder = new OkHttpClient.Builder();
|
||||||
if (insecureHttpClient) {
|
if (insecureHttpClient) {
|
||||||
configureInsecureClient(client);
|
configureInsecureClient(okBuilder);
|
||||||
}
|
}
|
||||||
return client;
|
return okBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureInsecureClient(final OkHttpClient client) {
|
private void configureInsecureClient(final OkHttpClient.Builder okBuilder) {
|
||||||
client.setSslSocketFactory(insecureSSLContext.getSocketFactory());
|
okBuilder.sslSocketFactory(insecureSSLContext.getSocketFactory(), insecureX509TrustManager);
|
||||||
|
HostnameVerifier insecureHostnameVerifier = (hostname, session) -> true;
|
||||||
final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
|
okBuilder.hostnameVerifier(insecureHostnameVerifier);
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean verify(final String hostname, final SSLSession session) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
client.setHostnameVerifier(hostnameVerifier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SSLContext createInsecureSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
|
private SSLContext createInsecureSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
|
||||||
final TrustManager[] certs = new TrustManager[] { new X509TrustManager() {
|
SSLContext insecureSSLContext = SSLContext.getInstance("TLS"); // TODO "TLS" or "SSL" as in
|
||||||
|
// FineractClient.Builder?
|
||||||
@Override
|
insecureSSLContext.init(null, new TrustManager[] { insecureX509TrustManager }, new SecureRandom());
|
||||||
public X509Certificate[] getAcceptedIssuers() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {}
|
|
||||||
} };
|
|
||||||
|
|
||||||
SSLContext insecureSSLContext = SSLContext.getInstance("TLS");
|
|
||||||
insecureSSLContext.init(null, certs, new SecureRandom());
|
|
||||||
return insecureSSLContext;
|
return insecureSSLContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,20 +100,23 @@ public final class ProcessorHelper {
|
|||||||
return new Callback() {
|
return new Callback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void success(final Object o, final Response response) {
|
public void onResponse(@SuppressWarnings("unused") Call call, retrofit2.Response response) {
|
||||||
LOG.info("URL: {} - Status: {}", url, response.getStatus());
|
LOG.info("URL: {} - Status: {}", url, response.code());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failure(final RetrofitError retrofitError) {
|
public void onFailure(@SuppressWarnings("unused") Call call, Throwable t) {
|
||||||
LOG.error("URL: {} - RetrofitError occured", url, retrofitError);
|
LOG.error("URL: {} - Retrofit failure occured", url, t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebHookService createWebHookService(final String url) {
|
public WebHookService createWebHookService(final String url) {
|
||||||
final OkHttpClient client = createClient();
|
final OkHttpClient client = createClient();
|
||||||
final RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(url).setClient(new OkClient(client)).build();
|
final Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
|
||||||
return restAdapter.create(WebHookService.class);
|
retrofitBuilder.baseUrl(url);
|
||||||
|
retrofitBuilder.client(client);
|
||||||
|
final Retrofit retrofit = retrofitBuilder.build();
|
||||||
|
return retrofit.create(WebHookService.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-31
@@ -34,18 +34,16 @@ import org.apache.fineract.portfolio.client.domain.Client;
|
|||||||
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
import org.apache.fineract.template.service.TemplateMergeService;
|
import org.apache.fineract.template.service.TemplateMergeService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.codehaus.jackson.JsonParseException;
|
||||||
|
import org.codehaus.jackson.map.JsonMappingException;
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import retrofit.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TwilioHookProcessor implements HookProcessor {
|
public class TwilioHookProcessor implements HookProcessor {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(TwilioHookProcessor.class);
|
|
||||||
|
|
||||||
private final HookConfigurationRepository hookConfigurationRepository;
|
private final HookConfigurationRepository hookConfigurationRepository;
|
||||||
private final TemplateMergeService templateMergeService;
|
private final TemplateMergeService templateMergeService;
|
||||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||||
@@ -63,7 +61,7 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final Hook hook, @SuppressWarnings("unused") final AppUser appUser, final String payload, final String entityName,
|
public void process(final Hook hook, @SuppressWarnings("unused") final AppUser appUser, final String payload, final String entityName,
|
||||||
final String actionName, final String tenantIdentifier, final String authToken) {
|
final String actionName, final String tenantIdentifier, final String authToken) throws IOException {
|
||||||
|
|
||||||
final SmsProviderData smsProviderData = new SmsProviderData(hook.getHookConfig());
|
final SmsProviderData smsProviderData = new SmsProviderData(hook.getHookConfig());
|
||||||
|
|
||||||
@@ -72,7 +70,7 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void sendRequest(final SmsProviderData smsProviderData, final String payload, String entityName, String actionName,
|
private void sendRequest(final SmsProviderData smsProviderData, final String payload, String entityName, String actionName,
|
||||||
final String tenantIdentifier, final String authToken, final Hook hook) {
|
final String tenantIdentifier, final String authToken, final Hook hook) throws IOException {
|
||||||
|
|
||||||
final WebHookService service = processorHelper.createWebHookService(smsProviderData.getUrl());
|
final WebHookService service = processorHelper.createWebHookService(smsProviderData.getUrl());
|
||||||
|
|
||||||
@@ -85,7 +83,7 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
smsProviderData.setEndpoint(System.getProperty("baseUrl"));
|
smsProviderData.setEndpoint(System.getProperty("baseUrl"));
|
||||||
smsProviderData.setTenantId(tenantIdentifier);
|
smsProviderData.setTenantId(tenantIdentifier);
|
||||||
smsProviderData.setMifosToken(authToken);
|
smsProviderData.setMifosToken(authToken);
|
||||||
apiKey = service.sendSmsBridgeConfigRequest(smsProviderData);
|
apiKey = service.sendSmsBridgeConfigRequest(smsProviderData).execute().body();
|
||||||
final HookConfiguration apiKeyEntry = HookConfiguration.createNew(hook, "string", apiKeyName, apiKey);
|
final HookConfiguration apiKeyEntry = HookConfiguration.createNew(hook, "string", apiKeyName, apiKey);
|
||||||
this.hookConfigurationRepository.save(apiKeyEntry);
|
this.hookConfigurationRepository.save(apiKeyEntry);
|
||||||
}
|
}
|
||||||
@@ -102,34 +100,30 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
} else {
|
} else {
|
||||||
json = JsonParser.parseString(payload).getAsJsonObject();
|
json = JsonParser.parseString(payload).getAsJsonObject();
|
||||||
}
|
}
|
||||||
service.sendSmsBridgeRequest(entityName, actionName, tenantIdentifier, apiKey, json, callback);
|
service.sendSmsBridgeRequest(entityName, actionName, tenantIdentifier, apiKey, json).enqueue(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject processUgdTemplate(final String payload, final Hook hook, final String authToken) {
|
private JsonObject processUgdTemplate(final String payload, final Hook hook, final String authToken)
|
||||||
|
throws JsonParseException, JsonMappingException, IOException {
|
||||||
JsonObject json = null;
|
JsonObject json = null;
|
||||||
try {
|
@SuppressWarnings("unchecked")
|
||||||
@SuppressWarnings("unchecked")
|
final HashMap<String, Object> map = new ObjectMapper().readValue(payload, HashMap.class);
|
||||||
final HashMap<String, Object> map = new ObjectMapper().readValue(payload, HashMap.class);
|
map.put("BASE_URI", System.getProperty("baseUrl"));
|
||||||
map.put("BASE_URI", System.getProperty("baseUrl"));
|
if (map.containsKey("clientId")) {
|
||||||
if (map.containsKey("clientId")) {
|
final Long clientId = Long.valueOf(Integer.toString((int) map.get("clientId")));
|
||||||
final Long clientId = Long.valueOf(Integer.toString((int) map.get("clientId")));
|
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
||||||
final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
|
final String mobileNo = client.mobileNo();
|
||||||
final String mobileNo = client.mobileNo();
|
if (mobileNo != null && !mobileNo.isEmpty()) {
|
||||||
if (mobileNo != null && !mobileNo.isEmpty()) {
|
this.templateMergeService.setAuthToken(authToken);
|
||||||
this.templateMergeService.setAuthToken(authToken);
|
final String compiledMessage = this.templateMergeService.compile(hook.getUgdTemplate(), map).replace("<p>", "")
|
||||||
final String compiledMessage = this.templateMergeService.compile(hook.getUgdTemplate(), map).replace("<p>", "")
|
.replace("</p>", "");
|
||||||
.replace("</p>", "");
|
final Map<String, String> jsonMap = new HashMap<>();
|
||||||
final Map<String, String> jsonMap = new HashMap<>();
|
jsonMap.put("mobileNo", mobileNo);
|
||||||
jsonMap.put("mobileNo", mobileNo);
|
jsonMap.put("message", compiledMessage);
|
||||||
jsonMap.put("message", compiledMessage);
|
final String jsonString = new Gson().toJson(jsonMap);
|
||||||
final String jsonString = new Gson().toJson(jsonMap);
|
json = JsonParser.parseString(jsonString).getAsJsonObject();
|
||||||
json = JsonParser.parseString(jsonString).getAsJsonObject();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.error("Problem occurred in processUgdTemplate function", e);
|
|
||||||
}
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -32,7 +32,7 @@ import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
|||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import retrofit.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class WebHookProcessor implements HookProcessor {
|
public class WebHookProcessor implements HookProcessor {
|
||||||
@@ -78,11 +78,11 @@ public class WebHookProcessor implements HookProcessor {
|
|||||||
|
|
||||||
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
||||||
final JsonObject json = JsonParser.parseString(payload).getAsJsonObject();
|
final JsonObject json = JsonParser.parseString(payload).getAsJsonObject();
|
||||||
service.sendJsonRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, json, callback);
|
service.sendJsonRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, json).enqueue(callback);
|
||||||
} else {
|
} else {
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
map = new Gson().fromJson(payload, map.getClass());
|
map = new Gson().fromJson(payload, map.getClass());
|
||||||
service.sendFormRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, map, callback);
|
service.sendFormRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, map).enqueue(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-18
@@ -21,14 +21,13 @@ package org.apache.fineract.infrastructure.hooks.processor;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.apache.fineract.infrastructure.hooks.processor.data.SmsProviderData;
|
import org.apache.fineract.infrastructure.hooks.processor.data.SmsProviderData;
|
||||||
import retrofit.Callback;
|
import retrofit2.Call;
|
||||||
import retrofit.client.Response;
|
import retrofit2.http.Body;
|
||||||
import retrofit.http.Body;
|
import retrofit2.http.FieldMap;
|
||||||
import retrofit.http.FieldMap;
|
import retrofit2.http.FormUrlEncoded;
|
||||||
import retrofit.http.FormUrlEncoded;
|
import retrofit2.http.GET;
|
||||||
import retrofit.http.GET;
|
import retrofit2.http.Header;
|
||||||
import retrofit.http.Header;
|
import retrofit2.http.POST;
|
||||||
import retrofit.http.POST;
|
|
||||||
|
|
||||||
public interface WebHookService {
|
public interface WebHookService {
|
||||||
|
|
||||||
@@ -40,27 +39,25 @@ public interface WebHookService {
|
|||||||
|
|
||||||
// Ping
|
// Ping
|
||||||
@GET("/")
|
@GET("/")
|
||||||
Response sendEmptyRequest();
|
Call<Void> sendEmptyRequest();
|
||||||
|
|
||||||
// Template - Web
|
// Template - Web
|
||||||
@POST("/")
|
@POST("/")
|
||||||
void sendJsonRequest(@Header(ENTITY_HEADER) String entityHeader, @Header(ACTION_HEADER) String actionHeader,
|
Call<Void> sendJsonRequest(@Header(ENTITY_HEADER) String entityHeader, @Header(ACTION_HEADER) String actionHeader,
|
||||||
@Header(TENANT_HEADER) String tenantHeader, @Header(ENDPOINT_HEADER) String endpointHeader, @Body JsonObject result,
|
@Header(TENANT_HEADER) String tenantHeader, @Header(ENDPOINT_HEADER) String endpointHeader, @Body JsonObject result);
|
||||||
Callback<Response> callBack);
|
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("/")
|
@POST("/")
|
||||||
void sendFormRequest(@Header(ENTITY_HEADER) String entityHeader, @Header(ACTION_HEADER) String actionHeader,
|
Call<Void> sendFormRequest(@Header(ENTITY_HEADER) String entityHeader, @Header(ACTION_HEADER) String actionHeader,
|
||||||
@Header(TENANT_HEADER) String tenantHeader, @Header(ENDPOINT_HEADER) String endpointHeader,
|
@Header(TENANT_HEADER) String tenantHeader, @Header(ENDPOINT_HEADER) String endpointHeader,
|
||||||
@FieldMap Map<String, String> params, Callback<Response> callBack);
|
@FieldMap Map<String, String> params);
|
||||||
|
|
||||||
// Template - SMS Bridge
|
// Template - SMS Bridge
|
||||||
@POST("/")
|
@POST("/")
|
||||||
void sendSmsBridgeRequest(@Header(ENTITY_HEADER) String entityHeader, @Header(ACTION_HEADER) String actionHeader,
|
Call<Void> sendSmsBridgeRequest(@Header(ENTITY_HEADER) String entityHeader, @Header(ACTION_HEADER) String actionHeader,
|
||||||
@Header(TENANT_HEADER) String tenantHeader, @Header(API_KEY_HEADER) String apiKeyHeader, @Body JsonObject result,
|
@Header(TENANT_HEADER) String tenantHeader, @Header(API_KEY_HEADER) String apiKeyHeader, @Body JsonObject result);
|
||||||
Callback<Response> callBack);
|
|
||||||
|
|
||||||
@POST("/configuration")
|
@POST("/configuration")
|
||||||
String sendSmsBridgeConfigRequest(@Body SmsProviderData config);
|
Call<String> sendSmsBridgeConfigRequest(@Body SmsProviderData config);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-10
@@ -30,6 +30,7 @@ import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.webT
|
|||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -67,7 +68,6 @@ import org.springframework.dao.DataIntegrityViolationException;
|
|||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import retrofit.RetrofitError;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class HookWritePlatformServiceJpaRepositoryImpl implements HookWritePlatformService {
|
public class HookWritePlatformServiceJpaRepositoryImpl implements HookWritePlatformService {
|
||||||
@@ -282,15 +282,10 @@ public class HookWritePlatformServiceJpaRepositoryImpl implements HookWritePlatf
|
|||||||
if (conf.getFieldName().equals(payloadURLName)) {
|
if (conf.getFieldName().equals(payloadURLName)) {
|
||||||
try {
|
try {
|
||||||
final WebHookService service = processorHelper.createWebHookService(fieldValue);
|
final WebHookService service = processorHelper.createWebHookService(fieldValue);
|
||||||
service.sendEmptyRequest();
|
service.sendEmptyRequest().execute();
|
||||||
} catch (RetrofitError re) {
|
} catch (IOException re) {
|
||||||
// Swallow error if it's because of method not supported or
|
String errorMessage = "url.invalid";
|
||||||
// if url throws 404 - required for integration test,
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(errorMessage);
|
||||||
// url generated on 1st POST request
|
|
||||||
if (re.getResponse() == null) {
|
|
||||||
String errorMessage = "url.invalid";
|
|
||||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-12
@@ -61,21 +61,16 @@ public class HookIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldSendOfficeCreationNotification() {
|
public void shouldSendOfficeCreationNotification() {
|
||||||
// Subject to https://echo-webhook.herokuapp.com being up
|
// Subject to https://echo-webhook.herokuapp.com being up
|
||||||
// See
|
// See http://www.jamesward.com/2014/06/11/testing-webhooks-was-a-pain-so-i-fixed-the-glitch
|
||||||
// http://www.jamesward.com/2014/06/11/testing-webhooks-was-a-pain-so-i-fixed-the-glitch
|
|
||||||
final String uniqueId = UUID.randomUUID().toString();
|
final String uniqueId = UUID.randomUUID().toString();
|
||||||
final String payloadURL = "http://echo-webhook.herokuapp.com:80/" + uniqueId + "?";
|
final String payloadURL = "http://echo-webhook.herokuapp.com:80/" + uniqueId + "/";
|
||||||
final Integer hookId = this.hookHelper.createHook(payloadURL);
|
final Integer hookId = this.hookHelper.createHook(payloadURL);
|
||||||
Assertions.assertNotNull(hookId);
|
Assertions.assertNotNull(hookId);
|
||||||
final Integer createdOfficeID = this.officeHelper.createOffice("01 January 2012");
|
final Integer createdOfficeID = this.officeHelper.createOffice("01 January 2012");
|
||||||
Assertions.assertNotNull(createdOfficeID);
|
Assertions.assertNotNull(createdOfficeID);
|
||||||
try {
|
try {
|
||||||
|
// sleep for a three seconds after each failure to increase the likelihood of the previous request for
|
||||||
/**
|
// creating office completing
|
||||||
* sleep for a three seconds after each failure to increase the likelihood of the previous request for
|
|
||||||
* creating office completing
|
|
||||||
**/
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
try {
|
try {
|
||||||
final String json = RestAssured.get(payloadURL.replace("?", "")).asString();
|
final String json = RestAssured.get(payloadURL.replace("?", "")).asString();
|
||||||
@@ -98,12 +93,11 @@ public class HookIntegrationTest {
|
|||||||
} finally {
|
} finally {
|
||||||
this.hookHelper.deleteHook(hookId.longValue());
|
this.hookHelper.deleteHook(hookId.longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createUpdateAndDeleteHook() {
|
public void createUpdateAndDeleteHook() {
|
||||||
final String payloadURL = "http://echo-webhook.herokuapp.com:80/Z7RXoCBdLSFMDrpn?";
|
final String payloadURL = "http://echo-webhook.herokuapp.com:80/Z7RXoCBdLSFMDrpn/";
|
||||||
final String updateURL = "http://localhost";
|
final String updateURL = "http://localhost";
|
||||||
|
|
||||||
Long hookId = this.hookHelper.createHook(payloadURL).longValue();
|
Long hookId = this.hookHelper.createHook(payloadURL).longValue();
|
||||||
@@ -116,6 +110,5 @@ public class HookIntegrationTest {
|
|||||||
this.hookHelper.deleteHook(hookId);
|
this.hookHelper.deleteHook(hookId);
|
||||||
this.hookHelper.verifyDeleteHook(hookId);
|
this.hookHelper.verifyDeleteHook(hookId);
|
||||||
LOG.info("---------------------SUCCESSFULLY DELETED AND VERIFIED HOOK------------------------- {}", hookId);
|
LOG.info("---------------------SUCCESSFULLY DELETED AND VERIFIED HOOK------------------------- {}", hookId);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user