FINERACT-1277-Message-Gateway-webhook (#1801)

This commit is contained in:
Manoj
2021-08-03 18:52:38 +05:30
committed by GitHub
parent 99f640b04d
commit 2250ee1e21
5 changed files with 160 additions and 0 deletions
@@ -40,6 +40,8 @@ public final class HookApiConstants {
public static final String elasticSearchTemplateName = "Elastic Search";
public static final String httpSMSTemplateName = "Message Gateway";
public static final String smsTemplateName = "SMS Bridge";
public static final String payloadURLName = "Payload URL";
@@ -68,6 +70,8 @@ public final class HookApiConstants {
public static final String templateNameParamName = "templateName";
public static final String SMSProviderIdParamName = "SMS Provider Id";
static final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(nameParamName, displayNameParamName,
templateIdParamName, isActiveParamName, configParamName, eventsParamName, templateNameParamName));
@@ -19,6 +19,7 @@
package org.apache.fineract.infrastructure.hooks.processor;
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.elasticSearchTemplateName;
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.httpSMSTemplateName;
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.smsTemplateName;
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.webTemplateName;
@@ -47,6 +48,8 @@ public class HookProcessorProvider implements ApplicationContextAware {
processor = this.applicationContext.getBean("webHookProcessor", WebHookProcessor.class);
} else if (templateName.equals(elasticSearchTemplateName)) {
processor = this.applicationContext.getBean("elasticSearchHookProcessor", ElasticSearchHookProcessor.class);
} else if (templateName.equals(httpSMSTemplateName)) {
processor = this.applicationContext.getBean("messageGatewayHookProcessor", MessageGatewayHookProcessor.class);
} else {
processor = null;
}
@@ -0,0 +1,121 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.hooks.processor;
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.SMSProviderIdParamName;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
import org.apache.fineract.infrastructure.hooks.domain.Hook;
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
import org.apache.fineract.infrastructure.sms.domain.SmsMessage;
import org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository;
import org.apache.fineract.infrastructure.sms.scheduler.SmsMessageScheduledJobService;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
import org.apache.fineract.template.domain.Template;
import org.apache.fineract.template.domain.TemplateRepository;
import org.apache.fineract.template.service.TemplateMergeService;
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.stereotype.Service;
@Service
public class MessageGatewayHookProcessor implements HookProcessor {
private static final Logger LOG = LoggerFactory.getLogger(MessageGatewayHookProcessor.class);
private final ClientRepositoryWrapper clientRepository;
private final TemplateRepository templateRepository;
private final TemplateMergeService templateMergeService;
private final SmsMessageRepository smsMessageRepository;
private final SmsMessageScheduledJobService smsMessageScheduledJobService;
@Autowired
public MessageGatewayHookProcessor(ClientRepositoryWrapper clientRepository, TemplateRepository templateRepository,
TemplateMergeService templateMergeService, SmsMessageRepository smsMessageRepository,
SmsMessageScheduledJobService smsMessageScheduledJobService) {
this.clientRepository = clientRepository;
this.templateRepository = templateRepository;
this.templateMergeService = templateMergeService;
this.smsMessageRepository = smsMessageRepository;
this.smsMessageScheduledJobService = smsMessageScheduledJobService;
}
@Override
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) throws IOException {
final Set<HookConfiguration> config = hook.getHookConfig();
Integer SMSProviderId = null;
for (final HookConfiguration conf : config) {
final String fieldName = conf.getFieldName();
if (fieldName.equals(SMSProviderIdParamName)) {
SMSProviderId = Integer.parseInt(conf.getFieldValue());
}
}
String templateName = entityName + "_" + actionName;
// 1 : find template via mapper using entity and action
Template template;
List<Template> templates = this.templateRepository.findByTemplateMapper("SMS_template_Key", templateName);
if (templates.isEmpty()) {
// load default template if set.
template = hook.getUgdTemplate();
} else {
template = templates.get(0);
}
if (template == null) {
LOG.error("Error : {} with name {}", "Template not found", templateName);
throw new GeneralPlatformDomainRuleException("error.msg.templates.not.found", "Template not found", templateName);
}
// 2.1 : get customer details for basic template mapping
// 2.2 : cook up scope map
Type type = new TypeToken<Map<String, String>>() {}.getType();
Map<String, Object> reqMap = new Gson().fromJson(payload, type);
if (reqMap.get("clientId") != null) {
Long clientId = (Long) reqMap.get("clientId");
Client client = clientRepository.findOneWithNotFoundDetection(clientId);
reqMap.put("clientName", client.getDisplayName());
// 3: compile template using Mustache
String smsText = this.templateMergeService.compile(template, reqMap);
// 4 : send message to the url
SmsMessage smsMessage = SmsMessage.pendingSms(null, null, client, null, smsText, client.mobileNo(), null, false);
this.smsMessageRepository.save(smsMessage);
smsMessageScheduledJobService.sendTriggeredMessage(Collections.singleton(smsMessage), SMSProviderId);
}
}
}
@@ -20,8 +20,13 @@ package org.apache.fineract.template.domain;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface TemplateRepository extends JpaRepository<Template, Long> {
List<Template> findByEntityAndType(TemplateEntity entity, TemplateType templateType);
@Query("select t from Template as t left join t.mappers as m where m.mapperkey = :mapperkey and m.mappervalue = :mappervalue")
List<Template> findByTemplateMapper(@Param("mapperkey") String mapperkey, @Param("mappervalue") String mappervalue);
}
@@ -0,0 +1,27 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
INSERT INTO m_hook_templates
( name)
VALUES('Message Gateway');
INSERT INTO m_hook_schema
(hook_template_id, field_type, field_name, placeholder, optional)
VALUES( (select id from m_hook_templates where name = 'Message Gateway'), 'string', 'SMS Provider Id', NULL, 0);;