FINERACT-1241-elastic-web-hook-update (#1488)
This commit is contained in:
@@ -79,7 +79,8 @@ dependencies {
|
|||||||
'io.swagger.core.v3:swagger-annotations',
|
'io.swagger.core.v3:swagger-annotations',
|
||||||
'org.webjars:webjars-locator-core',
|
'org.webjars:webjars-locator-core',
|
||||||
|
|
||||||
'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.1.0'
|
'com.google.cloud.sql:mysql-socket-factory-connector-j-8:1.1.0',
|
||||||
|
'com.squareup.retrofit2:converter-gson'
|
||||||
)
|
)
|
||||||
implementation ('org.apache.activemq:activemq-broker') {
|
implementation ('org.apache.activemq:activemq-broker') {
|
||||||
exclude group: 'org.apache.geronimo.specs'
|
exclude group: 'org.apache.geronimo.specs'
|
||||||
|
|||||||
+83
-13
@@ -18,8 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.commands.service;
|
package org.apache.fineract.commands.service;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.apache.fineract.batch.exception.ErrorHandler;
|
||||||
|
import org.apache.fineract.batch.exception.ErrorInfo;
|
||||||
import org.apache.fineract.commands.domain.CommandSource;
|
import org.apache.fineract.commands.domain.CommandSource;
|
||||||
import org.apache.fineract.commands.domain.CommandSourceRepository;
|
import org.apache.fineract.commands.domain.CommandSourceRepository;
|
||||||
import org.apache.fineract.commands.domain.CommandWrapper;
|
import org.apache.fineract.commands.domain.CommandWrapper;
|
||||||
@@ -38,6 +45,8 @@ import org.apache.fineract.infrastructure.hooks.event.HookEvent;
|
|||||||
import org.apache.fineract.infrastructure.hooks.event.HookEventSource;
|
import org.apache.fineract.infrastructure.hooks.event.HookEventSource;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
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.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -46,6 +55,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
@Service
|
@Service
|
||||||
public class SynchronousCommandProcessingService implements CommandProcessingService {
|
public class SynchronousCommandProcessingService implements CommandProcessingService {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SynchronousCommandProcessingService.class);
|
||||||
private PlatformSecurityContext context;
|
private PlatformSecurityContext context;
|
||||||
private final ApplicationContext applicationContext;
|
private final ApplicationContext applicationContext;
|
||||||
private final ToApiJsonSerializer<Map<String, Object>> toApiJsonSerializer;
|
private final ToApiJsonSerializer<Map<String, Object>> toApiJsonSerializer;
|
||||||
@@ -80,7 +90,14 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
|
|
||||||
final NewCommandSourceHandler handler = findCommandHandler(wrapper);
|
final NewCommandSourceHandler handler = findCommandHandler(wrapper);
|
||||||
|
|
||||||
final CommandProcessingResult result = handler.processCommand(command);
|
final CommandProcessingResult result;
|
||||||
|
try {
|
||||||
|
result = handler.processCommand(command);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// publish error event
|
||||||
|
publishErrorEvent(wrapper, command, t);
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
|
||||||
final AppUser maker = this.context.authenticatedUser(wrapper);
|
final AppUser maker = this.context.authenticatedUser(wrapper);
|
||||||
|
|
||||||
@@ -125,7 +142,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
}
|
}
|
||||||
result.setRollbackTransaction(null);
|
result.setRollbackTransaction(null);
|
||||||
|
|
||||||
publishEvent(wrapper.entityName(), wrapper.actionName(), result);
|
publishEvent(wrapper.entityName(), wrapper.actionName(), command, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -206,18 +223,71 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
return rollbackTransaction;
|
return rollbackTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishEvent(final String entityName, final String actionName, final CommandProcessingResult result) {
|
private void publishErrorEvent(CommandWrapper wrapper, JsonCommand command, Throwable t) {
|
||||||
|
|
||||||
final String authToken = ThreadLocalContextUtil.getAuthToken();
|
ErrorInfo ex;
|
||||||
final String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
if (t instanceof RuntimeException) {
|
||||||
final AppUser appUser = this.context.authenticatedUser(CommandWrapper.wrap(actionName, entityName, null, null));
|
final RuntimeException e = (RuntimeException) t;
|
||||||
|
ex = ErrorHandler.handler(e);
|
||||||
|
} else {
|
||||||
|
ex = new ErrorInfo(500, 9999, "{\"Exception\": " + t.toString() + "}");
|
||||||
|
}
|
||||||
|
|
||||||
final HookEventSource hookEventSource = new HookEventSource(entityName, actionName);
|
publishEvent(wrapper.entityName(), wrapper.actionName(), command, ex);
|
||||||
|
|
||||||
final String serializedResult = this.toApiResultJsonSerializer.serialize(result);
|
|
||||||
|
|
||||||
final HookEvent applicationEvent = new HookEvent(hookEventSource, serializedResult, tenantIdentifier, appUser, authToken);
|
|
||||||
|
|
||||||
applicationContext.publishEvent(applicationEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void publishEvent(final String entityName, final String actionName, JsonCommand command, final Object result) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
try {
|
||||||
|
final String authToken = ThreadLocalContextUtil.getAuthToken();
|
||||||
|
final String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
||||||
|
final AppUser appUser = this.context.authenticatedUser(CommandWrapper.wrap(actionName, entityName, null, null));
|
||||||
|
|
||||||
|
final HookEventSource hookEventSource = new HookEventSource(entityName, actionName);
|
||||||
|
|
||||||
|
// TODO: Add support for publishing array events
|
||||||
|
if (command.json() != null && command.json().startsWith("{")) {
|
||||||
|
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
||||||
|
Map<String, Object> myMap = gson.fromJson(command.json(), type);
|
||||||
|
|
||||||
|
Map<String, Object> reqmap = new HashMap<>();
|
||||||
|
reqmap.put("entityName", entityName);
|
||||||
|
reqmap.put("actionName", actionName);
|
||||||
|
reqmap.put("createdBy", context.authenticatedUser().getId());
|
||||||
|
reqmap.put("createdByName", context.authenticatedUser().getUsername());
|
||||||
|
reqmap.put("createdByFullName", context.authenticatedUser().getDisplayName());
|
||||||
|
|
||||||
|
reqmap.put("request", myMap);
|
||||||
|
if (result instanceof CommandProcessingResult) {
|
||||||
|
CommandProcessingResult resultCopy = CommandProcessingResult
|
||||||
|
.fromCommandProcessingResult((CommandProcessingResult) result);
|
||||||
|
|
||||||
|
reqmap.put("officeId", resultCopy.getOfficeId());
|
||||||
|
reqmap.put("clientId", resultCopy.getClientId());
|
||||||
|
resultCopy.setOfficeId(null);
|
||||||
|
reqmap.put("response", resultCopy);
|
||||||
|
} else if (result instanceof ErrorInfo) {
|
||||||
|
ErrorInfo ex = (ErrorInfo) result;
|
||||||
|
reqmap.put("status", "Exception");
|
||||||
|
|
||||||
|
Map<String, Object> errorMap = gson.fromJson(ex.getMessage(), type);
|
||||||
|
errorMap.put("errorCode", ex.getErrorCode());
|
||||||
|
errorMap.put("statusCode", ex.getStatusCode());
|
||||||
|
|
||||||
|
reqmap.put("response", errorMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
reqmap.put("timestamp", Instant.now().toString());
|
||||||
|
|
||||||
|
final String serializedResult = this.toApiResultJsonSerializer.serialize(reqmap);
|
||||||
|
|
||||||
|
final HookEvent applicationEvent = new HookEvent(hookEventSource, serializedResult, tenantIdentifier, appUser, authToken);
|
||||||
|
|
||||||
|
applicationContext.publishEvent(applicationEvent);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -44,6 +44,13 @@ public class CommandProcessingResult implements Serializable {
|
|||||||
private final Long glimId;
|
private final Long glimId;
|
||||||
private Boolean rollbackTransaction;
|
private Boolean rollbackTransaction;
|
||||||
|
|
||||||
|
public static CommandProcessingResult fromCommandProcessingResult(CommandProcessingResult commandResult) {
|
||||||
|
return new CommandProcessingResult(commandResult.commandId, commandResult.officeId, commandResult.groupId, commandResult.clientId,
|
||||||
|
commandResult.loanId, commandResult.savingsId, commandResult.resourceIdentifier, commandResult.resourceId,
|
||||||
|
commandResult.transactionId, commandResult.changes, commandResult.productId, commandResult.gsimId, commandResult.glimId,
|
||||||
|
commandResult.rollbackTransaction, commandResult.subResourceId);
|
||||||
|
}
|
||||||
|
|
||||||
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
|
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
|
||||||
final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final Long gsimId,
|
final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final Long gsimId,
|
||||||
final Long glimId, final String transactionId, final Map<String, Object> changes, final Long productId,
|
final Long glimId, final String transactionId, final Map<String, Object> changes, final Long productId,
|
||||||
|
|||||||
+2
@@ -38,6 +38,8 @@ public final class HookApiConstants {
|
|||||||
|
|
||||||
public static final String webTemplateName = "Web";
|
public static final String webTemplateName = "Web";
|
||||||
|
|
||||||
|
public static final String elasticSearchTemplateName = "Elastic Search";
|
||||||
|
|
||||||
public static final String smsTemplateName = "SMS Bridge";
|
public static final String smsTemplateName = "SMS Bridge";
|
||||||
|
|
||||||
public static final String payloadURLName = "Payload URL";
|
public static final String payloadURLName = "Payload URL";
|
||||||
|
|||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* 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.contentTypeName;
|
||||||
|
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.payloadURLName;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
|
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ElasticSearchHookProcessor implements HookProcessor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProcessorHelper processorHelper;
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
|
||||||
|
final Set<HookConfiguration> config = hook.getHookConfig();
|
||||||
|
|
||||||
|
String url = "";
|
||||||
|
String contentType = "";
|
||||||
|
|
||||||
|
for (final HookConfiguration conf : config) {
|
||||||
|
final String fieldName = conf.getFieldName();
|
||||||
|
if (fieldName.equals(payloadURLName)) {
|
||||||
|
url = conf.getFieldValue();
|
||||||
|
}
|
||||||
|
if (fieldName.equals(contentTypeName)) {
|
||||||
|
contentType = conf.getFieldValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendRequest(url, contentType, payload, entityName, actionName, tenantIdentifier, authToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void sendRequest(final String url, final String contentType, final String payload, final String entityName,
|
||||||
|
final String actionName, final String tenantIdentifier, @SuppressWarnings("unused") final String authToken) {
|
||||||
|
|
||||||
|
final String fineractEndpointUrl = System.getProperty("baseUrl");
|
||||||
|
final WebHookService service = processorHelper.createWebHookService(url);
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
final Callback callback = processorHelper.createCallback(url, payload);
|
||||||
|
|
||||||
|
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
||||||
|
final JsonObject json = new Gson().fromJson(payload, JsonObject.class);
|
||||||
|
service.sendJsonRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, json).enqueue(callback);
|
||||||
|
} else {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map = new Gson().fromJson(payload, map.getClass());
|
||||||
|
service.sendFormRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, map).enqueue(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.hooks.processor;
|
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.smsTemplateName;
|
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.smsTemplateName;
|
||||||
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.webTemplateName;
|
import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.webTemplateName;
|
||||||
|
|
||||||
@@ -44,6 +45,8 @@ public class HookProcessorProvider implements ApplicationContextAware {
|
|||||||
processor = this.applicationContext.getBean("twilioHookProcessor", TwilioHookProcessor.class);
|
processor = this.applicationContext.getBean("twilioHookProcessor", TwilioHookProcessor.class);
|
||||||
} else if (templateName.equals(webTemplateName)) {
|
} else if (templateName.equals(webTemplateName)) {
|
||||||
processor = this.applicationContext.getBean("webHookProcessor", WebHookProcessor.class);
|
processor = this.applicationContext.getBean("webHookProcessor", WebHookProcessor.class);
|
||||||
|
} else if (templateName.equals(elasticSearchTemplateName)) {
|
||||||
|
processor = this.applicationContext.getBean("elasticSearchHookProcessor", ElasticSearchHookProcessor.class);
|
||||||
} else {
|
} else {
|
||||||
processor = null;
|
processor = null;
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -34,6 +34,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public final class ProcessorHelper {
|
public final class ProcessorHelper {
|
||||||
@@ -116,7 +117,25 @@ public final class ProcessorHelper {
|
|||||||
final Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
|
final Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
|
||||||
retrofitBuilder.baseUrl(url);
|
retrofitBuilder.baseUrl(url);
|
||||||
retrofitBuilder.client(client);
|
retrofitBuilder.client(client);
|
||||||
|
retrofitBuilder.addConverterFactory(GsonConverterFactory.create());
|
||||||
final Retrofit retrofit = retrofitBuilder.build();
|
final Retrofit retrofit = retrofitBuilder.build();
|
||||||
return retrofit.create(WebHookService.class);
|
return retrofit.create(WebHookService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public Callback createCallback(final String url, String payload) {
|
||||||
|
|
||||||
|
return new Callback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(@SuppressWarnings("unused") Call call, retrofit2.Response response) {
|
||||||
|
LOG.info("URL: {} - Status: {}", url, response.code());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@SuppressWarnings("unused") Call call, Throwable t) {
|
||||||
|
LOG.error("URL: {} - Retrofit failure occured", url, t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -39,6 +39,7 @@ import javax.persistence.Table;
|
|||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
||||||
@@ -400,6 +401,17 @@ public class AppUser extends AbstractPersistableCustom implements PlatformUser {
|
|||||||
return this.username;
|
return this.username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
if (this.staff != null && StringUtils.isNotBlank(this.staff.displayName())) {
|
||||||
|
return this.staff.displayName();
|
||||||
|
}
|
||||||
|
String firstName = StringUtils.isNotBlank(this.firstname) ? this.firstname : "";
|
||||||
|
if (StringUtils.isNotBlank(this.lastname)) {
|
||||||
|
return firstName + " " + this.lastname;
|
||||||
|
}
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAccountNonExpired() {
|
public boolean isAccountNonExpired() {
|
||||||
return this.accountNonExpired;
|
return this.accountNonExpired;
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
--
|
||||||
|
-- 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('Elastic Search');
|
||||||
|
|
||||||
|
INSERT INTO m_hook_schema
|
||||||
|
(hook_template_id, field_type, field_name, placeholder, optional)
|
||||||
|
VALUES( (select id from m_hook_templates mht where name = 'Elastic Search'), 'string', 'Payload URL', 'http://<host>/<index name>/<type name>', 0);
|
||||||
|
INSERT INTO m_hook_schema
|
||||||
|
( hook_template_id, field_type, field_name, placeholder, optional)
|
||||||
|
VALUES( (select id from m_hook_templates mht where name = 'Elastic Search'), 'string', 'Content Type', 'json', 0);
|
||||||
|
INSERT INTO m_hook_schema
|
||||||
|
( hook_template_id, field_type, field_name, placeholder, optional)
|
||||||
|
VALUES( (select id from m_hook_templates mht where name = 'Elastic Search'), 'string', 'Index Name', NULL, 1);
|
||||||
Reference in New Issue
Block a user